#include #include #include //for memmove #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 { 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(RANDOM first, RANDOM last, OUTPUT result, random_access_iterator_tag) { cout << "random access iterators\n"; typedef typename iterator_traits::difference_type difference_type; for (difference_type n = last - first; n > 0; --n) { *result = *first; //(*result).operator=(*first); ++first; ++result; } return result; } template OUTPUT __my_copy(INPUT first, INPUT last, OUTPUT result, input_iterator_tag) { cout << "input iterators that are not random access\n"; for (; first != last; ++first, ++result) { *result = *first; //(*result).operator=(*first); } return result; } template inline OUTPUT __my_copy(INPUT first, INPUT last, OUTPUT result, __either) { typedef typename iterator_traits::iterator_category iterator_category; return __my_copy(first, last, result, iterator_category()); } 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() { //Can be copied with memmove. const int source1[] = {10, 20, 30}; const size_t n = sizeof source1 / sizeof source1[0]; int dest1[n]; my_copy(source1, source1 + n, dest1); //Line 108 calls 94. //Can be copied with memmove. date source2[n]; date dest2[n]; my_copy(source2, source2 + n, dest2); //Line 108 calls 85. //Can't be copied with memmove: //the int's are memovable, but list iterators are not pointers. const list li(source1, source1 + n); my_copy(li.begin(), li.end(), dest1); //Line 108 calls 76; 81 calls 63. //Can't be copied with memmove: //the iterators are pointers, but introspect's are not memmovable. const introspect source4[n]; introspect dest4[n]; my_copy(source4, source4 + n, dest4); //Line 108 calls 76; 81 calls 45. //Any type of pointer can be copied with memmove. const introspect *const source5[] = {source4, source4 + 1, source4 + 2}; const introspect *dest5[n]; my_copy(source5, source5 + n, dest5); //Line 108 calls 94. return EXIT_SUCCESS; }