Le 07/01/15 21:20, Peter Dimov a écrit :
This is a more formal statement of the same suggestion I've already given in other threads.
Currently, library developers who need type traits functionality face a choice: either to use the TypeTraits library, and make their libraries dependent on MPL, Preprocessor, TypeOf and Utility, or to duplicate its functionality locally.
Similarly, developers who want to specialize a type trait on a type of theirs, even a trivial empty struct, need to include the TypeTraits headers for the traits to be specialized, which brings in MPL and Preprocessor on a header-level, and makes their module dependent on TypeTraits and its dependencies listed above.
Local replication, as in Boost.Move, rightly attracts charges of code duplication, with the associated potential maintenance problems when the implementations diverge.
These two problems could be avoided if we were to have core type traits whose interface consisted solely of a member integral constant called "value", without any other required members or base classes, and which were only allowed to depend on Config or StaticAssert.
This solves the second problem because it will then be possible for a developer to specialize a trait, such as is_pod, by using a forward declaration of the form
template< class T > struct is_pod;
in the appropriate namespace, like boost::core_type_traits, and then adding his specializations:
template<> struct is_pod< blank > { BOOST_STATIC_CONSTANT( bool, value = true ); };
without including ANY additional headers.
If we look at the current implementation of Boost.TypeTraits, for example is_pointer, we see this:
template< typename T > struct is_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = (::boost::type_traits::ice_and< ::boost::detail::is_pointer_helper
::value , ::boost::type_traits::ice_not< ::boost::is_member_pointer<T>::value >::value >::value) ); }; in namespace detail, and then this:
BOOST_TT_AUX_BOOL_TRAIT_DEF1(is_pointer,T,::boost::detail::is_pointer_impl<T>::value)
which takes care of everything else.
Note that is_pointer_impl is EXACTLY what we need! It is the core implementation of the trait and exposes only ::value and nothing else. The full-featured boost::is_pointer is built on top of that.
If detail::is_pointer_impl was called core_type_traits::is_pointer, this would immediately take care of the two problems at the top of this post, while not affecting the users of Boost.TypeTraits in any way. I like this proposal. However, I'm wondering if BOOST_TT_AUX_BOOL_TRAIT_DEF1 is so heavy so that it can not be on CoreTypeTraitts?
But how this split would get ride of the MPL dependency? I suspect that you want common_type to stay in Boost.TypeTraits so that the Boost.CoreTypeTraits doesn't depend on Boost.Typeof. Couldn't Boost.TypeOf go also to CoreTypeTraits?
In particular, note that if a developer specializes detail::is_pointer_impl, is_pointer automatically picks up this specialization.
You surely mean core_type_traits::is_pointer.
Therefore,
I propose that a new module, libs/core_type_traits, is created, which:
- provides core type traits that only expose a member integral constant called "value" as part of its documented interface and nothing else;
- allows these traits to be forward declared, without requiring header inclusion;
- is not allowed to depend on anything except Config or StaticAssert; Could CoreTypeTraits depend on Core? Boost.Preprocessor?
- is the place to which TypeTraits's is_pointer_impls gradually migrate, along with their tests.
This
- solves the dependency problems some of us are facing,
- avoids unnecessary code duplication,
- still allows type trait specialization, with clients of both libraries automatically picking up the specialization,
- is backward compatible with respect to existing uses of Boost.TypeTraits because the new library will contain the same code and the same tests.
Thank you for your attention. :-)
Thanks for resurecting this issue, Vicente