Boost logo

Boost :

Subject: [boost] A proposal for the creation of a new module, Core Type Traits
From: Peter Dimov (lists_at_[hidden])
Date: 2015-01-07 15:20:15


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<typename
remove_cv<T>::type>::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.

In particular, note that if a developer specializes detail::is_pointer_impl,
is_pointer automatically picks up this specialization.

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;

- 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. :-)


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk