Martin Sebor wrote: > >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?
I'm just grouping closely related traits. >> rw/_meta_arr.h >> * __rw_rank >> * __rw_extent >> * __rw_is_array >> * __rw_remove_extent >> * __rw_remove_all_extents As an example, the array traits above are all closely related and their implementations are similar. There are five traits, and those traits span three sections of the standard. I'm open to doing some type of grouping, we just need to understand how we want to group them and then how we want to name the files. >> >>>> >>>>> * 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. I don't really see the motivation, but it is obvious that the committee thought it was important for the standard traits to do so, so we should probably follow suit in our internal implementation. If we did decide to do this then we would probably want our own write __rw_integral_constant and use that internally to avoid namespace pollution? Then I'd assume we'd want something like the following example for is_const... template <class T, T v> struct __rw_integral_constant { static const T value = v; typedef T value_type; typedef integral_constant<T,v> type; }; template <class T> struct __rw_is_const_impl { enum { _C_value = 0 }; }; template <class T> struct __rw_is_const_impl<const T> { enum { _C_value = 1 }; }; template <class T> struct __rw_is_const : __rw_integral_constant<bool, __rw_is_const_impl<T>::_C_value> { }; template <class T, T v> struct integral_constant : __rw_integral_constant<T,v> { }; template <class T> struct is_const : integral_constant<bool, __rw_is_const<T>::value> { }; >> >>> 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; Yes, if we go with the above approach then this problem just disappears for any trait inheriting from __rw_integral_constant. For the other types I can just expose the names that the standard defines. I'm okay with that if you think that the motivation is there. > >Martin >