]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/container/detail/copy_move_algo.hpp
update sources to v12.2.3
[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 {
41namespace container_detail {
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
68/////////////////////////
69// predeclarations
70/////////////////////////
71
7c673cae
FG
72template<class Pointer>
73class vector_iterator;
74
75template<class Pointer>
76class vector_const_iterator;
77
7c673cae
FG
78} //namespace container_detail {
79} //namespace container {
80
81namespace interprocess {
82
83template <class PointedType, class DifferenceType, class OffsetType, std::size_t OffsetAlignment>
84class offset_ptr;
85
86} //namespace interprocess {
87
88namespace container {
89
90namespace container_detail {
91
92/////////////////////////
93//vector_[const_]iterator
94/////////////////////////
95
7c673cae
FG
96template<class Pointer>
97struct are_elements_contiguous<boost::container::container_detail::vector_iterator<Pointer> >
98{
99 static const bool value = true;
100};
101
102template<class Pointer>
103struct 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
112template <class PointedType, class DifferenceType, class OffsetType, std::size_t OffsetAlignment>
113struct are_elements_contiguous< ::boost::interprocess::offset_ptr<PointedType, DifferenceType, OffsetType, OffsetAlignment> >
114{
115 static const bool value = true;
116};
117
118template <typename I, typename O>
119struct 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
129template <typename I, typename O>
130struct 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
137template <typename I, typename O>
138struct 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
145template <typename I, typename O, typename R>
146struct enable_if_memtransfer_copy_constructible
147 : enable_if<container_detail::is_memtransfer_copy_constructible<I, O>, R>
148{};
149
150template <typename I, typename O, typename R>
151struct disable_if_memtransfer_copy_constructible
152 : disable_if<container_detail::is_memtransfer_copy_constructible<I, O>, R>
153{};
154
155template <typename I, typename O, typename R>
156struct enable_if_memtransfer_copy_assignable
157 : enable_if<container_detail::is_memtransfer_copy_assignable<I, O>, R>
158{};
159
160template <typename I, typename O, typename R>
161struct disable_if_memtransfer_copy_assignable
162 : disable_if<container_detail::is_memtransfer_copy_assignable<I, O>, R>
163{};
164
165template
166 <typename I, // I models InputIterator
167 typename F> // F models ForwardIterator
168inline 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
179template
180 <typename I, // I models InputIterator
b32b8144 181 typename U, // U models unsigned integral constant
7c673cae 182 typename F> // F models ForwardIterator
b32b8144 183F 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
193template
194 <typename I, // I models InputIterator
b32b8144 195 typename U, // U models unsigned integral constant
7c673cae 196 typename F> // F models ForwardIterator
b32b8144 197I 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
207template
208 <typename I, // I models InputIterator
b32b8144 209 typename U, // U models unsigned integral constant
7c673cae 210 typename F> // F models ForwardIterator
b32b8144 211I 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
222template <typename O>
223struct 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
240template <typename O, typename R>
241struct enable_if_memzero_initializable
242 : enable_if_c<container_detail::is_memzero_initializable<O>::value, R>
243{};
244
245template <typename O, typename R>
246struct disable_if_memzero_initializable
247 : enable_if_c<!container_detail::is_memzero_initializable<O>::value, R>
248{};
249
250template <typename I, typename R>
251struct 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
257template <typename I, typename R>
258struct 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
280template
281 <typename Allocator,
282 typename I, // I models InputIterator
283 typename F> // F models ForwardIterator
284inline 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
304template
305 <typename Allocator,
306 typename I, // I models InputIterator
307 typename F> // F models ForwardIterator
308inline 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
325template
326 <typename Allocator,
327 typename I, // I models InputIterator
328 typename F> // F models ForwardIterator
329inline 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
349template
350 <typename Allocator,
351 typename I, // I models InputIterator
352 typename F> // F models ForwardIterator
353inline 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)
370template
371 <typename Allocator,
372 typename I, // I models InputIterator
373 typename F> // F models ForwardIterator
374inline 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
394template
395 <typename Allocator,
396 typename I, // I models InputIterator
397 typename F> // F models ForwardIterator
398inline 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
415template
416 <typename Allocator,
417 typename I, // I models InputIterator
418 typename F> // F models ForwardIterator
419inline 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
439template
440 <typename Allocator,
441 typename I, // I models InputIterator
442 typename F> // F models ForwardIterator
443inline 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
460template
461 <typename Allocator,
462 typename I, // I models InputIterator
463 typename F> // F models ForwardIterator
464inline 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
484template
485 <typename Allocator,
486 typename I, // I models InputIterator
487 typename F> // F models ForwardIterator
488inline 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)
505template
506 <typename Allocator,
507 typename I, // I models InputIterator
508 typename F> // F models ForwardIterator
509inline 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
529template
530 <typename Allocator,
531 typename I, // I models InputIterator
532 typename F> // F models ForwardIterator
533inline 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
550template
551 <typename Allocator,
552 typename F> // F models ForwardIterator
553inline 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
573template
574 <typename Allocator,
575 typename F> // F models ForwardIterator
576inline 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
598template
599 <typename Allocator,
600 typename F> // F models ForwardIterator
b32b8144 601inline 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
633template
634 <typename Allocator,
635 typename F, // F models ForwardIterator
636 typename T>
637inline 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
669template
670 <typename Allocator,
671 typename T,
672 typename F> // F models ForwardIterator
b32b8144 673inline 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
698template
699<typename I, // I models InputIterator
700typename F> // F models ForwardIterator
701inline 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
711template
712<typename I, // I models InputIterator
713typename F> // F models ForwardIterator
714inline 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
724template
725<typename I, // I models InputIterator
b32b8144 726typename U, // U models unsigned integral constant
7c673cae
FG
727typename F> // F models ForwardIterator
728inline 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
738template
739<typename I, // I models InputIterator
b32b8144 740typename U, // U models unsigned integral constant
7c673cae
FG
741typename F> // F models ForwardIterator
742inline 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
752template
753<typename I, // I models InputIterator
b32b8144 754typename U, // U models unsigned integral constant
7c673cae
FG
755typename F> // F models ForwardIterator
756inline 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
766template
767<typename I, // I models InputIterator
b32b8144 768typename U, // U models unsigned integral constant
7c673cae
FG
769typename F> // F models ForwardIterator
770inline 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
780template
781<typename I, // I models InputIterator
b32b8144 782typename U, // U models unsigned integral constant
7c673cae
FG
783typename F> // F models ForwardIterator
784inline 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
794template
795<typename I, // I models InputIterator
b32b8144 796typename U, // U models unsigned integral constant
7c673cae
FG
797typename F> // F models ForwardIterator
798inline 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
808template
809<typename I, // I models InputIterator
810typename F> // F models ForwardIterator
811inline 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
821template
822<typename I, // I models InputIterator
823typename F> // F models ForwardIterator
824inline 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
834template
835<typename I, // I models InputIterator
b32b8144 836typename U, // U models unsigned integral constant
7c673cae
FG
837typename F> // F models ForwardIterator
838inline 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
848template
849<typename I, // I models InputIterator
b32b8144 850typename U, // U models unsigned integral constant
7c673cae
FG
851typename F> // F models ForwardIterator
852inline 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
863template
864<typename I, // I models BidirectionalIterator
865typename F> // F models ForwardIterator
866inline 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
876template
877<typename I, // I models InputIterator
878typename F> // F models ForwardIterator
879inline 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
895template
896<typename I // I models InputIterator
b32b8144 897,typename U // U models unsigned integral constant
7c673cae
FG
898,typename F> // F models ForwardIterator
899inline 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
909template
910<typename I // I models InputIterator
b32b8144 911,typename U // U models unsigned integral constant
7c673cae
FG
912,typename F> // F models ForwardIterator
913inline 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
923template
924<typename I // I models InputIterator
b32b8144 925,typename U // U models unsigned integral constant
7c673cae
FG
926,typename F> // F models ForwardIterator
927inline 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
937template
938<typename I // I models InputIterator
b32b8144 939,typename U // U models unsigned integral constant
7c673cae
FG
940,typename F> // F models ForwardIterator
941inline 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
951template
952 <typename Allocator
953 ,typename I // I models InputIterator
954 ,typename U> // U models unsigned integral constant
955inline 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
965template
966 <typename Allocator
967 ,typename I // I models InputIterator
968 ,typename U> // U models unsigned integral constant
969inline 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
979template
980 <std::size_t MaxTmpBytes
981 ,typename Allocator
982 ,typename F // F models ForwardIterator
983 ,typename G // G models ForwardIterator
984 >
985inline 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
997static const std::size_t DeepSwapAllocNMaxStorage = std::size_t(1) << std::size_t(11); //2K bytes
998
999template
1000 <std::size_t MaxTmpBytes
1001 ,typename Allocator
1002 ,typename F // F models ForwardIterator
1003 ,typename G // G models ForwardIterator
1004 >
1005inline 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
1029template
1030 <std::size_t MaxTmpBytes
1031 ,typename Allocator
1032 ,typename F // F models ForwardIterator
1033 ,typename G // G models ForwardIterator
1034 >
1035inline 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
1107template
1108 <typename Allocator
1109 ,typename I // F models InputIterator
1110 ,typename O // G models OutputIterator
1111 >
1112void 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
1131template
1132 <typename Allocator
1133 ,typename I // F models InputIterator
1134 ,typename O // G models OutputIterator
1135 >
1136void 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