File indexing completed on 2025-10-14 08:22:27
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_CONTAINER_CONTAINER_VECTOR_HPP
0012 #define BOOST_CONTAINER_CONTAINER_VECTOR_HPP
0013
0014 #ifndef BOOST_CONFIG_HPP
0015 # include <boost/config.hpp>
0016 #endif
0017
0018 #if defined(BOOST_HAS_PRAGMA_ONCE)
0019 # pragma once
0020 #endif
0021
0022 #include <boost/container/detail/config_begin.hpp>
0023 #include <boost/container/detail/workaround.hpp>
0024
0025
0026 #include <boost/container/container_fwd.hpp>
0027 #include <boost/container/allocator_traits.hpp>
0028 #include <boost/container/new_allocator.hpp> //new_allocator
0029 #include <boost/container/throw_exception.hpp>
0030 #include <boost/container/options.hpp>
0031
0032 #include <boost/container/detail/advanced_insert_int.hpp>
0033 #include <boost/container/detail/algorithm.hpp> //equal()
0034 #include <boost/container/detail/alloc_helpers.hpp>
0035 #include <boost/container/detail/allocation_type.hpp>
0036 #include <boost/container/detail/copy_move_algo.hpp>
0037 #include <boost/container/detail/destroyers.hpp>
0038 #include <boost/container/detail/iterator.hpp>
0039 #include <boost/container/detail/iterators.hpp>
0040 #include <boost/move/detail/iterator_to_raw_pointer.hpp>
0041 #include <boost/container/detail/mpl.hpp>
0042 #include <boost/container/detail/next_capacity.hpp>
0043 #include <boost/container/detail/value_functors.hpp>
0044 #include <boost/move/detail/to_raw_pointer.hpp>
0045 #include <boost/container/detail/type_traits.hpp>
0046 #include <boost/container/detail/version_type.hpp>
0047
0048 #include <boost/intrusive/pointer_traits.hpp>
0049
0050 #include <boost/move/adl_move_swap.hpp>
0051 #include <boost/move/iterator.hpp>
0052 #include <boost/move/traits.hpp>
0053 #include <boost/move/utility_core.hpp>
0054 #include <boost/move/detail/launder.hpp>
0055
0056 #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
0057 #include <boost/move/detail/fwd_macros.hpp>
0058 #endif
0059 #include <boost/move/detail/move_helpers.hpp>
0060
0061 #include <boost/move/algo/adaptive_merge.hpp>
0062 #include <boost/move/algo/unique.hpp>
0063 #include <boost/move/algo/predicate.hpp>
0064 #include <boost/move/algo/detail/set_difference.hpp>
0065
0066 #include <boost/assert.hpp>
0067 #include <boost/cstdint.hpp>
0068
0069
0070 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
0071 #include <initializer_list> //for std::initializer_list
0072 #endif
0073
0074 namespace boost {
0075 namespace container {
0076
0077 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
0078
0079
0080 template <class Pointer, bool IsConst>
0081 class vec_iterator
0082 {
0083 public:
0084 typedef std::random_access_iterator_tag iterator_category;
0085 #ifdef BOOST_MOVE_CONTIGUOUS_ITERATOR_TAG
0086 typedef std::contiguous_iterator_tag iterator_concept;
0087 #endif
0088 typedef typename boost::intrusive::pointer_traits<Pointer>::element_type value_type;
0089
0090
0091
0092
0093
0094 #ifndef BOOST_GNU_STDLIB
0095
0096 typedef typename boost::intrusive::pointer_traits<Pointer>::element_type element_type;
0097 #endif
0098 typedef typename boost::intrusive::pointer_traits<Pointer>::difference_type difference_type;
0099 typedef typename boost::intrusive::pointer_traits<Pointer>::size_type size_type;
0100 typedef typename dtl::if_c
0101 < IsConst
0102 , typename boost::intrusive::pointer_traits<Pointer>::template
0103 rebind_pointer<const value_type>::type
0104 , Pointer
0105 >::type pointer;
0106 typedef typename boost::intrusive::pointer_traits<pointer> ptr_traits;
0107 typedef typename ptr_traits::reference reference;
0108
0109 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
0110 private:
0111 Pointer m_ptr;
0112
0113 class nat
0114 {
0115 public:
0116 Pointer get_ptr() const
0117 { return Pointer(); }
0118 };
0119 typedef typename dtl::if_c< IsConst
0120 , vec_iterator<Pointer, false>
0121 , nat>::type nonconst_iterator;
0122
0123 public:
0124 inline
0125 const Pointer &get_ptr() const BOOST_NOEXCEPT_OR_NOTHROW
0126 { return m_ptr; }
0127
0128 inline
0129 Pointer &get_ptr() BOOST_NOEXCEPT_OR_NOTHROW
0130 { return m_ptr; }
0131
0132 inline explicit vec_iterator(Pointer ptr) BOOST_NOEXCEPT_OR_NOTHROW
0133 : m_ptr(ptr)
0134 {}
0135 #endif
0136
0137 public:
0138
0139
0140 inline vec_iterator() BOOST_NOEXCEPT_OR_NOTHROW
0141 : m_ptr()
0142 {}
0143
0144 inline vec_iterator(const vec_iterator& other) BOOST_NOEXCEPT_OR_NOTHROW
0145 : m_ptr(other.get_ptr())
0146 {}
0147
0148 inline vec_iterator(const nonconst_iterator &other) BOOST_NOEXCEPT_OR_NOTHROW
0149 : m_ptr(other.get_ptr())
0150 {}
0151
0152 inline vec_iterator & operator=(const vec_iterator& other) BOOST_NOEXCEPT_OR_NOTHROW
0153 { m_ptr = other.get_ptr(); return *this; }
0154
0155
0156 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
0157 reference operator*() const BOOST_NOEXCEPT_OR_NOTHROW
0158 { BOOST_ASSERT(!!m_ptr); return *m_ptr; }
0159
0160 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
0161 pointer operator->() const BOOST_NOEXCEPT_OR_NOTHROW
0162 { return m_ptr; }
0163
0164 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
0165 reference operator[](difference_type off) const BOOST_NOEXCEPT_OR_NOTHROW
0166 { BOOST_ASSERT(!!m_ptr); return m_ptr[off]; }
0167
0168
0169 inline vec_iterator& operator++() BOOST_NOEXCEPT_OR_NOTHROW
0170 { BOOST_ASSERT(!!m_ptr); ++m_ptr; return *this; }
0171
0172 inline vec_iterator operator++(int) BOOST_NOEXCEPT_OR_NOTHROW
0173 { BOOST_ASSERT(!!m_ptr); return vec_iterator(m_ptr++); }
0174
0175 inline vec_iterator& operator--() BOOST_NOEXCEPT_OR_NOTHROW
0176 { BOOST_ASSERT(!!m_ptr); --m_ptr; return *this; }
0177
0178 inline vec_iterator operator--(int) BOOST_NOEXCEPT_OR_NOTHROW
0179 { BOOST_ASSERT(!!m_ptr); return vec_iterator(m_ptr--); }
0180
0181
0182 inline vec_iterator& operator+=(difference_type off) BOOST_NOEXCEPT_OR_NOTHROW
0183 { BOOST_ASSERT(m_ptr || !off); m_ptr += off; return *this; }
0184
0185 inline vec_iterator& operator-=(difference_type off) BOOST_NOEXCEPT_OR_NOTHROW
0186 { BOOST_ASSERT(m_ptr || !off); m_ptr -= off; return *this; }
0187
0188 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
0189 friend vec_iterator operator+(const vec_iterator &x, difference_type off) BOOST_NOEXCEPT_OR_NOTHROW
0190 { BOOST_ASSERT(x.m_ptr || !off); return vec_iterator(x.m_ptr+off); }
0191
0192 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
0193 friend vec_iterator operator+(difference_type off, vec_iterator right) BOOST_NOEXCEPT_OR_NOTHROW
0194 { BOOST_ASSERT(right.m_ptr || !off); right.m_ptr += off; return right; }
0195
0196 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
0197 friend vec_iterator operator-(vec_iterator left, difference_type off) BOOST_NOEXCEPT_OR_NOTHROW
0198 { BOOST_ASSERT(left.m_ptr || !off); left.m_ptr -= off; return left; }
0199
0200
0201 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
0202 friend difference_type operator-(const vec_iterator &left, const vec_iterator& right) BOOST_NOEXCEPT_OR_NOTHROW
0203 { return left.m_ptr - right.m_ptr; }
0204
0205
0206 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
0207 friend bool operator== (const vec_iterator& l, const vec_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
0208 { return l.m_ptr == r.m_ptr; }
0209
0210 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
0211 friend bool operator!= (const vec_iterator& l, const vec_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
0212 { return l.m_ptr != r.m_ptr; }
0213
0214 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
0215 friend bool operator< (const vec_iterator& l, const vec_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
0216 { return l.m_ptr < r.m_ptr; }
0217
0218 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
0219 friend bool operator<= (const vec_iterator& l, const vec_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
0220 { return l.m_ptr <= r.m_ptr; }
0221
0222 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
0223 friend bool operator> (const vec_iterator& l, const vec_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
0224 { return l.m_ptr > r.m_ptr; }
0225
0226 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
0227 friend bool operator>= (const vec_iterator& l, const vec_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
0228 { return l.m_ptr >= r.m_ptr; }
0229 };
0230
0231 template<class BiDirPosConstIt, class BiDirValueIt>
0232 struct vector_insert_ordered_cursor
0233 {
0234 typedef typename iterator_traits<BiDirPosConstIt>::value_type size_type;
0235 typedef typename iterator_traits<BiDirValueIt>::reference reference;
0236
0237 inline vector_insert_ordered_cursor(BiDirPosConstIt posit, BiDirValueIt valueit)
0238 : last_position_it(posit), last_value_it(valueit)
0239 {}
0240
0241 void operator --()
0242 {
0243 --last_value_it;
0244 --last_position_it;
0245 while(this->get_pos() == size_type(-1)){
0246 --last_value_it;
0247 --last_position_it;
0248 }
0249 }
0250
0251 inline size_type get_pos() const
0252 { return *last_position_it; }
0253
0254 inline reference get_val()
0255 { return *last_value_it; }
0256
0257 BiDirPosConstIt last_position_it;
0258 BiDirValueIt last_value_it;
0259 };
0260
0261 template<class Pointer, bool IsConst>
0262 inline const Pointer &vector_iterator_get_ptr(const vec_iterator<Pointer, IsConst> &it) BOOST_NOEXCEPT_OR_NOTHROW
0263 { return it.get_ptr(); }
0264
0265 template<class Pointer, bool IsConst>
0266 inline Pointer &get_ptr(vec_iterator<Pointer, IsConst> &it) BOOST_NOEXCEPT_OR_NOTHROW
0267 { return it.get_ptr(); }
0268
0269 struct initial_capacity_t {};
0270
0271 struct vector_uninitialized_size_t {};
0272 BOOST_CONTAINER_CONSTANT_VAR vector_uninitialized_size_t vector_uninitialized_size = vector_uninitialized_size_t();
0273
0274 struct maybe_initial_capacity_t {};
0275
0276 template <class T>
0277 struct vector_value_traits_base
0278 {
0279 BOOST_STATIC_CONSTEXPR bool trivial_dctr = dtl::is_trivially_destructible<T>::value;
0280 BOOST_STATIC_CONSTEXPR bool trivial_dctr_after_move = has_trivial_destructor_after_move<T>::value;
0281 };
0282
0283 template <class Allocator>
0284 struct vector_value_traits
0285 : public vector_value_traits_base<typename Allocator::value_type>
0286 {
0287 typedef vector_value_traits_base<typename Allocator::value_type> base_t;
0288
0289
0290 typedef typename dtl::if_c
0291 <base_t::trivial_dctr
0292 ,dtl::null_scoped_destructor_n<Allocator>
0293 ,dtl::scoped_destructor_n<Allocator>
0294 >::type ArrayDestructor;
0295
0296 typedef dtl::scoped_array_deallocator<Allocator> ArrayDeallocator;
0297 };
0298
0299
0300 template < class Allocator
0301 , class StoredSizeType
0302 , class AllocatorVersion = typename dtl::version<Allocator>::type
0303 >
0304 struct vector_alloc_holder
0305 : public Allocator
0306 {
0307 private:
0308 BOOST_MOVABLE_BUT_NOT_COPYABLE(vector_alloc_holder)
0309
0310 public:
0311 typedef Allocator allocator_type;
0312 typedef StoredSizeType stored_size_type;
0313 typedef boost::container::allocator_traits<allocator_type> allocator_traits_type;
0314 typedef typename allocator_traits_type::pointer pointer;
0315 typedef typename allocator_traits_type::size_type size_type;
0316 typedef typename allocator_traits_type::value_type value_type;
0317
0318
0319 private:
0320
0321 template<class SizeType>
0322 void do_initial_capacity(SizeType initial_capacity)
0323 {
0324 if (BOOST_UNLIKELY(initial_capacity > size_type(-1))) {
0325 boost::container::throw_length_error("get_next_capacity, allocator's max size reached");
0326 }
0327 else if (initial_capacity) {
0328 pointer reuse = pointer();
0329 size_type final_cap = static_cast<size_type>(initial_capacity);
0330 m_start = this->allocation_command(allocate_new, final_cap, final_cap, reuse);
0331 this->set_stored_capacity(final_cap);
0332 }
0333 }
0334
0335 template<class SizeType>
0336 void do_maybe_initial_capacity(pointer p, SizeType initial_capacity)
0337 {
0338 if (BOOST_UNLIKELY(initial_capacity > size_type(-1))) {
0339 boost::container::throw_length_error("get_next_capacity, allocator's max size reached");
0340 }
0341 else if (p) {
0342 m_start = p;
0343 }
0344 else {
0345 BOOST_ASSERT(initial_capacity > 0);
0346 pointer reuse = pointer();
0347 size_type final_cap = static_cast<size_type>(initial_capacity);
0348 m_start = this->allocation_command(allocate_new, final_cap, final_cap, reuse);
0349 this->set_stored_capacity(final_cap);
0350 }
0351 }
0352
0353 public:
0354
0355 template <bool PropagateAllocator>
0356 inline static bool is_propagable_from(const allocator_type &from_alloc, pointer p, const allocator_type &to_alloc)
0357 {
0358 (void)p; (void)to_alloc; (void)from_alloc;
0359 const bool all_storage_propagable = !allocator_traits_type::is_partially_propagable::value ||
0360 !allocator_traits_type::storage_is_unpropagable(from_alloc, p);
0361 return all_storage_propagable &&
0362 (PropagateAllocator || allocator_traits_type::is_always_equal::value || allocator_traits_type::equal(from_alloc, to_alloc));
0363 }
0364
0365 template <bool PropagateAllocator>
0366 inline static bool are_swap_propagable(const allocator_type &l_a, pointer l_p, const allocator_type &r_a, pointer r_p)
0367 {
0368 (void)l_p; (void)r_p; (void)l_a; (void)r_a;
0369 const bool all_storage_propagable = !allocator_traits_type::is_partially_propagable::value ||
0370 !(allocator_traits_type::storage_is_unpropagable(l_a, l_p) || allocator_traits_type::storage_is_unpropagable(r_a, r_p));
0371 return all_storage_propagable && (PropagateAllocator || allocator_traits_type::is_always_equal::value || allocator_traits_type::equal(l_a, r_a));
0372 }
0373
0374
0375 vector_alloc_holder()
0376 BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible<allocator_type>::value)
0377 : allocator_type(), m_start(), m_size(), m_capacity()
0378 {}
0379
0380
0381 template<class AllocConvertible>
0382 explicit vector_alloc_holder(BOOST_FWD_REF(AllocConvertible) a) BOOST_NOEXCEPT_OR_NOTHROW
0383 : allocator_type(boost::forward<AllocConvertible>(a)), m_start(), m_size(), m_capacity()
0384 {}
0385
0386
0387 template<class AllocConvertible, class SizeType>
0388 vector_alloc_holder(vector_uninitialized_size_t, BOOST_FWD_REF(AllocConvertible) a, SizeType initial_size)
0389 : allocator_type(boost::forward<AllocConvertible>(a))
0390 , m_start()
0391
0392 , m_size(static_cast<stored_size_type>(initial_size))
0393 , m_capacity()
0394 { this->do_initial_capacity(initial_size); }
0395
0396 template<class SizeType>
0397 vector_alloc_holder(vector_uninitialized_size_t, SizeType initial_size)
0398 : allocator_type()
0399 , m_start()
0400
0401 , m_size(static_cast<stored_size_type>(initial_size))
0402 , m_capacity()
0403 { this->do_initial_capacity(initial_size); }
0404
0405 vector_alloc_holder(initial_capacity_t, pointer p, size_type n)
0406 BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible<allocator_type>::value)
0407 : allocator_type()
0408 , m_start(p)
0409 , m_size()
0410
0411 , m_capacity(static_cast<stored_size_type>(n))
0412 {}
0413
0414 template<class AllocFwd>
0415 vector_alloc_holder(initial_capacity_t, pointer p, size_type n, BOOST_FWD_REF(AllocFwd) a)
0416 : allocator_type(::boost::forward<AllocFwd>(a))
0417 , m_start(p)
0418 , m_size()
0419 , m_capacity(n)
0420 {}
0421
0422 template<class AllocConvertible, class SizeType>
0423 vector_alloc_holder(maybe_initial_capacity_t, pointer p, SizeType initial_capacity, BOOST_FWD_REF(AllocConvertible) a)
0424 : allocator_type(boost::forward<AllocConvertible>(a))
0425
0426
0427 , m_size()
0428 , m_capacity(static_cast<stored_size_type>(initial_capacity))
0429 { this->do_maybe_initial_capacity(p, initial_capacity); }
0430
0431 template<class SizeType>
0432 vector_alloc_holder(maybe_initial_capacity_t, pointer p, SizeType initial_capacity)
0433 : allocator_type()
0434
0435
0436 , m_size()
0437 , m_capacity(static_cast<stored_size_type>(initial_capacity))
0438 { this->do_maybe_initial_capacity(p, initial_capacity); }
0439
0440 vector_alloc_holder(BOOST_RV_REF(vector_alloc_holder) holder) BOOST_NOEXCEPT_OR_NOTHROW
0441 : allocator_type(BOOST_MOVE_BASE(allocator_type, holder))
0442 , m_start(holder.m_start)
0443 , m_size(holder.m_size)
0444 , m_capacity(holder.m_capacity)
0445 {
0446 holder.m_start = pointer();
0447 holder.m_size = holder.m_capacity = 0;
0448 }
0449
0450 inline ~vector_alloc_holder() BOOST_NOEXCEPT_OR_NOTHROW
0451 {
0452 if(this->m_capacity){
0453 this->deallocate(this->m_start, this->m_capacity);
0454 }
0455 }
0456
0457 inline void set_stored_size(size_type s) BOOST_NOEXCEPT_OR_NOTHROW
0458 { this->m_size = static_cast<stored_size_type>(s); }
0459
0460 inline void dec_stored_size(size_type s) BOOST_NOEXCEPT_OR_NOTHROW
0461 { this->m_size = static_cast<stored_size_type>(this->m_size - s); }
0462
0463 inline void inc_stored_size(size_type s) BOOST_NOEXCEPT_OR_NOTHROW
0464 { this->m_size = static_cast<stored_size_type>(this->m_size + s); }
0465
0466 inline void set_stored_capacity(size_type c) BOOST_NOEXCEPT_OR_NOTHROW
0467 { this->m_capacity = static_cast<stored_size_type>(c); }
0468
0469 inline pointer allocation_command(boost::container::allocation_type command,
0470 size_type limit_size, size_type &prefer_in_recvd_out_size, pointer &reuse)
0471 {
0472 typedef typename dtl::version<allocator_type>::type alloc_version;
0473 return this->priv_allocation_command(alloc_version(), command, limit_size, prefer_in_recvd_out_size, reuse);
0474 }
0475
0476 inline pointer allocate(size_type n)
0477 {
0478 const size_type max_alloc = allocator_traits_type::max_size(this->alloc());
0479 const size_type max = max_alloc <= stored_size_type(-1) ? max_alloc : stored_size_type(-1);
0480 if (BOOST_UNLIKELY(max < n) )
0481 boost::container::throw_length_error("get_next_capacity, allocator's max size reached");
0482
0483 return allocator_traits_type::allocate(this->alloc(), n);
0484 }
0485
0486 inline void deallocate(const pointer &p, size_type n)
0487 {
0488 allocator_traits_type::deallocate(this->alloc(), p, n);
0489 }
0490
0491 bool try_expand_fwd(size_type at_least)
0492 {
0493
0494 const size_type new_cap = size_type(this->capacity() + at_least);
0495 size_type real_cap = new_cap;
0496 pointer reuse = this->start();
0497 bool const success = !!this->allocation_command(expand_fwd, new_cap, real_cap, reuse);
0498
0499 if(success){
0500 #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
0501 ++this->num_expand_fwd;
0502 #endif
0503 this->capacity(real_cap);
0504 }
0505 return success;
0506 }
0507
0508 template<class GrowthFactorType>
0509 size_type next_capacity(size_type additional_objects) const
0510 {
0511 BOOST_ASSERT(additional_objects > size_type(this->m_capacity - this->m_size));
0512 size_type max = allocator_traits_type::max_size(this->alloc());
0513 (clamp_by_stored_size_type<size_type>)(max, stored_size_type());
0514 const size_type remaining_cap = size_type(max - size_type(this->m_capacity));
0515 const size_type min_additional_cap = size_type(additional_objects - size_type(this->m_capacity - this->m_size));
0516
0517 if ( remaining_cap < min_additional_cap )
0518 boost::container::throw_length_error("get_next_capacity, allocator's max size reached");
0519
0520 return GrowthFactorType()( size_type(this->m_capacity), min_additional_cap, max);
0521 }
0522
0523 pointer m_start;
0524 stored_size_type m_size;
0525 stored_size_type m_capacity;
0526
0527 void swap_resources(vector_alloc_holder &x) BOOST_NOEXCEPT_OR_NOTHROW
0528 {
0529 boost::adl_move_swap(this->m_start, x.m_start);
0530 boost::adl_move_swap(this->m_size, x.m_size);
0531 boost::adl_move_swap(this->m_capacity, x.m_capacity);
0532 }
0533
0534 void steal_resources(vector_alloc_holder &x) BOOST_NOEXCEPT_OR_NOTHROW
0535 {
0536 this->m_start = x.m_start;
0537 this->m_size = x.m_size;
0538 this->m_capacity = x.m_capacity;
0539 x.m_start = pointer();
0540 x.m_size = x.m_capacity = 0;
0541 }
0542
0543 inline allocator_type &alloc() BOOST_NOEXCEPT_OR_NOTHROW
0544 { return *this; }
0545
0546 inline const allocator_type &alloc() const BOOST_NOEXCEPT_OR_NOTHROW
0547 { return *this; }
0548
0549 inline pointer start() const BOOST_NOEXCEPT_OR_NOTHROW
0550 { return m_start; }
0551 inline size_type capacity() const BOOST_NOEXCEPT_OR_NOTHROW
0552 { return m_capacity; }
0553 inline void start(const pointer &p) BOOST_NOEXCEPT_OR_NOTHROW
0554 { m_start = p; }
0555 inline void capacity(const size_type &c) BOOST_NOEXCEPT_OR_NOTHROW
0556 { BOOST_ASSERT( c <= stored_size_type(-1)); this->set_stored_capacity(c); }
0557
0558 static inline void on_capacity_overflow()
0559 { }
0560
0561 private:
0562 void priv_first_allocation(size_type cap)
0563 {
0564 if(cap){
0565 pointer reuse = pointer();
0566 m_start = this->allocation_command(allocate_new, cap, cap, reuse);
0567 m_capacity = cap;
0568 #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
0569 ++this->num_alloc;
0570 #endif
0571 }
0572 }
0573
0574 pointer priv_allocation_command(version_1, boost::container::allocation_type command,
0575 size_type limit_size,
0576 size_type &prefer_in_recvd_out_size,
0577 pointer &reuse)
0578 {
0579 (void)command;
0580 BOOST_ASSERT( (command & allocate_new));
0581 BOOST_ASSERT(!(command & nothrow_allocation));
0582
0583 if (BOOST_UNLIKELY(limit_size > stored_size_type(-1))){
0584 boost::container::throw_length_error("get_next_capacity, allocator's max size reached");
0585 }
0586 (clamp_by_stored_size_type<size_type>)(prefer_in_recvd_out_size, stored_size_type());
0587 pointer const p = this->allocate(prefer_in_recvd_out_size);
0588 reuse = pointer();
0589 return p;
0590 }
0591
0592 pointer priv_allocation_command(version_2, boost::container::allocation_type command,
0593 size_type limit_size,
0594 size_type &prefer_in_recvd_out_size,
0595 pointer &reuse)
0596 {
0597
0598 if (BOOST_UNLIKELY(limit_size > stored_size_type(-1))){
0599 boost::container::throw_length_error("get_next_capacity, allocator's max size reached");
0600 }
0601 (clamp_by_stored_size_type<size_type>)(prefer_in_recvd_out_size, stored_size_type());
0602
0603 pointer p = this->alloc().allocation_command(command, limit_size, prefer_in_recvd_out_size, reuse);
0604
0605 (clamp_by_stored_size_type<size_type>)(prefer_in_recvd_out_size, stored_size_type());
0606 return p;
0607 }
0608 };
0609
0610
0611 template <class Allocator, class StoredSizeType>
0612 struct vector_alloc_holder<Allocator, StoredSizeType, version_0>
0613 : public Allocator
0614 {
0615 private:
0616 BOOST_MOVABLE_BUT_NOT_COPYABLE(vector_alloc_holder)
0617
0618 public:
0619 typedef Allocator allocator_type;
0620 typedef boost::container::
0621 allocator_traits<allocator_type> allocator_traits_type;
0622 typedef typename allocator_traits_type::pointer pointer;
0623 typedef typename allocator_traits_type::size_type size_type;
0624 typedef typename allocator_traits_type::value_type value_type;
0625 typedef StoredSizeType stored_size_type;
0626
0627 template <class OtherAllocator, class OtherStoredSizeType, class OtherAllocatorVersion>
0628 friend struct vector_alloc_holder;
0629
0630
0631 vector_alloc_holder()
0632 BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible<allocator_type>::value)
0633 : allocator_type(), m_size()
0634 {}
0635
0636
0637 template<class AllocConvertible>
0638 explicit vector_alloc_holder(BOOST_FWD_REF(AllocConvertible) a) BOOST_NOEXCEPT_OR_NOTHROW
0639 : allocator_type(boost::forward<AllocConvertible>(a)), m_size()
0640 {}
0641
0642
0643 template<class AllocConvertible>
0644 vector_alloc_holder(vector_uninitialized_size_t, BOOST_FWD_REF(AllocConvertible) a, size_type initial_size)
0645 : allocator_type(boost::forward<AllocConvertible>(a))
0646 , m_size(static_cast<stored_size_type>(initial_size))
0647 {
0648
0649 this->priv_first_allocation(initial_size);
0650 }
0651
0652
0653 vector_alloc_holder(vector_uninitialized_size_t, size_type initial_size)
0654 : allocator_type()
0655 , m_size(static_cast<stored_size_type>(initial_size))
0656 {
0657
0658 this->priv_first_allocation(initial_size);
0659 }
0660
0661 vector_alloc_holder(BOOST_RV_REF(vector_alloc_holder) holder)
0662 : allocator_type(BOOST_MOVE_BASE(allocator_type, holder))
0663 , m_size(holder.m_size)
0664 {
0665 ::boost::container::uninitialized_move_alloc_n
0666 (this->alloc(), boost::movelib::to_raw_pointer(holder.start()), m_size, boost::movelib::to_raw_pointer(this->start()));
0667 ::boost::container::destroy_alloc_n
0668 (this->alloc(), boost::movelib::to_raw_pointer(holder.start()), m_size);
0669 holder.m_size = 0;
0670 }
0671
0672 template<class OtherAllocator, class OtherStoredSizeType, class OtherAllocatorVersion>
0673 vector_alloc_holder(BOOST_RV_REF_BEG vector_alloc_holder<OtherAllocator, OtherStoredSizeType, OtherAllocatorVersion> BOOST_RV_REF_END holder)
0674 : allocator_type()
0675 , m_size(holder.m_size)
0676 {
0677
0678 const size_type n = holder.m_size;
0679 this->priv_first_allocation(n);
0680 ::boost::container::uninitialized_move_alloc_n
0681 (this->alloc(), boost::movelib::to_raw_pointer(holder.start()), n, boost::movelib::to_raw_pointer(this->start()));
0682 }
0683
0684 static inline void on_capacity_overflow()
0685 { allocator_type::on_capacity_overflow(); }
0686
0687 inline void set_stored_size(size_type s) BOOST_NOEXCEPT_OR_NOTHROW
0688 { this->m_size = static_cast<stored_size_type>(s); }
0689
0690 inline void dec_stored_size(size_type s) BOOST_NOEXCEPT_OR_NOTHROW
0691 { this->m_size = static_cast<stored_size_type>(this->m_size - s); }
0692
0693 inline void inc_stored_size(size_type s) BOOST_NOEXCEPT_OR_NOTHROW
0694 { this->m_size = static_cast<stored_size_type>(this->m_size + s); }
0695
0696 inline void priv_first_allocation(size_type cap)
0697 {
0698 if(cap > allocator_type::internal_capacity){
0699 on_capacity_overflow();
0700 }
0701 }
0702
0703 inline void deep_swap(vector_alloc_holder &x)
0704 { this->priv_deep_swap(x); }
0705
0706 template<class OtherAllocator, class OtherStoredSizeType, class OtherAllocatorVersion>
0707 void deep_swap(vector_alloc_holder<OtherAllocator, OtherStoredSizeType, OtherAllocatorVersion> &x)
0708 {
0709 typedef typename real_allocator<value_type, OtherAllocator>::type other_allocator_type;
0710 if(this->m_size > other_allocator_type::internal_capacity || x.m_size > allocator_type::internal_capacity){
0711 on_capacity_overflow();
0712 }
0713 this->priv_deep_swap(x);
0714 }
0715
0716 inline void swap_resources(vector_alloc_holder &) BOOST_NOEXCEPT_OR_NOTHROW
0717 {
0718 on_capacity_overflow();
0719 }
0720
0721 inline void steal_resources(vector_alloc_holder &)
0722 {
0723 on_capacity_overflow();
0724 }
0725
0726 inline allocator_type &alloc() BOOST_NOEXCEPT_OR_NOTHROW
0727 { return *this; }
0728
0729 inline const allocator_type &alloc() const BOOST_NOEXCEPT_OR_NOTHROW
0730 { return *this; }
0731
0732 inline bool try_expand_fwd(size_type at_least)
0733 { return !at_least; }
0734
0735 inline pointer start() const BOOST_NOEXCEPT_OR_NOTHROW
0736 { return allocator_type::internal_storage(); }
0737
0738 inline size_type capacity() const BOOST_NOEXCEPT_OR_NOTHROW
0739 { return allocator_type::internal_capacity; }
0740
0741 stored_size_type m_size;
0742
0743 private:
0744
0745 template<class OtherAllocator, class OtherStoredSizeType, class OtherAllocatorVersion>
0746 void priv_deep_swap(vector_alloc_holder<OtherAllocator, OtherStoredSizeType, OtherAllocatorVersion> &x)
0747 {
0748 const size_type MaxTmpStorage = sizeof(value_type)*allocator_type::internal_capacity;
0749 value_type *const first_this = boost::movelib::to_raw_pointer(this->start());
0750 value_type *const first_x = boost::movelib::to_raw_pointer(x.start());
0751
0752 if(this->m_size < x.m_size){
0753 boost::container::deep_swap_alloc_n<MaxTmpStorage>(this->alloc(), first_this, this->m_size, first_x, x.m_size);
0754 }
0755 else{
0756 boost::container::deep_swap_alloc_n<MaxTmpStorage>(this->alloc(), first_x, x.m_size, first_this, this->m_size);
0757 }
0758 boost::adl_move_swap(this->m_size, x.m_size);
0759 }
0760 };
0761
0762 struct growth_factor_60;
0763 struct growth_factor_100;
0764
0765 template<class Options, class AllocatorSizeType>
0766 struct get_vector_opt
0767 {
0768 typedef vector_opt< typename default_if_void<typename Options::growth_factor_type, growth_factor_60>::type
0769 , typename default_if_void<typename Options::stored_size_type, AllocatorSizeType>::type
0770 > type;
0771 };
0772
0773 template<class AllocatorSizeType>
0774 struct get_vector_opt<void, AllocatorSizeType>
0775 {
0776 typedef vector_opt<growth_factor_60, AllocatorSizeType> type;
0777 };
0778
0779 #endif
0780
0781
0782
0783
0784
0785
0786
0787
0788
0789
0790 template <class T, class A BOOST_CONTAINER_DOCONLY(= void), class Options BOOST_CONTAINER_DOCONLY(= void) >
0791 class vector
0792 {
0793 public:
0794
0795
0796
0797
0798
0799 typedef T value_type;
0800 typedef BOOST_CONTAINER_IMPDEF
0801 (typename real_allocator<T BOOST_MOVE_I A>::type) allocator_type;
0802 typedef ::boost::container::allocator_traits<allocator_type> allocator_traits_t;
0803 typedef typename allocator_traits<allocator_type>::pointer pointer;
0804 typedef typename allocator_traits<allocator_type>::const_pointer const_pointer;
0805 typedef typename allocator_traits<allocator_type>::reference reference;
0806 typedef typename allocator_traits<allocator_type>::const_reference const_reference;
0807 typedef typename allocator_traits<allocator_type>::size_type size_type;
0808 typedef typename allocator_traits<allocator_type>::difference_type difference_type;
0809 typedef allocator_type stored_allocator_type;
0810 typedef BOOST_CONTAINER_IMPDEF(vec_iterator<pointer BOOST_MOVE_I false>) iterator;
0811 typedef BOOST_CONTAINER_IMPDEF(vec_iterator<pointer BOOST_MOVE_I true >) const_iterator;
0812 typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator<iterator>) reverse_iterator;
0813 typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator<const_iterator>) const_reverse_iterator;
0814
0815 private:
0816 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
0817
0818
0819 BOOST_CONTAINER_STATIC_ASSERT((dtl::is_same<value_type, typename allocator_traits_t::value_type>::value));
0820
0821 typedef typename boost::container::
0822 allocator_traits<allocator_type>::size_type alloc_size_type;
0823 typedef typename get_vector_opt<Options, alloc_size_type>::type options_type;
0824 typedef typename options_type::growth_factor_type growth_factor_type;
0825 typedef typename options_type::stored_size_type stored_size_type;
0826 typedef value_less<T> value_less_t;
0827
0828
0829 BOOST_CONTAINER_STATIC_ASSERT( (sizeof(stored_size_type) < sizeof(alloc_size_type) ||
0830 dtl::is_same<stored_size_type, alloc_size_type>::value) );
0831
0832 typedef typename dtl::version<allocator_type>::type alloc_version;
0833 typedef boost::container::vector_alloc_holder
0834 <allocator_type, stored_size_type> alloc_holder_t;
0835
0836 alloc_holder_t m_holder;
0837
0838 typedef allocator_traits<allocator_type> allocator_traits_type;
0839 template <class U, class UA, class UOptions>
0840 friend class vector;
0841
0842
0843 protected:
0844 template <bool PropagateAllocator>
0845 inline static bool is_propagable_from(const allocator_type &from_alloc, pointer p, const allocator_type &to_alloc)
0846 { return alloc_holder_t::template is_propagable_from<PropagateAllocator>(from_alloc, p, to_alloc); }
0847
0848 template <bool PropagateAllocator>
0849 inline static bool are_swap_propagable( const allocator_type &l_a, pointer l_p
0850 , const allocator_type &r_a, pointer r_p)
0851 { return alloc_holder_t::template are_swap_propagable<PropagateAllocator>(l_a, l_p, r_a, r_p); }
0852
0853 #endif
0854 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
0855 private:
0856 BOOST_COPYABLE_AND_MOVABLE(vector)
0857 typedef vector_value_traits<allocator_type> value_traits;
0858 typedef constant_iterator<T> cvalue_iterator;
0859
0860 protected:
0861
0862 inline void steal_resources(vector &x)
0863 { return this->m_holder.steal_resources(x.m_holder); }
0864
0865 inline void protected_set_size(size_type n)
0866 { this->m_holder.m_size = static_cast<stored_size_type>(n); }
0867
0868 template<class AllocFwd>
0869 inline vector(initial_capacity_t, pointer initial_memory, size_type cap, BOOST_FWD_REF(AllocFwd) a)
0870 : m_holder(initial_capacity_t(), initial_memory, cap, ::boost::forward<AllocFwd>(a))
0871 {}
0872
0873 template<class AllocFwd>
0874 inline vector(initial_capacity_t, pointer initial_memory, size_type cap, BOOST_FWD_REF(AllocFwd) a, vector &x)
0875 : m_holder(initial_capacity_t(), initial_memory, cap, ::boost::forward<AllocFwd>(a))
0876 {
0877 allocator_type &this_al = this->get_stored_allocator();
0878 if (this->template is_propagable_from<true>(x.get_stored_allocator(), x.data(), this_al)) {
0879 this->steal_resources(x);
0880 }
0881 else {
0882 const size_type sz = x.size();
0883 ::boost::container::uninitialized_move_alloc_n_source
0884 ( this_al, x.priv_raw_begin(), sz
0885
0886 , boost::move_detail::launder(this->priv_raw_begin()));
0887 this->protected_set_size(sz);
0888 x.clear();
0889 }
0890 }
0891
0892 inline vector(initial_capacity_t, pointer initial_memory, size_type cap)
0893 : m_holder(initial_capacity_t(), initial_memory, cap)
0894 {}
0895
0896 template<class SizeType, class AllocFwd>
0897 inline vector(maybe_initial_capacity_t, pointer p, SizeType initial_capacity, BOOST_FWD_REF(AllocFwd) a)
0898 : m_holder(maybe_initial_capacity_t(), p, initial_capacity, ::boost::forward<AllocFwd>(a))
0899 {
0900 #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
0901 this->num_alloc += size_type(p != pointer());
0902 #endif
0903 }
0904
0905 template<class SizeType>
0906 inline vector(maybe_initial_capacity_t, pointer p, SizeType initial_capacity)
0907 : m_holder(maybe_initial_capacity_t(), p, initial_capacity)
0908 {
0909 #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
0910 this->num_alloc += size_type(p != pointer());
0911 #endif
0912 }
0913
0914 template <class U>
0915 void protected_init_n(const size_type new_size, const U& u)
0916 {
0917 BOOST_ASSERT(this->empty());
0918 this->priv_resize_proxy(u).uninitialized_copy_n_and_update(this->m_holder.alloc(), this->priv_raw_begin(), new_size);
0919 this->m_holder.set_stored_size(new_size);
0920 }
0921
0922 #endif
0923
0924 public:
0925
0926
0927
0928
0929
0930
0931
0932
0933
0934
0935
0936 vector() BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible<allocator_type>::value)
0937 : m_holder()
0938 {}
0939
0940
0941
0942
0943
0944
0945 explicit vector(const allocator_type& a) BOOST_NOEXCEPT_OR_NOTHROW
0946 : m_holder(a)
0947 {}
0948
0949
0950
0951
0952
0953
0954
0955 explicit vector(size_type n)
0956 : m_holder(vector_uninitialized_size, n)
0957 {
0958 #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
0959 this->num_alloc += n != 0;
0960 #endif
0961 boost::container::uninitialized_value_init_alloc_n
0962 (this->m_holder.alloc(), n, this->priv_raw_begin());
0963 }
0964
0965
0966
0967
0968
0969
0970
0971
0972 explicit vector(size_type n, const allocator_type &a)
0973 : m_holder(vector_uninitialized_size, a, n)
0974 {
0975 #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
0976 this->num_alloc += n != 0;
0977 #endif
0978 boost::container::uninitialized_value_init_alloc_n
0979 (this->m_holder.alloc(), n, this->priv_raw_begin());
0980 }
0981
0982
0983
0984
0985
0986
0987
0988
0989
0990
0991 vector(size_type n, default_init_t)
0992 : m_holder(vector_uninitialized_size, n)
0993 {
0994 #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
0995 this->num_alloc += n != 0;
0996 #endif
0997 boost::container::uninitialized_default_init_alloc_n
0998 (this->m_holder.alloc(), n, this->priv_raw_begin());
0999 }
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010 vector(size_type n, default_init_t, const allocator_type &a)
1011 : m_holder(vector_uninitialized_size, a, n)
1012 {
1013 #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
1014 this->num_alloc += n != 0;
1015 #endif
1016 boost::container::uninitialized_default_init_alloc_n
1017 (this->m_holder.alloc(), n, this->priv_raw_begin());
1018 }
1019
1020
1021
1022
1023
1024
1025
1026
1027 vector(size_type n, const T& value)
1028 : m_holder(vector_uninitialized_size, n)
1029 {
1030 #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
1031 this->num_alloc += n != 0;
1032 #endif
1033 boost::container::uninitialized_fill_alloc_n
1034 (this->m_holder.alloc(), value, n, this->priv_raw_begin());
1035 }
1036
1037
1038
1039
1040
1041
1042
1043
1044 vector(size_type n, const T& value, const allocator_type& a)
1045 : m_holder(vector_uninitialized_size, a, n)
1046 {
1047 #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
1048 this->num_alloc += n != 0;
1049 #endif
1050 boost::container::uninitialized_fill_alloc_n
1051 (this->m_holder.alloc(), value, n, this->priv_raw_begin());
1052 }
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067 template <class InIt>
1068 vector(InIt first, InIt last
1069 BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I typename dtl::disable_if_c
1070 < dtl::is_convertible<InIt BOOST_MOVE_I size_type>::value
1071 BOOST_MOVE_I dtl::nat >::type * = 0)
1072 )
1073 : m_holder()
1074 { this->assign(first, last); }
1075
1076
1077
1078
1079
1080
1081
1082
1083 template <class InIt>
1084 vector(InIt first, InIt last, const allocator_type& a
1085 BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I typename dtl::disable_if_c
1086 < dtl::is_convertible<InIt BOOST_MOVE_I size_type>::value
1087 BOOST_MOVE_I dtl::nat >::type * = 0)
1088 )
1089 : m_holder(a)
1090 { this->assign(first, last); }
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100 vector(const vector &x)
1101 : m_holder( vector_uninitialized_size
1102 , allocator_traits_type::select_on_container_copy_construction(x.m_holder.alloc())
1103 , x.size())
1104 {
1105 #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
1106 this->num_alloc += x.size() != 0;
1107 #endif
1108 ::boost::container::uninitialized_copy_alloc_n
1109 ( this->m_holder.alloc(), x.priv_raw_begin()
1110 , x.size(), this->priv_raw_begin());
1111 }
1112
1113
1114
1115
1116
1117
1118 vector(BOOST_RV_REF(vector) x) BOOST_NOEXCEPT_OR_NOTHROW
1119 : m_holder(boost::move(x.m_holder))
1120 { BOOST_CONTAINER_STATIC_ASSERT((!allocator_traits_type::is_partially_propagable::value)); }
1121
1122 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
1123
1124
1125
1126
1127
1128
1129 vector(std::initializer_list<value_type> il, const allocator_type& a = allocator_type())
1130 : m_holder(vector_uninitialized_size, a, il.size())
1131 {
1132 #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
1133 this->num_alloc += il.size() != 0;
1134 #endif
1135 ::boost::container::uninitialized_copy_alloc_n_source
1136 ( this->m_holder.alloc(), il.begin()
1137 , static_cast<size_type>(il.size()), this->priv_raw_begin());
1138 }
1139 #endif
1140
1141 #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
1142
1143
1144
1145
1146
1147
1148
1149
1150 template<class OtherA>
1151 vector(BOOST_RV_REF_BEG vector<T, OtherA, Options> BOOST_RV_REF_END x
1152 , typename dtl::enable_if_c
1153 < dtl::is_version<typename real_allocator<T, OtherA>::type, 0>::value>::type * = 0
1154 )
1155 : m_holder(boost::move(x.m_holder))
1156 {}
1157
1158 #endif
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168 vector(const vector &x, const allocator_type &a)
1169 : m_holder(vector_uninitialized_size, a, x.size())
1170 {
1171 #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
1172 this->num_alloc += x.size() != 0;
1173 #endif
1174 ::boost::container::uninitialized_copy_alloc_n_source
1175 ( this->m_holder.alloc(), x.priv_raw_begin()
1176 , x.size(), this->priv_raw_begin());
1177 }
1178
1179
1180
1181
1182
1183
1184
1185
1186 vector(BOOST_RV_REF(vector) x, const allocator_type &a)
1187 : m_holder( vector_uninitialized_size, a
1188
1189 , is_propagable_from<false>(x.get_stored_allocator(), x.m_holder.start(), a) ? 0 : x.size()
1190 )
1191 {
1192
1193 if(is_propagable_from<false>(x.get_stored_allocator(), x.m_holder.start(), a)){
1194 this->m_holder.steal_resources(x.m_holder);
1195 }
1196 else{
1197 const size_type n = x.size();
1198 #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
1199 this->num_alloc += n != 0;
1200 #endif
1201 ::boost::container::uninitialized_move_alloc_n_source
1202 ( this->m_holder.alloc(), x.priv_raw_begin()
1203 , n, this->priv_raw_begin());
1204 }
1205 }
1206
1207
1208
1209
1210
1211
1212
1213 ~vector() BOOST_NOEXCEPT_OR_NOTHROW
1214 {
1215 boost::container::destroy_alloc_n
1216 (this->get_stored_allocator(), this->priv_raw_begin(), this->m_holder.m_size);
1217
1218 }
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228 inline vector& operator=(BOOST_COPY_ASSIGN_REF(vector) x)
1229 {
1230 if (BOOST_LIKELY(&x != this)){
1231 this->priv_copy_assign(x);
1232 }
1233 return *this;
1234 }
1235
1236 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
1237
1238
1239
1240 inline vector& operator=(std::initializer_list<value_type> il)
1241 {
1242 this->assign(il.begin(), il.end());
1243 return *this;
1244 }
1245 #endif
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258 inline vector& operator=(BOOST_RV_REF(vector) x)
1259 BOOST_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_move_assignment::value
1260 || allocator_traits_type::is_always_equal::value)
1261 {
1262 if (BOOST_LIKELY(&x != this)){
1263 this->priv_move_assign(boost::move(x));
1264 }
1265 return *this;
1266 }
1267
1268 #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280 template<class OtherA>
1281 inline typename dtl::enable_if_and
1282 < vector&
1283 , dtl::is_version<typename real_allocator<T, OtherA>::type, 0>
1284 , dtl::is_different<typename real_allocator<T, OtherA>::type, allocator_type>
1285 >::type
1286 operator=(BOOST_RV_REF_BEG vector<value_type, OtherA, Options> BOOST_RV_REF_END x)
1287 {
1288 this->priv_move_assign(boost::move(x));
1289 return *this;
1290 }
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302 template<class OtherA>
1303 inline typename dtl::enable_if_and
1304 < vector&
1305 , dtl::is_version<typename real_allocator<T, OtherA>::type, 0>
1306 , dtl::is_different<typename real_allocator<T, OtherA>::type, allocator_type>
1307 >::type
1308 operator=(const vector<value_type, OtherA, Options> &x)
1309 {
1310 this->priv_copy_assign(x);
1311 return *this;
1312 }
1313
1314 #endif
1315
1316
1317
1318
1319
1320
1321
1322 template <class InIt>
1323 void assign(InIt first, InIt last
1324
1325 BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I typename dtl::disable_if_or
1326 < void
1327 BOOST_MOVE_I dtl::is_convertible<InIt BOOST_MOVE_I size_type>
1328 BOOST_MOVE_I dtl::and_
1329 < dtl::is_different<alloc_version BOOST_MOVE_I version_0>
1330 BOOST_MOVE_I dtl::is_not_input_iterator<InIt>
1331 >
1332 >::type * = 0)
1333 )
1334 {
1335
1336 iterator cur = this->begin();
1337 const iterator end_it = this->end();
1338 for ( ; first != last && cur != end_it; ++cur, ++first){
1339 *cur = *first;
1340 }
1341
1342 if (first == last){
1343
1344 T* const end_pos = this->priv_raw_end();
1345 const size_type n = static_cast<size_type>(end_pos - boost::movelib::iterator_to_raw_pointer(cur));
1346 this->priv_destroy_last_n(n);
1347 }
1348 else{
1349
1350 this->insert(this->cend(), first, last);
1351 }
1352 }
1353
1354 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
1355
1356
1357
1358
1359
1360 inline void assign(std::initializer_list<T> il)
1361 {
1362 this->assign(il.begin(), il.end());
1363 }
1364 #endif
1365
1366
1367
1368
1369
1370
1371
1372 template <class FwdIt>
1373 void assign(FwdIt first, FwdIt last
1374
1375 BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I typename dtl::disable_if_or
1376 < void
1377 BOOST_MOVE_I dtl::is_same<alloc_version BOOST_MOVE_I version_0>
1378 BOOST_MOVE_I dtl::is_convertible<FwdIt BOOST_MOVE_I size_type>
1379 BOOST_MOVE_I dtl::is_input_iterator<FwdIt>
1380 >::type * = 0)
1381 )
1382 {
1383 typedef typename iter_size<FwdIt>::type it_size_type;
1384
1385
1386 const it_size_type sz = boost::container::iterator_udistance(first, last);
1387 if (BOOST_UNLIKELY(sz > size_type(-1))){
1388 boost::container::throw_length_error("vector::assign, FwdIt's max length reached");
1389 }
1390
1391 const size_type input_sz = static_cast<size_type>(sz);
1392 const size_type old_capacity = this->capacity();
1393 if(input_sz > old_capacity){
1394 size_type real_cap = 0;
1395 pointer reuse(this->m_holder.start());
1396 pointer const ret(this->m_holder.allocation_command(allocate_new|expand_fwd, input_sz, real_cap = input_sz, reuse));
1397 if(!reuse){
1398 #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
1399 ++this->num_alloc;
1400 #endif
1401 pointer const old_p = this->m_holder.start();
1402 if(old_p){
1403 this->priv_destroy_all();
1404 this->m_holder.deallocate(old_p, old_capacity);
1405 }
1406 this->m_holder.start(ret);
1407 this->m_holder.capacity(real_cap);
1408 this->m_holder.m_size = 0;
1409 this->priv_uninitialized_construct_at_end(first, last);
1410 return;
1411 }
1412 else{
1413 #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
1414 ++this->num_expand_fwd;
1415 #endif
1416 this->m_holder.capacity(real_cap);
1417
1418 }
1419 }
1420
1421 boost::container::copy_assign_range_alloc_n(this->m_holder.alloc(), first, input_sz, this->priv_raw_begin(), this->size());
1422 m_holder.set_stored_size(input_sz);
1423 }
1424
1425
1426
1427
1428
1429
1430
1431 inline void assign(size_type n, const value_type& val)
1432 { this->assign(cvalue_iterator(val, n), cvalue_iterator()); }
1433
1434
1435
1436
1437
1438
1439 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline allocator_type get_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
1440 { return this->m_holder.alloc(); }
1441
1442
1443
1444
1445
1446
1447
1448
1449 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
1450 stored_allocator_type &get_stored_allocator() BOOST_NOEXCEPT_OR_NOTHROW
1451 { return this->m_holder.alloc(); }
1452
1453
1454
1455
1456
1457
1458
1459
1460 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
1461 const stored_allocator_type &get_stored_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
1462 { return this->m_holder.alloc(); }
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline iterator begin() BOOST_NOEXCEPT_OR_NOTHROW
1476 { return iterator(this->m_holder.start()); }
1477
1478
1479
1480
1481
1482
1483 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline const_iterator begin() const BOOST_NOEXCEPT_OR_NOTHROW
1484 { return const_iterator(this->m_holder.start()); }
1485
1486
1487
1488
1489
1490
1491 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline iterator end() BOOST_NOEXCEPT_OR_NOTHROW
1492 {
1493 iterator it (this->m_holder.start());
1494 it += difference_type(this->m_holder.m_size);
1495 return it;
1496 }
1497
1498
1499
1500
1501
1502
1503 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW
1504 { return this->cend(); }
1505
1506
1507
1508
1509
1510
1511
1512 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline reverse_iterator rbegin() BOOST_NOEXCEPT_OR_NOTHROW
1513 { return reverse_iterator(this->end()); }
1514
1515
1516
1517
1518
1519
1520
1521 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline const_reverse_iterator rbegin() const BOOST_NOEXCEPT_OR_NOTHROW
1522 { return this->crbegin(); }
1523
1524
1525
1526
1527
1528
1529
1530 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline reverse_iterator rend() BOOST_NOEXCEPT_OR_NOTHROW
1531 { return reverse_iterator(this->begin()); }
1532
1533
1534
1535
1536
1537
1538
1539 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline const_reverse_iterator rend() const BOOST_NOEXCEPT_OR_NOTHROW
1540 { return this->crend(); }
1541
1542
1543
1544
1545
1546
1547 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline const_iterator cbegin() const BOOST_NOEXCEPT_OR_NOTHROW
1548 { return const_iterator(this->m_holder.start()); }
1549
1550
1551
1552
1553
1554
1555 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW
1556 {
1557 const_iterator it (this->m_holder.start());
1558 it += difference_type(this->m_holder.m_size);
1559 return it;
1560 }
1561
1562
1563
1564
1565
1566
1567
1568 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline const_reverse_iterator crbegin() const BOOST_NOEXCEPT_OR_NOTHROW
1569 { return const_reverse_iterator(this->end());}
1570
1571
1572
1573
1574
1575
1576
1577 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline const_reverse_iterator crend() const BOOST_NOEXCEPT_OR_NOTHROW
1578 { return const_reverse_iterator(this->begin()); }
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline bool empty() const BOOST_NOEXCEPT_OR_NOTHROW
1592 { return !this->m_holder.m_size; }
1593
1594
1595
1596
1597
1598
1599 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline size_type size() const BOOST_NOEXCEPT_OR_NOTHROW
1600 { return this->m_holder.m_size; }
1601
1602
1603
1604
1605
1606
1607 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW
1608 { return allocator_traits_type::max_size(this->m_holder.alloc()); }
1609
1610
1611
1612
1613
1614
1615
1616 inline void resize(size_type new_size)
1617 { this->priv_resize(new_size, value_init, alloc_version()); }
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627 inline void resize(size_type new_size, default_init_t)
1628 { this->priv_resize(new_size, default_init, alloc_version()); }
1629
1630
1631
1632
1633
1634
1635
1636 inline void resize(size_type new_size, const T& x)
1637 { this->priv_resize(new_size, x, alloc_version()); }
1638
1639
1640
1641
1642
1643
1644
1645 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline size_type capacity() const BOOST_NOEXCEPT_OR_NOTHROW
1646 { return this->m_holder.capacity(); }
1647
1648
1649
1650
1651
1652
1653
1654 inline void reserve(size_type new_cap)
1655 {
1656 if (this->capacity() < new_cap){
1657 this->priv_move_to_new_buffer(new_cap, alloc_version());
1658 }
1659 }
1660
1661
1662
1663
1664
1665
1666
1667 inline void shrink_to_fit()
1668 { this->priv_shrink_to_fit(alloc_version()); }
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline reference front() BOOST_NOEXCEPT_OR_NOTHROW
1685 {
1686 BOOST_ASSERT(!this->empty());
1687 return *this->m_holder.start();
1688 }
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline const_reference front() const BOOST_NOEXCEPT_OR_NOTHROW
1699 {
1700 BOOST_ASSERT(!this->empty());
1701 return *this->m_holder.start();
1702 }
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline reference back() BOOST_NOEXCEPT_OR_NOTHROW
1713 {
1714 BOOST_ASSERT(!this->empty());
1715 return this->m_holder.start()[difference_type(this->m_holder.m_size - 1u)];
1716 }
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline const_reference back() const BOOST_NOEXCEPT_OR_NOTHROW
1727 {
1728 BOOST_ASSERT(!this->empty());
1729 return this->m_holder.start()[this->m_holder.m_size - 1];
1730 }
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline reference operator[](size_type n) BOOST_NOEXCEPT_OR_NOTHROW
1741 {
1742 BOOST_ASSERT(this->m_holder.m_size > n);
1743 return this->m_holder.start()[difference_type(n)];
1744 }
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
1755 const_reference operator[](size_type n) const BOOST_NOEXCEPT_OR_NOTHROW
1756 {
1757 BOOST_ASSERT(this->m_holder.m_size > n);
1758 return this->m_holder.start()[n];
1759 }
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
1773 iterator nth(size_type n) BOOST_NOEXCEPT_OR_NOTHROW
1774 {
1775 BOOST_ASSERT(this->m_holder.m_size >= n);
1776 return iterator(this->m_holder.start()+difference_type(n));
1777 }
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
1791 const_iterator nth(size_type n) const BOOST_NOEXCEPT_OR_NOTHROW
1792 {
1793 BOOST_ASSERT(this->m_holder.m_size >= n);
1794 return const_iterator(this->m_holder.start()+difference_type(n));
1795 }
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
1808 size_type index_of(iterator p) BOOST_NOEXCEPT_OR_NOTHROW
1809 {
1810
1811 return this->priv_index_of(vector_iterator_get_ptr(p));
1812 }
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
1825 size_type index_of(const_iterator p) const BOOST_NOEXCEPT_OR_NOTHROW
1826 {
1827
1828 return this->priv_index_of(vector_iterator_get_ptr(p));
1829 }
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline reference at(size_type n)
1840 {
1841 this->priv_throw_if_out_of_range(n);
1842 return this->m_holder.start()[difference_type(n)];
1843 }
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline const_reference at(size_type n) const
1854 {
1855 this->priv_throw_if_out_of_range(n);
1856 return this->m_holder.start()[n];
1857 }
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline T* data() BOOST_NOEXCEPT_OR_NOTHROW
1872 { return this->priv_raw_begin(); }
1873
1874
1875
1876
1877
1878
1879
1880 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline const T * data() const BOOST_NOEXCEPT_OR_NOTHROW
1881 { return this->priv_raw_begin(); }
1882
1883
1884
1885
1886
1887
1888
1889 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899 template<class ...Args>
1900 inline reference emplace_back(BOOST_FWD_REF(Args)...args)
1901 {
1902 T* const p = this->priv_raw_end();
1903 if (BOOST_LIKELY(this->room_enough())){
1904
1905 allocator_traits_type::construct(this->m_holder.alloc(), p, ::boost::forward<Args>(args)...);
1906 ++this->m_holder.m_size;
1907 return *p;
1908 }
1909 else{
1910 typedef dtl::insert_emplace_proxy<allocator_type, Args...> proxy_t;
1911 return *this->priv_insert_forward_range_no_capacity
1912 (p, 1, proxy_t(::boost::forward<Args>(args)...), alloc_version());
1913 }
1914 }
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924 template<class ...Args>
1925 inline bool stable_emplace_back(BOOST_FWD_REF(Args)...args)
1926 {
1927 const bool is_room_enough = this->room_enough() || (alloc_version::value == 2 && this->m_holder.try_expand_fwd(1u));
1928 if (BOOST_LIKELY(is_room_enough)){
1929
1930 allocator_traits_type::construct(this->m_holder.alloc(), this->priv_raw_end(), ::boost::forward<Args>(args)...);
1931 ++this->m_holder.m_size;
1932 }
1933 return is_room_enough;
1934 }
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946 template<class ...Args>
1947 inline iterator emplace(const_iterator position, BOOST_FWD_REF(Args) ...args)
1948 {
1949 BOOST_ASSERT(this->priv_in_range_or_end(position));
1950
1951 typedef dtl::insert_emplace_proxy<allocator_type, Args...> proxy_t;
1952 return this->priv_insert_forward_range( vector_iterator_get_ptr(position), 1
1953 , proxy_t(::boost::forward<Args>(args)...));
1954 }
1955
1956 #else
1957
1958 #define BOOST_CONTAINER_VECTOR_EMPLACE_CODE(N) \
1959 BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
1960 inline reference emplace_back(BOOST_MOVE_UREF##N)\
1961 {\
1962 T* const p = this->priv_raw_end();\
1963 if (BOOST_LIKELY(this->room_enough())){\
1964 allocator_traits_type::construct (this->m_holder.alloc()\
1965 , this->priv_raw_end() BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
1966 ++this->m_holder.m_size;\
1967 return *p;\
1968 }\
1969 else{\
1970 typedef dtl::insert_emplace_proxy_arg##N<allocator_type BOOST_MOVE_I##N BOOST_MOVE_TARG##N> proxy_t;\
1971 return *this->priv_insert_forward_range_no_capacity\
1972 ( p, 1, proxy_t(BOOST_MOVE_FWD##N), alloc_version());\
1973 }\
1974 }\
1975 \
1976 BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
1977 inline bool stable_emplace_back(BOOST_MOVE_UREF##N)\
1978 {\
1979 const bool is_room_enough = this->room_enough() || (alloc_version::value == 2 && this->m_holder.try_expand_fwd(1u));\
1980 if (BOOST_LIKELY(is_room_enough)){\
1981 allocator_traits_type::construct (this->m_holder.alloc()\
1982 , this->priv_raw_end() BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
1983 ++this->m_holder.m_size;\
1984 }\
1985 return is_room_enough;\
1986 }\
1987 \
1988 BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
1989 inline iterator emplace(const_iterator pos BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
1990 {\
1991 BOOST_ASSERT(this->priv_in_range_or_end(pos));\
1992 typedef dtl::insert_emplace_proxy_arg##N<allocator_type BOOST_MOVE_I##N BOOST_MOVE_TARG##N> proxy_t;\
1993 return this->priv_insert_forward_range(vector_iterator_get_ptr(pos), 1, proxy_t(BOOST_MOVE_FWD##N));\
1994 }\
1995
1996 BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_VECTOR_EMPLACE_CODE)
1997 #undef BOOST_CONTAINER_VECTOR_EMPLACE_CODE
1998
1999 #endif
2000
2001 #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
2002
2003
2004
2005
2006
2007
2008 void push_back(const T &x);
2009
2010
2011
2012
2013
2014
2015
2016
2017 void push_back(T &&x);
2018 #else
2019 BOOST_MOVE_CONVERSION_AWARE_CATCH(push_back, T, void, priv_push_back)
2020 #endif
2021
2022 #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
2023
2024
2025
2026
2027
2028
2029
2030
2031 iterator insert(const_iterator position, const T &x);
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041 iterator insert(const_iterator position, T &&x);
2042 #else
2043 BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert, T, iterator, priv_insert, const_iterator, const_iterator)
2044 #endif
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055 inline iterator insert(const_iterator p, size_type n, const T& x)
2056 {
2057 BOOST_ASSERT(this->priv_in_range_or_end(p));
2058 dtl::insert_n_copies_proxy<allocator_type> proxy(x);
2059 return this->priv_insert_forward_range(vector_iterator_get_ptr(p), n, proxy);
2060 }
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072 template <class InIt>
2073 iterator insert(const_iterator pos, InIt first, InIt last
2074 #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
2075 , typename dtl::disable_if_or
2076 < void
2077 , dtl::is_convertible<InIt, size_type>
2078 , dtl::is_not_input_iterator<InIt>
2079 >::type * = 0
2080 #endif
2081 )
2082 {
2083 BOOST_ASSERT(this->priv_in_range_or_end(pos));
2084 const size_type n_pos = size_type(pos - this->cbegin());
2085 iterator it(vector_iterator_get_ptr(pos));
2086 for(;first != last; ++first){
2087 it = this->emplace(it, *first);
2088 ++it;
2089 }
2090 return iterator(this->m_holder.start() + difference_type(n_pos));
2091 }
2092
2093 #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
2094 template <class FwdIt>
2095 inline iterator insert(const_iterator pos, FwdIt first, FwdIt last
2096 , typename dtl::disable_if_or
2097 < void
2098 , dtl::is_convertible<FwdIt, size_type>
2099 , dtl::is_input_iterator<FwdIt>
2100 >::type * = 0
2101 )
2102 {
2103 typedef typename iter_size<FwdIt>::type it_size_type;
2104 BOOST_ASSERT(this->priv_in_range_or_end(pos));
2105 const it_size_type sz = boost::container::iterator_udistance(first, last);
2106 if (BOOST_UNLIKELY(sz > size_type(-1))){
2107 boost::container::throw_length_error("vector::insert, FwdIt's max length reached");
2108 }
2109
2110 dtl::insert_range_proxy<allocator_type, FwdIt> proxy(first);
2111 return this->priv_insert_forward_range(vector_iterator_get_ptr(pos), static_cast<size_type>(sz), proxy);
2112 }
2113 #endif
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130 #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
2131 template <class InIt>
2132 inline iterator insert(const_iterator pos, size_type num, InIt first, InIt last)
2133 {
2134 BOOST_ASSERT(this->priv_in_range_or_end(pos));
2135 BOOST_ASSERT(dtl::is_input_iterator<InIt>::value ||
2136 num == boost::container::iterator_udistance(first, last));
2137 (void)last;
2138 dtl::insert_range_proxy<allocator_type, InIt> proxy(first);
2139 return this->priv_insert_forward_range(vector_iterator_get_ptr(pos), num, proxy);
2140 }
2141 #endif
2142
2143 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
2144
2145
2146
2147
2148
2149
2150
2151 inline iterator insert(const_iterator position, std::initializer_list<value_type> il)
2152 {
2153
2154 return this->insert(position, il.begin(), il.end());
2155 }
2156 #endif
2157
2158
2159
2160
2161
2162
2163 inline void pop_back() BOOST_NOEXCEPT_OR_NOTHROW
2164 {
2165 BOOST_ASSERT(!this->empty());
2166
2167 allocator_traits_type::destroy(this->get_stored_allocator(), this->priv_raw_end() - 1);
2168 --this->m_holder.m_size;
2169 }
2170
2171
2172
2173
2174
2175
2176
2177 iterator erase(const_iterator position)
2178 {
2179 BOOST_ASSERT(this->priv_in_range(position));
2180 const pointer p = vector_iterator_get_ptr(position);
2181 T *const pos_ptr = boost::movelib::to_raw_pointer(p);
2182 T *const end_ptr = this->priv_raw_end();
2183
2184
2185 (void)::boost::container::move(pos_ptr + 1, end_ptr, pos_ptr);
2186
2187 T *const last_ptr = end_ptr-1;
2188 if(!value_traits::trivial_dctr_after_move || pos_ptr == last_ptr){
2189 allocator_traits_type::destroy(this->get_stored_allocator(), last_ptr);
2190 }
2191 --this->m_holder.m_size;
2192 return iterator(p);
2193 }
2194
2195
2196
2197
2198
2199
2200
2201 iterator erase(const_iterator first, const_iterator last)
2202 {
2203 BOOST_ASSERT(this->priv_in_range_or_end(first));
2204 BOOST_ASSERT(this->priv_in_range_or_end(last));
2205 BOOST_ASSERT(first <= last);
2206 if(first != last){
2207 T* const old_end_ptr = this->priv_raw_end();
2208 T* const first_ptr = boost::movelib::to_raw_pointer(vector_iterator_get_ptr(first));
2209 T* const last_ptr = boost::movelib::to_raw_pointer(vector_iterator_get_ptr(last));
2210 T* const new_last_ptr = boost::movelib::to_raw_pointer(boost::container::move(last_ptr, old_end_ptr, first_ptr));
2211 const size_type n = static_cast<size_type>(old_end_ptr - new_last_ptr);
2212 if(!value_traits::trivial_dctr_after_move || old_end_ptr == last_ptr){
2213 boost::container::destroy_alloc_n(this->get_stored_allocator(), new_last_ptr, n);
2214 }
2215 this->m_holder.dec_stored_size(n);
2216 }
2217 return iterator(vector_iterator_get_ptr(first));
2218 }
2219
2220
2221
2222
2223
2224
2225 inline void swap(vector& x)
2226 BOOST_NOEXCEPT_IF( ((allocator_traits_type::propagate_on_container_swap::value
2227 || allocator_traits_type::is_always_equal::value) &&
2228 !dtl::is_version<allocator_type, 0>::value))
2229 {
2230 this->priv_swap(x, dtl::bool_<dtl::is_version<allocator_type, 0>::value>());
2231 }
2232
2233 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
2234
2235
2236
2237
2238
2239
2240
2241
2242 template<class OtherA>
2243 inline void swap(vector<T, OtherA, Options> & x
2244 , typename dtl::enable_if_and
2245 < void
2246 , dtl::is_version<typename real_allocator<T, OtherA>::type, 0>
2247 , dtl::is_different<typename real_allocator<T, OtherA>::type, allocator_type>
2248 >::type * = 0
2249 )
2250 { this->m_holder.deep_swap(x.m_holder); }
2251
2252 #endif
2253
2254
2255
2256
2257
2258
2259 inline void clear() BOOST_NOEXCEPT_OR_NOTHROW
2260 { this->priv_destroy_all(); }
2261
2262
2263
2264
2265 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline friend bool operator==(const vector& x, const vector& y)
2266 { return x.size() == y.size() && ::boost::container::algo_equal(x.begin(), x.end(), y.begin()); }
2267
2268
2269
2270
2271 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline friend bool operator!=(const vector& x, const vector& y)
2272 { return !(x == y); }
2273
2274
2275
2276
2277 BOOST_CONTAINER_ATTRIBUTE_NODISCARD friend bool operator<(const vector& x, const vector& y)
2278 { return boost::container::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
2279
2280
2281
2282
2283 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline friend bool operator>(const vector& x, const vector& y)
2284 { return y < x; }
2285
2286
2287
2288
2289 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline friend bool operator<=(const vector& x, const vector& y)
2290 { return !(y < x); }
2291
2292
2293
2294
2295 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline friend bool operator>=(const vector& x, const vector& y)
2296 { return !(x < y); }
2297
2298
2299
2300
2301 inline friend void swap(vector& x, vector& y)
2302 BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT(x.swap(y)))
2303 { x.swap(y); }
2304
2305 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315 bool stable_reserve(size_type new_cap)
2316 {
2317 const size_type cp = this->capacity();
2318 return cp >= new_cap || (alloc_version::value == 2 && this->m_holder.try_expand_fwd(size_type(new_cap - cp)));
2319 }
2320
2321 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
2322
2323 template<class BiDirPosConstIt, class BiDirValueIt>
2324 inline void insert_ordered_at(const size_type element_count, BiDirPosConstIt last_position_it, BiDirValueIt last_value_it)
2325 {
2326 typedef vector_insert_ordered_cursor<BiDirPosConstIt, BiDirValueIt> inserter_t;
2327 return this->priv_insert_ordered_at(element_count, inserter_t(last_position_it, last_value_it));
2328 }
2329
2330 template<class InputIt>
2331 inline void merge(InputIt first, InputIt last)
2332 { this->merge(first, last, value_less_t()); }
2333
2334 template<class InputIt, class Compare>
2335 inline
2336 typename dtl::enable_if_c
2337 < !dtl::is_input_iterator<InputIt>::value &&
2338 dtl::is_same<value_type, typename iterator_traits<InputIt>::value_type>::value
2339 , void>::type
2340 merge(InputIt first, InputIt last, Compare comp)
2341 {
2342 size_type const s = this->size();
2343 size_type const c = this->capacity();
2344 size_type n = 0;
2345 size_type const free_cap = c - s;
2346
2347 if(free_cap < (n = boost::container::iterator_udistance(first, last))){
2348 this->priv_merge_in_new_buffer(first, n, comp, alloc_version());
2349 }
2350 else{
2351 this->priv_merge_generic(first, last, comp);
2352 }
2353 }
2354
2355 template<class InputIt, class Compare>
2356 inline
2357 typename dtl::enable_if_c
2358 < dtl::is_input_iterator<InputIt>::value ||
2359 !dtl::is_same<value_type, typename iterator_traits<InputIt>::value_type>::value
2360 , void>::type
2361 merge(InputIt first, InputIt last, Compare comp)
2362 {
2363 this->priv_merge_generic(first, last, comp);
2364 }
2365
2366 template<class InputIt>
2367 inline void merge_unique(InputIt first, InputIt last)
2368 { this->merge_unique(first, last, value_less_t()); }
2369
2370 template<class InputIt, class Compare>
2371 inline
2372 typename dtl::enable_if_c
2373 < !dtl::is_input_iterator<InputIt>::value &&
2374 dtl::is_same<value_type, typename iterator_traits<InputIt>::value_type>::value
2375 , void>::type
2376 merge_unique(InputIt first, InputIt last, Compare comp)
2377 {
2378 size_type const old_size = this->size();
2379 this->priv_set_difference_back(first, last, comp);
2380 T *const raw_beg = this->priv_raw_begin();
2381 T *const raw_end = this->priv_raw_end();
2382 T *raw_pos = raw_beg + old_size;
2383 boost::movelib::adaptive_merge(raw_beg, raw_pos, raw_end, comp, raw_end, this->capacity() - this->size());
2384 }
2385
2386 template<class InputIt, class Compare>
2387 inline
2388 typename dtl::enable_if_c
2389 < dtl::is_input_iterator<InputIt>::value ||
2390 !dtl::is_same<value_type, typename iterator_traits<InputIt>::value_type>::value
2391 , void>::type
2392 merge_unique(InputIt first, InputIt last, Compare comp)
2393 {
2394 iterator pos = this->insert(this->end(), first, last);
2395 const iterator e = boost::movelib::inplace_set_unique_difference(pos, this->end(), this->begin(), pos, comp);
2396 this->erase(e, this->end());
2397 boost::movelib::adaptive_merge( this->begin(), pos, e, comp
2398 , this->priv_raw_end(), this->capacity() - this->size());
2399 }
2400
2401
2402 T *unused_storage(size_type &sz)
2403 {
2404 sz = static_cast<size_type>(this->capacity() - this->size());
2405 return this->priv_raw_end();
2406 }
2407
2408 #endif
2409
2410 private:
2411 template<class InputIt, class Compare>
2412 inline void priv_merge_generic(InputIt first, InputIt last, Compare comp)
2413 {
2414 size_type const old_s = this->size();
2415 this->insert(this->cend(), first, last);
2416 T* const raw_beg = this->priv_raw_begin();
2417 T* const raw_end = this->priv_raw_end();
2418 T* const raw_pos = raw_beg + old_s;
2419 boost::movelib::adaptive_merge(raw_beg, raw_pos, raw_end, comp, raw_end, this->capacity() - this->size());
2420 }
2421
2422 template<class PositionValue>
2423 void priv_insert_ordered_at(const size_type element_count, PositionValue position_value)
2424 {
2425 const size_type old_size_pos = this->size();
2426 this->reserve(old_size_pos + element_count);
2427 T* const begin_ptr = this->priv_raw_begin();
2428 size_type insertions_left = element_count;
2429 size_type prev_pos = old_size_pos;
2430 size_type old_hole_size = element_count;
2431
2432
2433
2434 typename value_traits::ArrayDestructor past_hole_values_destroyer
2435 (begin_ptr + old_size_pos + element_count, this->m_holder.alloc(), size_type(0u));
2436
2437
2438 while(insertions_left){
2439 --position_value;
2440 size_type const pos = position_value.get_pos();
2441 BOOST_ASSERT(pos != size_type(-1) && pos <= old_size_pos && pos <= prev_pos);
2442
2443
2444
2445 size_type new_hole_size = (pos != prev_pos)
2446 ? priv_insert_ordered_at_shift_range(pos, prev_pos, this->size(), insertions_left)
2447 : old_hole_size
2448 ;
2449 if(new_hole_size){
2450
2451 past_hole_values_destroyer.increment_size_backwards(prev_pos - pos);
2452
2453 allocator_traits_type::construct(this->m_holder.alloc(), begin_ptr + pos + insertions_left - 1, position_value.get_val());
2454 if(--new_hole_size){
2455
2456 past_hole_values_destroyer.increment_size_backwards(size_type(1u));
2457 }
2458 else{
2459
2460 past_hole_values_destroyer.release();
2461 this->m_holder.inc_stored_size(element_count);
2462 }
2463 }
2464 else{
2465 if(old_hole_size){
2466
2467 past_hole_values_destroyer.release();
2468 this->m_holder.inc_stored_size(element_count);
2469 }
2470
2471 begin_ptr[pos + insertions_left - 1] = position_value.get_val();
2472 }
2473 --insertions_left;
2474 old_hole_size = new_hole_size;
2475 prev_pos = pos;
2476 }
2477 }
2478
2479 template<class InputIt, class Compare>
2480 void priv_set_difference_back(InputIt first1, InputIt last1, Compare comp)
2481 {
2482 T * old_first2 = this->priv_raw_begin();
2483 T * first2 = old_first2;
2484 T * last2 = this->priv_raw_end();
2485
2486 while (first1 != last1) {
2487 if (first2 == last2){
2488 this->insert(this->cend(), first1, last1);
2489 return;
2490 }
2491
2492 if (comp(*first1, *first2)) {
2493 this->emplace_back(*first1);
2494 T * const raw_begin = this->priv_raw_begin();
2495 if(old_first2 != raw_begin)
2496 {
2497
2498 first2 = raw_begin + (first2 - old_first2);
2499 last2 = raw_begin + (last2 - old_first2);
2500 old_first2 = raw_begin;
2501 }
2502 ++first1;
2503 }
2504 else {
2505 if (!comp(*first2, *first1)) {
2506 ++first1;
2507 }
2508 ++first2;
2509 }
2510 }
2511 }
2512
2513 template<class FwdIt, class Compare>
2514 inline void priv_merge_in_new_buffer(FwdIt, size_type, Compare, version_0)
2515 {
2516 alloc_holder_t::on_capacity_overflow();
2517 }
2518
2519 template<class FwdIt, class Compare, class Version>
2520 void priv_merge_in_new_buffer(FwdIt first, size_type n, Compare comp, Version)
2521 {
2522 size_type const new_size = this->size() + n;
2523 size_type new_cap = new_size;
2524 pointer p = pointer();
2525 pointer const new_storage = this->m_holder.allocation_command(allocate_new, new_size, new_cap, p);
2526
2527 BOOST_ASSERT((new_cap >= this->size() ) && (new_cap - this->size()) >= n);
2528 allocator_type &a = this->m_holder.alloc();
2529 typename value_traits::ArrayDeallocator new_buffer_deallocator(new_storage, a, new_cap);
2530 typename value_traits::ArrayDestructor new_values_destroyer(new_storage, a, 0u);
2531 T* pbeg = this->priv_raw_begin();
2532 size_type const old_size = this->size();
2533 T* const pend = pbeg + old_size;
2534 T* d_first = boost::movelib::to_raw_pointer(new_storage);
2535 size_type added = n;
2536
2537 while(1){
2538 if(!n) {
2539 ::boost::container::uninitialized_move_alloc(this->m_holder.alloc(), pbeg, pend, d_first);
2540 break;
2541 }
2542 else if(pbeg == pend) {
2543 ::boost::container::uninitialized_move_alloc_n(this->m_holder.alloc(), first, n, d_first);
2544 break;
2545 }
2546
2547 else if(comp(*first, *pbeg)) {
2548 allocator_traits_type::construct( this->m_holder.alloc(), d_first, *first );
2549 new_values_destroyer.increment_size(1u);
2550 ++first;
2551 --n;
2552 ++d_first;
2553 }
2554 else{
2555 allocator_traits_type::construct( this->m_holder.alloc(), d_first, boost::move(*pbeg) );
2556 new_values_destroyer.increment_size(1u);
2557 ++pbeg;
2558 ++d_first;
2559 }
2560 }
2561
2562
2563 pointer const old_p = this->m_holder.start();
2564 size_type const old_cap = this->m_holder.capacity();
2565 boost::container::destroy_alloc_n(a, boost::movelib::to_raw_pointer(old_p), old_size);
2566 if (old_cap > 0) {
2567 this->m_holder.deallocate(old_p, old_cap);
2568 }
2569 m_holder.set_stored_size(old_size + added);
2570 this->m_holder.start(new_storage);
2571 this->m_holder.capacity(new_cap);
2572 new_buffer_deallocator.release();
2573 new_values_destroyer.release();
2574 }
2575
2576 inline bool room_enough() const
2577 { return this->m_holder.m_size != this->m_holder.capacity(); }
2578
2579 inline pointer back_ptr() const
2580 { return this->m_holder.start() + difference_type(this->m_holder.m_size); }
2581
2582 inline size_type priv_index_of(pointer p) const
2583 {
2584 BOOST_ASSERT(this->m_holder.start() <= p);
2585 BOOST_ASSERT(p <= (this->m_holder.start()+difference_type(this->size())));
2586 return static_cast<size_type>(p - this->m_holder.start());
2587 }
2588
2589 template<class OtherA>
2590 void priv_move_assign(BOOST_RV_REF_BEG vector<T, OtherA, Options> BOOST_RV_REF_END x
2591 , typename dtl::enable_if_c
2592 < dtl::is_version<typename real_allocator<T, OtherA>::type, 0>::value >::type * = 0)
2593 {
2594 if(!dtl::is_same<typename real_allocator<T, OtherA>::type, allocator_type>::value &&
2595 this->capacity() < x.size()){
2596 alloc_holder_t::on_capacity_overflow();
2597 }
2598 T* const this_start = this->priv_raw_begin();
2599 T* const other_start = x.priv_raw_begin();
2600 const size_type this_sz = m_holder.m_size;
2601 const size_type other_sz = static_cast<size_type>(x.m_holder.m_size);
2602 boost::container::move_assign_range_alloc_n(this->m_holder.alloc(), other_start, other_sz, this_start, this_sz);
2603 m_holder.set_stored_size(other_sz);
2604
2605
2606 x.clear();
2607 }
2608
2609 template<class OtherA>
2610 void priv_move_assign_steal_or_assign(BOOST_RV_REF_BEG vector<T, OtherA, Options> BOOST_RV_REF_END x, dtl::true_type )
2611 {
2612 this->clear();
2613 if (BOOST_LIKELY(!!this->m_holder.m_start))
2614 this->m_holder.deallocate(this->m_holder.m_start, this->m_holder.m_capacity);
2615 this->m_holder.steal_resources(x.m_holder);
2616 }
2617
2618 template<class OtherA>
2619 void priv_move_assign_steal_or_assign(BOOST_RV_REF_BEG vector<T, OtherA, Options> BOOST_RV_REF_END x, dtl::false_type )
2620 {
2621 const bool propagate_alloc = allocator_traits_type::propagate_on_container_move_assignment::value;
2622 allocator_type& this_alloc = this->m_holder.alloc();
2623 allocator_type& x_alloc = x.m_holder.alloc();
2624
2625
2626
2627 const bool is_buffer_propagable_from_x = is_propagable_from<propagate_alloc>(x_alloc, x.m_holder.start(), this_alloc);
2628
2629 if (is_buffer_propagable_from_x) {
2630 this->priv_move_assign_steal_or_assign(boost::move(x), dtl::true_type());
2631 }
2632
2633
2634 else {
2635 this->assign( boost::make_move_iterator(boost::movelib::iterator_to_raw_pointer(x.begin()))
2636 , boost::make_move_iterator(boost::movelib::iterator_to_raw_pointer(x.end())) );
2637 x.clear();
2638 }
2639 }
2640
2641 template<class OtherA>
2642 void priv_move_assign(BOOST_RV_REF_BEG vector<T, OtherA, Options> BOOST_RV_REF_END x
2643 , typename dtl::disable_if_or
2644 < void
2645 , dtl::is_version<typename real_allocator<T, OtherA>::type, 0>
2646 , dtl::is_different<typename real_allocator<T, OtherA>::type, allocator_type>
2647 >::type * = 0)
2648 {
2649
2650
2651 BOOST_ASSERT(this != &x || x.size() == 0);
2652 const bool alloc_is_always_equal = allocator_traits_type::is_always_equal::value;
2653 const bool propagate_alloc = allocator_traits_type::propagate_on_container_move_assignment::value;
2654 const bool partially_propagable_alloc = allocator_traits_type::is_partially_propagable::value;
2655 const bool data_can_be_always_be_stolen = alloc_is_always_equal || (propagate_alloc && !partially_propagable_alloc);
2656
2657 this->priv_move_assign_steal_or_assign(boost::move(x), dtl::bool_<data_can_be_always_be_stolen>());
2658
2659
2660 allocator_type& this_alloc = this->m_holder.alloc();
2661 allocator_type& x_alloc = x.m_holder.alloc();
2662 dtl::move_alloc(this_alloc, x_alloc, dtl::bool_<propagate_alloc>());
2663 }
2664
2665 template<class OtherA>
2666 void priv_copy_assign(const vector<T, OtherA, Options> &x
2667 , typename dtl::enable_if_c
2668 < dtl::is_version<typename real_allocator<T, OtherA>::type, 0>::value >::type * = 0)
2669 {
2670 if(!dtl::is_same<typename real_allocator<T, OtherA>::type, allocator_type>::value &&
2671 this->capacity() < x.size()){
2672 alloc_holder_t::on_capacity_overflow();
2673 }
2674 T* const this_start = this->priv_raw_begin();
2675 T* const other_start = x.priv_raw_begin();
2676 const size_type this_sz = m_holder.m_size;
2677 const size_type other_sz = static_cast<size_type>(x.m_holder.m_size);
2678 boost::container::copy_assign_range_alloc_n(this->m_holder.alloc(), other_start, other_sz, this_start, this_sz);
2679 m_holder.set_stored_size(other_sz);
2680 }
2681
2682 template<class OtherA>
2683 typename dtl::disable_if_or
2684 < void
2685 , dtl::is_version<typename real_allocator<T, OtherA>::type, 0>
2686 , dtl::is_different<typename real_allocator<T, OtherA>::type, allocator_type>
2687 >::type
2688 priv_copy_assign(const vector<T, OtherA, Options> &x)
2689 {
2690 allocator_type &this_alloc = this->m_holder.alloc();
2691 const allocator_type &x_alloc = x.m_holder.alloc();
2692 dtl::bool_<allocator_traits_type::
2693 propagate_on_container_copy_assignment::value> flag;
2694 if(flag && this_alloc != x_alloc){
2695 this->clear();
2696 this->shrink_to_fit();
2697 }
2698 dtl::assign_alloc(this_alloc, x_alloc, flag);
2699 this->assign( x.priv_raw_begin(), x.priv_raw_end() );
2700 }
2701
2702 template<class Vector>
2703 inline void priv_swap(Vector &x, dtl::true_type)
2704 { this->m_holder.deep_swap(x.m_holder); }
2705
2706 template<class Vector>
2707 void priv_swap(Vector &x, dtl::false_type)
2708 {
2709 BOOST_ASSERT(allocator_traits_type::propagate_on_container_swap::value ||
2710 allocator_traits_type::is_always_equal::value ||
2711 this->get_stored_allocator() == x.get_stored_allocator());
2712
2713 if (BOOST_UNLIKELY(&x == this)) {
2714 return;
2715 }
2716
2717
2718 this->m_holder.swap_resources(x.m_holder);
2719
2720 dtl::bool_<allocator_traits_type::propagate_on_container_swap::value> flag;
2721 dtl::swap_alloc(this->m_holder.alloc(), x.m_holder.alloc(), flag);
2722 }
2723
2724 protected:
2725 template<class Vector>
2726 void prot_swap_small(Vector &x, std::size_t internal_capacity)
2727 {
2728 if (BOOST_UNLIKELY(&x == this)){
2729 return;
2730 }
2731
2732 const bool propagate_alloc = allocator_traits_type::propagate_on_container_swap::value;
2733 if(are_swap_propagable<propagate_alloc>
2734 ( this->get_stored_allocator(), this->m_holder.start(), x.get_stored_allocator(), x.m_holder.start())){
2735 this->priv_swap(x, dtl::false_());
2736 return;
2737 }
2738
2739 allocator_type &th_al = this->get_stored_allocator();
2740 allocator_type &ot_al = x.get_stored_allocator();
2741
2742 const bool is_this_data_propagable = is_propagable_from<propagate_alloc>(th_al, this->data(), ot_al);
2743 const bool is_that_data_propagable = is_propagable_from<propagate_alloc>(ot_al, x.data(), th_al);
2744
2745 if(internal_capacity && (is_this_data_propagable || is_that_data_propagable)) {
2746
2747 vector& extmem = is_this_data_propagable ? *this : x;
2748 vector& intmem = is_this_data_propagable ? x : *this;
2749
2750
2751 pointer const orig_extdata = extmem.data();
2752 const size_type orig_extmem_size = extmem.size();
2753 const size_type orig_extmem_cap = extmem.capacity();
2754
2755
2756 extmem.m_holder.m_start = extmem.get_stored_allocator().internal_storage();
2757 extmem.m_holder.set_stored_size(0u);
2758 extmem.m_holder.set_stored_capacity(internal_capacity);
2759
2760 {
2761
2762 typename value_traits::ArrayDeallocator new_buffer_deallocator(orig_extdata, extmem.get_stored_allocator(), orig_extmem_cap);
2763 typename value_traits::ArrayDestructor new_values_destroyer(orig_extdata, extmem.get_stored_allocator(), orig_extmem_size);
2764
2765
2766 BOOST_ASSERT(extmem.capacity() >= intmem.size());
2767 ::boost::container::uninitialized_move_alloc_n
2768 (intmem.get_stored_allocator(), intmem.priv_raw_begin(), intmem.size(), extmem.priv_raw_begin());
2769
2770
2771 extmem.m_holder.set_stored_size(intmem.size());
2772
2773 new_buffer_deallocator.release();
2774 new_values_destroyer.release();
2775 }
2776
2777
2778 boost::container::destroy_alloc_n
2779 ( intmem.get_stored_allocator(), intmem.priv_raw_begin()
2780 , intmem.size());
2781
2782
2783 intmem.m_holder.m_start = orig_extdata;
2784 intmem.m_holder.set_stored_size(orig_extmem_size);
2785 intmem.m_holder.set_stored_capacity(orig_extmem_cap);
2786
2787
2788 dtl::swap_alloc(this->m_holder.alloc(), x.m_holder.alloc(), dtl::bool_<propagate_alloc>());
2789 }
2790 else {
2791 bool const t_smaller = this->size() < x.size();
2792 vector &sml = t_smaller ? *this : x;
2793 vector &big = t_smaller ? x : *this;
2794
2795
2796 size_type const common_elements = sml.size();
2797 for(size_type i = 0; i != common_elements; ++i){
2798 boost::adl_move_swap(sml[i], big[i]);
2799 }
2800
2801
2802 dtl::swap_alloc(this->m_holder.alloc(), x.m_holder.alloc(), dtl::bool_<propagate_alloc>());
2803
2804
2805 T *const raw_big_nth = boost::movelib::iterator_to_raw_pointer(big.nth(common_elements));
2806 sml.insert(sml.cend()
2807 , boost::make_move_iterator(raw_big_nth)
2808 , boost::make_move_iterator(boost::movelib::iterator_to_raw_pointer(big.end())));
2809
2810
2811 boost::container::destroy_alloc_n
2812 ( sml.get_stored_allocator(), raw_big_nth
2813 , std::size_t(big.m_holder.m_size - common_elements));
2814 big.m_holder.set_stored_size(common_elements);
2815 }
2816 }
2817 private:
2818 inline void priv_move_to_new_buffer(size_type, version_0)
2819 { alloc_holder_t::on_capacity_overflow(); }
2820
2821 inline dtl::insert_range_proxy<allocator_type, boost::move_iterator<T*> > priv_dummy_empty_proxy()
2822 {
2823 return dtl::insert_range_proxy<allocator_type, boost::move_iterator<T*> >
2824 (::boost::make_move_iterator((T *)0));
2825 }
2826
2827 inline void priv_move_to_new_buffer(size_type new_cap, version_1)
2828 {
2829
2830
2831 pointer const p = this->m_holder.allocate(new_cap);
2832 #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
2833 ++this->num_alloc;
2834 #endif
2835
2836 this->priv_insert_forward_range_new_allocation
2837 ( boost::movelib::to_raw_pointer(p), new_cap, this->priv_raw_end(), 0, this->priv_dummy_empty_proxy());
2838 }
2839
2840 void priv_move_to_new_buffer(size_type new_cap, version_2)
2841 {
2842
2843
2844 bool same_buffer_start;
2845 size_type real_cap = 0;
2846 pointer reuse(this->m_holder.start());
2847 pointer const ret(this->m_holder.allocation_command(allocate_new | expand_fwd | expand_bwd, new_cap, real_cap = new_cap, reuse));
2848
2849
2850 same_buffer_start = reuse && this->m_holder.start() == ret;
2851 if(same_buffer_start){
2852 #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
2853 ++this->num_expand_fwd;
2854 #endif
2855 this->m_holder.capacity(real_cap);
2856 }
2857 else{
2858 T * const new_mem = boost::movelib::to_raw_pointer(ret);
2859 T * const ins_pos = this->priv_raw_end();
2860 if(reuse){
2861 #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
2862 ++this->num_expand_bwd;
2863 #endif
2864 this->priv_insert_forward_range_expand_backwards
2865 ( new_mem, real_cap, ins_pos, 0, this->priv_dummy_empty_proxy());
2866 }
2867 else{
2868 #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
2869 ++this->num_alloc;
2870 #endif
2871 this->priv_insert_forward_range_new_allocation
2872 ( new_mem, real_cap, ins_pos, 0, this->priv_dummy_empty_proxy());
2873 }
2874 }
2875 }
2876
2877 void priv_destroy_last_n(const size_type n) BOOST_NOEXCEPT_OR_NOTHROW
2878 {
2879 BOOST_ASSERT(n <= this->m_holder.m_size);
2880 boost::container::destroy_alloc_n(this->get_stored_allocator(), this->priv_raw_end() - n, n);
2881 this->m_holder.dec_stored_size(n);
2882 }
2883
2884 template<class InpIt>
2885 void priv_uninitialized_construct_at_end(InpIt first, InpIt last)
2886 {
2887 T* const old_end_pos = this->priv_raw_end();
2888 T* const new_end_pos = boost::container::uninitialized_copy_alloc(this->m_holder.alloc(), first, last, old_end_pos);
2889 this->m_holder.inc_stored_size(static_cast<size_type>(new_end_pos - old_end_pos));
2890 }
2891
2892 void priv_destroy_all() BOOST_NOEXCEPT_OR_NOTHROW
2893 {
2894 boost::container::destroy_alloc_n
2895 (this->get_stored_allocator(), this->priv_raw_begin(), this->m_holder.m_size);
2896 this->m_holder.m_size = 0;
2897 }
2898
2899 template<class U>
2900 inline iterator priv_insert(const const_iterator &p, BOOST_FWD_REF(U) u)
2901 {
2902 return this->emplace(p, ::boost::forward<U>(u));
2903 }
2904
2905 template <class U>
2906 inline void priv_push_back(BOOST_FWD_REF(U) u)
2907 {
2908 this->emplace_back(::boost::forward<U>(u));
2909 }
2910
2911
2912 inline void priv_push_back(::boost::move_detail::nat)
2913 {}
2914
2915 inline iterator priv_insert(const_iterator, ::boost::move_detail::nat)
2916 { return iterator(); }
2917
2918 inline dtl::insert_n_copies_proxy<allocator_type> priv_resize_proxy(const T &x)
2919 { return dtl::insert_n_copies_proxy<allocator_type>(x); }
2920
2921 inline dtl::insert_default_initialized_n_proxy<allocator_type> priv_resize_proxy(default_init_t)
2922 { return dtl::insert_default_initialized_n_proxy<allocator_type>(); }
2923
2924 inline dtl::insert_value_initialized_n_proxy<allocator_type> priv_resize_proxy(value_init_t)
2925 { return dtl::insert_value_initialized_n_proxy<allocator_type>(); }
2926
2927 protected:
2928 void prot_shrink_to_fit_small(pointer const small_buffer, const size_type small_capacity)
2929 {
2930 const size_type cp = this->m_holder.capacity();
2931 if (cp && this->m_holder.m_start != small_buffer) {
2932 const size_type sz = this->size();
2933 if (!sz) {
2934 if (BOOST_LIKELY(!!this->m_holder.m_start))
2935 this->m_holder.deallocate(this->m_holder.m_start, cp);
2936 this->m_holder.m_start = small_buffer;
2937 this->m_holder.set_stored_capacity(small_capacity);
2938 }
2939 else if(sz <= small_capacity) {
2940 T *const oldbuf = boost::movelib::to_raw_pointer(this->m_holder.m_start);
2941 ::boost::container::uninitialized_move_alloc_n
2942 ( this->get_stored_allocator()
2943 , oldbuf
2944 , sz
2945 , boost::movelib::to_raw_pointer(small_buffer)
2946 );
2947 boost::container::destroy_alloc_n(this->get_stored_allocator(), oldbuf, sz);
2948
2949 if (BOOST_LIKELY(!!this->m_holder.m_start))
2950 this->m_holder.deallocate(this->m_holder.m_start, cp);
2951
2952 this->m_holder.m_start = small_buffer;
2953 this->m_holder.set_stored_capacity(small_capacity);
2954 }
2955 else if (sz < cp) {
2956 this->priv_move_to_new_buffer(sz, alloc_version());
2957 }
2958 }
2959 }
2960
2961 private:
2962 inline void priv_shrink_to_fit(version_0) BOOST_NOEXCEPT_OR_NOTHROW
2963 {}
2964
2965 void priv_shrink_to_fit(version_1)
2966 {
2967 const size_type cp = this->m_holder.capacity();
2968 if(cp){
2969 const size_type sz = this->size();
2970 if(!sz){
2971 if(BOOST_LIKELY(!!this->m_holder.m_start))
2972 this->m_holder.deallocate(this->m_holder.m_start, cp);
2973 this->m_holder.m_start = pointer();
2974 this->m_holder.m_capacity = 0;
2975 }
2976 else if(sz < cp){
2977 this->priv_move_to_new_buffer(sz, alloc_version());
2978 }
2979 }
2980 }
2981
2982 void priv_shrink_to_fit(version_2) BOOST_NOEXCEPT_OR_NOTHROW
2983 {
2984 const size_type cp = this->m_holder.capacity();
2985 if(cp){
2986 const size_type sz = this->size();
2987 if(!sz){
2988 if(BOOST_LIKELY(!!this->m_holder.m_start))
2989 this->m_holder.deallocate(this->m_holder.m_start, cp);
2990 this->m_holder.m_start = pointer();
2991 this->m_holder.m_capacity = 0;
2992 }
2993 else{
2994 size_type received_size = sz;
2995 pointer reuse(this->m_holder.start());
2996 if(this->m_holder.allocation_command
2997 (shrink_in_place | nothrow_allocation, cp, received_size, reuse)){
2998 this->m_holder.capacity(received_size);
2999 #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
3000 ++this->num_shrink;
3001 #endif
3002 }
3003 }
3004 }
3005 }
3006
3007 #ifdef _MSC_VER
3008 #pragma warning (push)
3009 #pragma warning(disable: 4702)
3010 #endif
3011 template <class InsertionProxy>
3012 inline iterator priv_insert_forward_range_no_capacity
3013 (T * const, const size_type, const InsertionProxy , version_0)
3014 {
3015 return alloc_holder_t::on_capacity_overflow(), iterator();
3016 }
3017 #ifdef _MSC_VER
3018 #pragma warning (pop)
3019 #endif
3020
3021 template <class InsertionProxy>
3022 BOOST_CONTAINER_NOINLINE iterator priv_insert_forward_range_no_capacity
3023 (T *const raw_pos, const size_type n, const InsertionProxy insert_range_proxy, version_1)
3024 {
3025
3026 const size_type n_pos = static_cast<size_type>(raw_pos - this->priv_raw_begin());
3027
3028 const size_type new_cap = this->m_holder.template next_capacity<growth_factor_type>(n);
3029
3030 T * const new_buf = boost::movelib::to_raw_pointer(this->m_holder.allocate(new_cap));
3031 #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
3032 ++this->num_alloc;
3033 #endif
3034 this->priv_insert_forward_range_new_allocation(new_buf, new_cap, raw_pos, n, insert_range_proxy);
3035 return iterator(this->m_holder.start() + difference_type(n_pos));
3036 }
3037
3038 template <class InsertionProxy>
3039 BOOST_CONTAINER_NOINLINE iterator priv_insert_forward_range_no_capacity
3040 (T *const raw_pos, const size_type n, const InsertionProxy insert_range_proxy, version_2)
3041 {
3042
3043 const size_type n_pos = size_type(raw_pos - this->priv_raw_begin());
3044
3045
3046
3047 size_type real_cap = this->m_holder.template next_capacity<growth_factor_type>(n);
3048 pointer reuse(this->m_holder.start());
3049 pointer const ret (this->m_holder.allocation_command
3050 (allocate_new | expand_fwd | expand_bwd, size_type(this->m_holder.m_size + n), real_cap, reuse));
3051
3052
3053 if(reuse){
3054
3055 if(this->m_holder.start() == ret){
3056 #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
3057 ++this->num_expand_fwd;
3058 #endif
3059 this->m_holder.capacity(real_cap);
3060
3061 this->priv_insert_forward_range_expand_forward
3062 (raw_pos, n, insert_range_proxy, dtl::bool_<dtl::is_single_value_proxy<InsertionProxy>::value>());
3063 }
3064
3065 else{
3066 #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
3067 ++this->num_expand_bwd;
3068 #endif
3069 this->priv_insert_forward_range_expand_backwards
3070 (boost::movelib::to_raw_pointer(ret), real_cap, raw_pos, n, insert_range_proxy);
3071 }
3072 }
3073
3074 else{
3075 #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
3076 ++this->num_alloc;
3077 #endif
3078 this->priv_insert_forward_range_new_allocation
3079 ( boost::movelib::to_raw_pointer(ret), real_cap, raw_pos, n, insert_range_proxy);
3080 }
3081
3082 return iterator(this->m_holder.start() + (difference_type)(n_pos));
3083 }
3084
3085 template <class InsertionProxy>
3086 inline iterator priv_insert_forward_range
3087 (const pointer &pos, const size_type n, const InsertionProxy insert_range_proxy)
3088 {
3089 BOOST_ASSERT(this->m_holder.capacity() >= this->m_holder.m_size);
3090 T *const p = boost::movelib::to_raw_pointer(pos);
3091
3092 if (BOOST_LIKELY(n <= (this->m_holder.capacity() - this->m_holder.m_size))){
3093
3094 this->priv_insert_forward_range_expand_forward
3095 (p, n, insert_range_proxy, dtl::bool_<dtl::is_single_value_proxy<InsertionProxy>::value>());
3096 return iterator(pos);
3097 }
3098 else{
3099 return this->priv_insert_forward_range_no_capacity(p, n, insert_range_proxy, alloc_version());
3100 }
3101 }
3102
3103 template <class U>
3104 void priv_resize(const size_type new_size, const U &u, version_0)
3105 {
3106 const size_type sz = this->m_holder.m_size;
3107 if (new_size > this->capacity()){
3108
3109 alloc_holder_t::on_capacity_overflow();
3110 }
3111 else if (new_size < sz){
3112
3113 this->priv_destroy_last_n(sz - new_size);
3114 }
3115 else{
3116 T* const old_finish = this->priv_raw_end();
3117 this->priv_resize_proxy(u).uninitialized_copy_n_and_update(this->m_holder.alloc(), old_finish, new_size - sz);
3118 this->m_holder.set_stored_size(new_size);
3119 }
3120 }
3121
3122 template <class U, class AllocVersion>
3123 void priv_resize(const size_type new_size, const U &u, AllocVersion)
3124 {
3125 const size_type sz = this->m_holder.m_size;
3126 if (new_size < sz){
3127
3128 this->priv_destroy_last_n(size_type(sz - new_size));
3129 }
3130 else {
3131 this->priv_insert_forward_range(this->back_ptr(), size_type(new_size - sz), this->priv_resize_proxy(u));
3132 }
3133 }
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186 size_type priv_insert_ordered_at_shift_range
3187 (size_type first_pos, size_type last_pos, size_type limit_pos, size_type shift_count)
3188 {
3189 BOOST_ASSERT(first_pos <= last_pos);
3190 BOOST_ASSERT(last_pos <= limit_pos);
3191
3192 T* const begin_ptr = this->priv_raw_begin();
3193 T* const first_ptr = begin_ptr + first_pos;
3194 T* const last_ptr = begin_ptr + last_pos;
3195
3196 size_type hole_size = 0;
3197
3198 if((last_pos + shift_count) <= limit_pos){
3199
3200 boost::container::move_backward(first_ptr, last_ptr, last_ptr + shift_count);
3201 }
3202
3203 else if((first_pos + shift_count) >= limit_pos){
3204
3205 ::boost::container::uninitialized_move_alloc
3206 (this->m_holder.alloc(), first_ptr, last_ptr, first_ptr + shift_count);
3207
3208
3209 hole_size = static_cast<size_type>(first_pos + shift_count - limit_pos);
3210 }
3211
3212 else{
3213
3214 T* const limit_ptr = begin_ptr + limit_pos;
3215 T* const boundary_ptr = limit_ptr - shift_count;
3216 ::boost::container::uninitialized_move_alloc(this->m_holder.alloc(), boundary_ptr, last_ptr, limit_ptr);
3217
3218 boost::container::move_backward(first_ptr, boundary_ptr, limit_ptr);
3219 }
3220 return hole_size;
3221 }
3222
3223 private:
3224 inline T *priv_raw_begin() const
3225 { return boost::movelib::to_raw_pointer(m_holder.start()); }
3226
3227 inline T* priv_raw_end() const
3228 { return this->priv_raw_begin() + this->m_holder.m_size; }
3229
3230 template <class InsertionProxy>
3231 inline void priv_insert_forward_range_expand_forward
3232 (T* const raw_pos, const size_type, InsertionProxy insert_range_proxy, dtl::true_type)
3233 {
3234 BOOST_ASSERT(this->room_enough());
3235
3236 T* const old_finish = this->priv_raw_end();
3237 allocator_type & a = this->m_holder.alloc();
3238
3239 if (old_finish == raw_pos){
3240 insert_range_proxy.uninitialized_copy_n_and_update(a, old_finish, 1);
3241 ++this->m_holder.m_size;
3242 }
3243 else{
3244
3245
3246 T * const before_old_finish = old_finish-1;
3247
3248 allocator_traits_type::construct(a, old_finish, ::boost::move(*before_old_finish));
3249 ++this->m_holder.m_size;
3250
3251 boost::container::move_backward(raw_pos, before_old_finish, old_finish);
3252
3253 insert_range_proxy.copy_n_and_update(a, raw_pos, 1);
3254 }
3255 }
3256
3257 template <class InsertionProxy>
3258 inline void priv_insert_forward_range_expand_forward
3259 (T* const raw_pos, const size_type n, InsertionProxy insert_range_proxy, dtl::false_type)
3260 {
3261
3262 boost::container::expand_forward_and_insert_alloc
3263 ( this->m_holder.alloc(), raw_pos, this->priv_raw_end(), n, insert_range_proxy);
3264 this->m_holder.inc_stored_size(n);
3265 }
3266
3267 template <class InsertionProxy>
3268 void priv_insert_forward_range_new_allocation
3269 (T* const new_start, size_type new_cap, T* const pos, const size_type n, InsertionProxy insert_range_proxy)
3270 {
3271
3272 allocator_type &a = this->m_holder.alloc();
3273 T * const raw_old_buffer = this->priv_raw_begin();
3274
3275 typename value_traits::ArrayDeallocator new_buffer_deallocator(new_start, a, new_cap);
3276 boost::container::uninitialized_move_and_insert_alloc
3277 (a, raw_old_buffer, pos, this->priv_raw_end(), new_start, n, insert_range_proxy);
3278 new_buffer_deallocator.release();
3279
3280
3281 if(raw_old_buffer){
3282 BOOST_IF_CONSTEXPR(!has_trivial_destructor_after_move<value_type>::value)
3283 boost::container::destroy_alloc_n(a, raw_old_buffer, this->m_holder.m_size);
3284 this->m_holder.deallocate(this->m_holder.start(), this->m_holder.capacity());
3285 }
3286
3287 this->m_holder.start(new_start);
3288 this->m_holder.inc_stored_size(n);
3289 this->m_holder.capacity(new_cap);
3290 }
3291
3292 template <class InsertionProxy>
3293 void priv_insert_forward_range_expand_backwards
3294 (T* const new_start, const size_type new_capacity,
3295 T* const pos, const size_type n, InsertionProxy insert_range_proxy)
3296 {
3297 T* const old_start = this->priv_raw_begin();
3298 const size_type old_size = this->m_holder.m_size;
3299 allocator_type& a = this->m_holder.alloc();
3300
3301
3302 this->m_holder.start(new_start);
3303 this->m_holder.capacity(new_capacity);
3304 this->m_holder.m_size = 0;
3305
3306 expand_backward_forward_and_insert_alloc(old_start, old_size, new_start, pos, n, insert_range_proxy, a);
3307
3308
3309 this->m_holder.m_size = stored_size_type(old_size + n);
3310 }
3311
3312 void priv_throw_if_out_of_range(size_type n) const
3313 {
3314
3315 if (n >= this->size()){
3316 throw_out_of_range("vector::at out of range");
3317 }
3318 }
3319
3320 inline bool priv_in_range(const_iterator pos) const
3321 {
3322 return (this->begin() <= pos) && (pos < this->end());
3323 }
3324
3325 inline bool priv_in_range_or_end(const_iterator pos) const
3326 {
3327 return (this->begin() <= pos) && (pos <= this->end());
3328 }
3329
3330 #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
3331 public:
3332 unsigned int num_expand_fwd;
3333 unsigned int num_expand_bwd;
3334 unsigned int num_shrink;
3335 unsigned int num_alloc;
3336 void reset_alloc_stats()
3337 { num_expand_fwd = num_expand_bwd = num_alloc = 0, num_shrink = 0; }
3338 #endif
3339 #endif
3340 };
3341
3342 #ifndef BOOST_CONTAINER_NO_CXX17_CTAD
3343
3344 template <typename InputIterator>
3345 vector(InputIterator, InputIterator) ->
3346 vector<typename iter_value<InputIterator>::type>;
3347
3348 template <typename InputIterator, typename Allocator>
3349 vector(InputIterator, InputIterator, Allocator const&) ->
3350 vector<typename iter_value<InputIterator>::type, Allocator>;
3351
3352 #endif
3353
3354
3355 }}
3356
3357 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
3358
3359 namespace boost {
3360
3361
3362
3363 template <class T, class Allocator, class Options>
3364 struct has_trivial_destructor_after_move<boost::container::vector<T, Allocator, Options> >
3365 {
3366 typedef typename boost::container::vector<T, Allocator, Options>::allocator_type allocator_type;
3367 typedef typename ::boost::container::allocator_traits<allocator_type>::pointer pointer;
3368 BOOST_STATIC_CONSTEXPR bool value = ::boost::has_trivial_destructor_after_move<allocator_type>::value &&
3369 ::boost::has_trivial_destructor_after_move<pointer>::value;
3370 };
3371
3372 }
3373
3374
3375 #ifdef BOOST_GNU_STDLIB
3376
3377 #include <boost/move/detail/std_ns_begin.hpp>
3378
3379 BOOST_MOVE_STD_NS_BEG
3380
3381 template <class Pointer, bool IsConst>
3382 struct pointer_traits< boost::container::vec_iterator<Pointer, IsConst> >
3383 : public boost::intrusive::pointer_traits< boost::container::vec_iterator<Pointer, IsConst> >
3384 {};
3385
3386 BOOST_MOVE_STD_NS_END
3387
3388 #include <boost/move/detail/std_ns_end.hpp>
3389
3390 #endif
3391
3392 #endif
3393
3394 #include <boost/container/detail/config_end.hpp>
3395
3396 #endif