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