4 * (C) Copyright John Maddock 1999-2005.
5 * Use, modification and distribution are subject to the
6 * Boost Software License, Version 1.0. (See accompanying file
7 * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9 * This file provides some example of type_traits usage -
10 * by "optimising" various algorithms:
12 * opt::copy - optimised for trivial copy (cf std::copy)
22 #include <boost/test/included/prg_exec_monitor.hpp>
23 #include <boost/timer.hpp>
24 #include <boost/type_traits.hpp>
34 // same semantics as std::copy
35 // calls memcpy where appropriate.
40 template<typename I1, typename I2, bool b>
41 I2 copy_imp(I1 first, I1 last, I2 out, const boost::integral_constant<bool, b>&)
53 T* copy_imp(const T* first, const T* last, T* out, const boost::true_type&)
55 memmove(out, first, (last-first)*sizeof(T));
56 return out+(last-first);
62 template<typename I1, typename I2>
63 inline I2 copy(I1 first, I1 last, I2 out)
66 // We can copy with memcpy if T has a trivial assignment operator,
67 // and if the iterator arguments are actually pointers (this last
68 // requirement we detect with overload resolution):
70 typedef typename std::iterator_traits<I1>::value_type value_type;
71 return detail::copy_imp(first, last, out, boost::has_trivial_assign<value_type>());
79 template<typename I1, typename I2>
80 inline I2 copy(I1 first, I1 last, I2 out)
82 return opt::detail::copy_imp(first, last, out, boost::false_type());
88 // define some global data:
90 const int array_size = 1000;
91 int i_array_[array_size] = {0,};
92 const int ci_array_[array_size] = {0,};
93 char c_array_[array_size] = {0,};
94 const char cc_array_[array_size] = { 0,};
96 // since arrays aren't iterators we define a set of pointer
97 // aliases into the arrays (otherwise the compiler is entitled
98 // to deduce the type passed to the template functions as
99 // T (&)[N] rather than T*).
100 int* i_array = i_array_;
101 const int* ci_array = ci_array_;
102 char* c_array = c_array_;
103 const char* cc_array = cc_array_;
105 const int iter_count = 1000000;
107 int cpp_main(int argc, char* argv[])
112 cout << "Measuring times in micro-seconds per 1000 elements processed" << endl << endl;
113 cout << "testing copy...\n"
114 "[Some standard library versions may already perform this optimisation.]" << endl;
117 opt::copy(ci_array, ci_array + array_size, i_array);
119 // time optimised version:
121 for(i = 0; i < iter_count; ++i)
123 opt::copy(ci_array, ci_array + array_size, i_array);
125 result = t.elapsed();
126 cout << "opt::copy<const int*, int*>: " << result << endl;
129 non_opt::copy(ci_array, ci_array + array_size, i_array);
131 // time non-optimised version:
133 for(i = 0; i < iter_count; ++i)
135 non_opt::copy(ci_array, ci_array + array_size, i_array);
137 result = t.elapsed();
138 cout << "non_opt::copy<const int*, int*>: " << result << endl;
141 std::copy(ci_array, ci_array + array_size, i_array);
143 // time standard version:
145 for(i = 0; i < iter_count; ++i)
147 std::copy(ci_array, ci_array + array_size, i_array);
149 result = t.elapsed();
150 cout << "std::copy<const int*, int*>: " << result << endl;
153 opt::copy(cc_array, cc_array + array_size, c_array);
155 // time optimised version:
157 for(i = 0; i < iter_count; ++i)
159 opt::copy(cc_array, cc_array + array_size, c_array);
161 result = t.elapsed();
162 cout << "opt::copy<const char*, char*>: " << result << endl;
165 non_opt::copy(cc_array, cc_array + array_size, c_array);
167 // time optimised version:
169 for(i = 0; i < iter_count; ++i)
171 non_opt::copy(cc_array, cc_array + array_size, c_array);
173 result = t.elapsed();
174 cout << "non_opt::copy<const char*, char*>: " << result << endl;
177 std::copy(cc_array, cc_array + array_size, c_array);
179 // time standard version:
181 for(i = 0; i < iter_count; ++i)
183 std::copy(cc_array, cc_array + array_size, c_array);
185 result = t.elapsed();
186 cout << "std::copy<const char*, char*>: " << result << endl;