C++ Type Traits
by John Maddock and Steve Cleary

Listing One
template <typename T> 
struct is_void
{ static const bool value = false; };

template <> 
struct is_void<void>
{ static const bool value = true; };

Listing Two
template <typename T> 
struct is_pointer 
{ static const bool value = false; };
 
template <typename T> 
struct is_pointer<T*> 
{ static const bool value = true; };

Listing Three
template <typename T> 
struct remove_bounds
{ typedef T type; };

template <typename T, std::size_t N> 
struct remove_bounds<T[N]>
{ typedef T type; };

Listing Four
namespace detail{
template <bool b>
struct copier
{
   template<typename I1, typename I2>
   static I2 do_copy(I1 first, I1 last, I2 out);
};
template <bool b>
template<typename I1, typename I2>
I2 copier<b>::do_copy(I1 first, I1 last, I2 out)
{
   while(first != last)
   {
      *out = *first;
      ++out;
      ++first;
   }
   return out;
}
template <>
struct copier<true>
{
   template<typename I1, typename I2>
   static I2* do_copy(I1* first, I1* last, I2* out)
   {
      memcpy(out, first, (last-first)*sizeof(I2));
      return out+(last-first);
   }
};
}
template<typename I1, typename I2>
inline I2 copy(I1 first, I1 last, I2 out)
{
   typedef typename 
    boost::remove_cv<
     typename std::iterator_traits<I1>
      ::value_type>::type v1_t;
   typedef typename 
    boost::remove_cv<
     typename std::iterator_traits<I2>
      ::value_type>::type v2_t;
   enum{ can_opt = 
      boost::is_same<v1_t, v2_t>::value
      && boost::is_pointer<I1>::value
      && boost::is_pointer<I2>::value
      && boost::
      has_trivial_assign<v1_t>::value 
   };
   return detail::copier<can_opt>::
      do_copy(first, last, out);
}

Listing Five
template <typename T1, typename T2> 
struct pair 
{
  typedef T1 first_type;
  typedef T2 second_type;

  T1 first;
  T2 second;

  pair(const T1 & nfirst, const T2 & nsecond)
  :first(nfirst), second(nsecond) { }
};

Listing Six
template <typename T1, typename T2> 
struct pair 
{
  typedef T1 first_type;
  typedef T2 second_type;

  T1 first;
  T2 second;

  pair(boost::add_reference<const T1>::type nfirst,
       boost::add_reference<const T2>::type nsecond)
  :first(nfirst), second(nsecond) { }
};





2

