Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:30:23

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