]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/type_traits/examples/copy_example.cpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / type_traits / examples / copy_example.cpp
1
2 /*
3 *
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)
8 *
9 * This file provides some example of type_traits usage -
10 * by "optimising" various algorithms:
11 *
12 * opt::copy - optimised for trivial copy (cf std::copy)
13 *
14 */
15
16 #include <iostream>
17 #include <typeinfo>
18 #include <algorithm>
19 #include <iterator>
20 #include <memory>
21
22 #include <boost/test/included/prg_exec_monitor.hpp>
23 #include <boost/timer.hpp>
24 #include <boost/type_traits.hpp>
25
26 using std::cout;
27 using std::endl;
28 using std::cin;
29
30 namespace opt{
31
32 //
33 // opt::copy
34 // same semantics as std::copy
35 // calls memcpy where appropriate.
36 //
37
38 namespace detail{
39
40 template<typename I1, typename I2, bool b>
41 I2 copy_imp(I1 first, I1 last, I2 out, const boost::integral_constant<bool, b>&)
42 {
43 while(first != last)
44 {
45 *out = *first;
46 ++out;
47 ++first;
48 }
49 return out;
50 }
51
52 template<typename T>
53 T* copy_imp(const T* first, const T* last, T* out, const boost::true_type&)
54 {
55 memmove(out, first, (last-first)*sizeof(T));
56 return out+(last-first);
57 }
58
59
60 }
61
62 template<typename I1, typename I2>
63 inline I2 copy(I1 first, I1 last, I2 out)
64 {
65 //
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):
69 //
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>());
72 }
73
74 } // namespace opt
75
76 namespace non_opt
77 {
78
79 template<typename I1, typename I2>
80 inline I2 copy(I1 first, I1 last, I2 out)
81 {
82 return opt::detail::copy_imp(first, last, out, boost::false_type());
83 }
84
85 }
86
87 //
88 // define some global data:
89 //
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,};
95 //
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_;
104
105 const int iter_count = 1000000;
106
107 int cpp_main(int argc, char* argv[])
108 {
109 boost::timer t;
110 double result;
111 int i;
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;
115
116 // cache load:
117 opt::copy(ci_array, ci_array + array_size, i_array);
118
119 // time optimised version:
120 t.restart();
121 for(i = 0; i < iter_count; ++i)
122 {
123 opt::copy(ci_array, ci_array + array_size, i_array);
124 }
125 result = t.elapsed();
126 cout << "opt::copy<const int*, int*>: " << result << endl;
127
128 // cache load:
129 non_opt::copy(ci_array, ci_array + array_size, i_array);
130
131 // time non-optimised version:
132 t.restart();
133 for(i = 0; i < iter_count; ++i)
134 {
135 non_opt::copy(ci_array, ci_array + array_size, i_array);
136 }
137 result = t.elapsed();
138 cout << "non_opt::copy<const int*, int*>: " << result << endl;
139
140 // cache load:
141 std::copy(ci_array, ci_array + array_size, i_array);
142
143 // time standard version:
144 t.restart();
145 for(i = 0; i < iter_count; ++i)
146 {
147 std::copy(ci_array, ci_array + array_size, i_array);
148 }
149 result = t.elapsed();
150 cout << "std::copy<const int*, int*>: " << result << endl;
151
152 // cache load:
153 opt::copy(cc_array, cc_array + array_size, c_array);
154
155 // time optimised version:
156 t.restart();
157 for(i = 0; i < iter_count; ++i)
158 {
159 opt::copy(cc_array, cc_array + array_size, c_array);
160 }
161 result = t.elapsed();
162 cout << "opt::copy<const char*, char*>: " << result << endl;
163
164 // cache load:
165 non_opt::copy(cc_array, cc_array + array_size, c_array);
166
167 // time optimised version:
168 t.restart();
169 for(i = 0; i < iter_count; ++i)
170 {
171 non_opt::copy(cc_array, cc_array + array_size, c_array);
172 }
173 result = t.elapsed();
174 cout << "non_opt::copy<const char*, char*>: " << result << endl;
175
176 // cache load:
177 std::copy(cc_array, cc_array + array_size, c_array);
178
179 // time standard version:
180 t.restart();
181 for(i = 0; i < iter_count; ++i)
182 {
183 std::copy(cc_array, cc_array + array_size, c_array);
184 }
185 result = t.elapsed();
186 cout << "std::copy<const char*, char*>: " << result << endl;
187
188 return 0;
189 }
190
191
192
193
194
195
196
197