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