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