Listing 8

#include <type_traits>
#include <iostream>
using std::tr1::has_trivial_assign;
using std::tr1::false_type; using std::tr1::true_type;
using std::cout;

template <class Ty>
Ty *do_copy(const Ty *first, const Ty *last, Ty *dest,
  const true_type&)
  { // copy with memcpy
  cout << "using memcpy\n";
  unsigned n = last - first;
  memcpy(dest, first, n * sizeof(Ty));
  return dest + n;
  }
template <class Ty>
Ty *do_copy(const Ty *first, const Ty *last, Ty *dest,
  const false_type&)
  { // copy element by element
  cout << "using element copy\n";
  while (first != last)
    *dest++ = *first++;
  return dest;
  }
template <class Ty>
Ty *copy(const Ty *first, const Ty *last, Ty *dest)
  { // dispatch based on trivial assignment
  return do_copy(first, last, dest, has_trivial_assign<Ty>());
  }
struct S
  { // struct without trivial assignment
  S& operator=(const S& right)
    {
    return *this;
    }
  };
int main()
  { // demonstrate use of has_trivial_assign
  int int_data[20];
  int int_copy[20];
  copy(int_data, int_data + 20, int_copy);
  S s_data[20];
  S s_copy[20];
  copy(s_data, s_data + 20, s_copy);
  return 0;
  }