]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/type_traits/doc/examples.qbk
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / type_traits / doc / examples.qbk
1 [/
2 Copyright 2007 John Maddock.
3 Distributed under the Boost Software License, Version 1.0.
4 (See accompanying file LICENSE_1_0.txt or copy at
5 http://www.boost.org/LICENSE_1_0.txt).
6 ]
7
8 [section:examples Examples]
9
10 [section:copy An Optimized Version of std::copy]
11
12 Demonstrates a version of `std::copy` that uses `__has_trivial_assign` to
13 determine whether to use `memcpy` to optimise the copy operation
14 (see [@../../examples/copy_example.cpp copy_example.cpp]):
15
16 //
17 // opt::copy
18 // same semantics as std::copy
19 // calls memcpy where appropriate.
20 //
21
22 namespace detail{
23
24 template<typename I1, typename I2, bool b>
25 I2 copy_imp(I1 first, I1 last, I2 out, const boost::__integral_constant<bool, b>&)
26 {
27 while(first != last)
28 {
29 *out = *first;
30 ++out;
31 ++first;
32 }
33 return out;
34 }
35
36 template<typename T>
37 T* copy_imp(const T* first, const T* last, T* out, const boost::__true_type&)
38 {
39 memmove(out, first, (last-first)*sizeof(T));
40 return out+(last-first);
41 }
42
43
44 }
45
46 template<typename I1, typename I2>
47 inline I2 copy(I1 first, I1 last, I2 out)
48 {
49 //
50 // We can copy with memcpy if T has a trivial assignment operator,
51 // and if the iterator arguments are actually pointers (this last
52 // requirement we detect with overload resolution):
53 //
54 typedef typename std::iterator_traits<I1>::value_type value_type;
55 return detail::copy_imp(first, last, out, boost::__has_trivial_assign<value_type>());
56 }
57
58
59 [endsect]
60
61 [section:fill An Optimised Version of std::fill]
62
63 Demonstrates a version of `std::fill` that uses `__has_trivial_assign` to
64 determine whether to use `memset` to optimise the fill operation
65 (see [@../../examples/fill_example.cpp fill_example.cpp]):
66
67 //
68 // fill
69 // same as std::fill, but uses memset where appropriate
70 //
71 namespace detail{
72
73 template <typename I, typename T, bool b>
74 void do_fill(I first, I last, const T& val, const boost::__integral_constant<bool, b>&)
75 {
76 while(first != last)
77 {
78 *first = val;
79 ++first;
80 }
81 }
82
83 template <typename T>
84 void do_fill(T* first, T* last, const T& val, const boost::__true_type&)
85 {
86 std::memset(first, val, last-first);
87 }
88
89 }
90
91 template <class I, class T>
92 inline void fill(I first, I last, const T& val)
93 {
94 //
95 // We can do an optimised fill if T has a trivial assignment
96 // operator and if it's size is one:
97 //
98 typedef boost::__integral_constant<bool,
99 ::boost::__has_trivial_assign<T>::value && (sizeof(T) == 1)> truth_type;
100 detail::do_fill(first, last, val, truth_type());
101 }
102
103
104 [endsect]
105
106 [section:destruct An Example that Omits Destructor Calls For Types with Trivial Destructors]
107
108 Demonstrates a simple algorithm that uses `__has_trivial_destruct` to
109 determine whether to destructors need to be called
110 (see [@../../examples/trivial_destructor_example.cpp trivial_destructor_example.cpp]):
111
112 //
113 // algorithm destroy_array:
114 // The reverse of std::unitialized_copy, takes a block of
115 // initialized memory and calls destructors on all objects therein.
116 //
117
118 namespace detail{
119
120 template <class T>
121 void do_destroy_array(T* first, T* last, const boost::__false_type&)
122 {
123 while(first != last)
124 {
125 first->~T();
126 ++first;
127 }
128 }
129
130 template <class T>
131 inline void do_destroy_array(T* first, T* last, const boost::__true_type&)
132 {
133 }
134
135 } // namespace detail
136
137 template <class T>
138 inline void destroy_array(T* p1, T* p2)
139 {
140 detail::do_destroy_array(p1, p2, ::boost::__has_trivial_destructor<T>());
141 }
142
143
144 [endsect]
145
146 [section:iter An improved Version of std::iter_swap]
147
148 Demonstrates a version of `std::iter_swap` that use type traits to
149 determine whether an it's arguments are proxy iterators or not,
150 if they're not then it just does a `std::swap` of it's dereferenced
151 arguments (the
152 same as `std::iter_swap` does), however if they are proxy iterators
153 then takes special care over the swap to ensure that the algorithm
154 works correctly for both proxy iterators, and even iterators of
155 different types
156 (see [@../../examples/iter_swap_example.cpp iter_swap_example.cpp]):
157
158 //
159 // iter_swap:
160 // tests whether iterator is a proxy iterator or not, and
161 // uses optimal form accordingly:
162 //
163 namespace detail{
164
165 template <typename I>
166 static void do_swap(I one, I two, const boost::__false_type&)
167 {
168 typedef typename std::iterator_traits<I>::value_type v_t;
169 v_t v = *one;
170 *one = *two;
171 *two = v;
172 }
173 template <typename I>
174 static void do_swap(I one, I two, const boost::__true_type&)
175 {
176 using std::swap;
177 swap(*one, *two);
178 }
179
180 }
181
182 template <typename I1, typename I2>
183 inline void iter_swap(I1 one, I2 two)
184 {
185 //
186 // See is both arguments are non-proxying iterators,
187 // and if both iterator the same type:
188 //
189 typedef typename std::iterator_traits<I1>::reference r1_t;
190 typedef typename std::iterator_traits<I2>::reference r2_t;
191
192 typedef boost::__integral_constant<bool,
193 ::boost::__is_reference<r1_t>::value
194 && ::boost::__is_reference<r2_t>::value
195 && ::boost::__is_same<r1_t, r2_t>::value> truth_type;
196
197 detail::do_swap(one, two, truth_type());
198 }
199
200
201 [endsect]
202
203 [section:to_double Convert Numeric Types and Enums to double]
204
205 Demonstrates a conversion of
206 [@../../../../libs/numeric/conversion/doc/html/boost_numericconversion/definitions.html#boost_numericconversion.definitions.numeric_types
207 Numeric Types]
208 and enum types to double:
209
210 template<class T>
211 inline double to_double(T const& value)
212 {
213 typedef typename boost::promote<T>::type promoted;
214 return boost::numeric::converter<double,promoted>::convert(value);
215 }
216
217 [endsect]
218
219 [section:improved_min Improving std::min with common_type]
220
221 An improved `std::min` function could be written like this:
222
223 template <class T, class U>
224 typename __common_type<T, U>::type min(T t, U u)
225 {
226 return t < u ? t : u;
227 }
228
229 And now expressions such as:
230
231 min(1, 2.0)
232
233 will actually compile and return the correct type!
234
235 [endsect]
236 [endsect]
237