#include #include #include //for memmove #include #include #include #include "introspect.h" #include "date.h" using namespace std; //The is_memmovable member of class __copy_traits is a typedef for __true or __false. struct __either {}; struct __true : public __either {}; struct __false: public __either {}; /* struct __copy_traits takes a data type T and tells us if a variable of that type can be copied with memmove. If so, the is_memmovable member of __copy_traits will be a typedef for __true; otherwise it will be a typedef for __false. */ template struct __copy_traits { typedef __false is_memmovable; }; template struct __copy_traits { //partial specialization typedef __true is_memmovable; }; template struct __copy_traits { //same as above, but with const typedef __true is_memmovable; }; template <> struct __copy_traits {typedef __true is_memmovable;}; template <> struct __copy_traits {typedef __true is_memmovable;}; //etc. template <> struct __copy_traits {typedef __true is_memmovable;}; template <> struct __copy_traits {typedef __true is_memmovable;}; template <> struct __copy_traits {typedef __true is_memmovable;}; //Etc.: define a specialization for each type T that can be copied with memmove. template OUTPUT __my_copy(INPUT first, INPUT last, OUTPUT result, __either) { cout << "can't use memmove\n"; for (; first != last; ++first, ++result) { *result = *first; } return result; } template T *__my_copy(T *first, T *last, T* result, __true) { cout << "memmove with read/write source\n"; memmove(result, first, (last - first) * sizeof (T)); return result + (last - first); } template //same as above, but with const's T *__my_copy(const T *first, const T *last, T* result, __true) { cout << "memmove with read-only source\n"; memmove(result, first, (last - first) * sizeof (T)); return result + (last - first); } template inline OUTPUT my_copy(INPUT first, INPUT last, OUTPUT result) { typedef typename iterator_traits::value_type value_type; typedef typename __copy_traits::is_memmovable is_memmovable; return __my_copy(first, last, result, is_memmovable()); } int main() { const date source1[] = { date(date::july, 4, 1776), date(date::october, 29, 1929), date(date::december, 7, 1941) }; const size_t n1 = sizeof source1 / sizeof source1[0]; vector v(source1, source1 + n1); my_copy(v.begin(), v.end(), ostream_iterator(cout, "\n")); cout << "\n"; const size_t n2 = 3; const introspect source2[n2]; introspect dest2[n2]; my_copy(source2, source2 + n2, dest2); copy(dest2, dest2 + n2, ostream_iterator(cout, "\n")); cout << "\n"; const size_t n3 = n1; date dest3[n3]; my_copy(source1, source1 + n3, dest3); copy(dest3, dest3 + n3, ostream_iterator(cout, "\n")); cout << "\n"; date source4[] = { date(date::july, 20, 1969), date(date::september, 11, 2001), date() }; const size_t n4 = sizeof source4 / sizeof source4[0]; date dest4[n4]; my_copy(source4, source4 + n4, dest4); copy(dest4, dest4 + n4, ostream_iterator(cout, "\n")); return EXIT_SUCCESS; }