1 //////////////////////////////////////////////////////////////////////////////
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)
7 // See http://www.boost.org/libs/container for documentation.
9 //////////////////////////////////////////////////////////////////////////////
10 #ifndef BOOST_CONTAINER_DETAIL_COPY_MOVE_ALGO_HPP
11 #define BOOST_CONTAINER_DETAIL_COPY_MOVE_ALGO_HPP
13 #ifndef BOOST_CONFIG_HPP
14 # include <boost/config.hpp>
17 #if defined(BOOST_HAS_PRAGMA_ONCE)
22 #include <boost/container/allocator_traits.hpp>
24 #include <boost/container/detail/iterator.hpp>
25 #include <boost/move/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>
31 #include <boost/move/adl_move_swap.hpp>
32 #include <boost/move/iterator.hpp>
33 #include <boost/move/utility_core.hpp>
35 #include <boost/core/no_exceptions_support.hpp>
37 #include <cstring> //for emmove/memcpy
41 namespace container_detail {
44 struct are_elements_contiguous
46 static const bool value = false;
49 /////////////////////////
51 /////////////////////////
54 struct are_elements_contiguous<T*>
56 static const bool value = true;
59 /////////////////////////
61 /////////////////////////
64 struct are_elements_contiguous< ::boost::move_iterator<It> >
65 : are_elements_contiguous<It>
68 /////////////////////////
70 /////////////////////////
72 template<class Pointer>
73 class vector_iterator;
75 template<class Pointer>
76 class vector_const_iterator;
78 } //namespace container_detail {
79 } //namespace container {
81 namespace interprocess {
83 template <class PointedType, class DifferenceType, class OffsetType, std::size_t OffsetAlignment>
86 } //namespace interprocess {
90 namespace container_detail {
92 /////////////////////////
93 //vector_[const_]iterator
94 /////////////////////////
96 template<class Pointer>
97 struct are_elements_contiguous<boost::container::container_detail::vector_iterator<Pointer> >
99 static const bool value = true;
102 template<class Pointer>
103 struct are_elements_contiguous<boost::container::container_detail::vector_const_iterator<Pointer> >
105 static const bool value = true;
108 /////////////////////////
110 /////////////////////////
112 template <class PointedType, class DifferenceType, class OffsetType, std::size_t OffsetAlignment>
113 struct are_elements_contiguous< ::boost::interprocess::offset_ptr<PointedType, DifferenceType, OffsetType, OffsetAlignment> >
115 static const bool value = true;
118 template <typename I, typename O>
119 struct are_contiguous_and_same
120 : boost::move_detail::and_
121 < are_elements_contiguous<I>
122 , are_elements_contiguous<O>
123 , is_same< typename remove_const< typename ::boost::container::iterator_traits<I>::value_type >::type
124 , typename ::boost::container::iterator_traits<O>::value_type
129 template <typename I, typename O>
130 struct is_memtransfer_copy_assignable
131 : boost::move_detail::and_
132 < are_contiguous_and_same<I, O>
133 , container_detail::is_trivially_copy_assignable< typename ::boost::container::iterator_traits<I>::value_type >
137 template <typename I, typename O>
138 struct is_memtransfer_copy_constructible
139 : boost::move_detail::and_
140 < are_contiguous_and_same<I, O>
141 , container_detail::is_trivially_copy_constructible< typename ::boost::container::iterator_traits<I>::value_type >
145 template <typename I, typename O, typename R>
146 struct enable_if_memtransfer_copy_constructible
147 : enable_if<container_detail::is_memtransfer_copy_constructible<I, O>, R>
150 template <typename I, typename O, typename R>
151 struct disable_if_memtransfer_copy_constructible
152 : disable_if<container_detail::is_memtransfer_copy_constructible<I, O>, R>
155 template <typename I, typename O, typename R>
156 struct enable_if_memtransfer_copy_assignable
157 : enable_if<container_detail::is_memtransfer_copy_assignable<I, O>, R>
160 template <typename I, typename O, typename R>
161 struct disable_if_memtransfer_copy_assignable
162 : disable_if<container_detail::is_memtransfer_copy_assignable<I, O>, R>
166 <typename I, // I models InputIterator
167 typename F> // F models ForwardIterator
168 inline F memmove(I f, I l, F r) BOOST_NOEXCEPT_OR_NOTHROW
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);
173 std::memmove(boost::movelib::iterator_to_raw_pointer(r), boost::movelib::iterator_to_raw_pointer(f), sizeof(value_type)*n);
174 boost::container::iterator_advance(r, n);
180 <typename I, // I models InputIterator
181 typename U, // U models unsigned integral constant
182 typename F> // F models ForwardIterator
183 F memmove_n(I f, U n, F r) BOOST_NOEXCEPT_OR_NOTHROW
185 typedef typename boost::container::iterator_traits<I>::value_type value_type;
187 std::memmove(boost::movelib::iterator_to_raw_pointer(r), boost::movelib::iterator_to_raw_pointer(f), sizeof(value_type)*n);
188 boost::container::iterator_advance(r, n);
194 <typename I, // I models InputIterator
195 typename U, // U models unsigned integral constant
196 typename F> // F models ForwardIterator
197 I memmove_n_source(I f, U n, F r) BOOST_NOEXCEPT_OR_NOTHROW
200 typedef typename boost::container::iterator_traits<I>::value_type value_type;
201 std::memmove(boost::movelib::iterator_to_raw_pointer(r), boost::movelib::iterator_to_raw_pointer(f), sizeof(value_type)*n);
202 boost::container::iterator_advance(f, n);
208 <typename I, // I models InputIterator
209 typename U, // U models unsigned integral constant
210 typename F> // F models ForwardIterator
211 I memmove_n_source_dest(I f, U n, F &r) BOOST_NOEXCEPT_OR_NOTHROW
213 typedef typename boost::container::iterator_traits<I>::value_type value_type;
215 std::memmove(boost::movelib::iterator_to_raw_pointer(r), boost::movelib::iterator_to_raw_pointer(f), sizeof(value_type)*n);
216 boost::container::iterator_advance(f, n);
217 boost::container::iterator_advance(r, n);
222 template <typename O>
223 struct is_memzero_initializable
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
231 #if defined(BOOST_CONTAINER_MEMZEROED_FLOATING_POINT_IS_ZERO)
232 || container_detail::is_floating_point<value_type>::value
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
240 template <typename O, typename R>
241 struct enable_if_memzero_initializable
242 : enable_if_c<container_detail::is_memzero_initializable<O>::value, R>
245 template <typename O, typename R>
246 struct disable_if_memzero_initializable
247 : enable_if_c<!container_detail::is_memzero_initializable<O>::value, R>
250 template <typename I, typename R>
251 struct enable_if_trivially_destructible
252 : enable_if_c < container_detail::is_trivially_destructible
253 <typename boost::container::iterator_traits<I>::value_type>::value
257 template <typename I, typename R>
258 struct disable_if_trivially_destructible
259 : enable_if_c <!container_detail::is_trivially_destructible
260 <typename boost::container::iterator_traits<I>::value_type>::value
264 } //namespace container_detail {
266 //////////////////////////////////////////////////////////////////////////////
268 // uninitialized_move_alloc
270 //////////////////////////////////////////////////////////////////////////////
275 //! for (; f != l; ++r, ++f)
276 //! allocator_traits::construct(a, &*r, boost::move(*f));
279 //! <b>Returns</b>: r
282 typename I, // I models InputIterator
283 typename F> // F models ForwardIterator
284 inline typename container_detail::disable_if_memtransfer_copy_constructible<I, F, F>::type
285 uninitialized_move_alloc(Allocator &a, I f, I l, F r)
290 allocator_traits<Allocator>::construct(a, boost::movelib::iterator_to_raw_pointer(r), boost::move(*f));
295 for (; back != r; ++back){
296 allocator_traits<Allocator>::destroy(a, boost::movelib::iterator_to_raw_pointer(back));
306 typename I, // I models InputIterator
307 typename F> // F models ForwardIterator
308 inline typename container_detail::enable_if_memtransfer_copy_constructible<I, F, F>::type
309 uninitialized_move_alloc(Allocator &, I f, I l, F r) BOOST_NOEXCEPT_OR_NOTHROW
310 { return container_detail::memmove(f, l, r); }
312 //////////////////////////////////////////////////////////////////////////////
314 // uninitialized_move_alloc_n
316 //////////////////////////////////////////////////////////////////////////////
320 //! for (; n--; ++r, ++f)
321 //! allocator_traits::construct(a, &*r, boost::move(*f));
324 //! <b>Returns</b>: r
327 typename I, // I models InputIterator
328 typename F> // F models ForwardIterator
329 inline typename container_detail::disable_if_memtransfer_copy_constructible<I, F, F>::type
330 uninitialized_move_alloc_n(Allocator &a, I f, typename boost::container::allocator_traits<Allocator>::size_type n, F r)
335 allocator_traits<Allocator>::construct(a, boost::movelib::iterator_to_raw_pointer(r), boost::move(*f));
340 for (; back != r; ++back){
341 allocator_traits<Allocator>::destroy(a, boost::movelib::iterator_to_raw_pointer(back));
351 typename I, // I models InputIterator
352 typename F> // F models ForwardIterator
353 inline typename container_detail::enable_if_memtransfer_copy_constructible<I, F, F>::type
354 uninitialized_move_alloc_n(Allocator &, I f, typename boost::container::allocator_traits<Allocator>::size_type n, F r) BOOST_NOEXCEPT_OR_NOTHROW
355 { return container_detail::memmove_n(f, n, r); }
357 //////////////////////////////////////////////////////////////////////////////
359 // uninitialized_move_alloc_n_source
361 //////////////////////////////////////////////////////////////////////////////
365 //! for (; n--; ++r, ++f)
366 //! allocator_traits::construct(a, &*r, boost::move(*f));
369 //! <b>Returns</b>: f (after incremented)
372 typename I, // I models InputIterator
373 typename F> // F models ForwardIterator
374 inline typename container_detail::disable_if_memtransfer_copy_constructible<I, F, I>::type
375 uninitialized_move_alloc_n_source(Allocator &a, I f, typename boost::container::allocator_traits<Allocator>::size_type n, F r)
380 allocator_traits<Allocator>::construct(a, boost::movelib::iterator_to_raw_pointer(r), boost::move(*f));
385 for (; back != r; ++back){
386 allocator_traits<Allocator>::destroy(a, boost::movelib::iterator_to_raw_pointer(back));
396 typename I, // I models InputIterator
397 typename F> // F models ForwardIterator
398 inline typename container_detail::enable_if_memtransfer_copy_constructible<I, F, I>::type
399 uninitialized_move_alloc_n_source(Allocator &, I f, typename boost::container::allocator_traits<Allocator>::size_type n, F r) BOOST_NOEXCEPT_OR_NOTHROW
400 { return container_detail::memmove_n_source(f, n, r); }
402 //////////////////////////////////////////////////////////////////////////////
404 // uninitialized_copy_alloc
406 //////////////////////////////////////////////////////////////////////////////
410 //! for (; f != l; ++r, ++f)
411 //! allocator_traits::construct(a, &*r, *f);
414 //! <b>Returns</b>: r
417 typename I, // I models InputIterator
418 typename F> // F models ForwardIterator
419 inline typename container_detail::disable_if_memtransfer_copy_constructible<I, F, F>::type
420 uninitialized_copy_alloc(Allocator &a, I f, I l, F r)
425 allocator_traits<Allocator>::construct(a, boost::movelib::iterator_to_raw_pointer(r), *f);
430 for (; back != r; ++back){
431 allocator_traits<Allocator>::destroy(a, boost::movelib::iterator_to_raw_pointer(back));
441 typename I, // I models InputIterator
442 typename F> // F models ForwardIterator
443 inline typename container_detail::enable_if_memtransfer_copy_constructible<I, F, F>::type
444 uninitialized_copy_alloc(Allocator &, I f, I l, F r) BOOST_NOEXCEPT_OR_NOTHROW
445 { return container_detail::memmove(f, l, r); }
447 //////////////////////////////////////////////////////////////////////////////
449 // uninitialized_copy_alloc_n
451 //////////////////////////////////////////////////////////////////////////////
455 //! for (; n--; ++r, ++f)
456 //! allocator_traits::construct(a, &*r, *f);
459 //! <b>Returns</b>: r
462 typename I, // I models InputIterator
463 typename F> // F models ForwardIterator
464 inline typename container_detail::disable_if_memtransfer_copy_constructible<I, F, F>::type
465 uninitialized_copy_alloc_n(Allocator &a, I f, typename boost::container::allocator_traits<Allocator>::size_type n, F r)
470 allocator_traits<Allocator>::construct(a, boost::movelib::iterator_to_raw_pointer(r), *f);
475 for (; back != r; ++back){
476 allocator_traits<Allocator>::destroy(a, boost::movelib::iterator_to_raw_pointer(back));
486 typename I, // I models InputIterator
487 typename F> // F models ForwardIterator
488 inline typename container_detail::enable_if_memtransfer_copy_constructible<I, F, F>::type
489 uninitialized_copy_alloc_n(Allocator &, I f, typename boost::container::allocator_traits<Allocator>::size_type n, F r) BOOST_NOEXCEPT_OR_NOTHROW
490 { return container_detail::memmove_n(f, n, r); }
492 //////////////////////////////////////////////////////////////////////////////
494 // uninitialized_copy_alloc_n_source
496 //////////////////////////////////////////////////////////////////////////////
500 //! for (; n--; ++r, ++f)
501 //! allocator_traits::construct(a, &*r, *f);
504 //! <b>Returns</b>: f (after incremented)
507 typename I, // I models InputIterator
508 typename F> // F models ForwardIterator
509 inline typename container_detail::disable_if_memtransfer_copy_constructible<I, F, I>::type
510 uninitialized_copy_alloc_n_source(Allocator &a, I f, typename boost::container::allocator_traits<Allocator>::size_type n, F r)
515 boost::container::construct_in_place(a, boost::movelib::iterator_to_raw_pointer(r), f);
520 for (; back != r; ++back){
521 allocator_traits<Allocator>::destroy(a, boost::movelib::iterator_to_raw_pointer(back));
531 typename I, // I models InputIterator
532 typename F> // F models ForwardIterator
533 inline typename container_detail::enable_if_memtransfer_copy_constructible<I, F, I>::type
534 uninitialized_copy_alloc_n_source(Allocator &, I f, typename boost::container::allocator_traits<Allocator>::size_type n, F r) BOOST_NOEXCEPT_OR_NOTHROW
535 { return container_detail::memmove_n_source(f, n, r); }
537 //////////////////////////////////////////////////////////////////////////////
539 // uninitialized_value_init_alloc_n
541 //////////////////////////////////////////////////////////////////////////////
545 //! for (; n--; ++r, ++f)
546 //! allocator_traits::construct(a, &*r);
549 //! <b>Returns</b>: r
552 typename F> // F models ForwardIterator
553 inline typename container_detail::disable_if_memzero_initializable<F, F>::type
554 uninitialized_value_init_alloc_n(Allocator &a, typename boost::container::allocator_traits<Allocator>::size_type n, F r)
559 allocator_traits<Allocator>::construct(a, boost::movelib::iterator_to_raw_pointer(r));
564 for (; back != r; ++back){
565 allocator_traits<Allocator>::destroy(a, boost::movelib::iterator_to_raw_pointer(back));
575 typename F> // F models ForwardIterator
576 inline typename container_detail::enable_if_memzero_initializable<F, F>::type
577 uninitialized_value_init_alloc_n(Allocator &, typename boost::container::allocator_traits<Allocator>::size_type n, F r)
579 typedef typename boost::container::iterator_traits<F>::value_type value_type;
580 std::memset((void*)boost::movelib::iterator_to_raw_pointer(r), 0, sizeof(value_type)*n);
581 boost::container::iterator_advance(r, n);
585 //////////////////////////////////////////////////////////////////////////////
587 // uninitialized_default_init_alloc_n
589 //////////////////////////////////////////////////////////////////////////////
593 //! for (; n--; ++r, ++f)
594 //! allocator_traits::construct(a, &*r);
597 //! <b>Returns</b>: r
600 typename F> // F models ForwardIterator
601 inline F uninitialized_default_init_alloc_n(Allocator &a, typename boost::container::allocator_traits<Allocator>::size_type n, F r)
606 allocator_traits<Allocator>::construct(a, boost::movelib::iterator_to_raw_pointer(r), default_init);
611 for (; back != r; ++back){
612 allocator_traits<Allocator>::destroy(a, boost::movelib::iterator_to_raw_pointer(back));
620 //////////////////////////////////////////////////////////////////////////////
622 // uninitialized_fill_alloc
624 //////////////////////////////////////////////////////////////////////////////
628 //! for (; f != l; ++r, ++f)
629 //! allocator_traits::construct(a, &*r, *f);
632 //! <b>Returns</b>: r
635 typename F, // F models ForwardIterator
637 inline void uninitialized_fill_alloc(Allocator &a, F f, F l, const T &t)
642 allocator_traits<Allocator>::construct(a, boost::movelib::iterator_to_raw_pointer(f), t);
647 for (; back != l; ++back){
648 allocator_traits<Allocator>::destroy(a, boost::movelib::iterator_to_raw_pointer(back));
656 //////////////////////////////////////////////////////////////////////////////
658 // uninitialized_fill_alloc_n
660 //////////////////////////////////////////////////////////////////////////////
664 //! for (; n--; ++r, ++f)
665 //! allocator_traits::construct(a, &*r, v);
668 //! <b>Returns</b>: r
672 typename F> // F models ForwardIterator
673 inline F uninitialized_fill_alloc_n(Allocator &a, const T &v, typename boost::container::allocator_traits<Allocator>::size_type n, F r)
678 allocator_traits<Allocator>::construct(a, boost::movelib::iterator_to_raw_pointer(r), v);
683 for (; back != r; ++back){
684 allocator_traits<Allocator>::destroy(a, boost::movelib::iterator_to_raw_pointer(back));
692 //////////////////////////////////////////////////////////////////////////////
696 //////////////////////////////////////////////////////////////////////////////
699 <typename I, // I models InputIterator
700 typename F> // F models ForwardIterator
701 inline typename container_detail::disable_if_memtransfer_copy_assignable<I, F, F>::type
712 <typename I, // I models InputIterator
713 typename F> // F models ForwardIterator
714 inline typename container_detail::enable_if_memtransfer_copy_assignable<I, F, F>::type
715 copy(I f, I l, F r) BOOST_NOEXCEPT_OR_NOTHROW
716 { return container_detail::memmove(f, l, r); }
718 //////////////////////////////////////////////////////////////////////////////
722 //////////////////////////////////////////////////////////////////////////////
725 <typename I, // I models InputIterator
726 typename U, // U models unsigned integral constant
727 typename F> // F models ForwardIterator
728 inline typename container_detail::disable_if_memtransfer_copy_assignable<I, F, F>::type
729 copy_n(I f, U n, F r)
739 <typename I, // I models InputIterator
740 typename U, // U models unsigned integral constant
741 typename F> // F models ForwardIterator
742 inline typename container_detail::enable_if_memtransfer_copy_assignable<I, F, F>::type
743 copy_n(I f, U n, F r) BOOST_NOEXCEPT_OR_NOTHROW
744 { return container_detail::memmove_n(f, n, r); }
746 //////////////////////////////////////////////////////////////////////////////
750 //////////////////////////////////////////////////////////////////////////////
753 <typename I, // I models InputIterator
754 typename U, // U models unsigned integral constant
755 typename F> // F models ForwardIterator
756 inline typename container_detail::disable_if_memtransfer_copy_assignable<I, F, I>::type
757 copy_n_source(I f, U n, F r)
760 boost::container::assign_in_place(r, f);
767 <typename I, // I models InputIterator
768 typename U, // U models unsigned integral constant
769 typename F> // F models ForwardIterator
770 inline typename container_detail::enable_if_memtransfer_copy_assignable<I, F, I>::type
771 copy_n_source(I f, U n, F r) BOOST_NOEXCEPT_OR_NOTHROW
772 { return container_detail::memmove_n_source(f, n, r); }
774 //////////////////////////////////////////////////////////////////////////////
776 // copy_n_source_dest
778 //////////////////////////////////////////////////////////////////////////////
781 <typename I, // I models InputIterator
782 typename U, // U models unsigned integral constant
783 typename F> // F models ForwardIterator
784 inline typename container_detail::disable_if_memtransfer_copy_assignable<I, F, I>::type
785 copy_n_source_dest(I f, U n, F &r)
795 <typename I, // I models InputIterator
796 typename U, // U models unsigned integral constant
797 typename F> // F models ForwardIterator
798 inline typename container_detail::enable_if_memtransfer_copy_assignable<I, F, I>::type
799 copy_n_source_dest(I f, U n, F &r) BOOST_NOEXCEPT_OR_NOTHROW
800 { return container_detail::memmove_n_source_dest(f, n, r); }
802 //////////////////////////////////////////////////////////////////////////////
806 //////////////////////////////////////////////////////////////////////////////
809 <typename I, // I models InputIterator
810 typename F> // F models ForwardIterator
811 inline typename container_detail::disable_if_memtransfer_copy_assignable<I, F, F>::type
815 *r = ::boost::move(*f);
822 <typename I, // I models InputIterator
823 typename F> // F models ForwardIterator
824 inline typename container_detail::enable_if_memtransfer_copy_assignable<I, F, F>::type
825 move(I f, I l, F r) BOOST_NOEXCEPT_OR_NOTHROW
826 { return container_detail::memmove(f, l, r); }
828 //////////////////////////////////////////////////////////////////////////////
832 //////////////////////////////////////////////////////////////////////////////
835 <typename I, // I models InputIterator
836 typename U, // U models unsigned integral constant
837 typename F> // F models ForwardIterator
838 inline typename container_detail::disable_if_memtransfer_copy_assignable<I, F, F>::type
839 move_n(I f, U n, F r)
842 *r = ::boost::move(*f);
849 <typename I, // I models InputIterator
850 typename U, // U models unsigned integral constant
851 typename F> // F models ForwardIterator
852 inline typename container_detail::enable_if_memtransfer_copy_assignable<I, F, F>::type
853 move_n(I f, U n, F r) BOOST_NOEXCEPT_OR_NOTHROW
854 { return container_detail::memmove_n(f, n, r); }
857 //////////////////////////////////////////////////////////////////////////////
861 //////////////////////////////////////////////////////////////////////////////
864 <typename I, // I models BidirectionalIterator
865 typename F> // F models ForwardIterator
866 inline typename container_detail::disable_if_memtransfer_copy_assignable<I, F, F>::type
867 move_backward(I f, I l, F r)
871 *r = ::boost::move(*l);
877 <typename I, // I models InputIterator
878 typename F> // F models ForwardIterator
879 inline typename container_detail::enable_if_memtransfer_copy_assignable<I, F, F>::type
880 move_backward(I f, I l, F r) BOOST_NOEXCEPT_OR_NOTHROW
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);
885 std::memmove((boost::movelib::iterator_to_raw_pointer)(r), (boost::movelib::iterator_to_raw_pointer)(f), sizeof(value_type)*n);
889 //////////////////////////////////////////////////////////////////////////////
891 // move_n_source_dest
893 //////////////////////////////////////////////////////////////////////////////
896 <typename I // I models InputIterator
897 ,typename U // U models unsigned integral constant
898 ,typename F> // F models ForwardIterator
899 inline typename container_detail::disable_if_memtransfer_copy_assignable<I, F, I>::type
900 move_n_source_dest(I f, U n, F &r)
903 *r = ::boost::move(*f);
910 <typename I // I models InputIterator
911 ,typename U // U models unsigned integral constant
912 ,typename F> // F models ForwardIterator
913 inline typename container_detail::enable_if_memtransfer_copy_assignable<I, F, I>::type
914 move_n_source_dest(I f, U n, F &r) BOOST_NOEXCEPT_OR_NOTHROW
915 { return container_detail::memmove_n_source_dest(f, n, r); }
917 //////////////////////////////////////////////////////////////////////////////
921 //////////////////////////////////////////////////////////////////////////////
924 <typename I // I models InputIterator
925 ,typename U // U models unsigned integral constant
926 ,typename F> // F models ForwardIterator
927 inline typename container_detail::disable_if_memtransfer_copy_assignable<I, F, I>::type
928 move_n_source(I f, U n, F r)
931 *r = ::boost::move(*f);
938 <typename I // I models InputIterator
939 ,typename U // U models unsigned integral constant
940 ,typename F> // F models ForwardIterator
941 inline typename container_detail::enable_if_memtransfer_copy_assignable<I, F, I>::type
942 move_n_source(I f, U n, F r) BOOST_NOEXCEPT_OR_NOTHROW
943 { return container_detail::memmove_n_source(f, n, r); }
945 //////////////////////////////////////////////////////////////////////////////
949 //////////////////////////////////////////////////////////////////////////////
953 ,typename I // I models InputIterator
954 ,typename U> // U models unsigned integral constant
955 inline typename container_detail::disable_if_trivially_destructible<I, void>::type
956 destroy_alloc_n(Allocator &a, I f, U n)
960 allocator_traits<Allocator>::destroy(a, boost::movelib::iterator_to_raw_pointer(f));
967 ,typename I // I models InputIterator
968 ,typename U> // U models unsigned integral constant
969 inline typename container_detail::enable_if_trivially_destructible<I, void>::type
970 destroy_alloc_n(Allocator &, I, U)
973 //////////////////////////////////////////////////////////////////////////////
977 //////////////////////////////////////////////////////////////////////////////
980 <std::size_t MaxTmpBytes
982 ,typename F // F models ForwardIterator
983 ,typename G // G models ForwardIterator
985 inline typename container_detail::disable_if_memtransfer_copy_assignable<F, G, void>::type
986 deep_swap_alloc_n( Allocator &a, F short_range_f, typename allocator_traits<Allocator>::size_type n_i
987 , G large_range_f, typename allocator_traits<Allocator>::size_type n_j)
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);
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);
997 static const std::size_t DeepSwapAllocNMaxStorage = std::size_t(1) << std::size_t(11); //2K bytes
1000 <std::size_t MaxTmpBytes
1002 ,typename F // F models ForwardIterator
1003 ,typename G // G models ForwardIterator
1005 inline typename container_detail::enable_if_c
1006 < container_detail::is_memtransfer_copy_assignable<F, G>::value && (MaxTmpBytes <= DeepSwapAllocNMaxStorage) && false
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)
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;
1016 const std::size_t n_i_bytes = sizeof(value_type)*n_i;
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));
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);
1030 <std::size_t MaxTmpBytes
1032 ,typename F // F models ForwardIterator
1033 ,typename G // G models ForwardIterator
1035 inline typename container_detail::enable_if_c
1036 < container_detail::is_memtransfer_copy_assignable<F, G>::value && true//(MaxTmpBytes > DeepSwapAllocNMaxStorage)
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)
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);
1047 std::size_t n_i_bytes = sizeof(value_type)*n_i;
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)));
1050 char *stora_ptr = static_cast<char*>(static_cast<void*>(&storage));
1052 std::size_t szt_times = n_i_bytes/sizeof_storage;
1053 const std::size_t szt_rem = n_i_bytes%sizeof_storage;
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){
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;
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;
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;
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;
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);
1101 //////////////////////////////////////////////////////////////////////////////
1103 // copy_assign_range_alloc_n
1105 //////////////////////////////////////////////////////////////////////////////
1109 ,typename I // F models InputIterator
1110 ,typename O // G models OutputIterator
1112 void copy_assign_range_alloc_n( Allocator &a, I inp_start, typename allocator_traits<Allocator>::size_type n_i
1113 , O out_start, typename allocator_traits<Allocator>::size_type n_o )
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
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);
1125 //////////////////////////////////////////////////////////////////////////////
1127 // move_assign_range_alloc_n
1129 //////////////////////////////////////////////////////////////////////////////
1133 ,typename I // F models InputIterator
1134 ,typename O // G models OutputIterator
1136 void move_assign_range_alloc_n( Allocator &a, I inp_start, typename allocator_traits<Allocator>::size_type n_i
1137 , O out_start, typename allocator_traits<Allocator>::size_type n_o )
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
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);
1149 } //namespace container {
1150 } //namespace boost {
1152 #endif //#ifndef BOOST_CONTAINER_DETAIL_COPY_MOVE_ALGO_HPP