Travis Vitek wrote:
[...]
On a related note, I wonder if it would make sense to consolidate
some of the implementation headers that we don't expect to be useful
in the rest of the library on their own (e.g., all the ctor
headers/traits).

I think it would. I'd like to consolidate these a little further. I'd
like to either put them in headers by category, something like this
[those not mentioned would go into their own header].

My initial thought was to group them based on how they are
likely to be used in the rest of the library. Another option
would be to follow the breakdown used by the standard. Your
organization doesn't seem to fall into either of these two
categories. What was your rationale for it?


  rw/_meta_cv.h
    * __rw_add_const
    * __rw_add_volatile
    * __rw_add_cv
    * __rw_is_const
    * __rw_is_volatile
    * __rw_remove_const
    * __rw_remove_volatile
    * __rw_remove_cv

  rw/_meta_trivial.h
    * __rw_is_trivial
    * __rw_has_trivial_ctor
    * __rw_has_trivial_copy
    * __rw_has_trivial_assign
    * __rw_has_trivial_dtor

  rw/_meta_nothrow.h
    * __rw_has_nothrow_ctor
    * __rw_has_nothrow_copy
    * __rw_has_nothrow_assign
    * __rw_has_nothrow_dtor

  rw/_meta_sign.h
    * __rw_is_signed
    * __rw_is_unsigned
    * __rw_make_signed
    * __rw_make_unsigned

  rw/_meta_arr.h
    * __rw_rank
    * __rw_extent
    * __rw_is_array
    * __rw_remove_extent
    * __rw_remove_all_extents

  rw/_meta_ptr.h
    * __rw_add_pointer
    * __rw_remove_pointer
    * __rw_is_pointer

  rw/_meta_ref.h
    * __rw_is_lval_ref
    * __rw_is_rval_ref
    * __rw_is_ref
    * __rw_add_lval_ref
    * __rw_add_rval_ref

  rw/_meta_member.h
    * __rw_is_mem_ptr
    * __rw_is_mem_obj_ptr
    * __rw_is_mem_fun_ptr

  rw/_meta_align.h
    * __rw_aligned_storage
    * __rw_aligned_union

  rw/_meta_decay.h
    * __rw_decay

  rw/_meta_other.h
    * __rw_enable_if
    * __rw_conditional

What do you think of this?


 *  Do the trait member (e.g., _C_type, _C_value) need to be
privatized or would it make more sense to use the required names?
I'm not sure what you're saying here. The types in the public interface all have the required names [from the
base integral_constant template].

Everything else is an internal class, and I thought that we always
needed to use privatized names for internal classes exposed in the
headers. Using names consistent with those in the public interface
doesn't buy us anything significant that I can think of, and there is no requirement that I know of saying we should.

[snip]

One reason why I asked the question was that if we derived the
standard traits from the implementation-defined ones we wouldn't
need to re-declare these members. (I now see that we don't use
derivation).

We're not allowed to. In all cases the public type is required to to
inherit 'directly or indirectly' from integral_constant<T,V>.

Right. That could be another wrinkle. Our traits won't
work with generic code that takes integral_constant<T, V>
by reference.


Another, and probably far more important reason for keeping the
names of the members the same, to make our implementation traits
look and feel like standard traits, i.e., conform to the traits
requirements. Otherwise the rest of our library won't be able
to easily use the private traits.

But this should only be an issue if we are passing around traits as
template parameters, right?

Right.


All of the scenerios I can think of we would be using __rw_enable_if or
specialization on non-type template parameters. Can you think of any
case where the name of the member would be important?

I searched the latest draft standard to see if traits were
being used anywhere in the spec but didn't get any hits.

I hadn't thought too deeply about how the traits could be
used, but I have used traits outside of enable_if. I think
its should be easy to contrive code that wouldn't work with
our approach. Let me try:

    // transforms T if it satisfies Property<T>
    // by applying Transformer<T>, otherwise leaves
    // T unchanged:

    template <class T,
              template <class> Property,
              template <class> Transformer>
    struct TransformIf;

Martin

Reply via email to