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