Boost logo

Boost :

From: John Maddock (John_Maddock_at_[hidden])
Date: 2000-10-22 05:51:17


Jesse,

>Thanks for pointing this out (I was thinking of using code like this at
>work :-)). The fix is pretty easy of course:

You may want to look at the DDJ type traits article (in
libs/utility/c++_type_traits.htm) as that also has an optimised copy like
yours:

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);
}

-John.


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