[/ 
  Copyright 2007 John Maddock.
  Distributed under the Boost Software License, Version 1.0.
  (See accompanying file LICENSE_1_0.txt or copy at
  http://www.boost.org/LICENSE_1_0.txt).
]

[section:transform Type Traits that Transform One Type to Another]

The following templates transform one type to another, 
based upon some well-defined rule. 
Each template has a single member called `type` that is the 
result of applying the transformation to the template argument `T`.

[*Synopsis:]

   template <class T>
   struct __add_const;

   template <class T>
   struct __add_cv;
   
   template <class T>
   struct __add_pointer;

   template <class T>
   struct __add_reference;

   template <class T>
   struct __add_volatile;

   template <class T>
   struct __decay;

   template <class T>
   struct __floating_point_promotion;

   template <class T>
   struct __integral_promotion;

   template <class T>
   struct __make_signed;

   template <class T>
   struct __make_unsigned;

   template <class T>
   struct __promote;

   template <class T>
   struct __remove_all_extents;

   template <class T>
   struct __remove_const;

   template <class T>
   struct __remove_cv;

   template <class T>
   struct __remove_extent;

   template <class T>
   struct __remove_pointer;

   template <class T>
   struct __remove_reference;

   template <class T>
   struct __remove_volatile;

[h4 Broken Compiler Workarounds:]

For all of these templates support for partial specialization of class templates is 
required to correctly implement the transformation. 
On the other hand, practice shows that many of the templates from this 
category are very useful, and often essential for implementing some 
generic libraries. Lack of these templates is often one of the major 
limiting factors in porting those libraries to compilers that do not yet 
support this language feature. As some of these compilers are going to be 
around for a while, and at least one of them is very wide-spread, 
it was decided that the library should provide workarounds where possible. 

The basic idea behind the workaround is to manually define full 
specializations of all type transformation templates for all fundamental types, 
and all their 1st and 2nd rank cv-[un]qualified derivative pointer types, and to 
provide a user-level macro that will define all the explicit specializations needed 
for any user-defined type T. 

The first part guarantees the successful compilation of something like this:

   BOOST_STATIC_ASSERT((is_same<char, remove_reference<char&>::type>::value));
   BOOST_STATIC_ASSERT((is_same<char const, remove_reference<char const&>::type>::value));
   BOOST_STATIC_ASSERT((is_same<char volatile, remove_reference<char volatile&>::type>::value));
   BOOST_STATIC_ASSERT((is_same<char const volatile, remove_reference<char const volatile&>::type>::value));
   BOOST_STATIC_ASSERT((is_same<char*, remove_reference<char*&>::type>::value));
   BOOST_STATIC_ASSERT((is_same<char const*, remove_reference<char const*&>::type>::value));
   ...
   BOOST_STATIC_ASSERT((is_same<char const volatile* const volatile* const volatile, remove_reference<char const volatile* const volatile* const volatile&>::type>::value));
   
and the second part provides the library's users with a mechanism to make the 
above code work not only for `char`, `int` or other built-in type, 
but for their own types as well:

   namespace myspace{
      struct MyClass {};
   }
   // declare this at global scope:
   BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION(myspace::MyClass)
   // transformations on myspace::MyClass now work:
   BOOST_STATIC_ASSERT((is_same<myspace::MyClass, remove_reference<myspace::MyClass&>::type>::value));
   BOOST_STATIC_ASSERT((is_same<myspace::MyClass, remove_const<myspace::MyClass const>::type>::value));
   // etc.
   
Note that the macro BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION evaluates 
to nothing on those compilers that *do* support partial specialization.

[endsect]

