Chris@102
|
1 //////////////////////////////////////////////////////////////////////////////
|
Chris@102
|
2 //
|
Chris@102
|
3 // (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
|
Chris@102
|
4 // Software License, Version 1.0. (See accompanying file
|
Chris@102
|
5 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@102
|
6 //
|
Chris@102
|
7 // See http://www.boost.org/libs/container for documentation.
|
Chris@102
|
8 //
|
Chris@102
|
9 //////////////////////////////////////////////////////////////////////////////
|
Chris@102
|
10 #ifndef BOOST_CONTAINER_DETAIL_UTILITIES_HPP
|
Chris@102
|
11 #define BOOST_CONTAINER_DETAIL_UTILITIES_HPP
|
Chris@102
|
12
|
Chris@102
|
13 #ifndef BOOST_CONFIG_HPP
|
Chris@102
|
14 # include <boost/config.hpp>
|
Chris@102
|
15 #endif
|
Chris@102
|
16
|
Chris@102
|
17 #if defined(BOOST_HAS_PRAGMA_ONCE)
|
Chris@102
|
18 # pragma once
|
Chris@102
|
19 #endif
|
Chris@102
|
20
|
Chris@102
|
21 // container
|
Chris@102
|
22 #include <boost/container/allocator_traits.hpp>
|
Chris@102
|
23 // container/detail
|
Chris@102
|
24 #include <boost/container/detail/iterator.hpp>
|
Chris@102
|
25 #include <boost/container/detail/iterator_to_raw_pointer.hpp>
|
Chris@102
|
26 #include <boost/container/detail/mpl.hpp>
|
Chris@102
|
27 #include <boost/container/detail/type_traits.hpp>
|
Chris@102
|
28 // move
|
Chris@102
|
29 #include <boost/move/adl_move_swap.hpp>
|
Chris@102
|
30 #include <boost/move/iterator.hpp>
|
Chris@102
|
31 #include <boost/move/utility_core.hpp>
|
Chris@102
|
32 // other
|
Chris@102
|
33 #include <boost/core/no_exceptions_support.hpp>
|
Chris@102
|
34 // std
|
Chris@102
|
35 #include <cstring> //for emmove/memcpy
|
Chris@102
|
36
|
Chris@102
|
37 namespace boost {
|
Chris@102
|
38 namespace container {
|
Chris@102
|
39 namespace container_detail {
|
Chris@102
|
40
|
Chris@102
|
41 template<class I>
|
Chris@102
|
42 struct are_elements_contiguous
|
Chris@102
|
43 {
|
Chris@102
|
44 static const bool value = false;
|
Chris@102
|
45 };
|
Chris@102
|
46
|
Chris@102
|
47 /////////////////////////
|
Chris@102
|
48 // raw pointers
|
Chris@102
|
49 /////////////////////////
|
Chris@102
|
50
|
Chris@102
|
51 template<class T>
|
Chris@102
|
52 struct are_elements_contiguous<T*>
|
Chris@102
|
53 {
|
Chris@102
|
54 static const bool value = true;
|
Chris@102
|
55 };
|
Chris@102
|
56
|
Chris@102
|
57 /////////////////////////
|
Chris@102
|
58 // move iterators
|
Chris@102
|
59 /////////////////////////
|
Chris@102
|
60
|
Chris@102
|
61 template<class It>
|
Chris@102
|
62 struct are_elements_contiguous< ::boost::move_iterator<It> >
|
Chris@102
|
63 : are_elements_contiguous<It>
|
Chris@102
|
64 {};
|
Chris@102
|
65
|
Chris@102
|
66 /////////////////////////
|
Chris@102
|
67 // predeclarations
|
Chris@102
|
68 /////////////////////////
|
Chris@102
|
69
|
Chris@102
|
70 #ifndef BOOST_CONTAINER_VECTOR_ITERATOR_IS_POINTER
|
Chris@102
|
71
|
Chris@102
|
72 template<class Pointer>
|
Chris@102
|
73 class vector_iterator;
|
Chris@102
|
74
|
Chris@102
|
75 template<class Pointer>
|
Chris@102
|
76 class vector_const_iterator;
|
Chris@102
|
77
|
Chris@102
|
78 #endif //BOOST_CONTAINER_VECTOR_ITERATOR_IS_POINTER
|
Chris@102
|
79
|
Chris@102
|
80 } //namespace container_detail {
|
Chris@102
|
81 } //namespace container {
|
Chris@102
|
82
|
Chris@102
|
83 namespace interprocess {
|
Chris@102
|
84
|
Chris@102
|
85 template <class PointedType, class DifferenceType, class OffsetType, std::size_t OffsetAlignment>
|
Chris@102
|
86 class offset_ptr;
|
Chris@102
|
87
|
Chris@102
|
88 } //namespace interprocess {
|
Chris@102
|
89
|
Chris@102
|
90 namespace container {
|
Chris@102
|
91
|
Chris@102
|
92 namespace container_detail {
|
Chris@102
|
93
|
Chris@102
|
94 /////////////////////////
|
Chris@102
|
95 //vector_[const_]iterator
|
Chris@102
|
96 /////////////////////////
|
Chris@102
|
97
|
Chris@102
|
98 #ifndef BOOST_CONTAINER_VECTOR_ITERATOR_IS_POINTER
|
Chris@102
|
99
|
Chris@102
|
100 template<class Pointer>
|
Chris@102
|
101 struct are_elements_contiguous<boost::container::container_detail::vector_iterator<Pointer> >
|
Chris@102
|
102 {
|
Chris@102
|
103 static const bool value = true;
|
Chris@102
|
104 };
|
Chris@102
|
105
|
Chris@102
|
106 template<class Pointer>
|
Chris@102
|
107 struct are_elements_contiguous<boost::container::container_detail::vector_const_iterator<Pointer> >
|
Chris@102
|
108 {
|
Chris@102
|
109 static const bool value = true;
|
Chris@102
|
110 };
|
Chris@102
|
111
|
Chris@102
|
112 #endif //BOOST_CONTAINER_VECTOR_ITERATOR_IS_POINTER
|
Chris@102
|
113
|
Chris@102
|
114 /////////////////////////
|
Chris@102
|
115 // offset_ptr
|
Chris@102
|
116 /////////////////////////
|
Chris@102
|
117
|
Chris@102
|
118 template <class PointedType, class DifferenceType, class OffsetType, std::size_t OffsetAlignment>
|
Chris@102
|
119 struct are_elements_contiguous< ::boost::interprocess::offset_ptr<PointedType, DifferenceType, OffsetType, OffsetAlignment> >
|
Chris@102
|
120 {
|
Chris@102
|
121 static const bool value = true;
|
Chris@102
|
122 };
|
Chris@102
|
123
|
Chris@102
|
124 template <typename I, typename O>
|
Chris@102
|
125 struct are_contiguous_and_same
|
Chris@102
|
126 {
|
Chris@102
|
127 static const bool is_same_io =
|
Chris@102
|
128 is_same< typename remove_const< typename ::boost::container::iterator_traits<I>::value_type >::type
|
Chris@102
|
129 , typename ::boost::container::iterator_traits<O>::value_type
|
Chris@102
|
130 >::value;
|
Chris@102
|
131 static const bool value = is_same_io &&
|
Chris@102
|
132 are_elements_contiguous<I>::value &&
|
Chris@102
|
133 are_elements_contiguous<O>::value;
|
Chris@102
|
134 };
|
Chris@102
|
135
|
Chris@102
|
136 template <typename I, typename O>
|
Chris@102
|
137 struct is_memtransfer_copy_assignable
|
Chris@102
|
138 {
|
Chris@102
|
139 static const bool value = are_contiguous_and_same<I, O>::value &&
|
Chris@102
|
140 container_detail::is_trivially_copy_assignable< typename ::boost::container::iterator_traits<I>::value_type >::value;
|
Chris@102
|
141 };
|
Chris@102
|
142
|
Chris@102
|
143 template <typename I, typename O>
|
Chris@102
|
144 struct is_memtransfer_copy_constructible
|
Chris@102
|
145 {
|
Chris@102
|
146 static const bool value = are_contiguous_and_same<I, O>::value &&
|
Chris@102
|
147 container_detail::is_trivially_copy_constructible< typename ::boost::container::iterator_traits<I>::value_type >::value;
|
Chris@102
|
148 };
|
Chris@102
|
149
|
Chris@102
|
150 template <typename I, typename O, typename R>
|
Chris@102
|
151 struct enable_if_memtransfer_copy_constructible
|
Chris@102
|
152 : enable_if_c<container_detail::is_memtransfer_copy_constructible<I, O>::value, R>
|
Chris@102
|
153 {};
|
Chris@102
|
154
|
Chris@102
|
155 template <typename I, typename O, typename R>
|
Chris@102
|
156 struct disable_if_memtransfer_copy_constructible
|
Chris@102
|
157 : enable_if_c<!container_detail::is_memtransfer_copy_constructible<I, O>::value, R>
|
Chris@102
|
158 {};
|
Chris@102
|
159
|
Chris@102
|
160 template <typename I, typename O, typename R>
|
Chris@102
|
161 struct enable_if_memtransfer_copy_assignable
|
Chris@102
|
162 : enable_if_c<container_detail::is_memtransfer_copy_assignable<I, O>::value, R>
|
Chris@102
|
163 {};
|
Chris@102
|
164
|
Chris@102
|
165 template <typename I, typename O, typename R>
|
Chris@102
|
166 struct disable_if_memtransfer_copy_assignable
|
Chris@102
|
167 : enable_if_c<!container_detail::is_memtransfer_copy_assignable<I, O>::value, R>
|
Chris@102
|
168 {};
|
Chris@102
|
169
|
Chris@102
|
170 template
|
Chris@102
|
171 <typename I, // I models InputIterator
|
Chris@102
|
172 typename F> // F models ForwardIterator
|
Chris@102
|
173 inline F memmove(I f, I l, F r) BOOST_NOEXCEPT_OR_NOTHROW
|
Chris@102
|
174 {
|
Chris@102
|
175 typedef typename boost::container::iterator_traits<I>::value_type value_type;
|
Chris@102
|
176 typename boost::container::iterator_traits<I>::difference_type n = boost::container::iterator_distance(f, l);
|
Chris@102
|
177 std::memmove((iterator_to_raw_pointer)(r), (iterator_to_raw_pointer)(f), sizeof(value_type)*n);
|
Chris@102
|
178 boost::container::iterator_advance(r, n);
|
Chris@102
|
179 return r;
|
Chris@102
|
180 }
|
Chris@102
|
181
|
Chris@102
|
182 template
|
Chris@102
|
183 <typename I, // I models InputIterator
|
Chris@102
|
184 typename F> // F models ForwardIterator
|
Chris@102
|
185 F memmove_n(I f, typename boost::container::iterator_traits<I>::difference_type n, F r) BOOST_NOEXCEPT_OR_NOTHROW
|
Chris@102
|
186 {
|
Chris@102
|
187 typedef typename boost::container::iterator_traits<I>::value_type value_type;
|
Chris@102
|
188 std::memmove((iterator_to_raw_pointer)(r), (iterator_to_raw_pointer)(f), sizeof(value_type)*n);
|
Chris@102
|
189 boost::container::iterator_advance(r, n);
|
Chris@102
|
190 return r;
|
Chris@102
|
191 }
|
Chris@102
|
192
|
Chris@102
|
193 template
|
Chris@102
|
194 <typename I, // I models InputIterator
|
Chris@102
|
195 typename F> // F models ForwardIterator
|
Chris@102
|
196 I memmove_n_source(I f, typename boost::container::iterator_traits<I>::difference_type n, F r) BOOST_NOEXCEPT_OR_NOTHROW
|
Chris@102
|
197 {
|
Chris@102
|
198 typedef typename boost::container::iterator_traits<I>::value_type value_type;
|
Chris@102
|
199 std::memmove((iterator_to_raw_pointer)(r), (iterator_to_raw_pointer)(f), sizeof(value_type)*n);
|
Chris@102
|
200 boost::container::iterator_advance(f, n);
|
Chris@102
|
201 return f;
|
Chris@102
|
202 }
|
Chris@102
|
203
|
Chris@102
|
204 template
|
Chris@102
|
205 <typename I, // I models InputIterator
|
Chris@102
|
206 typename F> // F models ForwardIterator
|
Chris@102
|
207 I memmove_n_source_dest(I f, typename boost::container::iterator_traits<I>::difference_type n, F &r) BOOST_NOEXCEPT_OR_NOTHROW
|
Chris@102
|
208 {
|
Chris@102
|
209 typedef typename boost::container::iterator_traits<I>::value_type value_type;
|
Chris@102
|
210 std::memmove((iterator_to_raw_pointer)(r), (iterator_to_raw_pointer)(f), sizeof(value_type)*n);
|
Chris@102
|
211 boost::container::iterator_advance(f, n);
|
Chris@102
|
212 boost::container::iterator_advance(r, n);
|
Chris@102
|
213 return f;
|
Chris@102
|
214 }
|
Chris@102
|
215
|
Chris@102
|
216 template <typename O>
|
Chris@102
|
217 struct is_memzero_initializable
|
Chris@102
|
218 {
|
Chris@102
|
219 typedef typename ::boost::container::iterator_traits<O>::value_type value_type;
|
Chris@102
|
220 static const bool value = are_elements_contiguous<O>::value &&
|
Chris@102
|
221 ( container_detail::is_integral<value_type>::value || container_detail::is_enum<value_type>::value
|
Chris@102
|
222 #if defined(BOOST_CONTAINER_MEMZEROED_POINTER_IS_NULL)
|
Chris@102
|
223 || container_detail::is_pointer<value_type>::value
|
Chris@102
|
224 #endif
|
Chris@102
|
225 #if defined(BOOST_CONTAINER_MEMZEROED_FLOATING_POINT_IS_ZERO)
|
Chris@102
|
226 || container_detail::is_floating_point<value_type>::value
|
Chris@102
|
227 #endif
|
Chris@102
|
228 #if defined(BOOST_CONTAINER_MEMZEROED_FLOATING_POINT_IS_ZERO) && defined(BOOST_CONTAINER_MEMZEROED_POINTER_IS_NULL)
|
Chris@102
|
229 || container_detail::is_pod<value_type>::value
|
Chris@102
|
230 #endif
|
Chris@102
|
231 );
|
Chris@102
|
232 };
|
Chris@102
|
233
|
Chris@102
|
234 template <typename O, typename R>
|
Chris@102
|
235 struct enable_if_memzero_initializable
|
Chris@102
|
236 : enable_if_c<container_detail::is_memzero_initializable<O>::value, R>
|
Chris@102
|
237 {};
|
Chris@102
|
238
|
Chris@102
|
239 template <typename O, typename R>
|
Chris@102
|
240 struct disable_if_memzero_initializable
|
Chris@102
|
241 : enable_if_c<!container_detail::is_memzero_initializable<O>::value, R>
|
Chris@102
|
242 {};
|
Chris@102
|
243
|
Chris@102
|
244 template <typename I, typename R>
|
Chris@102
|
245 struct enable_if_trivially_destructible
|
Chris@102
|
246 : enable_if_c < false/*container_detail::is_trivially_destructible
|
Chris@102
|
247 <typename boost::container::iterator_traits<I>::value_type>::value*/
|
Chris@102
|
248 , R>
|
Chris@102
|
249 {};
|
Chris@102
|
250
|
Chris@102
|
251 template <typename I, typename R>
|
Chris@102
|
252 struct disable_if_trivially_destructible
|
Chris@102
|
253 : enable_if_c <true/*!container_detail::is_trivially_destructible
|
Chris@102
|
254 <typename boost::container::iterator_traits<I>::value_type>::value*/
|
Chris@102
|
255 , R>
|
Chris@102
|
256 {};
|
Chris@102
|
257
|
Chris@102
|
258 } //namespace container_detail {
|
Chris@102
|
259
|
Chris@102
|
260 //////////////////////////////////////////////////////////////////////////////
|
Chris@102
|
261 //
|
Chris@102
|
262 // uninitialized_move_alloc
|
Chris@102
|
263 //
|
Chris@102
|
264 //////////////////////////////////////////////////////////////////////////////
|
Chris@102
|
265
|
Chris@102
|
266
|
Chris@102
|
267 //! <b>Effects</b>:
|
Chris@102
|
268 //! \code
|
Chris@102
|
269 //! for (; f != l; ++r, ++f)
|
Chris@102
|
270 //! allocator_traits::construct(a, &*r, boost::move(*f));
|
Chris@102
|
271 //! \endcode
|
Chris@102
|
272 //!
|
Chris@102
|
273 //! <b>Returns</b>: r
|
Chris@102
|
274 template
|
Chris@102
|
275 <typename Allocator,
|
Chris@102
|
276 typename I, // I models InputIterator
|
Chris@102
|
277 typename F> // F models ForwardIterator
|
Chris@102
|
278 inline typename container_detail::disable_if_memtransfer_copy_constructible<I, F, F>::type
|
Chris@102
|
279 uninitialized_move_alloc(Allocator &a, I f, I l, F r)
|
Chris@102
|
280 {
|
Chris@102
|
281 F back = r;
|
Chris@102
|
282 BOOST_TRY{
|
Chris@102
|
283 while (f != l) {
|
Chris@102
|
284 allocator_traits<Allocator>::construct(a, container_detail::iterator_to_raw_pointer(r), boost::move(*f));
|
Chris@102
|
285 ++f; ++r;
|
Chris@102
|
286 }
|
Chris@102
|
287 }
|
Chris@102
|
288 BOOST_CATCH(...){
|
Chris@102
|
289 for (; back != r; ++back){
|
Chris@102
|
290 allocator_traits<Allocator>::destroy(a, container_detail::iterator_to_raw_pointer(back));
|
Chris@102
|
291 }
|
Chris@102
|
292 BOOST_RETHROW;
|
Chris@102
|
293 }
|
Chris@102
|
294 BOOST_CATCH_END
|
Chris@102
|
295 return r;
|
Chris@102
|
296 }
|
Chris@102
|
297
|
Chris@102
|
298 template
|
Chris@102
|
299 <typename Allocator,
|
Chris@102
|
300 typename I, // I models InputIterator
|
Chris@102
|
301 typename F> // F models ForwardIterator
|
Chris@102
|
302 inline typename container_detail::enable_if_memtransfer_copy_constructible<I, F, F>::type
|
Chris@102
|
303 uninitialized_move_alloc(Allocator &, I f, I l, F r) BOOST_NOEXCEPT_OR_NOTHROW
|
Chris@102
|
304 { return container_detail::memmove(f, l, r); }
|
Chris@102
|
305
|
Chris@102
|
306 //////////////////////////////////////////////////////////////////////////////
|
Chris@102
|
307 //
|
Chris@102
|
308 // uninitialized_move_alloc_n
|
Chris@102
|
309 //
|
Chris@102
|
310 //////////////////////////////////////////////////////////////////////////////
|
Chris@102
|
311
|
Chris@102
|
312 //! <b>Effects</b>:
|
Chris@102
|
313 //! \code
|
Chris@102
|
314 //! for (; n--; ++r, ++f)
|
Chris@102
|
315 //! allocator_traits::construct(a, &*r, boost::move(*f));
|
Chris@102
|
316 //! \endcode
|
Chris@102
|
317 //!
|
Chris@102
|
318 //! <b>Returns</b>: r
|
Chris@102
|
319 template
|
Chris@102
|
320 <typename Allocator,
|
Chris@102
|
321 typename I, // I models InputIterator
|
Chris@102
|
322 typename F> // F models ForwardIterator
|
Chris@102
|
323 inline typename container_detail::disable_if_memtransfer_copy_constructible<I, F, F>::type
|
Chris@102
|
324 uninitialized_move_alloc_n(Allocator &a, I f, typename boost::container::iterator_traits<I>::difference_type n, F r)
|
Chris@102
|
325 {
|
Chris@102
|
326 F back = r;
|
Chris@102
|
327 BOOST_TRY{
|
Chris@102
|
328 while (n--) {
|
Chris@102
|
329 allocator_traits<Allocator>::construct(a, container_detail::iterator_to_raw_pointer(r), boost::move(*f));
|
Chris@102
|
330 ++f; ++r;
|
Chris@102
|
331 }
|
Chris@102
|
332 }
|
Chris@102
|
333 BOOST_CATCH(...){
|
Chris@102
|
334 for (; back != r; ++back){
|
Chris@102
|
335 allocator_traits<Allocator>::destroy(a, container_detail::iterator_to_raw_pointer(back));
|
Chris@102
|
336 }
|
Chris@102
|
337 BOOST_RETHROW;
|
Chris@102
|
338 }
|
Chris@102
|
339 BOOST_CATCH_END
|
Chris@102
|
340 return r;
|
Chris@102
|
341 }
|
Chris@102
|
342
|
Chris@102
|
343 template
|
Chris@102
|
344 <typename Allocator,
|
Chris@102
|
345 typename I, // I models InputIterator
|
Chris@102
|
346 typename F> // F models ForwardIterator
|
Chris@102
|
347 inline typename container_detail::enable_if_memtransfer_copy_constructible<I, F, F>::type
|
Chris@102
|
348 uninitialized_move_alloc_n(Allocator &, I f, typename boost::container::iterator_traits<I>::difference_type n, F r) BOOST_NOEXCEPT_OR_NOTHROW
|
Chris@102
|
349 { return container_detail::memmove_n(f, n, r); }
|
Chris@102
|
350
|
Chris@102
|
351 //////////////////////////////////////////////////////////////////////////////
|
Chris@102
|
352 //
|
Chris@102
|
353 // uninitialized_move_alloc_n_source
|
Chris@102
|
354 //
|
Chris@102
|
355 //////////////////////////////////////////////////////////////////////////////
|
Chris@102
|
356
|
Chris@102
|
357 //! <b>Effects</b>:
|
Chris@102
|
358 //! \code
|
Chris@102
|
359 //! for (; n--; ++r, ++f)
|
Chris@102
|
360 //! allocator_traits::construct(a, &*r, boost::move(*f));
|
Chris@102
|
361 //! \endcode
|
Chris@102
|
362 //!
|
Chris@102
|
363 //! <b>Returns</b>: f (after incremented)
|
Chris@102
|
364 template
|
Chris@102
|
365 <typename Allocator,
|
Chris@102
|
366 typename I, // I models InputIterator
|
Chris@102
|
367 typename F> // F models ForwardIterator
|
Chris@102
|
368 inline typename container_detail::disable_if_memtransfer_copy_constructible<I, F, I>::type
|
Chris@102
|
369 uninitialized_move_alloc_n_source(Allocator &a, I f, typename boost::container::iterator_traits<I>::difference_type n, F r)
|
Chris@102
|
370 {
|
Chris@102
|
371 F back = r;
|
Chris@102
|
372 BOOST_TRY{
|
Chris@102
|
373 while (n--) {
|
Chris@102
|
374 allocator_traits<Allocator>::construct(a, container_detail::iterator_to_raw_pointer(r), boost::move(*f));
|
Chris@102
|
375 ++f; ++r;
|
Chris@102
|
376 }
|
Chris@102
|
377 }
|
Chris@102
|
378 BOOST_CATCH(...){
|
Chris@102
|
379 for (; back != r; ++back){
|
Chris@102
|
380 allocator_traits<Allocator>::destroy(a, container_detail::iterator_to_raw_pointer(back));
|
Chris@102
|
381 }
|
Chris@102
|
382 BOOST_RETHROW;
|
Chris@102
|
383 }
|
Chris@102
|
384 BOOST_CATCH_END
|
Chris@102
|
385 return f;
|
Chris@102
|
386 }
|
Chris@102
|
387
|
Chris@102
|
388 template
|
Chris@102
|
389 <typename Allocator,
|
Chris@102
|
390 typename I, // I models InputIterator
|
Chris@102
|
391 typename F> // F models ForwardIterator
|
Chris@102
|
392 inline typename container_detail::enable_if_memtransfer_copy_constructible<I, F, I>::type
|
Chris@102
|
393 uninitialized_move_alloc_n_source(Allocator &, I f, typename boost::container::iterator_traits<I>::difference_type n, F r) BOOST_NOEXCEPT_OR_NOTHROW
|
Chris@102
|
394 { return container_detail::memmove_n_source(f, n, r); }
|
Chris@102
|
395
|
Chris@102
|
396 //////////////////////////////////////////////////////////////////////////////
|
Chris@102
|
397 //
|
Chris@102
|
398 // uninitialized_copy_alloc
|
Chris@102
|
399 //
|
Chris@102
|
400 //////////////////////////////////////////////////////////////////////////////
|
Chris@102
|
401
|
Chris@102
|
402 //! <b>Effects</b>:
|
Chris@102
|
403 //! \code
|
Chris@102
|
404 //! for (; f != l; ++r, ++f)
|
Chris@102
|
405 //! allocator_traits::construct(a, &*r, *f);
|
Chris@102
|
406 //! \endcode
|
Chris@102
|
407 //!
|
Chris@102
|
408 //! <b>Returns</b>: r
|
Chris@102
|
409 template
|
Chris@102
|
410 <typename Allocator,
|
Chris@102
|
411 typename I, // I models InputIterator
|
Chris@102
|
412 typename F> // F models ForwardIterator
|
Chris@102
|
413 inline typename container_detail::disable_if_memtransfer_copy_constructible<I, F, F>::type
|
Chris@102
|
414 uninitialized_copy_alloc(Allocator &a, I f, I l, F r)
|
Chris@102
|
415 {
|
Chris@102
|
416 F back = r;
|
Chris@102
|
417 BOOST_TRY{
|
Chris@102
|
418 while (f != l) {
|
Chris@102
|
419 allocator_traits<Allocator>::construct(a, container_detail::iterator_to_raw_pointer(r), *f);
|
Chris@102
|
420 ++f; ++r;
|
Chris@102
|
421 }
|
Chris@102
|
422 }
|
Chris@102
|
423 BOOST_CATCH(...){
|
Chris@102
|
424 for (; back != r; ++back){
|
Chris@102
|
425 allocator_traits<Allocator>::destroy(a, container_detail::iterator_to_raw_pointer(back));
|
Chris@102
|
426 }
|
Chris@102
|
427 BOOST_RETHROW;
|
Chris@102
|
428 }
|
Chris@102
|
429 BOOST_CATCH_END
|
Chris@102
|
430 return r;
|
Chris@102
|
431 }
|
Chris@102
|
432
|
Chris@102
|
433 template
|
Chris@102
|
434 <typename Allocator,
|
Chris@102
|
435 typename I, // I models InputIterator
|
Chris@102
|
436 typename F> // F models ForwardIterator
|
Chris@102
|
437 inline typename container_detail::enable_if_memtransfer_copy_constructible<I, F, F>::type
|
Chris@102
|
438 uninitialized_copy_alloc(Allocator &, I f, I l, F r) BOOST_NOEXCEPT_OR_NOTHROW
|
Chris@102
|
439 { return container_detail::memmove(f, l, r); }
|
Chris@102
|
440
|
Chris@102
|
441 //////////////////////////////////////////////////////////////////////////////
|
Chris@102
|
442 //
|
Chris@102
|
443 // uninitialized_copy_alloc_n
|
Chris@102
|
444 //
|
Chris@102
|
445 //////////////////////////////////////////////////////////////////////////////
|
Chris@102
|
446
|
Chris@102
|
447 //! <b>Effects</b>:
|
Chris@102
|
448 //! \code
|
Chris@102
|
449 //! for (; n--; ++r, ++f)
|
Chris@102
|
450 //! allocator_traits::construct(a, &*r, *f);
|
Chris@102
|
451 //! \endcode
|
Chris@102
|
452 //!
|
Chris@102
|
453 //! <b>Returns</b>: r
|
Chris@102
|
454 template
|
Chris@102
|
455 <typename Allocator,
|
Chris@102
|
456 typename I, // I models InputIterator
|
Chris@102
|
457 typename F> // F models ForwardIterator
|
Chris@102
|
458 inline typename container_detail::disable_if_memtransfer_copy_constructible<I, F, F>::type
|
Chris@102
|
459 uninitialized_copy_alloc_n(Allocator &a, I f, typename boost::container::iterator_traits<I>::difference_type n, F r)
|
Chris@102
|
460 {
|
Chris@102
|
461 F back = r;
|
Chris@102
|
462 BOOST_TRY{
|
Chris@102
|
463 while (n--) {
|
Chris@102
|
464 allocator_traits<Allocator>::construct(a, container_detail::iterator_to_raw_pointer(r), *f);
|
Chris@102
|
465 ++f; ++r;
|
Chris@102
|
466 }
|
Chris@102
|
467 }
|
Chris@102
|
468 BOOST_CATCH(...){
|
Chris@102
|
469 for (; back != r; ++back){
|
Chris@102
|
470 allocator_traits<Allocator>::destroy(a, container_detail::iterator_to_raw_pointer(back));
|
Chris@102
|
471 }
|
Chris@102
|
472 BOOST_RETHROW;
|
Chris@102
|
473 }
|
Chris@102
|
474 BOOST_CATCH_END
|
Chris@102
|
475 return r;
|
Chris@102
|
476 }
|
Chris@102
|
477
|
Chris@102
|
478 template
|
Chris@102
|
479 <typename Allocator,
|
Chris@102
|
480 typename I, // I models InputIterator
|
Chris@102
|
481 typename F> // F models ForwardIterator
|
Chris@102
|
482 inline typename container_detail::enable_if_memtransfer_copy_constructible<I, F, F>::type
|
Chris@102
|
483 uninitialized_copy_alloc_n(Allocator &, I f, typename boost::container::iterator_traits<I>::difference_type n, F r) BOOST_NOEXCEPT_OR_NOTHROW
|
Chris@102
|
484 { return container_detail::memmove_n(f, n, r); }
|
Chris@102
|
485
|
Chris@102
|
486 //////////////////////////////////////////////////////////////////////////////
|
Chris@102
|
487 //
|
Chris@102
|
488 // uninitialized_copy_alloc_n_source
|
Chris@102
|
489 //
|
Chris@102
|
490 //////////////////////////////////////////////////////////////////////////////
|
Chris@102
|
491
|
Chris@102
|
492 //! <b>Effects</b>:
|
Chris@102
|
493 //! \code
|
Chris@102
|
494 //! for (; n--; ++r, ++f)
|
Chris@102
|
495 //! allocator_traits::construct(a, &*r, *f);
|
Chris@102
|
496 //! \endcode
|
Chris@102
|
497 //!
|
Chris@102
|
498 //! <b>Returns</b>: f (after incremented)
|
Chris@102
|
499 template
|
Chris@102
|
500 <typename Allocator,
|
Chris@102
|
501 typename I, // I models InputIterator
|
Chris@102
|
502 typename F> // F models ForwardIterator
|
Chris@102
|
503 inline typename container_detail::disable_if_memtransfer_copy_constructible<I, F, I>::type
|
Chris@102
|
504 uninitialized_copy_alloc_n_source(Allocator &a, I f, typename boost::container::iterator_traits<I>::difference_type n, F r)
|
Chris@102
|
505 {
|
Chris@102
|
506 F back = r;
|
Chris@102
|
507 BOOST_TRY{
|
Chris@102
|
508 while (n--) {
|
Chris@102
|
509 allocator_traits<Allocator>::construct(a, container_detail::iterator_to_raw_pointer(r), *f);
|
Chris@102
|
510 ++f; ++r;
|
Chris@102
|
511 }
|
Chris@102
|
512 }
|
Chris@102
|
513 BOOST_CATCH(...){
|
Chris@102
|
514 for (; back != r; ++back){
|
Chris@102
|
515 allocator_traits<Allocator>::destroy(a, container_detail::iterator_to_raw_pointer(back));
|
Chris@102
|
516 }
|
Chris@102
|
517 BOOST_RETHROW;
|
Chris@102
|
518 }
|
Chris@102
|
519 BOOST_CATCH_END
|
Chris@102
|
520 return f;
|
Chris@102
|
521 }
|
Chris@102
|
522
|
Chris@102
|
523 template
|
Chris@102
|
524 <typename Allocator,
|
Chris@102
|
525 typename I, // I models InputIterator
|
Chris@102
|
526 typename F> // F models ForwardIterator
|
Chris@102
|
527 inline typename container_detail::enable_if_memtransfer_copy_constructible<I, F, I>::type
|
Chris@102
|
528 uninitialized_copy_alloc_n_source(Allocator &, I f, typename boost::container::iterator_traits<I>::difference_type n, F r) BOOST_NOEXCEPT_OR_NOTHROW
|
Chris@102
|
529 { return container_detail::memmove_n_source(f, n, r); }
|
Chris@102
|
530
|
Chris@102
|
531 //////////////////////////////////////////////////////////////////////////////
|
Chris@102
|
532 //
|
Chris@102
|
533 // uninitialized_value_init_alloc_n
|
Chris@102
|
534 //
|
Chris@102
|
535 //////////////////////////////////////////////////////////////////////////////
|
Chris@102
|
536
|
Chris@102
|
537 //! <b>Effects</b>:
|
Chris@102
|
538 //! \code
|
Chris@102
|
539 //! for (; n--; ++r, ++f)
|
Chris@102
|
540 //! allocator_traits::construct(a, &*r);
|
Chris@102
|
541 //! \endcode
|
Chris@102
|
542 //!
|
Chris@102
|
543 //! <b>Returns</b>: r
|
Chris@102
|
544 template
|
Chris@102
|
545 <typename Allocator,
|
Chris@102
|
546 typename F> // F models ForwardIterator
|
Chris@102
|
547 inline typename container_detail::disable_if_memzero_initializable<F, F>::type
|
Chris@102
|
548 uninitialized_value_init_alloc_n(Allocator &a, typename allocator_traits<Allocator>::difference_type n, F r)
|
Chris@102
|
549 {
|
Chris@102
|
550 F back = r;
|
Chris@102
|
551 BOOST_TRY{
|
Chris@102
|
552 while (n--) {
|
Chris@102
|
553 allocator_traits<Allocator>::construct(a, container_detail::iterator_to_raw_pointer(r));
|
Chris@102
|
554 ++r;
|
Chris@102
|
555 }
|
Chris@102
|
556 }
|
Chris@102
|
557 BOOST_CATCH(...){
|
Chris@102
|
558 for (; back != r; ++back){
|
Chris@102
|
559 allocator_traits<Allocator>::destroy(a, container_detail::iterator_to_raw_pointer(back));
|
Chris@102
|
560 }
|
Chris@102
|
561 BOOST_RETHROW;
|
Chris@102
|
562 }
|
Chris@102
|
563 BOOST_CATCH_END
|
Chris@102
|
564 return r;
|
Chris@102
|
565 }
|
Chris@102
|
566
|
Chris@102
|
567 template
|
Chris@102
|
568 <typename Allocator,
|
Chris@102
|
569 typename F> // F models ForwardIterator
|
Chris@102
|
570 inline typename container_detail::enable_if_memzero_initializable<F, F>::type
|
Chris@102
|
571 uninitialized_value_init_alloc_n(Allocator &, typename allocator_traits<Allocator>::difference_type n, F r)
|
Chris@102
|
572 {
|
Chris@102
|
573 typedef typename boost::container::iterator_traits<F>::value_type value_type;
|
Chris@102
|
574 std::memset((void*)container_detail::iterator_to_raw_pointer(r), 0, sizeof(value_type)*n);
|
Chris@102
|
575 boost::container::iterator_advance(r, n);
|
Chris@102
|
576 return r;
|
Chris@102
|
577 }
|
Chris@102
|
578
|
Chris@102
|
579 //////////////////////////////////////////////////////////////////////////////
|
Chris@102
|
580 //
|
Chris@102
|
581 // uninitialized_default_init_alloc_n
|
Chris@102
|
582 //
|
Chris@102
|
583 //////////////////////////////////////////////////////////////////////////////
|
Chris@102
|
584
|
Chris@102
|
585 //! <b>Effects</b>:
|
Chris@102
|
586 //! \code
|
Chris@102
|
587 //! for (; n--; ++r, ++f)
|
Chris@102
|
588 //! allocator_traits::construct(a, &*r);
|
Chris@102
|
589 //! \endcode
|
Chris@102
|
590 //!
|
Chris@102
|
591 //! <b>Returns</b>: r
|
Chris@102
|
592 template
|
Chris@102
|
593 <typename Allocator,
|
Chris@102
|
594 typename F> // F models ForwardIterator
|
Chris@102
|
595 inline F uninitialized_default_init_alloc_n(Allocator &a, typename allocator_traits<Allocator>::difference_type n, F r)
|
Chris@102
|
596 {
|
Chris@102
|
597 F back = r;
|
Chris@102
|
598 BOOST_TRY{
|
Chris@102
|
599 while (n--) {
|
Chris@102
|
600 allocator_traits<Allocator>::construct(a, container_detail::iterator_to_raw_pointer(r), default_init);
|
Chris@102
|
601 ++r;
|
Chris@102
|
602 }
|
Chris@102
|
603 }
|
Chris@102
|
604 BOOST_CATCH(...){
|
Chris@102
|
605 for (; back != r; ++back){
|
Chris@102
|
606 allocator_traits<Allocator>::destroy(a, container_detail::iterator_to_raw_pointer(back));
|
Chris@102
|
607 }
|
Chris@102
|
608 BOOST_RETHROW;
|
Chris@102
|
609 }
|
Chris@102
|
610 BOOST_CATCH_END
|
Chris@102
|
611 return r;
|
Chris@102
|
612 }
|
Chris@102
|
613
|
Chris@102
|
614 //////////////////////////////////////////////////////////////////////////////
|
Chris@102
|
615 //
|
Chris@102
|
616 // uninitialized_fill_alloc
|
Chris@102
|
617 //
|
Chris@102
|
618 //////////////////////////////////////////////////////////////////////////////
|
Chris@102
|
619
|
Chris@102
|
620 //! <b>Effects</b>:
|
Chris@102
|
621 //! \code
|
Chris@102
|
622 //! for (; f != l; ++r, ++f)
|
Chris@102
|
623 //! allocator_traits::construct(a, &*r, *f);
|
Chris@102
|
624 //! \endcode
|
Chris@102
|
625 //!
|
Chris@102
|
626 //! <b>Returns</b>: r
|
Chris@102
|
627 template
|
Chris@102
|
628 <typename Allocator,
|
Chris@102
|
629 typename F, // F models ForwardIterator
|
Chris@102
|
630 typename T>
|
Chris@102
|
631 inline void uninitialized_fill_alloc(Allocator &a, F f, F l, const T &t)
|
Chris@102
|
632 {
|
Chris@102
|
633 F back = f;
|
Chris@102
|
634 BOOST_TRY{
|
Chris@102
|
635 while (f != l) {
|
Chris@102
|
636 allocator_traits<Allocator>::construct(a, container_detail::iterator_to_raw_pointer(f), t);
|
Chris@102
|
637 ++f;
|
Chris@102
|
638 }
|
Chris@102
|
639 }
|
Chris@102
|
640 BOOST_CATCH(...){
|
Chris@102
|
641 for (; back != l; ++back){
|
Chris@102
|
642 allocator_traits<Allocator>::destroy(a, container_detail::iterator_to_raw_pointer(back));
|
Chris@102
|
643 }
|
Chris@102
|
644 BOOST_RETHROW;
|
Chris@102
|
645 }
|
Chris@102
|
646 BOOST_CATCH_END
|
Chris@102
|
647 }
|
Chris@102
|
648
|
Chris@102
|
649
|
Chris@102
|
650 //////////////////////////////////////////////////////////////////////////////
|
Chris@102
|
651 //
|
Chris@102
|
652 // uninitialized_fill_alloc_n
|
Chris@102
|
653 //
|
Chris@102
|
654 //////////////////////////////////////////////////////////////////////////////
|
Chris@102
|
655
|
Chris@102
|
656 //! <b>Effects</b>:
|
Chris@102
|
657 //! \code
|
Chris@102
|
658 //! for (; n--; ++r, ++f)
|
Chris@102
|
659 //! allocator_traits::construct(a, &*r, v);
|
Chris@102
|
660 //! \endcode
|
Chris@102
|
661 //!
|
Chris@102
|
662 //! <b>Returns</b>: r
|
Chris@102
|
663 template
|
Chris@102
|
664 <typename Allocator,
|
Chris@102
|
665 typename T,
|
Chris@102
|
666 typename F> // F models ForwardIterator
|
Chris@102
|
667 inline F uninitialized_fill_alloc_n(Allocator &a, const T &v, typename allocator_traits<Allocator>::difference_type n, F r)
|
Chris@102
|
668 {
|
Chris@102
|
669 F back = r;
|
Chris@102
|
670 BOOST_TRY{
|
Chris@102
|
671 while (n--) {
|
Chris@102
|
672 allocator_traits<Allocator>::construct(a, container_detail::iterator_to_raw_pointer(r), v);
|
Chris@102
|
673 ++r;
|
Chris@102
|
674 }
|
Chris@102
|
675 }
|
Chris@102
|
676 BOOST_CATCH(...){
|
Chris@102
|
677 for (; back != r; ++back){
|
Chris@102
|
678 allocator_traits<Allocator>::destroy(a, container_detail::iterator_to_raw_pointer(back));
|
Chris@102
|
679 }
|
Chris@102
|
680 BOOST_RETHROW;
|
Chris@102
|
681 }
|
Chris@102
|
682 BOOST_CATCH_END
|
Chris@102
|
683 return r;
|
Chris@102
|
684 }
|
Chris@102
|
685
|
Chris@102
|
686 //////////////////////////////////////////////////////////////////////////////
|
Chris@102
|
687 //
|
Chris@102
|
688 // copy
|
Chris@102
|
689 //
|
Chris@102
|
690 //////////////////////////////////////////////////////////////////////////////
|
Chris@102
|
691
|
Chris@102
|
692 template
|
Chris@102
|
693 <typename I, // I models InputIterator
|
Chris@102
|
694 typename F> // F models ForwardIterator
|
Chris@102
|
695 inline typename container_detail::disable_if_memtransfer_copy_assignable<I, F, F>::type
|
Chris@102
|
696 copy(I f, I l, F r)
|
Chris@102
|
697 {
|
Chris@102
|
698 while (f != l) {
|
Chris@102
|
699 *r = *f;
|
Chris@102
|
700 ++f; ++r;
|
Chris@102
|
701 }
|
Chris@102
|
702 return r;
|
Chris@102
|
703 }
|
Chris@102
|
704
|
Chris@102
|
705 template
|
Chris@102
|
706 <typename I, // I models InputIterator
|
Chris@102
|
707 typename F> // F models ForwardIterator
|
Chris@102
|
708 inline typename container_detail::enable_if_memtransfer_copy_assignable<I, F, F>::type
|
Chris@102
|
709 copy(I f, I l, F r) BOOST_NOEXCEPT_OR_NOTHROW
|
Chris@102
|
710 { return container_detail::memmove(f, l, r); }
|
Chris@102
|
711
|
Chris@102
|
712 //////////////////////////////////////////////////////////////////////////////
|
Chris@102
|
713 //
|
Chris@102
|
714 // copy_n
|
Chris@102
|
715 //
|
Chris@102
|
716 //////////////////////////////////////////////////////////////////////////////
|
Chris@102
|
717
|
Chris@102
|
718 template
|
Chris@102
|
719 <typename I, // I models InputIterator
|
Chris@102
|
720 typename F> // F models ForwardIterator
|
Chris@102
|
721 inline typename container_detail::disable_if_memtransfer_copy_assignable<I, F, F>::type
|
Chris@102
|
722 copy_n(I f, typename boost::container::iterator_traits<I>::difference_type n, F r)
|
Chris@102
|
723 {
|
Chris@102
|
724 while (n--) {
|
Chris@102
|
725 *r = *f;
|
Chris@102
|
726 ++f; ++r;
|
Chris@102
|
727 }
|
Chris@102
|
728 return r;
|
Chris@102
|
729 }
|
Chris@102
|
730
|
Chris@102
|
731 template
|
Chris@102
|
732 <typename I, // I models InputIterator
|
Chris@102
|
733 typename F> // F models ForwardIterator
|
Chris@102
|
734 inline typename container_detail::enable_if_memtransfer_copy_assignable<I, F, F>::type
|
Chris@102
|
735 copy_n(I f, typename boost::container::iterator_traits<I>::difference_type n, F r) BOOST_NOEXCEPT_OR_NOTHROW
|
Chris@102
|
736 { return container_detail::memmove_n(f, n, r); }
|
Chris@102
|
737
|
Chris@102
|
738 //////////////////////////////////////////////////////////////////////////////
|
Chris@102
|
739 //
|
Chris@102
|
740 // copy_n_source
|
Chris@102
|
741 //
|
Chris@102
|
742 //////////////////////////////////////////////////////////////////////////////
|
Chris@102
|
743
|
Chris@102
|
744 template
|
Chris@102
|
745 <typename I, // I models InputIterator
|
Chris@102
|
746 typename F> // F models ForwardIterator
|
Chris@102
|
747 inline typename container_detail::disable_if_memtransfer_copy_assignable<I, F, I>::type
|
Chris@102
|
748 copy_n_source(I f, typename boost::container::iterator_traits<I>::difference_type n, F r)
|
Chris@102
|
749 {
|
Chris@102
|
750 while (n--) {
|
Chris@102
|
751 *r = *f;
|
Chris@102
|
752 ++f; ++r;
|
Chris@102
|
753 }
|
Chris@102
|
754 return f;
|
Chris@102
|
755 }
|
Chris@102
|
756
|
Chris@102
|
757 template
|
Chris@102
|
758 <typename I, // I models InputIterator
|
Chris@102
|
759 typename F> // F models ForwardIterator
|
Chris@102
|
760 inline typename container_detail::enable_if_memtransfer_copy_assignable<I, F, I>::type
|
Chris@102
|
761 copy_n_source(I f, typename boost::container::iterator_traits<I>::difference_type n, F r) BOOST_NOEXCEPT_OR_NOTHROW
|
Chris@102
|
762 { return container_detail::memmove_n_source(f, n, r); }
|
Chris@102
|
763
|
Chris@102
|
764 //////////////////////////////////////////////////////////////////////////////
|
Chris@102
|
765 //
|
Chris@102
|
766 // copy_n_source_dest
|
Chris@102
|
767 //
|
Chris@102
|
768 //////////////////////////////////////////////////////////////////////////////
|
Chris@102
|
769
|
Chris@102
|
770 template
|
Chris@102
|
771 <typename I, // I models InputIterator
|
Chris@102
|
772 typename F> // F models ForwardIterator
|
Chris@102
|
773 inline typename container_detail::disable_if_memtransfer_copy_assignable<I, F, I>::type
|
Chris@102
|
774 copy_n_source_dest(I f, typename boost::container::iterator_traits<I>::difference_type n, F &r)
|
Chris@102
|
775 {
|
Chris@102
|
776 while (n--) {
|
Chris@102
|
777 *r = *f;
|
Chris@102
|
778 ++f; ++r;
|
Chris@102
|
779 }
|
Chris@102
|
780 return f;
|
Chris@102
|
781 }
|
Chris@102
|
782
|
Chris@102
|
783 template
|
Chris@102
|
784 <typename I, // I models InputIterator
|
Chris@102
|
785 typename F> // F models ForwardIterator
|
Chris@102
|
786 inline typename container_detail::enable_if_memtransfer_copy_assignable<I, F, I>::type
|
Chris@102
|
787 copy_n_source_dest(I f, typename boost::container::iterator_traits<I>::difference_type n, F &r) BOOST_NOEXCEPT_OR_NOTHROW
|
Chris@102
|
788 { return container_detail::memmove_n_source_dest(f, n, r); }
|
Chris@102
|
789
|
Chris@102
|
790 //////////////////////////////////////////////////////////////////////////////
|
Chris@102
|
791 //
|
Chris@102
|
792 // move
|
Chris@102
|
793 //
|
Chris@102
|
794 //////////////////////////////////////////////////////////////////////////////
|
Chris@102
|
795
|
Chris@102
|
796 template
|
Chris@102
|
797 <typename I, // I models InputIterator
|
Chris@102
|
798 typename F> // F models ForwardIterator
|
Chris@102
|
799 inline typename container_detail::disable_if_memtransfer_copy_assignable<I, F, F>::type
|
Chris@102
|
800 move(I f, I l, F r)
|
Chris@102
|
801 {
|
Chris@102
|
802 while (f != l) {
|
Chris@102
|
803 *r = ::boost::move(*f);
|
Chris@102
|
804 ++f; ++r;
|
Chris@102
|
805 }
|
Chris@102
|
806 return r;
|
Chris@102
|
807 }
|
Chris@102
|
808
|
Chris@102
|
809 template
|
Chris@102
|
810 <typename I, // I models InputIterator
|
Chris@102
|
811 typename F> // F models ForwardIterator
|
Chris@102
|
812 inline typename container_detail::enable_if_memtransfer_copy_assignable<I, F, F>::type
|
Chris@102
|
813 move(I f, I l, F r) BOOST_NOEXCEPT_OR_NOTHROW
|
Chris@102
|
814 { return container_detail::memmove(f, l, r); }
|
Chris@102
|
815
|
Chris@102
|
816 //////////////////////////////////////////////////////////////////////////////
|
Chris@102
|
817 //
|
Chris@102
|
818 // move_n
|
Chris@102
|
819 //
|
Chris@102
|
820 //////////////////////////////////////////////////////////////////////////////
|
Chris@102
|
821
|
Chris@102
|
822 template
|
Chris@102
|
823 <typename I, // I models InputIterator
|
Chris@102
|
824 typename F> // F models ForwardIterator
|
Chris@102
|
825 inline typename container_detail::disable_if_memtransfer_copy_assignable<I, F, F>::type
|
Chris@102
|
826 move_n(I f, typename boost::container::iterator_traits<I>::difference_type n, F r)
|
Chris@102
|
827 {
|
Chris@102
|
828 while (n--) {
|
Chris@102
|
829 *r = ::boost::move(*f);
|
Chris@102
|
830 ++f; ++r;
|
Chris@102
|
831 }
|
Chris@102
|
832 return r;
|
Chris@102
|
833 }
|
Chris@102
|
834
|
Chris@102
|
835 template
|
Chris@102
|
836 <typename I, // I models InputIterator
|
Chris@102
|
837 typename F> // F models ForwardIterator
|
Chris@102
|
838 inline typename container_detail::enable_if_memtransfer_copy_assignable<I, F, F>::type
|
Chris@102
|
839 move_n(I f, typename boost::container::iterator_traits<I>::difference_type n, F r) BOOST_NOEXCEPT_OR_NOTHROW
|
Chris@102
|
840 { return container_detail::memmove_n(f, n, r); }
|
Chris@102
|
841
|
Chris@102
|
842
|
Chris@102
|
843 //////////////////////////////////////////////////////////////////////////////
|
Chris@102
|
844 //
|
Chris@102
|
845 // move_backward
|
Chris@102
|
846 //
|
Chris@102
|
847 //////////////////////////////////////////////////////////////////////////////
|
Chris@102
|
848
|
Chris@102
|
849 template
|
Chris@102
|
850 <typename I, // I models BidirectionalIterator
|
Chris@102
|
851 typename F> // F models ForwardIterator
|
Chris@102
|
852 inline typename container_detail::disable_if_memtransfer_copy_assignable<I, F, F>::type
|
Chris@102
|
853 move_backward(I f, I l, F r)
|
Chris@102
|
854 {
|
Chris@102
|
855 while (f != l) {
|
Chris@102
|
856 --l; --r;
|
Chris@102
|
857 *r = ::boost::move(*l);
|
Chris@102
|
858 }
|
Chris@102
|
859 return r;
|
Chris@102
|
860 }
|
Chris@102
|
861
|
Chris@102
|
862 template
|
Chris@102
|
863 <typename I, // I models InputIterator
|
Chris@102
|
864 typename F> // F models ForwardIterator
|
Chris@102
|
865 inline typename container_detail::enable_if_memtransfer_copy_assignable<I, F, F>::type
|
Chris@102
|
866 move_backward(I f, I l, F r) BOOST_NOEXCEPT_OR_NOTHROW
|
Chris@102
|
867 {
|
Chris@102
|
868 typedef typename boost::container::iterator_traits<I>::value_type value_type;
|
Chris@102
|
869 const typename boost::container::iterator_traits<I>::difference_type n = boost::container::iterator_distance(f, l);
|
Chris@102
|
870 r -= n;
|
Chris@102
|
871 std::memmove((container_detail::iterator_to_raw_pointer)(r), (container_detail::iterator_to_raw_pointer)(f), sizeof(value_type)*n);
|
Chris@102
|
872 return r;
|
Chris@102
|
873 }
|
Chris@102
|
874
|
Chris@102
|
875 //////////////////////////////////////////////////////////////////////////////
|
Chris@102
|
876 //
|
Chris@102
|
877 // move_n_source_dest
|
Chris@102
|
878 //
|
Chris@102
|
879 //////////////////////////////////////////////////////////////////////////////
|
Chris@102
|
880
|
Chris@102
|
881 template
|
Chris@102
|
882 <typename I // I models InputIterator
|
Chris@102
|
883 ,typename F> // F models ForwardIterator
|
Chris@102
|
884 inline typename container_detail::disable_if_memtransfer_copy_assignable<I, F, I>::type
|
Chris@102
|
885 move_n_source_dest(I f, typename boost::container::iterator_traits<I>::difference_type n, F &r)
|
Chris@102
|
886 {
|
Chris@102
|
887 while (n--) {
|
Chris@102
|
888 *r = ::boost::move(*f);
|
Chris@102
|
889 ++f; ++r;
|
Chris@102
|
890 }
|
Chris@102
|
891 return f;
|
Chris@102
|
892 }
|
Chris@102
|
893
|
Chris@102
|
894 template
|
Chris@102
|
895 <typename I // I models InputIterator
|
Chris@102
|
896 ,typename F> // F models ForwardIterator
|
Chris@102
|
897 inline typename container_detail::enable_if_memtransfer_copy_assignable<I, F, I>::type
|
Chris@102
|
898 move_n_source_dest(I f, typename boost::container::iterator_traits<I>::difference_type n, F &r) BOOST_NOEXCEPT_OR_NOTHROW
|
Chris@102
|
899 { return container_detail::memmove_n_source_dest(f, n, r); }
|
Chris@102
|
900
|
Chris@102
|
901 //////////////////////////////////////////////////////////////////////////////
|
Chris@102
|
902 //
|
Chris@102
|
903 // move_n_source
|
Chris@102
|
904 //
|
Chris@102
|
905 //////////////////////////////////////////////////////////////////////////////
|
Chris@102
|
906
|
Chris@102
|
907 template
|
Chris@102
|
908 <typename I // I models InputIterator
|
Chris@102
|
909 ,typename F> // F models ForwardIterator
|
Chris@102
|
910 inline typename container_detail::disable_if_memtransfer_copy_assignable<I, F, I>::type
|
Chris@102
|
911 move_n_source(I f, typename boost::container::iterator_traits<I>::difference_type n, F r)
|
Chris@102
|
912 {
|
Chris@102
|
913 while (n--) {
|
Chris@102
|
914 *r = ::boost::move(*f);
|
Chris@102
|
915 ++f; ++r;
|
Chris@102
|
916 }
|
Chris@102
|
917 return f;
|
Chris@102
|
918 }
|
Chris@102
|
919
|
Chris@102
|
920 template
|
Chris@102
|
921 <typename I // I models InputIterator
|
Chris@102
|
922 ,typename F> // F models ForwardIterator
|
Chris@102
|
923 inline typename container_detail::enable_if_memtransfer_copy_assignable<I, F, I>::type
|
Chris@102
|
924 move_n_source(I f, typename boost::container::iterator_traits<I>::difference_type n, F r) BOOST_NOEXCEPT_OR_NOTHROW
|
Chris@102
|
925 { return container_detail::memmove_n_source(f, n, r); }
|
Chris@102
|
926
|
Chris@102
|
927 //////////////////////////////////////////////////////////////////////////////
|
Chris@102
|
928 //
|
Chris@102
|
929 // destroy_alloc_n
|
Chris@102
|
930 //
|
Chris@102
|
931 //////////////////////////////////////////////////////////////////////////////
|
Chris@102
|
932
|
Chris@102
|
933 template
|
Chris@102
|
934 <typename Allocator
|
Chris@102
|
935 ,typename I // I models InputIterator
|
Chris@102
|
936 ,typename U> // U models unsigned integral constant
|
Chris@102
|
937 inline typename container_detail::disable_if_trivially_destructible<I, void>::type
|
Chris@102
|
938 destroy_alloc_n(Allocator &a, I f, U n)
|
Chris@102
|
939 {
|
Chris@102
|
940 while(n--){
|
Chris@102
|
941 allocator_traits<Allocator>::destroy(a, container_detail::iterator_to_raw_pointer(f));
|
Chris@102
|
942 ++f;
|
Chris@102
|
943 }
|
Chris@102
|
944 }
|
Chris@102
|
945
|
Chris@102
|
946 template
|
Chris@102
|
947 <typename Allocator
|
Chris@102
|
948 ,typename I // I models InputIterator
|
Chris@102
|
949 ,typename U> // U models unsigned integral constant
|
Chris@102
|
950 inline typename container_detail::enable_if_trivially_destructible<I, void>::type
|
Chris@102
|
951 destroy_alloc_n(Allocator &, I, U)
|
Chris@102
|
952 {}
|
Chris@102
|
953
|
Chris@102
|
954 //////////////////////////////////////////////////////////////////////////////
|
Chris@102
|
955 //
|
Chris@102
|
956 // deep_swap_alloc_n
|
Chris@102
|
957 //
|
Chris@102
|
958 //////////////////////////////////////////////////////////////////////////////
|
Chris@102
|
959
|
Chris@102
|
960 template
|
Chris@102
|
961 <std::size_t MaxTmpBytes
|
Chris@102
|
962 ,typename Allocator
|
Chris@102
|
963 ,typename F // F models ForwardIterator
|
Chris@102
|
964 ,typename G // G models ForwardIterator
|
Chris@102
|
965 >
|
Chris@102
|
966 inline typename container_detail::disable_if_memtransfer_copy_assignable<F, G, void>::type
|
Chris@102
|
967 deep_swap_alloc_n( Allocator &a, F short_range_f, typename allocator_traits<Allocator>::size_type n_i
|
Chris@102
|
968 , G large_range_f, typename allocator_traits<Allocator>::size_type n_j)
|
Chris@102
|
969 {
|
Chris@102
|
970 typename allocator_traits<Allocator>::size_type n = 0;
|
Chris@102
|
971 for (; n != n_i ; ++short_range_f, ++large_range_f, ++n){
|
Chris@102
|
972 boost::adl_move_swap(*short_range_f, *large_range_f);
|
Chris@102
|
973 }
|
Chris@102
|
974 boost::container::uninitialized_move_alloc_n(a, large_range_f, n_j - n_i, short_range_f); // may throw
|
Chris@102
|
975 boost::container::destroy_alloc_n(a, large_range_f, n_j - n_i);
|
Chris@102
|
976 }
|
Chris@102
|
977
|
Chris@102
|
978 static const std::size_t DeepSwapAllocNMaxStorage = std::size_t(1) << std::size_t(11); //2K bytes
|
Chris@102
|
979
|
Chris@102
|
980 template
|
Chris@102
|
981 <std::size_t MaxTmpBytes
|
Chris@102
|
982 ,typename Allocator
|
Chris@102
|
983 ,typename F // F models ForwardIterator
|
Chris@102
|
984 ,typename G // G models ForwardIterator
|
Chris@102
|
985 >
|
Chris@102
|
986 inline typename container_detail::enable_if_c
|
Chris@102
|
987 < container_detail::is_memtransfer_copy_assignable<F, G>::value && (MaxTmpBytes <= DeepSwapAllocNMaxStorage) && false
|
Chris@102
|
988 , void>::type
|
Chris@102
|
989 deep_swap_alloc_n( Allocator &a, F short_range_f, typename allocator_traits<Allocator>::size_type n_i
|
Chris@102
|
990 , G large_range_f, typename allocator_traits<Allocator>::size_type n_j)
|
Chris@102
|
991 {
|
Chris@102
|
992 typedef typename allocator_traits<Allocator>::value_type value_type;
|
Chris@102
|
993 typedef typename container_detail::aligned_storage
|
Chris@102
|
994 <MaxTmpBytes, container_detail::alignment_of<value_type>::value>::type storage_type;
|
Chris@102
|
995 storage_type storage;
|
Chris@102
|
996
|
Chris@102
|
997 const std::size_t n_i_bytes = sizeof(value_type)*n_i;
|
Chris@102
|
998 void *const large_ptr = static_cast<void*>(container_detail::iterator_to_raw_pointer(large_range_f));
|
Chris@102
|
999 void *const short_ptr = static_cast<void*>(container_detail::iterator_to_raw_pointer(short_range_f));
|
Chris@102
|
1000 void *const stora_ptr = static_cast<void*>(container_detail::iterator_to_raw_pointer(storage));
|
Chris@102
|
1001 std::memcpy(stora_ptr, large_ptr, n_i_bytes);
|
Chris@102
|
1002 std::memcpy(large_ptr, short_ptr, n_i_bytes);
|
Chris@102
|
1003 std::memcpy(short_ptr, stora_ptr, n_i_bytes);
|
Chris@102
|
1004 boost::container::iterator_advance(large_range_f, n_i);
|
Chris@102
|
1005 boost::container::iterator_advance(short_range_f, n_i);
|
Chris@102
|
1006 boost::container::uninitialized_move_alloc_n(a, large_range_f, n_j - n_i, short_range_f); // may throw
|
Chris@102
|
1007 boost::container::destroy_alloc_n(a, large_range_f, n_j - n_i);
|
Chris@102
|
1008 }
|
Chris@102
|
1009
|
Chris@102
|
1010 template
|
Chris@102
|
1011 <std::size_t MaxTmpBytes
|
Chris@102
|
1012 ,typename Allocator
|
Chris@102
|
1013 ,typename F // F models ForwardIterator
|
Chris@102
|
1014 ,typename G // G models ForwardIterator
|
Chris@102
|
1015 >
|
Chris@102
|
1016 inline typename container_detail::enable_if_c
|
Chris@102
|
1017 < container_detail::is_memtransfer_copy_assignable<F, G>::value && true//(MaxTmpBytes > DeepSwapAllocNMaxStorage)
|
Chris@102
|
1018 , void>::type
|
Chris@102
|
1019 deep_swap_alloc_n( Allocator &a, F short_range_f, typename allocator_traits<Allocator>::size_type n_i
|
Chris@102
|
1020 , G large_range_f, typename allocator_traits<Allocator>::size_type n_j)
|
Chris@102
|
1021 {
|
Chris@102
|
1022 typedef typename allocator_traits<Allocator>::value_type value_type;
|
Chris@102
|
1023 typedef typename container_detail::aligned_storage
|
Chris@102
|
1024 <DeepSwapAllocNMaxStorage, container_detail::alignment_of<value_type>::value>::type storage_type;
|
Chris@102
|
1025 storage_type storage;
|
Chris@102
|
1026 const std::size_t sizeof_storage = sizeof(storage);
|
Chris@102
|
1027
|
Chris@102
|
1028 std::size_t n_i_bytes = sizeof(value_type)*n_i;
|
Chris@102
|
1029 char *large_ptr = static_cast<char*>(static_cast<void*>(container_detail::iterator_to_raw_pointer(large_range_f)));
|
Chris@102
|
1030 char *short_ptr = static_cast<char*>(static_cast<void*>(container_detail::iterator_to_raw_pointer(short_range_f)));
|
Chris@102
|
1031 char *stora_ptr = static_cast<char*>(static_cast<void*>(&storage));
|
Chris@102
|
1032
|
Chris@102
|
1033 std::size_t szt_times = n_i_bytes/sizeof_storage;
|
Chris@102
|
1034 const std::size_t szt_rem = n_i_bytes%sizeof_storage;
|
Chris@102
|
1035
|
Chris@102
|
1036 //Loop unrolling using Duff's device, as it seems it helps on some architectures
|
Chris@102
|
1037 const std::size_t Unroll = 4;
|
Chris@102
|
1038 std::size_t n = (szt_times + (Unroll-1))/Unroll;
|
Chris@102
|
1039 const std::size_t branch_number = (!szt_times)*Unroll + (szt_times % Unroll);
|
Chris@102
|
1040 switch(branch_number){
|
Chris@102
|
1041 case 4:
|
Chris@102
|
1042 break;
|
Chris@102
|
1043 case 0: do{
|
Chris@102
|
1044 std::memcpy(stora_ptr, large_ptr, sizeof_storage);
|
Chris@102
|
1045 std::memcpy(large_ptr, short_ptr, sizeof_storage);
|
Chris@102
|
1046 std::memcpy(short_ptr, stora_ptr, sizeof_storage);
|
Chris@102
|
1047 large_ptr += sizeof_storage;
|
Chris@102
|
1048 short_ptr += sizeof_storage;
|
Chris@102
|
1049 BOOST_CONTAINER_FALLTHOUGH
|
Chris@102
|
1050 case 3:
|
Chris@102
|
1051 std::memcpy(stora_ptr, large_ptr, sizeof_storage);
|
Chris@102
|
1052 std::memcpy(large_ptr, short_ptr, sizeof_storage);
|
Chris@102
|
1053 std::memcpy(short_ptr, stora_ptr, sizeof_storage);
|
Chris@102
|
1054 large_ptr += sizeof_storage;
|
Chris@102
|
1055 short_ptr += sizeof_storage;
|
Chris@102
|
1056 BOOST_CONTAINER_FALLTHOUGH
|
Chris@102
|
1057 case 2:
|
Chris@102
|
1058 std::memcpy(stora_ptr, large_ptr, sizeof_storage);
|
Chris@102
|
1059 std::memcpy(large_ptr, short_ptr, sizeof_storage);
|
Chris@102
|
1060 std::memcpy(short_ptr, stora_ptr, sizeof_storage);
|
Chris@102
|
1061 large_ptr += sizeof_storage;
|
Chris@102
|
1062 short_ptr += sizeof_storage;
|
Chris@102
|
1063 BOOST_CONTAINER_FALLTHOUGH
|
Chris@102
|
1064 case 1:
|
Chris@102
|
1065 std::memcpy(stora_ptr, large_ptr, sizeof_storage);
|
Chris@102
|
1066 std::memcpy(large_ptr, short_ptr, sizeof_storage);
|
Chris@102
|
1067 std::memcpy(short_ptr, stora_ptr, sizeof_storage);
|
Chris@102
|
1068 large_ptr += sizeof_storage;
|
Chris@102
|
1069 short_ptr += sizeof_storage;
|
Chris@102
|
1070 } while(--n);
|
Chris@102
|
1071 }
|
Chris@102
|
1072 std::memcpy(stora_ptr, large_ptr, szt_rem);
|
Chris@102
|
1073 std::memcpy(large_ptr, short_ptr, szt_rem);
|
Chris@102
|
1074 std::memcpy(short_ptr, stora_ptr, szt_rem);
|
Chris@102
|
1075 boost::container::iterator_advance(large_range_f, n_i);
|
Chris@102
|
1076 boost::container::iterator_advance(short_range_f, n_i);
|
Chris@102
|
1077 boost::container::uninitialized_move_alloc_n(a, large_range_f, n_j - n_i, short_range_f); // may throw
|
Chris@102
|
1078 boost::container::destroy_alloc_n(a, large_range_f, n_j - n_i);
|
Chris@102
|
1079 }
|
Chris@102
|
1080
|
Chris@102
|
1081
|
Chris@102
|
1082 //////////////////////////////////////////////////////////////////////////////
|
Chris@102
|
1083 //
|
Chris@102
|
1084 // copy_assign_range_alloc_n
|
Chris@102
|
1085 //
|
Chris@102
|
1086 //////////////////////////////////////////////////////////////////////////////
|
Chris@102
|
1087
|
Chris@102
|
1088 template
|
Chris@102
|
1089 <typename Allocator
|
Chris@102
|
1090 ,typename I // F models InputIterator
|
Chris@102
|
1091 ,typename O // G models OutputIterator
|
Chris@102
|
1092 >
|
Chris@102
|
1093 void copy_assign_range_alloc_n( Allocator &a, I inp_start, typename allocator_traits<Allocator>::size_type n_i
|
Chris@102
|
1094 , O out_start, typename allocator_traits<Allocator>::size_type n_o )
|
Chris@102
|
1095 {
|
Chris@102
|
1096 if (n_o < n_i){
|
Chris@102
|
1097 inp_start = boost::container::copy_n_source_dest(inp_start, n_o, out_start); // may throw
|
Chris@102
|
1098 boost::container::uninitialized_copy_alloc_n(a, inp_start, n_i - n_o, out_start);// may throw
|
Chris@102
|
1099 }
|
Chris@102
|
1100 else{
|
Chris@102
|
1101 out_start = boost::container::copy_n(inp_start, n_i, out_start); // may throw
|
Chris@102
|
1102 boost::container::destroy_alloc_n(a, out_start, n_o - n_i);
|
Chris@102
|
1103 }
|
Chris@102
|
1104 }
|
Chris@102
|
1105
|
Chris@102
|
1106 //////////////////////////////////////////////////////////////////////////////
|
Chris@102
|
1107 //
|
Chris@102
|
1108 // move_assign_range_alloc_n
|
Chris@102
|
1109 //
|
Chris@102
|
1110 //////////////////////////////////////////////////////////////////////////////
|
Chris@102
|
1111
|
Chris@102
|
1112 template
|
Chris@102
|
1113 <typename Allocator
|
Chris@102
|
1114 ,typename I // F models InputIterator
|
Chris@102
|
1115 ,typename O // G models OutputIterator
|
Chris@102
|
1116 >
|
Chris@102
|
1117 void move_assign_range_alloc_n( Allocator &a, I inp_start, typename allocator_traits<Allocator>::size_type n_i
|
Chris@102
|
1118 , O out_start, typename allocator_traits<Allocator>::size_type n_o )
|
Chris@102
|
1119 {
|
Chris@102
|
1120 if (n_o < n_i){
|
Chris@102
|
1121 inp_start = boost::container::move_n_source_dest(inp_start, n_o, out_start); // may throw
|
Chris@102
|
1122 boost::container::uninitialized_move_alloc_n(a, inp_start, n_i - n_o, out_start); // may throw
|
Chris@102
|
1123 }
|
Chris@102
|
1124 else{
|
Chris@102
|
1125 out_start = boost::container::move_n(inp_start, n_i, out_start); // may throw
|
Chris@102
|
1126 boost::container::destroy_alloc_n(a, out_start, n_o - n_i);
|
Chris@102
|
1127 }
|
Chris@102
|
1128 }
|
Chris@102
|
1129
|
Chris@102
|
1130 } //namespace container {
|
Chris@102
|
1131 } //namespace boost {
|
Chris@102
|
1132
|
Chris@102
|
1133 #endif //#ifndef BOOST_CONTAINER_DETAIL_UTILITIES_HPP
|