Introduction
The Boost type-traits library contains a set of very specific traits classes, each of which encapsulate a single trait from the C++ type system; for example, is a type a pointer or a reference type? Or does a type have a trivial constructor, or a const-qualifier?
The type-traits classes share a unified design: each class inherits from a the type true_type if the type has the specified property and inherits from false_type otherwise.
The type-traits library also contains a set of classes that perform a specific transformation on a type; for example, they can remove a top-level const or volatile qualifier from a type. Each class that performs a transformation defines a single typedef-member type that is the result of the transformation.
The boost type_traits library is partly finished in "Macro" form, so it is difficult to read. I rearrange the source code in a clear form.
I will divide the boost type_traits library into four parts to study and publish.
Type Tranformers
boost::add_const
Add appropriate const attribute to a type.
template< typename T >
struct add_const
{typedef T const type;};
template< typename T >
struct add_const<T&>
{typedef T& type;};
template< typename T >
struct add_const<T*>
{typedef T* const type;};
template< typename T >
struct add_const<T const>
{typedef T const type;};
Expression Result type
add_const<int>::type int const
add_const<int&>::type int&
add_const<int*>::type int* const
add_const<int const>::type int const
boost::add_cv
Add appropriate const volatile attribute to a type.
The source and situation is the same as boost::add_const and omitted.
Expression Result type
add_const<int>::type int const volatile
add_const<int&>::type int&
add_const<int*>::type int* const volatile
add_const<int const>::type int const volatile
boost::add_pointer
Get the appropriate pointer type of a input type.
template <typename T>
struct add_pointer_impl
{
typedef T* type;
};
template <typename T>
struct add_pointer_impl<T&>
{
typedef T* type;
};
template <typename T>
struct add_pointer_impl<T&const>
{
typedef T* type;
};
template <typename T>
struct add_pointer_impl<T&volatile>
{
typedef T* type;
};
template <typename T>
struct add_pointer_impl<T&const volatile>
{
typedef T* type;
};
template <typename T>
struct add_pointer_impl
{
typedef typename remove_reference<T>::type no_ref_type;
typedef no_ref_type* type;
};
template<typename T>
struct add_pointer
{
typedef typename add_pointer_impl<T>::type type;
};
Expression Result Type
add_pointer<int>::type int*
add_pointer<int const&>::type int const*
add_pointer<int*>::type int**
add_pointer<int*&>::type int**
boost::add_reference
If T is not a reference type then T&, otherwise T.
Note that C++ does not support reference to reference.
//T is a non-reference type, T& is the result
template <bool x>
struct reference_adder
{
template <typename T> struct result_
{
typedef T& type;
};
};
//T is a reference type, so T is the result
template <>
struct reference_adder<true>
{
template <typename T> struct result_
{
typedef T type;
};
};
template <typename T>
struct add_reference_impl
{
typedef typename reference_adder<::boost::is_reference<T>::value>::
template result_<T> result_struct;
typedef typename result_struct::type type;
};
//partial specialization for reference type
template< typename T >
struct add_reference_impl<T&>
{typedef T& type;};
//partial specialization for void, void const, void volatile, void const volatile
template<>
struct add_reference_impl<void>
{typedef void type;};
template<>
struct add_reference_impl<void const>
{typedef void const type;};
template<>
struct add_reference_impl<void volatile>
{typedef void volatile type;};
template<>
struct add_reference_impl<void const volatile>
{typedef void const volatile type;};
template< typename T >
struct add_reference
{
typedef typename add_reference_impl<T>::type
type;
};
Expression Result Type
add_reference<int>::type int&
add_reference<int const&>::type int const&
add_reference<int*>::type int*&
add_reference<int*&>::type int*&
boost::add_volatile
The same type as T volatile for all T.
Note that C++ does not support a volatile reference. It is meaningless.
//T to T volatile
template< typename T >
struct add_volatile
{typedef T volatile type;};
//T& to T&
template< typename T >
struct add_volatile<T&>
{typedef T& type;};
Expression Result Type
add_volatile<int>::type int volatile
add_volatile<int&>::type int&
add_volatile<int*>::type int* volatile
add_volatile<int const>::type int const volatile
boost::remove_all_extents
Remove all array attribute.
//a wrapper that provide the interface of typedef
template< typename T >
struct remove_all_extents
{typedef T type;};
//1d array to its raw type
template< typename T, std::size_t N >
struct remove_all_extents<T[N]>
{typedef typename boost::remove_all_extents<T>::type type;};
template< typename T, std::size_t N >
struct remove_all_extents<T const[N]>
{typedef typename boost::remove_all_extents<T const>::type type;};
template< typename T, std::size_t N >
struct remove_all_extents<T volatile[N]>
{typedef typename boost::remove_all_extents<T volatile>::type type;};
template< typename T, std::size_t N >
struct remove_all_extents<T const volatile[N]>
{typedef typename boost::remove_all_extents<T const volatile>::type type;};
//n-d array to (n-1)-d array(n>=2)
template< typename T >
struct remove_all_extents<T[]>
{typedef typename boost::remove_all_extents<T>::type type;};
template< typename T >
struct remove_all_extents<T const[]>
{typedef typename boost::remove_all_extents<T const>::type type;};
template< typename T >
struct remove_all_extents<T volatile[]>
{typedef typename boost::remove_all_extents<T volatile>::type type;};
template< typename T >
struct remove_all_extents<T const volatile[]>
Expression Result Type
remove_all_extents<int>::type int
remove_all_extents<int const[2]>::type int const
remove_all_extents<int[][2]>::type int
remove_all_extents<int[2][3][4]>::type int
remove_all_extents<int const*>::type int const*
boost::remove_const
Any top level const-qualifier will be removed. There is no "T const& to T&" or "T const * to T*", but "T const to T" and "T const volatile to T volatile" Are provided.
cv_traits_imp::is_const is not used in this module.
//T*, const T*, volatile T*, const volatile T* to T
template <typename T> struct cv_traits_imp {};
template <typename T>
struct cv_traits_imp<T*>
{
static const bool is_const = false;
static const bool is_volatile = false;
typedef T unqualified_type;
};
template <typename T>
struct cv_traits_imp<const T*>
{
static const bool is_const = true;
static const bool is_volatile = false;
typedef T unqualified_type;
};
template <typename T>
struct cv_traits_imp<volatile T*>
{
static const bool is_const = false;
static const bool is_volatile = true;
typedef T unqualified_type;
};
template <typename T>
struct cv_traits_imp<const volatile T*>
{
static const bool is_const = true;
static const bool is_volatile = true;
typedef T unqualified_type;
};
//non-volatile type
template <typename T, bool is_vol>
struct remove_const_helper
{
typedef T type;
};
//为了把T const volatile转换成T volatile,必须加此中间层
template <typename T>
struct remove_const_helper<T, true>
{
typedef T volatile type;
};