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;
};
//this is for all pointer type
template <typename T>
struct remove_const_impl
{
typedef typename remove_const_helper<
typename cv_traits_imp<T*>::unqualified_type
, ::boost::is_volatile<T>::value
>::type type;
};
//a wrapper that implemented by remove_const_impl
template< typename T > struct remove_const
{typedef typename remove_const_impl<T>::type type;};
//T& to T&
template< typename T > struct remove_const<T&>
{typedef T& type;};
//T const[N] to T[N]
template<typename T, std::size_t N>
struct remove_const<T const[N]>
{typedef T type[N];};
//T volatile const[N] to T volatile[N]
template<typename T, std::size_t N>
struct remove_const<T const volatile[N]>
{typedef T volatile type[N];};
Expression Result Type
remove_const<int>::type int
remove_const<int const>::type int
remove_const<int const volatile>::type int volatile
remove_const<int const&>::type int const&
remove_const<int const*>::type int const*
boost::remove_cv
Any top level cv-qualifier will be removed. See cv_traits_imp in boost::remove_const.
//a wrapper that implemented by remove_const_impl
template< typename T > struct remove_cv
{typedef typename cv_traits_imp<T*>::unqualified_type type;};
//T& to T&
template< typename T > struct remove_cv<T&>
{typedef T& type;};
//T const[N] to T[N]
template<typename T, std::size_t N>
struct remove_cv<T const[N]>
{typedef T type[N];};
//T volatile const[N] to T [N]
template<typename T, std::size_t N>
struct remove_cv<T const volatile[N]>
{typedef T type[N];};
Expression Result Type
remove_cv<int>::type int
remove_cv<int const>::type int
remove_cv<int const volatile>::type int
remove_cv<int const&>::type int const&
remove_cv<int const*>::type int const*
boost::remove_extent
If T is an array type, then removes the topmost array bound, otherwise leaves T unchanged.
//On perceiving the former content, "remove_extent" should not be hard for you.
//for non-array type
template< typename T > struct remove_extent
{typedef typename T type;};
//for 1d array
template<typename T, std::size_t N>
struct remove_extent<T[N]>
{typedef T type;};
template<typename T, std::size_t N>
struct remove_extent<T const[N]>
{typedef T const type;};
template<typename T, std::size_t N>
struct remove_extent<T volatile[N]>
{typedef T volatile type;};
template<typename T, std::size_t N>
struct remove_extent<T const volatile[N]>
{typedef T const volatile type;};
//for n-d array(n>=2)
template< typename T > struct remove_extent<T[]>
{typedef T type;};
template< typename T > struct remove_extent<T const[]>
{typedef T const type;};
template< typename T > struct remove_extent<T volatile[]>
{typedef T volatile type;};
template< typename T >
struct remove_extent<T const volatile[]>
{typedef T const volatile type;};
Expression Result Type
remove_extent<int>::type int
remove_extent<int const[2]>::type int const
remove_extent<int[2][4]>::type int[4]
remove_extent<int[][2]>::type int[2]
remove_extent<int const*>::type int const*
boost::remove_pointer
If T is a pointer type, then removes the right-most pointer, otherwise T remains unchanged.
//for non-pointer type
template< typename T > struct remove_pointer
{typedef typename T type;};
//for cv-pointer type
template< typename T > struct remove_pointer<T*>
{typedef typename T type;};
template< typename T > struct remove_pointer<T* const>
{typedef typename T type;};
template< typename T > struct remove_pointer<T* volatile>
{typedef typename T type;};
template< typename T >
struct remove_pointer<T* const volatile>
{typedef typename T type;};
Expression Result Type
remove_pointer<int>::type int
remove_pointer<int const*>::type int const
remove_pointer<int const**>::type int const*
remove_pointer<int&>::type int&
remove_pointer<int*&>::type int*&
boost::remove_reference
If T is a reference type, then removes the right-most pointer, otherwise T remains unchanged.
template< typename T > struct remove_reference
{typedef typename T type;};
template< typename T > struct remove_reference<T&>
{typedef typename T type;};
Expression Result Type
remove_reference<int>::type int
remove_reference<int const&>::type int const
remove_reference<int*>::type int*
remove_reference<int*&>::type int*
boost::remove_volatile
The same type as T, but with any top level volatile-qualifier removed. See cv_traits_imp in boost::remove_const.
//all are like remove_const
template <typename T, bool is_const>
struct remove_volatile_helper
{
typedef T type;
};
template <typename T>
struct remove_volatile_helper<T,true>
{
typedef T const type;
};
template <typename T>
struct remove_volatile_impl
{
typedef typename remove_volatile_helper<
typename cv_traits_imp<T*>::unqualified_type
, ::boost::is_const<T>::value
>::type type;
};
template< typename T >
struct remove_volatile
{typedef typename remove_volatile_impl<T>::type type;};
template< typename T >
struct remove_volatile<T&>
{typedef T& type;};
template<typename T, std::size_t N>
struct remove_volatile_impl<T volatile[N]>
{typedef T type[N];};
template<typename T, std::size_t N>
struct remove_volatile_impl<T const volatile[N]>
{typedef T const type[N];};
Expression Result Type
remove_volatile<int>::type int
remove_volatile<int volatile>::type int
remove_volatile<int const volatile>::type int const
remove_volatile<int volatile&>::type int volatile &
remove_volatile<int volatile*>::type int volatile *