John Maddock wrote:
The idea of artificially splitting up type_traits seems pretty abhorrent to be honest.
Based on that description I suspect that I didn't explain myself clearly enough, as I don't believe the refactoring is artificial at all. A new module, core type traits, is created, with its contents corresponding more or less to the standard type traits, minus the integral_constant requirement, plus the requirement to not depend on anything non-core, and hence, minus common_type. This module contains, to take an example, namespace boost { namespace core_type_traits { template<class T> struct is_pointer { BOOST_STATIC_CONSTANT( bool, value = false ); }; template<class T> struct is_pointer { BOOST_STATIC_CONSTANT( bool, value = true ); }; } // core_type_traits } // boost (workarounds omitted for brevity.) A valid alternative implementation for it is: namespace boost { namespace core_type_traits { using std::is_pointer; } } boost::is_pointer is not removed from type traits. It is just implemented as: namespace boost { template<class T> struct is_pointer: public mpl::bool_< core_type_traits::is_pointer<T>::value > { BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_pointer,(T)) }; BOOST_TT_AUX_TEMPLATE_ARITY_SPEC(1,is_pointer) } // boost That is, the MPL support is decoupled from the actual logic. Currently, is_pointer happens to be implemented in exactly such a way, except that the core part is called is_pointer_impl. Now a type can specialize core_type_traits::is_pod so that ::value is true and all existing uses of boost::is_pod will see mpl::true_. I honestly don't see what do you consider artificial in such an approach. It's basic layering.