Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:34:58

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 #ifndef BOOST_CONTAINER_DEQUE_HPP
0011 #define BOOST_CONTAINER_DEQUE_HPP
0012 
0013 #ifndef BOOST_CONFIG_HPP
0014 #  include <boost/config.hpp>
0015 #endif
0016 
0017 #if defined(BOOST_HAS_PRAGMA_ONCE)
0018 #  pragma once
0019 #endif
0020 
0021 #include <boost/container/detail/config_begin.hpp>
0022 #include <boost/container/detail/workaround.hpp>
0023 // container
0024 #include <boost/container/allocator_traits.hpp>
0025 #include <boost/container/container_fwd.hpp>
0026 #include <boost/container/new_allocator.hpp> //new_allocator
0027 #include <boost/container/throw_exception.hpp>
0028 #include <boost/container/options.hpp>
0029 // container/detail
0030 #include <boost/container/detail/advanced_insert_int.hpp>
0031 #include <boost/container/detail/algorithm.hpp> //algo_equal(), algo_lexicographical_compare
0032 #include <boost/container/detail/alloc_helpers.hpp>
0033 #include <boost/container/detail/copy_move_algo.hpp>
0034 #include <boost/container/detail/iterator.hpp>
0035 #include <boost/move/detail/iterator_to_raw_pointer.hpp>
0036 #include <boost/container/detail/iterators.hpp>
0037 #include <boost/container/detail/min_max.hpp>
0038 #include <boost/container/detail/mpl.hpp>
0039 #include <boost/move/detail/to_raw_pointer.hpp>
0040 #include <boost/container/detail/type_traits.hpp>
0041 // move
0042 #include <boost/move/adl_move_swap.hpp>
0043 #include <boost/move/iterator.hpp>
0044 #include <boost/move/traits.hpp>
0045 #include <boost/move/utility_core.hpp>
0046 // move/detail
0047 #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
0048 #include <boost/move/detail/fwd_macros.hpp>
0049 #endif
0050 #include <boost/move/detail/move_helpers.hpp>
0051 // other
0052 #include <boost/assert.hpp>
0053 // std
0054 #include <cstddef>
0055 
0056 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
0057 #include <initializer_list>
0058 #endif
0059 
0060 namespace boost {
0061 namespace container {
0062 
0063 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
0064 template <class T, class Allocator, class Options>
0065 class deque;
0066 
0067 template <class T>
0068 struct deque_value_traits
0069 {
0070    typedef T value_type;
0071    static const bool trivial_dctr = dtl::is_trivially_destructible<value_type>::value;
0072    static const bool trivial_dctr_after_move = ::boost::has_trivial_destructor_after_move<value_type>::value;
0073 };
0074 
0075 template<class T, std::size_t BlockBytes, std::size_t BlockSize>
0076 struct deque_block_size
0077 {
0078    BOOST_STATIC_ASSERT_MSG(!(BlockBytes && BlockSize), "BlockBytes and BlockSize can't be specified at the same time");
0079    static const std::size_t block_bytes = BlockBytes ? BlockBytes : 512u;
0080    static const std::size_t value       = BlockSize ? BlockSize : (sizeof(T) < block_bytes ? (block_bytes/sizeof(T)) : std::size_t(1));
0081 };
0082 
0083 namespace dtl {
0084 
0085 // Class invariants:
0086 //  For any nonsingular iterator i:
0087 //    i.node is the address of an element in the map array.  The
0088 //      contents of i.node is a pointer to the beginning of a node.
0089 //    i.first == //(i.node)
0090 //    i.last  == i.first + node_size
0091 //    i.cur is a pointer in the range [i.first, i.last).  NOTE:
0092 //      the implication of this is that i.cur is always a dereferenceable
0093 //      pointer, even if i is a past-the-end iterator.
0094 //  Start and Finish are always nonsingular iterators.  NOTE: this means
0095 //    that an empty deque must have one node, and that a deque
0096 //    with N elements, where N is the buffer size, must have two nodes.
0097 //  For every node other than start.node and finish.node, every element
0098 //    in the node is an initialized object.  If start.node == finish.node,
0099 //    then [start.cur, finish.cur) are initialized objects, and
0100 //    the elements outside that range are uninitialized storage.  Otherwise,
0101 //    [start.cur, start.last) and [finish.first, finish.cur) are initialized
0102 //    objects, and [start.first, start.cur) and [finish.cur, finish.last)
0103 //    are uninitialized storage.
0104 //  [map, map + map_size) is a valid, non-empty range.
0105 //  [start.node, finish.node] is a valid range contained within
0106 //    [map, map + map_size).
0107 //  A pointer in the range [map, map + map_size) points to an allocated node
0108 //    if and only if the pointer is in the range [start.node, finish.node].
0109 template<class Pointer, bool IsConst>
0110 class deque_iterator
0111 {
0112    public:
0113    typedef std::random_access_iterator_tag                                          iterator_category;
0114    typedef typename boost::intrusive::pointer_traits<Pointer>::element_type         value_type;
0115    typedef typename boost::intrusive::pointer_traits<Pointer>::difference_type      difference_type;
0116    typedef typename boost::intrusive::pointer_traits<Pointer>::size_type            size_type;
0117    typedef typename if_c
0118       < IsConst
0119       , typename boost::intrusive::pointer_traits<Pointer>::template
0120                                  rebind_pointer<const value_type>::type
0121       , Pointer
0122       >::type                                                                       pointer;
0123    typedef typename if_c
0124       < IsConst
0125       , const value_type&
0126       , value_type&
0127       >::type                                                                       reference;
0128 
0129    class nat;
0130    typedef typename dtl::if_c< IsConst
0131                              , deque_iterator<Pointer, false>
0132                              , nat>::type                                           nonconst_iterator;
0133 
0134    typedef Pointer                                                                  val_alloc_ptr;
0135    typedef typename boost::intrusive::pointer_traits<Pointer>::
0136       template rebind_pointer<Pointer>::type                                        index_pointer;
0137 
0138    Pointer m_cur;
0139    Pointer m_first;
0140    Pointer m_last;
0141    index_pointer  m_node;
0142 
0143    public:
0144 
0145    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE Pointer get_cur()          const  {  return m_cur;  }
0146    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE Pointer get_first()        const  {  return m_first;  }
0147    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE Pointer get_last()         const  {  return m_last;  }
0148    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE index_pointer get_node()   const  {  return m_node;  }
0149 
0150    BOOST_CONTAINER_FORCEINLINE deque_iterator(val_alloc_ptr x, index_pointer y, difference_type block_size) BOOST_NOEXCEPT_OR_NOTHROW
0151       : m_cur(x), m_first(*y), m_last(*y + block_size), m_node(y)
0152    {}
0153 
0154    BOOST_CONTAINER_FORCEINLINE deque_iterator(val_alloc_ptr x, index_pointer y, size_type block_size) BOOST_NOEXCEPT_OR_NOTHROW
0155       : m_cur(x), m_first(*y), m_last(*y + difference_type(block_size)), m_node(y)
0156    {}
0157 
0158    BOOST_CONTAINER_FORCEINLINE deque_iterator() BOOST_NOEXCEPT_OR_NOTHROW
0159       : m_cur(), m_first(), m_last(), m_node()  //Value initialization to achieve "null iterators" (N3644)
0160    {}
0161 
0162    BOOST_CONTAINER_FORCEINLINE deque_iterator(const deque_iterator& x) BOOST_NOEXCEPT_OR_NOTHROW
0163       : m_cur(x.get_cur()), m_first(x.get_first()), m_last(x.get_last()), m_node(x.get_node())
0164    {}
0165 
0166    BOOST_CONTAINER_FORCEINLINE deque_iterator(const nonconst_iterator& x) BOOST_NOEXCEPT_OR_NOTHROW
0167       : m_cur(x.get_cur()), m_first(x.get_first()), m_last(x.get_last()), m_node(x.get_node())
0168    {}
0169 
0170    BOOST_CONTAINER_FORCEINLINE deque_iterator(Pointer cur, Pointer first, Pointer last, index_pointer node) BOOST_NOEXCEPT_OR_NOTHROW
0171       : m_cur(cur), m_first(first), m_last(last), m_node(node)
0172    {}
0173 
0174    BOOST_CONTAINER_FORCEINLINE deque_iterator& operator=(const deque_iterator& x) BOOST_NOEXCEPT_OR_NOTHROW
0175    {  m_cur = x.get_cur(); m_first = x.get_first(); m_last = x.get_last(); m_node = x.get_node(); return *this; }
0176 
0177    BOOST_CONTAINER_FORCEINLINE deque_iterator<Pointer, false> unconst() const BOOST_NOEXCEPT_OR_NOTHROW
0178    {
0179       return deque_iterator<Pointer, false>(this->get_cur(), this->get_first(), this->get_last(), this->get_node());
0180    }
0181 
0182    BOOST_CONTAINER_FORCEINLINE reference operator*() const BOOST_NOEXCEPT_OR_NOTHROW
0183       { return *this->m_cur; }
0184 
0185    BOOST_CONTAINER_FORCEINLINE pointer operator->() const BOOST_NOEXCEPT_OR_NOTHROW
0186       { return this->m_cur; }
0187 
0188    BOOST_CONTAINER_ATTRIBUTE_NODISCARD difference_type operator-(const deque_iterator& x) const BOOST_NOEXCEPT_OR_NOTHROW
0189    {
0190       if(!this->m_cur && !x.m_cur){
0191          return 0;
0192       }
0193       const difference_type block_size = m_last - m_first;
0194       BOOST_ASSERT(block_size);
0195       return block_size * (this->m_node - x.m_node - 1) +
0196          (this->m_cur - this->m_first) + (x.m_last - x.m_cur);
0197    }
0198 
0199    deque_iterator& operator++() BOOST_NOEXCEPT_OR_NOTHROW
0200    {
0201       BOOST_ASSERT(!!m_cur);
0202       ++this->m_cur;
0203       if (this->m_cur == this->m_last) {
0204          const difference_type block_size = m_last - m_first;
0205          BOOST_ASSERT(block_size);
0206          this->priv_set_node(this->m_node + 1, block_size);
0207          this->m_cur = this->m_first;
0208       }
0209       return *this;
0210    }
0211 
0212    BOOST_CONTAINER_FORCEINLINE deque_iterator operator++(int) BOOST_NOEXCEPT_OR_NOTHROW
0213    {
0214       deque_iterator tmp(*this);
0215       ++*this;
0216       return tmp;
0217    }
0218 
0219    deque_iterator& operator--() BOOST_NOEXCEPT_OR_NOTHROW
0220    {
0221       BOOST_ASSERT(!!m_cur);
0222       if (this->m_cur == this->m_first) {
0223          const difference_type block_size = m_last - m_first;
0224          BOOST_ASSERT(block_size);
0225          this->priv_set_node(this->m_node - 1, block_size);
0226          this->m_cur = this->m_last;
0227       }
0228       --this->m_cur;
0229       return *this;
0230    }
0231 
0232    BOOST_CONTAINER_FORCEINLINE deque_iterator operator--(int) BOOST_NOEXCEPT_OR_NOTHROW
0233    {
0234       deque_iterator tmp(*this);
0235       --*this;
0236       return tmp;
0237    }
0238 
0239    deque_iterator& operator+=(difference_type n) BOOST_NOEXCEPT_OR_NOTHROW
0240    {
0241       if (!n)
0242          return *this;
0243       BOOST_ASSERT(!!m_cur);
0244       difference_type offset = n + (this->m_cur - this->m_first);
0245       const difference_type block_size = m_last - m_first;
0246       BOOST_ASSERT(block_size);
0247       if (offset >= 0 && offset < block_size)
0248          this->m_cur += difference_type(n);
0249       else {
0250          difference_type node_offset =
0251          offset > 0 ? (offset / block_size)
0252                     : (-difference_type((-offset - 1) / block_size) - 1);
0253          this->priv_set_node(this->m_node + node_offset, size_type(block_size));
0254          this->m_cur = this->m_first +
0255          (offset - node_offset * block_size);
0256       }
0257       return *this;
0258    }
0259 
0260    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0261       deque_iterator operator+(difference_type n) const BOOST_NOEXCEPT_OR_NOTHROW
0262       {  deque_iterator tmp(*this); return tmp += n;  }
0263 
0264    BOOST_CONTAINER_FORCEINLINE
0265       deque_iterator& operator-=(difference_type n) BOOST_NOEXCEPT_OR_NOTHROW
0266       { return *this += -n; }
0267 
0268    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0269       deque_iterator operator-(difference_type n) const BOOST_NOEXCEPT_OR_NOTHROW
0270       {  deque_iterator tmp(*this); return tmp -= n;  }
0271 
0272    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0273       reference operator[](difference_type n) const BOOST_NOEXCEPT_OR_NOTHROW
0274       { return *(*this + n); }
0275 
0276    //Comparisons
0277    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0278       friend bool operator==(const deque_iterator& l, const deque_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
0279       { return l.m_cur == r.m_cur; }
0280 
0281    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0282       friend bool operator!=(const deque_iterator& l, const deque_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
0283       { return l.m_cur != r.m_cur; }
0284 
0285    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0286       friend bool operator<(const deque_iterator& l, const deque_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
0287       {  return (l.m_node == r.m_node) ? (l.m_cur < r.m_cur) : (l.m_node < r.m_node);  }
0288 
0289    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0290       friend bool operator>(const deque_iterator& l, const deque_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
0291       { return r < l; }
0292 
0293    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0294       friend bool operator<=(const deque_iterator& l, const deque_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
0295       { return !(r < l); }
0296 
0297    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0298       friend bool operator>=(const deque_iterator& l, const deque_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
0299       { return !(l < r); }
0300 
0301    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0302       friend deque_iterator operator+(difference_type n, deque_iterator x) BOOST_NOEXCEPT_OR_NOTHROW
0303       {  return x += n;  }
0304 
0305    BOOST_CONTAINER_FORCEINLINE void priv_set_node(index_pointer new_node, size_type block_size) BOOST_NOEXCEPT_OR_NOTHROW
0306    {  return this->priv_set_node(new_node, difference_type(block_size)); }
0307 
0308    BOOST_CONTAINER_FORCEINLINE void priv_set_node(index_pointer new_node, difference_type block_size) BOOST_NOEXCEPT_OR_NOTHROW
0309    {
0310       this->m_node = new_node;
0311       this->m_first = *new_node;
0312       this->m_last = this->m_first + block_size;
0313    }
0314 };
0315 
0316 }  //namespace dtl {
0317 
0318 template<class Options>
0319 struct get_deque_opt
0320 {
0321    typedef Options type;
0322 };
0323 
0324 template<>
0325 struct get_deque_opt<void>
0326 {
0327    typedef deque_null_opt type;
0328 };
0329 
0330 // Deque base class.  It has two purposes.  First, its constructor
0331 //  and destructor allocate (but don't initialize) storage.  This makes
0332 //  exception safety easier.
0333 template <class Allocator, class Options>
0334 class deque_base
0335 {
0336    BOOST_COPYABLE_AND_MOVABLE(deque_base)
0337    public:
0338    typedef allocator_traits<Allocator>                            val_alloc_traits_type;
0339    typedef typename val_alloc_traits_type::value_type             val_alloc_val;
0340    typedef typename val_alloc_traits_type::pointer                val_alloc_ptr;
0341    typedef typename val_alloc_traits_type::const_pointer          val_alloc_cptr;
0342    typedef typename val_alloc_traits_type::reference              val_alloc_ref;
0343    typedef typename val_alloc_traits_type::const_reference        val_alloc_cref;
0344    typedef typename val_alloc_traits_type::difference_type        val_alloc_diff;
0345    typedef typename val_alloc_traits_type::size_type              val_alloc_size;
0346    typedef typename val_alloc_traits_type::template
0347       portable_rebind_alloc<val_alloc_ptr>::type                  ptr_alloc_t;
0348    typedef allocator_traits<ptr_alloc_t>                          ptr_alloc_traits_type;
0349    typedef typename ptr_alloc_traits_type::value_type             ptr_alloc_val;
0350    typedef typename ptr_alloc_traits_type::pointer                ptr_alloc_ptr;
0351    typedef typename ptr_alloc_traits_type::const_pointer          ptr_alloc_cptr;
0352    typedef typename ptr_alloc_traits_type::reference              ptr_alloc_ref;
0353    typedef typename ptr_alloc_traits_type::const_reference        ptr_alloc_cref;
0354    typedef Allocator                                                      allocator_type;
0355    typedef allocator_type                                         stored_allocator_type;
0356    typedef val_alloc_size                                         size_type;
0357    typedef val_alloc_diff                                         difference_type;
0358 
0359    private:
0360    typedef typename get_deque_opt<Options>::type                  options_type;
0361 
0362    protected:
0363    typedef dtl::deque_iterator<val_alloc_ptr, false> iterator;
0364    typedef dtl::deque_iterator<val_alloc_ptr, true > const_iterator;
0365 
0366    BOOST_CONSTEXPR BOOST_CONTAINER_FORCEINLINE static size_type get_block_size() BOOST_NOEXCEPT_OR_NOTHROW
0367       { return deque_block_size<val_alloc_val, options_type::block_bytes, options_type::block_size>::value; }
0368 
0369    BOOST_CONSTEXPR BOOST_CONTAINER_FORCEINLINE static val_alloc_diff get_block_ssize() BOOST_NOEXCEPT_OR_NOTHROW
0370       { return val_alloc_diff((get_block_size)()); }
0371 
0372    typedef deque_value_traits<val_alloc_val>             traits_t;
0373    typedef ptr_alloc_t                                   map_allocator_type;
0374 
0375    BOOST_CONTAINER_FORCEINLINE val_alloc_ptr priv_allocate_node()
0376       {  return this->alloc().allocate(get_block_size());  }
0377 
0378    BOOST_CONTAINER_FORCEINLINE void priv_deallocate_node(val_alloc_ptr p) BOOST_NOEXCEPT_OR_NOTHROW
0379       {  this->alloc().deallocate(p, get_block_size());  }
0380 
0381    BOOST_CONTAINER_FORCEINLINE ptr_alloc_ptr priv_allocate_map(size_type n)
0382       { return this->ptr_alloc().allocate(n); }
0383 
0384    BOOST_CONTAINER_FORCEINLINE void priv_deallocate_map(ptr_alloc_ptr p, size_type n) BOOST_NOEXCEPT_OR_NOTHROW
0385       { this->ptr_alloc().deallocate(p, n); }
0386 
0387    BOOST_CONTAINER_FORCEINLINE deque_base(size_type num_elements, const allocator_type& a)
0388       :  members_(a)
0389    { this->priv_initialize_map(num_elements); }
0390 
0391    BOOST_CONTAINER_FORCEINLINE explicit deque_base(const allocator_type& a)
0392       :  members_(a)
0393    {}
0394 
0395    BOOST_CONTAINER_FORCEINLINE deque_base()
0396       :  members_()
0397    {}
0398 
0399    BOOST_CONTAINER_FORCEINLINE explicit deque_base(BOOST_RV_REF(deque_base) x)
0400       :  members_( boost::move(x.ptr_alloc())
0401                  , boost::move(x.alloc()) )
0402    {}
0403 
0404    ~deque_base()
0405    {
0406       if (this->members_.m_map) {
0407          this->priv_destroy_nodes(this->members_.m_start.m_node, this->members_.m_finish.m_node + 1);
0408          this->priv_deallocate_map(this->members_.m_map, this->members_.m_map_size);
0409       }
0410    }
0411 
0412    private:
0413    deque_base(const deque_base&);
0414 
0415    protected:
0416 
0417    void swap_members(deque_base &x) BOOST_NOEXCEPT_OR_NOTHROW
0418    {
0419       ::boost::adl_move_swap(this->members_.m_start, x.members_.m_start);
0420       ::boost::adl_move_swap(this->members_.m_finish, x.members_.m_finish);
0421       ::boost::adl_move_swap(this->members_.m_map, x.members_.m_map);
0422       ::boost::adl_move_swap(this->members_.m_map_size, x.members_.m_map_size);
0423    }
0424 
0425    void priv_initialize_map(size_type num_elements)
0426    {
0427 //      if(num_elements){
0428          size_type num_nodes = num_elements / get_block_size() + 1;
0429 
0430          this->members_.m_map_size = dtl::max_value((size_type) InitialMapSize, num_nodes + 2);
0431          this->members_.m_map = this->priv_allocate_map(this->members_.m_map_size);
0432 
0433          ptr_alloc_ptr nstart = this->members_.m_map + difference_type(this->members_.m_map_size - num_nodes) / 2;
0434          ptr_alloc_ptr nfinish = nstart + difference_type(num_nodes);
0435 
0436          BOOST_CONTAINER_TRY {
0437             this->priv_create_nodes(nstart, nfinish);
0438          }
0439          BOOST_CONTAINER_CATCH(...){
0440             this->priv_deallocate_map(this->members_.m_map, this->members_.m_map_size);
0441             this->members_.m_map = 0;
0442             this->members_.m_map_size = 0;
0443             BOOST_CONTAINER_RETHROW
0444          }
0445          BOOST_CONTAINER_CATCH_END
0446 
0447          this->members_.m_start.priv_set_node(nstart, get_block_size());
0448          this->members_.m_finish.priv_set_node(nfinish - 1, get_block_size());
0449          this->members_.m_start.m_cur = this->members_.m_start.m_first;
0450          this->members_.m_finish.m_cur = this->members_.m_finish.m_first + difference_type(num_elements % get_block_size());
0451 //      }
0452    }
0453 
0454    void priv_create_nodes(ptr_alloc_ptr nstart, ptr_alloc_ptr nfinish)
0455    {
0456       ptr_alloc_ptr cur = nstart;
0457       BOOST_CONTAINER_TRY {
0458          for (; cur < nfinish; ++cur)
0459             *cur = this->priv_allocate_node();
0460       }
0461       BOOST_CONTAINER_CATCH(...){
0462          this->priv_destroy_nodes(nstart, cur);
0463          BOOST_CONTAINER_RETHROW
0464       }
0465       BOOST_CONTAINER_CATCH_END
0466    }
0467 
0468    void priv_destroy_nodes(ptr_alloc_ptr nstart, ptr_alloc_ptr nfinish) BOOST_NOEXCEPT_OR_NOTHROW
0469    {
0470       for (ptr_alloc_ptr n = nstart; n < nfinish; ++n)
0471          this->priv_deallocate_node(*n);
0472    }
0473 
0474    void priv_clear_map() BOOST_NOEXCEPT_OR_NOTHROW
0475    {
0476       if (this->members_.m_map) {
0477          this->priv_destroy_nodes(this->members_.m_start.m_node, this->members_.m_finish.m_node + 1);
0478          this->priv_deallocate_map(this->members_.m_map, this->members_.m_map_size);
0479          this->members_.m_map = 0;
0480          this->members_.m_map_size = 0;
0481          this->members_.m_start = iterator();
0482          this->members_.m_finish = this->members_.m_start;
0483       }
0484    }
0485 
0486    enum { InitialMapSize = 8 };
0487 
0488    protected:
0489    struct members_holder
0490       :  public ptr_alloc_t
0491       ,  public allocator_type
0492    {
0493       members_holder()
0494          :  map_allocator_type(), allocator_type()
0495          ,  m_map(0), m_map_size(0)
0496          ,  m_start(), m_finish(m_start)
0497       {}
0498 
0499       explicit members_holder(const allocator_type &a)
0500          :  map_allocator_type(a), allocator_type(a)
0501          ,  m_map(0), m_map_size(0)
0502          ,  m_start(), m_finish(m_start)
0503       {}
0504 
0505       template<class ValAllocConvertible, class PtrAllocConvertible>
0506       members_holder(BOOST_FWD_REF(PtrAllocConvertible) pa, BOOST_FWD_REF(ValAllocConvertible) va)
0507          : map_allocator_type(boost::forward<PtrAllocConvertible>(pa))
0508          , allocator_type    (boost::forward<ValAllocConvertible>(va))
0509          , m_map(0), m_map_size(0)
0510          , m_start(), m_finish(m_start)
0511       {}
0512 
0513       ptr_alloc_ptr   m_map;
0514       val_alloc_size  m_map_size;
0515       iterator        m_start;
0516       iterator        m_finish;
0517    } members_;
0518 
0519    BOOST_CONTAINER_FORCEINLINE ptr_alloc_t &ptr_alloc() BOOST_NOEXCEPT_OR_NOTHROW
0520    {  return members_;  }
0521 
0522    BOOST_CONTAINER_FORCEINLINE const ptr_alloc_t &ptr_alloc() const BOOST_NOEXCEPT_OR_NOTHROW
0523    {  return members_;  }
0524 
0525    BOOST_CONTAINER_FORCEINLINE allocator_type &alloc() BOOST_NOEXCEPT_OR_NOTHROW
0526    {  return members_;  }
0527 
0528    BOOST_CONTAINER_FORCEINLINE const allocator_type &alloc() const BOOST_NOEXCEPT_OR_NOTHROW
0529    {  return members_;  }
0530 };
0531 #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
0532 
0533 #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
0534 //! A double-ended queue is a sequence that supports random access to elements, constant time insertion
0535 //! and removal of elements at the end of the sequence, and linear time insertion and removal of elements in the middle.
0536 //!
0537 //! \tparam T The type of object that is stored in the deque
0538 //! \tparam A The allocator used for all internal memory management, use void
0539 //!   for the default allocator
0540 //! \tparam Options A type produced from \c boost::container::deque_options.
0541 template <class T, class Allocator = void, class Options = void>
0542 #else
0543 template <class T, class Allocator, class Options>
0544 #endif
0545 class deque : protected deque_base<typename real_allocator<T, Allocator>::type, Options>
0546 {
0547    #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
0548    private:
0549    typedef deque_base<typename real_allocator<T, Allocator>::type, Options> Base;
0550    #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
0551    typedef typename real_allocator<T, Allocator>::type ValAllocator;
0552    typedef constant_iterator<T> c_it;
0553 
0554    public:
0555 
0556    //////////////////////////////////////////////
0557    //
0558    //                    types
0559    //
0560    //////////////////////////////////////////////
0561 
0562    typedef T                                                                           value_type;
0563    typedef ValAllocator                                                                allocator_type;
0564    typedef typename ::boost::container::allocator_traits<ValAllocator>::pointer           pointer;
0565    typedef typename ::boost::container::allocator_traits<ValAllocator>::const_pointer     const_pointer;
0566    typedef typename ::boost::container::allocator_traits<ValAllocator>::reference         reference;
0567    typedef typename ::boost::container::allocator_traits<ValAllocator>::const_reference   const_reference;
0568    typedef typename ::boost::container::allocator_traits<ValAllocator>::size_type         size_type;
0569    typedef typename ::boost::container::allocator_traits<ValAllocator>::difference_type   difference_type;
0570    typedef BOOST_CONTAINER_IMPDEF(allocator_type)                                      stored_allocator_type;
0571    typedef BOOST_CONTAINER_IMPDEF(typename Base::iterator)                             iterator;
0572    typedef BOOST_CONTAINER_IMPDEF(typename Base::const_iterator)                       const_iterator;
0573    typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator<iterator>)        reverse_iterator;
0574    typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator<const_iterator>)  const_reverse_iterator;
0575 
0576    #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
0577 
0578    private:                      // Internal typedefs
0579    BOOST_COPYABLE_AND_MOVABLE(deque)
0580    typedef typename Base::ptr_alloc_ptr index_pointer;
0581    typedef allocator_traits<ValAllocator>                  allocator_traits_type;
0582 
0583    #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
0584 
0585    using Base::get_block_ssize;
0586 
0587    public:
0588 
0589    using Base::get_block_size;
0590 
0591 
0592    //////////////////////////////////////////////
0593    //
0594    //          construct/copy/destroy
0595    //
0596    //////////////////////////////////////////////
0597 
0598    //! <b>Effects</b>: Default constructors a deque.
0599    //!
0600    //! <b>Throws</b>: If allocator_type's default constructor throws.
0601    //!
0602    //! <b>Complexity</b>: Constant.
0603    BOOST_CONTAINER_FORCEINLINE deque()
0604       BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible<ValAllocator>::value)
0605       : Base()
0606    {}
0607 
0608    //! <b>Effects</b>: Constructs a deque taking the allocator as parameter.
0609    //!
0610    //! <b>Throws</b>: Nothing
0611    //!
0612    //! <b>Complexity</b>: Constant.
0613    BOOST_CONTAINER_FORCEINLINE explicit deque(const allocator_type& a) BOOST_NOEXCEPT_OR_NOTHROW
0614       : Base(a)
0615    {}
0616 
0617    //! <b>Effects</b>: Constructs a deque
0618    //!   and inserts n value initialized values.
0619    //!
0620    //! <b>Throws</b>: If allocator_type's default constructor
0621    //!   throws or T's value initialization throws.
0622    //!
0623    //! <b>Complexity</b>: Linear to n.
0624    BOOST_CONTAINER_FORCEINLINE explicit deque(size_type n)
0625       : Base(n, allocator_type())
0626    {
0627       dtl::insert_value_initialized_n_proxy<ValAllocator> proxy;
0628       proxy.uninitialized_copy_n_and_update(this->alloc(), this->begin(), n);
0629       //deque_base will deallocate in case of exception...
0630    }
0631 
0632    //! <b>Effects</b>: Constructs a deque
0633    //!   and inserts n default initialized values.
0634    //!
0635    //! <b>Throws</b>: If allocator_type's default constructor
0636    //!   throws or T's default initialization or copy constructor throws.
0637    //!
0638    //! <b>Complexity</b>: Linear to n.
0639    //!
0640    //! <b>Note</b>: Non-standard extension
0641    BOOST_CONTAINER_FORCEINLINE deque(size_type n, default_init_t)
0642       : Base(n, allocator_type())
0643    {
0644       dtl::insert_default_initialized_n_proxy<ValAllocator> proxy;
0645       proxy.uninitialized_copy_n_and_update(this->alloc(), this->begin(), n);
0646       //deque_base will deallocate in case of exception...
0647    }
0648 
0649    //! <b>Effects</b>: Constructs a deque that will use a copy of allocator a
0650    //!   and inserts n value initialized values.
0651    //!
0652    //! <b>Throws</b>: If allocator_type's default constructor
0653    //!   throws or T's value initialization throws.
0654    //!
0655    //! <b>Complexity</b>: Linear to n.
0656    BOOST_CONTAINER_FORCEINLINE explicit deque(size_type n, const allocator_type &a)
0657       : Base(n, a)
0658    {
0659       dtl::insert_value_initialized_n_proxy<ValAllocator> proxy;
0660       proxy.uninitialized_copy_n_and_update(this->alloc(), this->begin(), n);
0661       //deque_base will deallocate in case of exception...
0662    }
0663 
0664    //! <b>Effects</b>: Constructs a deque that will use a copy of allocator a
0665    //!   and inserts n default initialized values.
0666    //!
0667    //! <b>Throws</b>: If allocator_type's default constructor
0668    //!   throws or T's default initialization or copy constructor throws.
0669    //!
0670    //! <b>Complexity</b>: Linear to n.
0671    //!
0672    //! <b>Note</b>: Non-standard extension
0673    BOOST_CONTAINER_FORCEINLINE deque(size_type n, default_init_t, const allocator_type &a)
0674       : Base(n, a)
0675    {
0676       dtl::insert_default_initialized_n_proxy<ValAllocator> proxy;
0677       proxy.uninitialized_copy_n_and_update(this->alloc(), this->begin(), n);
0678       //deque_base will deallocate in case of exception...
0679    }
0680 
0681    //! <b>Effects</b>: Constructs a deque that will use a copy of allocator a
0682    //!   and inserts n copies of value.
0683    //!
0684    //! <b>Throws</b>: If allocator_type's default constructor
0685    //!   throws or T's copy constructor throws.
0686    //!
0687    //! <b>Complexity</b>: Linear to n.
0688    BOOST_CONTAINER_FORCEINLINE deque(size_type n, const value_type& value)
0689       : Base(n, allocator_type())
0690    { this->priv_fill_initialize(value); }
0691 
0692    //! <b>Effects</b>: Constructs a deque that will use a copy of allocator a
0693    //!   and inserts n copies of value.
0694    //!
0695    //! <b>Throws</b>: If allocator_type's default constructor
0696    //!   throws or T's copy constructor throws.
0697    //!
0698    //! <b>Complexity</b>: Linear to n.
0699    BOOST_CONTAINER_FORCEINLINE deque(size_type n, const value_type& value, const allocator_type& a)
0700       : Base(n, a)
0701    { this->priv_fill_initialize(value); }
0702 
0703    //! <b>Effects</b>: Constructs a deque that will use a copy of allocator a
0704    //!   and inserts a copy of the range [first, last) in the deque.
0705    //!
0706    //! <b>Throws</b>: If allocator_type's default constructor
0707    //!   throws or T's constructor taking a dereferenced InIt throws.
0708    //!
0709    //! <b>Complexity</b>: Linear to the range [first, last).
0710    template <class InIt>
0711    BOOST_CONTAINER_FORCEINLINE deque(InIt first, InIt last
0712       #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
0713       , typename dtl::disable_if_convertible
0714          <InIt, size_type>::type * = 0
0715       #endif
0716       )
0717       : Base(allocator_type())
0718    {
0719       this->priv_range_initialize(first, last);
0720    }
0721 
0722    //! <b>Effects</b>: Constructs a deque that will use a copy of allocator a
0723    //!   and inserts a copy of the range [first, last) in the deque.
0724    //!
0725    //! <b>Throws</b>: If allocator_type's default constructor
0726    //!   throws or T's constructor taking a dereferenced InIt throws.
0727    //!
0728    //! <b>Complexity</b>: Linear to the range [first, last).
0729    template <class InIt>
0730    BOOST_CONTAINER_FORCEINLINE deque(InIt first, InIt last, const allocator_type& a
0731       #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
0732       , typename dtl::disable_if_convertible
0733          <InIt, size_type>::type * = 0
0734       #endif
0735       )
0736       : Base(a)
0737    {
0738       this->priv_range_initialize(first, last);
0739    }
0740 
0741 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
0742    //! <b>Effects</b>: Constructs a deque that will use a copy of allocator a
0743    //!   and inserts a copy of the range [il.begin(), il.end()) in the deque.
0744    //!
0745    //! <b>Throws</b>: If allocator_type's default constructor
0746    //!   throws or T's constructor taking a dereferenced std::initializer_list iterator throws.
0747    //!
0748    //! <b>Complexity</b>: Linear to the range [il.begin(), il.end()).
0749    BOOST_CONTAINER_FORCEINLINE deque(std::initializer_list<value_type> il, const allocator_type& a = allocator_type())
0750       : Base(a)
0751    {
0752       this->priv_range_initialize(il.begin(), il.end());
0753    }
0754 #endif
0755 
0756    //! <b>Effects</b>: Copy constructs a deque.
0757    //!
0758    //! <b>Postcondition</b>: x == *this.
0759    //!
0760    //! <b>Complexity</b>: Linear to the elements x contains.
0761    BOOST_CONTAINER_FORCEINLINE deque(const deque& x)
0762       :  Base(allocator_traits_type::select_on_container_copy_construction(x.alloc()))
0763    {
0764       if(x.size()){
0765          this->priv_initialize_map(x.size());
0766          boost::container::uninitialized_copy_alloc
0767             (this->alloc(), x.begin(), x.end(), this->members_.m_start);
0768       }
0769    }
0770 
0771    //! <b>Effects</b>: Move constructor. Moves x's resources to *this.
0772    //!
0773    //! <b>Throws</b>: If allocator_type's copy constructor throws.
0774    //!
0775    //! <b>Complexity</b>: Constant.
0776    BOOST_CONTAINER_FORCEINLINE deque(BOOST_RV_REF(deque) x) BOOST_NOEXCEPT_OR_NOTHROW
0777       :  Base(BOOST_MOVE_BASE(Base, x))
0778    {  this->swap_members(x);   }
0779 
0780    //! <b>Effects</b>: Copy constructs a vector using the specified allocator.
0781    //!
0782    //! <b>Postcondition</b>: x == *this.
0783    //!
0784    //! <b>Throws</b>: If allocation
0785    //!   throws or T's copy constructor throws.
0786    //!
0787    //! <b>Complexity</b>: Linear to the elements x contains.
0788    deque(const deque& x, const allocator_type &a)
0789       :  Base(a)
0790    {
0791       if(x.size()){
0792          this->priv_initialize_map(x.size());
0793          boost::container::uninitialized_copy_alloc
0794             (this->alloc(), x.begin(), x.end(), this->members_.m_start);
0795       }
0796    }
0797 
0798    //! <b>Effects</b>: Move constructor using the specified allocator.
0799    //!                 Moves x's resources to *this if a == allocator_type().
0800    //!                 Otherwise copies values from x to *this.
0801    //!
0802    //! <b>Throws</b>: If allocation or T's copy constructor throws.
0803    //!
0804    //! <b>Complexity</b>: Constant if a == x.get_allocator(), linear otherwise.
0805    deque(BOOST_RV_REF(deque) x, const allocator_type &a)
0806       :  Base(a)
0807    {
0808       if(x.alloc() == a){
0809          this->swap_members(x);
0810       }
0811       else{
0812          if(x.size()){
0813             this->priv_initialize_map(x.size());
0814             boost::container::uninitialized_copy_alloc
0815                ( this->alloc(), boost::make_move_iterator(x.begin())
0816                , boost::make_move_iterator(x.end()), this->members_.m_start);
0817          }
0818       }
0819    }
0820 
0821    //! <b>Effects</b>: Destroys the deque. All stored values are destroyed
0822    //!   and used memory is deallocated.
0823    //!
0824    //! <b>Throws</b>: Nothing.
0825    //!
0826    //! <b>Complexity</b>: Linear to the number of elements.
0827    BOOST_CONTAINER_FORCEINLINE ~deque() BOOST_NOEXCEPT_OR_NOTHROW
0828    {
0829       this->priv_destroy_range(this->members_.m_start, this->members_.m_finish);
0830    }
0831 
0832    //! <b>Effects</b>: Makes *this contain the same elements as x.
0833    //!
0834    //! <b>Postcondition</b>: this->size() == x.size(). *this contains a copy
0835    //! of each of x's elements.
0836    //!
0837    //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
0838    //!
0839    //! <b>Complexity</b>: Linear to the number of elements in x.
0840    deque& operator= (BOOST_COPY_ASSIGN_REF(deque) x)
0841    {
0842       if (BOOST_LIKELY(&x != this)){
0843          allocator_type &this_alloc     = this->alloc();
0844          const allocator_type &x_alloc  = x.alloc();
0845          dtl::bool_<allocator_traits_type::
0846             propagate_on_container_copy_assignment::value> flag;
0847          if(flag && this_alloc != x_alloc){
0848             this->clear();
0849             this->shrink_to_fit();
0850          }
0851          dtl::assign_alloc(this->alloc(), x.alloc(), flag);
0852          dtl::assign_alloc(this->ptr_alloc(), x.ptr_alloc(), flag);
0853          this->assign(x.cbegin(), x.cend());
0854       }
0855       return *this;
0856    }
0857 
0858    //! <b>Effects</b>: Move assignment. All x's values are transferred to *this.
0859    //!
0860    //! <b>Throws</b>: If allocator_traits_type::propagate_on_container_move_assignment
0861    //!   is false and (allocation throws or value_type's move constructor throws)
0862    //!
0863    //! <b>Complexity</b>: Constant if allocator_traits_type::
0864    //!   propagate_on_container_move_assignment is true or
0865    //!   this->get>allocator() == x.get_allocator(). Linear otherwise.
0866    deque& operator= (BOOST_RV_REF(deque) x)
0867       BOOST_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_move_assignment::value
0868                                   || allocator_traits_type::is_always_equal::value)
0869    {
0870       if (BOOST_LIKELY(this != &x)) {
0871          allocator_type &this_alloc = this->alloc();
0872          allocator_type &x_alloc    = x.alloc();
0873          const bool propagate_alloc = allocator_traits_type::
0874                propagate_on_container_move_assignment::value;
0875          dtl::bool_<propagate_alloc> flag;
0876          const bool allocators_equal = this_alloc == x_alloc; (void)allocators_equal;
0877          //Resources can be transferred if both allocators are
0878          //going to be equal after this function (either propagated or already equal)
0879          if(propagate_alloc || allocators_equal){
0880             //Destroy objects but retain memory in case x reuses it in the future
0881             this->clear();
0882             //Move allocator if needed
0883             dtl::move_alloc(this_alloc, x_alloc, flag);
0884             dtl::move_alloc(this->ptr_alloc(), x.ptr_alloc(), flag);
0885             //Nothrow swap
0886             this->swap_members(x);
0887          }
0888          //Else do a one by one move
0889          else{
0890             this->assign( boost::make_move_iterator(x.begin())
0891                         , boost::make_move_iterator(x.end()));
0892          }
0893       }
0894       return *this;
0895    }
0896 
0897 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
0898    //! <b>Effects</b>: Makes *this contain the same elements as il.
0899    //!
0900    //! <b>Postcondition</b>: this->size() == il.size(). *this contains a copy
0901    //! of each of x's elements.
0902    //!
0903    //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
0904    //!
0905    //! <b>Complexity</b>: Linear to the number of elements in il.
0906    BOOST_CONTAINER_FORCEINLINE deque& operator=(std::initializer_list<value_type> il)
0907    {
0908       this->assign(il.begin(), il.end());
0909       return *this;
0910    }
0911 #endif
0912 
0913    //! <b>Effects</b>: Assigns the n copies of val to *this.
0914    //!
0915    //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
0916    //!
0917    //! <b>Complexity</b>: Linear to n.
0918    BOOST_CONTAINER_FORCEINLINE void assign(size_type n, const T& val)
0919    {
0920       this->assign(c_it(val, n), c_it());
0921    }
0922 
0923    //! <b>Effects</b>: Assigns the the range [first, last) to *this.
0924    //!
0925    //! <b>Throws</b>: If memory allocation throws or
0926    //!   T's constructor from dereferencing InIt throws.
0927    //!
0928    //! <b>Complexity</b>: Linear to n.
0929    template <class InIt>
0930    void assign(InIt first, InIt last
0931       #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
0932       , typename dtl::disable_if_or
0933          < void
0934          , dtl::is_convertible<InIt, size_type>
0935          , dtl::is_not_input_iterator<InIt>
0936          >::type * = 0
0937       #endif
0938       )
0939    {
0940       iterator cur = this->begin();
0941       for ( ; first != last && cur != end(); ++cur, ++first){
0942          *cur = *first;
0943       }
0944       if (first == last){
0945          this->erase(cur, this->cend());
0946       }
0947       else{
0948          this->insert(this->cend(), first, last);
0949       }
0950    }
0951 
0952    #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
0953    template <class FwdIt>
0954    void assign(FwdIt first, FwdIt last
0955       , typename dtl::disable_if_or
0956          < void
0957          , dtl::is_convertible<FwdIt, size_type>
0958          , dtl::is_input_iterator<FwdIt>
0959          >::type * = 0
0960       )
0961    {
0962       const size_type len = boost::container::iterator_udistance(first, last);
0963       if (len > size()) {
0964          FwdIt mid = first;
0965          boost::container::iterator_uadvance(mid, this->size());
0966          boost::container::copy(first, mid, begin());
0967          this->insert(this->cend(), mid, last);
0968       }
0969       else{
0970          this->erase(boost::container::copy(first, last, this->begin()), cend());
0971       }
0972    }
0973    #endif
0974 
0975 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
0976    //! <b>Effects</b>: Assigns the the range [il.begin(), il.end()) to *this.
0977    //!
0978    //! <b>Throws</b>: If memory allocation throws or
0979    //!   T's constructor from dereferencing std::initializer_list iterator throws.
0980    //!
0981    //! <b>Complexity</b>: Linear to il.size().
0982    BOOST_CONTAINER_FORCEINLINE void assign(std::initializer_list<value_type> il)
0983    {   this->assign(il.begin(), il.end());   }
0984 #endif
0985 
0986    //! <b>Effects</b>: Returns a copy of the internal allocator.
0987    //!
0988    //! <b>Throws</b>: If allocator's copy constructor throws.
0989    //!
0990    //! <b>Complexity</b>: Constant.
0991    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0992       allocator_type get_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
0993    { return Base::alloc(); }
0994 
0995    //! <b>Effects</b>: Returns a reference to the internal allocator.
0996    //!
0997    //! <b>Throws</b>: Nothing
0998    //!
0999    //! <b>Complexity</b>: Constant.
1000    //!
1001    //! <b>Note</b>: Non-standard extension.
1002    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1003       const stored_allocator_type &get_stored_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
1004    {  return Base::alloc(); }
1005 
1006    //////////////////////////////////////////////
1007    //
1008    //                iterators
1009    //
1010    //////////////////////////////////////////////
1011 
1012    //! <b>Effects</b>: Returns a reference to the internal allocator.
1013    //!
1014    //! <b>Throws</b>: Nothing
1015    //!
1016    //! <b>Complexity</b>: Constant.
1017    //!
1018    //! <b>Note</b>: Non-standard extension.
1019    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1020       stored_allocator_type &get_stored_allocator() BOOST_NOEXCEPT_OR_NOTHROW
1021    {  return Base::alloc(); }
1022 
1023    //! <b>Effects</b>: Returns an iterator to the first element contained in the deque.
1024    //!
1025    //! <b>Throws</b>: Nothing.
1026    //!
1027    //! <b>Complexity</b>: Constant.
1028    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1029       iterator begin() BOOST_NOEXCEPT_OR_NOTHROW
1030       { return this->members_.m_start; }
1031 
1032    //! <b>Effects</b>: Returns a const_iterator to the first element contained in the deque.
1033    //!
1034    //! <b>Throws</b>: Nothing.
1035    //!
1036    //! <b>Complexity</b>: Constant.
1037    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1038       const_iterator begin() const BOOST_NOEXCEPT_OR_NOTHROW
1039       { return this->members_.m_start; }
1040 
1041    //! <b>Effects</b>: Returns an iterator to the end of the deque.
1042    //!
1043    //! <b>Throws</b>: Nothing.
1044    //!
1045    //! <b>Complexity</b>: Constant.
1046    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1047       iterator end() BOOST_NOEXCEPT_OR_NOTHROW
1048       { return this->members_.m_finish; }
1049 
1050    //! <b>Effects</b>: Returns a const_iterator to the end of the deque.
1051    //!
1052    //! <b>Throws</b>: Nothing.
1053    //!
1054    //! <b>Complexity</b>: Constant.
1055    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1056       const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW
1057       { return this->members_.m_finish; }
1058 
1059    //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
1060    //! of the reversed deque.
1061    //!
1062    //! <b>Throws</b>: Nothing.
1063    //!
1064    //! <b>Complexity</b>: Constant.
1065    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1066       reverse_iterator rbegin() BOOST_NOEXCEPT_OR_NOTHROW
1067       { return reverse_iterator(this->members_.m_finish); }
1068 
1069    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
1070    //! of the reversed deque.
1071    //!
1072    //! <b>Throws</b>: Nothing.
1073    //!
1074    //! <b>Complexity</b>: Constant.
1075    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1076       const_reverse_iterator rbegin() const BOOST_NOEXCEPT_OR_NOTHROW
1077       { return const_reverse_iterator(this->members_.m_finish); }
1078 
1079    //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
1080    //! of the reversed deque.
1081    //!
1082    //! <b>Throws</b>: Nothing.
1083    //!
1084    //! <b>Complexity</b>: Constant.
1085    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1086       reverse_iterator rend() BOOST_NOEXCEPT_OR_NOTHROW
1087       { return reverse_iterator(this->members_.m_start); }
1088 
1089    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
1090    //! of the reversed deque.
1091    //!
1092    //! <b>Throws</b>: Nothing.
1093    //!
1094    //! <b>Complexity</b>: Constant.
1095    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1096       const_reverse_iterator rend() const BOOST_NOEXCEPT_OR_NOTHROW
1097       { return const_reverse_iterator(this->members_.m_start); }
1098 
1099    //! <b>Effects</b>: Returns a const_iterator to the first element contained in the deque.
1100    //!
1101    //! <b>Throws</b>: Nothing.
1102    //!
1103    //! <b>Complexity</b>: Constant.
1104    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1105       const_iterator cbegin() const BOOST_NOEXCEPT_OR_NOTHROW
1106       { return this->members_.m_start; }
1107 
1108    //! <b>Effects</b>: Returns a const_iterator to the end of the deque.
1109    //!
1110    //! <b>Throws</b>: Nothing.
1111    //!
1112    //! <b>Complexity</b>: Constant.
1113    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1114       const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW
1115       { return this->members_.m_finish; }
1116 
1117    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
1118    //! of the reversed deque.
1119    //!
1120    //! <b>Throws</b>: Nothing.
1121    //!
1122    //! <b>Complexity</b>: Constant.
1123    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1124       const_reverse_iterator crbegin() const BOOST_NOEXCEPT_OR_NOTHROW
1125       { return const_reverse_iterator(this->members_.m_finish); }
1126 
1127    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
1128    //! of the reversed deque.
1129    //!
1130    //! <b>Throws</b>: Nothing.
1131    //!
1132    //! <b>Complexity</b>: Constant.
1133    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1134       const_reverse_iterator crend() const BOOST_NOEXCEPT_OR_NOTHROW
1135       { return const_reverse_iterator(this->members_.m_start); }
1136 
1137    //////////////////////////////////////////////
1138    //
1139    //                capacity
1140    //
1141    //////////////////////////////////////////////
1142 
1143    //! <b>Effects</b>: Returns true if the deque contains no elements.
1144    //!
1145    //! <b>Throws</b>: Nothing.
1146    //!
1147    //! <b>Complexity</b>: Constant.
1148    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1149       bool empty() const BOOST_NOEXCEPT_OR_NOTHROW
1150    { return this->members_.m_finish == this->members_.m_start; }
1151 
1152    //! <b>Effects</b>: Returns the number of the elements contained in the deque.
1153    //!
1154    //! <b>Throws</b>: Nothing.
1155    //!
1156    //! <b>Complexity</b>: Constant.
1157    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1158       size_type size() const BOOST_NOEXCEPT_OR_NOTHROW
1159       { return size_type(this->members_.m_finish - this->members_.m_start); }
1160 
1161    //! <b>Effects</b>: Returns the largest possible size of the deque.
1162    //!
1163    //! <b>Throws</b>: Nothing.
1164    //!
1165    //! <b>Complexity</b>: Constant.
1166    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1167       size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW
1168       { return allocator_traits_type::max_size(this->alloc()); }
1169 
1170    //! <b>Effects</b>: Inserts or erases elements at the end such that
1171    //!   the size becomes n. New elements are value initialized.
1172    //!
1173    //! <b>Throws</b>: If memory allocation throws, or T's constructor throws.
1174    //!
1175    //! <b>Complexity</b>: Linear to the difference between size() and new_size.
1176    void resize(size_type new_size)
1177    {
1178       const size_type len = size();
1179       if (new_size < len)
1180          this->priv_erase_last_n(len - new_size);
1181       else{
1182          const size_type n = new_size - this->size();
1183          dtl::insert_value_initialized_n_proxy<ValAllocator> proxy;
1184          priv_insert_back_aux_impl(n, proxy);
1185       }
1186    }
1187 
1188    //! <b>Effects</b>: Inserts or erases elements at the end such that
1189    //!   the size becomes n. New elements are default initialized.
1190    //!
1191    //! <b>Throws</b>: If memory allocation throws, or T's constructor throws.
1192    //!
1193    //! <b>Complexity</b>: Linear to the difference between size() and new_size.
1194    //!
1195    //! <b>Note</b>: Non-standard extension
1196    void resize(size_type new_size, default_init_t)
1197    {
1198       const size_type len = size();
1199       if (new_size < len)
1200          this->priv_erase_last_n(len - new_size);
1201       else{
1202          const size_type n = new_size - this->size();
1203          dtl::insert_default_initialized_n_proxy<ValAllocator> proxy;
1204          priv_insert_back_aux_impl(n, proxy);
1205       }
1206    }
1207 
1208    //! <b>Effects</b>: Inserts or erases elements at the end such that
1209    //!   the size becomes n. New elements are copy constructed from x.
1210    //!
1211    //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
1212    //!
1213    //! <b>Complexity</b>: Linear to the difference between size() and new_size.
1214    void resize(size_type new_size, const value_type& x)
1215    {
1216       const size_type len = size();
1217       if (new_size < len)
1218          this->erase(this->members_.m_start + difference_type(new_size), this->members_.m_finish);
1219       else
1220          this->insert(this->members_.m_finish, new_size - len, x);
1221    }
1222 
1223    //! <b>Effects</b>: Tries to deallocate the excess of memory created
1224    //!   with previous allocations. The size of the deque is unchanged
1225    //!
1226    //! <b>Throws</b>: If memory allocation throws.
1227    //!
1228    //! <b>Complexity</b>: Constant.
1229    void shrink_to_fit()
1230    {
1231       //This deque implementation already
1232       //deallocates excess nodes when erasing
1233       //so there is nothing to do except for
1234       //empty deque
1235       if(this->empty()){
1236          this->priv_clear_map();
1237       }
1238    }
1239 
1240    //////////////////////////////////////////////
1241    //
1242    //               element access
1243    //
1244    //////////////////////////////////////////////
1245 
1246    //! <b>Requires</b>: !empty()
1247    //!
1248    //! <b>Effects</b>: Returns a reference to the first
1249    //!   element of the container.
1250    //!
1251    //! <b>Throws</b>: Nothing.
1252    //!
1253    //! <b>Complexity</b>: Constant.
1254    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1255       reference front() BOOST_NOEXCEPT_OR_NOTHROW
1256    {
1257       BOOST_ASSERT(!this->empty());
1258       return *this->members_.m_start;
1259    }
1260 
1261    //! <b>Requires</b>: !empty()
1262    //!
1263    //! <b>Effects</b>: Returns a const reference to the first element
1264    //!   from the beginning of the container.
1265    //!
1266    //! <b>Throws</b>: Nothing.
1267    //!
1268    //! <b>Complexity</b>: Constant.
1269    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1270       const_reference front() const BOOST_NOEXCEPT_OR_NOTHROW
1271    {
1272       BOOST_ASSERT(!this->empty());
1273       return *this->members_.m_start;
1274    }
1275 
1276    //! <b>Requires</b>: !empty()
1277    //!
1278    //! <b>Effects</b>: Returns a reference to the last
1279    //!   element of the container.
1280    //!
1281    //! <b>Throws</b>: Nothing.
1282    //!
1283    //! <b>Complexity</b>: Constant.
1284    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1285       reference back() BOOST_NOEXCEPT_OR_NOTHROW
1286    {
1287       BOOST_ASSERT(!this->empty());
1288       return *(end()-1);
1289    }
1290 
1291    //! <b>Requires</b>: !empty()
1292    //!
1293    //! <b>Effects</b>: Returns a const reference to the last
1294    //!   element of the container.
1295    //!
1296    //! <b>Throws</b>: Nothing.
1297    //!
1298    //! <b>Complexity</b>: Constant.
1299    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1300       const_reference back() const BOOST_NOEXCEPT_OR_NOTHROW
1301    {
1302       BOOST_ASSERT(!this->empty());
1303       return *(cend()-1);
1304    }
1305 
1306    //! <b>Requires</b>: size() > n.
1307    //!
1308    //! <b>Effects</b>: Returns a reference to the nth element
1309    //!   from the beginning of the container.
1310    //!
1311    //! <b>Throws</b>: Nothing.
1312    //!
1313    //! <b>Complexity</b>: Constant.
1314    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1315       reference operator[](size_type n) BOOST_NOEXCEPT_OR_NOTHROW
1316    {
1317       BOOST_ASSERT(this->size() > n);
1318       return this->members_.m_start[difference_type(n)];
1319    }
1320 
1321    //! <b>Requires</b>: size() > n.
1322    //!
1323    //! <b>Effects</b>: Returns a const reference to the nth element
1324    //!   from the beginning of the container.
1325    //!
1326    //! <b>Throws</b>: Nothing.
1327    //!
1328    //! <b>Complexity</b>: Constant.
1329    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1330       const_reference operator[](size_type n) const BOOST_NOEXCEPT_OR_NOTHROW
1331    {
1332       BOOST_ASSERT(this->size() > n);
1333       return this->members_.m_start[difference_type(n)];
1334    }
1335 
1336    //! <b>Requires</b>: size() >= n.
1337    //!
1338    //! <b>Effects</b>: Returns an iterator to the nth element
1339    //!   from the beginning of the container. Returns end()
1340    //!   if n == size().
1341    //!
1342    //! <b>Throws</b>: Nothing.
1343    //!
1344    //! <b>Complexity</b>: Constant.
1345    //!
1346    //! <b>Note</b>: Non-standard extension
1347    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1348       iterator nth(size_type n) BOOST_NOEXCEPT_OR_NOTHROW
1349    {
1350       BOOST_ASSERT(this->size() >= n);
1351       return iterator(this->begin()+difference_type(n));
1352    }
1353 
1354    //! <b>Requires</b>: size() >= n.
1355    //!
1356    //! <b>Effects</b>: Returns a const_iterator to the nth element
1357    //!   from the beginning of the container. Returns end()
1358    //!   if n == size().
1359    //!
1360    //! <b>Throws</b>: Nothing.
1361    //!
1362    //! <b>Complexity</b>: Constant.
1363    //!
1364    //! <b>Note</b>: Non-standard extension
1365    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1366       const_iterator nth(size_type n) const BOOST_NOEXCEPT_OR_NOTHROW
1367    {
1368       BOOST_ASSERT(this->size() >= n);
1369       return const_iterator(this->cbegin()+difference_type(n));
1370    }
1371 
1372    //! <b>Requires</b>: begin() <= p <= end().
1373    //!
1374    //! <b>Effects</b>: Returns the index of the element pointed by p
1375    //!   and size() if p == end().
1376    //!
1377    //! <b>Throws</b>: Nothing.
1378    //!
1379    //! <b>Complexity</b>: Constant.
1380    //!
1381    //! <b>Note</b>: Non-standard extension
1382    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1383       size_type index_of(iterator p) BOOST_NOEXCEPT_OR_NOTHROW
1384    {
1385       //Range checked priv_index_of
1386       return this->priv_index_of(p);
1387    }
1388 
1389    //! <b>Requires</b>: begin() <= p <= end().
1390    //!
1391    //! <b>Effects</b>: Returns the index of the element pointed by p
1392    //!   and size() if p == end().
1393    //!
1394    //! <b>Throws</b>: Nothing.
1395    //!
1396    //! <b>Complexity</b>: Constant.
1397    //!
1398    //! <b>Note</b>: Non-standard extension
1399    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1400       size_type index_of(const_iterator p) const BOOST_NOEXCEPT_OR_NOTHROW
1401    {
1402       //Range checked priv_index_of
1403       return this->priv_index_of(p);
1404    }
1405 
1406    //! <b>Requires</b>: size() > n.
1407    //!
1408    //! <b>Effects</b>: Returns a reference to the nth element
1409    //!   from the beginning of the container.
1410    //!
1411    //! <b>Throws</b>: range_error if n >= size()
1412    //!
1413    //! <b>Complexity</b>: Constant.
1414    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1415       reference at(size_type n)
1416    {
1417       this->priv_throw_if_out_of_range(n);
1418       return (*this)[n];
1419    }
1420 
1421    //! <b>Requires</b>: size() > n.
1422    //!
1423    //! <b>Effects</b>: Returns a const reference to the nth element
1424    //!   from the beginning of the container.
1425    //!
1426    //! <b>Throws</b>: range_error if n >= size()
1427    //!
1428    //! <b>Complexity</b>: Constant.
1429    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1430       const_reference at(size_type n) const
1431    {
1432       this->priv_throw_if_out_of_range(n);
1433       return (*this)[n];
1434    }
1435 
1436    //////////////////////////////////////////////
1437    //
1438    //                modifiers
1439    //
1440    //////////////////////////////////////////////
1441 
1442    #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
1443 
1444    //! <b>Effects</b>: Inserts an object of type T constructed with
1445    //!   std::forward<Args>(args)... in the beginning of the deque.
1446    //!
1447    //! <b>Returns</b>: A reference to the created object.
1448    //!
1449    //! <b>Throws</b>: If memory allocation throws or the in-place constructor throws.
1450    //!
1451    //! <b>Complexity</b>: Amortized constant time
1452    template <class... Args>
1453    reference emplace_front(BOOST_FWD_REF(Args)... args)
1454    {
1455       if(this->priv_push_front_simple_available()){
1456          reference r = *this->priv_push_front_simple_pos();
1457          allocator_traits_type::construct
1458             ( this->alloc()
1459             , this->priv_push_front_simple_pos()
1460             , boost::forward<Args>(args)...);
1461          this->priv_push_front_simple_commit();
1462          return r;
1463       }
1464       else{
1465          typedef dtl::insert_nonmovable_emplace_proxy<ValAllocator, Args...> type;
1466          return *this->priv_insert_front_aux_impl(1, type(boost::forward<Args>(args)...));
1467       }
1468    }
1469 
1470    //! <b>Effects</b>: Inserts an object of type T constructed with
1471    //!   std::forward<Args>(args)... in the end of the deque.
1472    //!
1473    //! <b>Returns</b>: A reference to the created object.
1474    //!
1475    //! <b>Throws</b>: If memory allocation throws or the in-place constructor throws.
1476    //!
1477    //! <b>Complexity</b>: Amortized constant time
1478    template <class... Args>
1479    reference emplace_back(BOOST_FWD_REF(Args)... args)
1480    {
1481       if(this->priv_push_back_simple_available()){
1482          reference r = *this->priv_push_back_simple_pos();
1483          allocator_traits_type::construct
1484             ( this->alloc()
1485             , this->priv_push_back_simple_pos()
1486             , boost::forward<Args>(args)...);
1487          this->priv_push_back_simple_commit();
1488          return r;
1489       }
1490       else{
1491          typedef dtl::insert_nonmovable_emplace_proxy<ValAllocator, Args...> type;
1492          return *this->priv_insert_back_aux_impl(1, type(boost::forward<Args>(args)...));
1493       }
1494    }
1495 
1496    //! <b>Requires</b>: p must be a valid iterator of *this.
1497    //!
1498    //! <b>Effects</b>: Inserts an object of type T constructed with
1499    //!   std::forward<Args>(args)... before p
1500    //!
1501    //! <b>Throws</b>: If memory allocation throws or the in-place constructor throws.
1502    //!
1503    //! <b>Complexity</b>: If p is end(), amortized constant time
1504    //!   Linear time otherwise.
1505    template <class... Args>
1506    iterator emplace(const_iterator p, BOOST_FWD_REF(Args)... args)
1507    {
1508       BOOST_ASSERT(this->priv_in_range_or_end(p));
1509       if(p == this->cbegin()){
1510          this->emplace_front(boost::forward<Args>(args)...);
1511          return this->begin();
1512       }
1513       else if(p == this->cend()){
1514          this->emplace_back(boost::forward<Args>(args)...);
1515          return (this->end()-1);
1516       }
1517       else{
1518          typedef dtl::insert_emplace_proxy<ValAllocator, Args...> type;
1519          return this->priv_insert_aux_impl(p, 1, type(boost::forward<Args>(args)...));
1520       }
1521    }
1522 
1523    #else //!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
1524 
1525    #define BOOST_CONTAINER_DEQUE_EMPLACE_CODE(N) \
1526    BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N\
1527    reference emplace_front(BOOST_MOVE_UREF##N)\
1528    {\
1529       if(priv_push_front_simple_available()){\
1530          reference r = *this->priv_push_front_simple_pos();\
1531          allocator_traits_type::construct\
1532             ( this->alloc(), this->priv_push_front_simple_pos() BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
1533          priv_push_front_simple_commit();\
1534          return r;\
1535       }\
1536       else{\
1537          typedef dtl::insert_nonmovable_emplace_proxy##N\
1538                <ValAllocator BOOST_MOVE_I##N BOOST_MOVE_TARG##N> type;\
1539          return *priv_insert_front_aux_impl(1, type(BOOST_MOVE_FWD##N));\
1540       }\
1541    }\
1542    \
1543    BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N\
1544    reference emplace_back(BOOST_MOVE_UREF##N)\
1545    {\
1546       if(priv_push_back_simple_available()){\
1547          reference r = *this->priv_push_back_simple_pos();\
1548          allocator_traits_type::construct\
1549             ( this->alloc(), this->priv_push_back_simple_pos() BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
1550          priv_push_back_simple_commit();\
1551          return r;\
1552       }\
1553       else{\
1554          typedef dtl::insert_nonmovable_emplace_proxy##N\
1555                <ValAllocator BOOST_MOVE_I##N BOOST_MOVE_TARG##N> type;\
1556          return *priv_insert_back_aux_impl(1, type(BOOST_MOVE_FWD##N));\
1557       }\
1558    }\
1559    \
1560    BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N\
1561    iterator emplace(const_iterator p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
1562    {\
1563       BOOST_ASSERT(this->priv_in_range_or_end(p));\
1564       if(p == this->cbegin()){\
1565          this->emplace_front(BOOST_MOVE_FWD##N);\
1566          return this->begin();\
1567       }\
1568       else if(p == cend()){\
1569          this->emplace_back(BOOST_MOVE_FWD##N);\
1570          return (--this->end());\
1571       }\
1572       else{\
1573          typedef dtl::insert_emplace_proxy_arg##N\
1574                <ValAllocator BOOST_MOVE_I##N BOOST_MOVE_TARG##N> type;\
1575          return this->priv_insert_aux_impl(p, 1, type(BOOST_MOVE_FWD##N));\
1576       }\
1577    }
1578    //
1579    BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_DEQUE_EMPLACE_CODE)
1580    #undef BOOST_CONTAINER_DEQUE_EMPLACE_CODE
1581 
1582    #endif   // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
1583 
1584    #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
1585    //! <b>Effects</b>: Inserts a copy of x at the front of the deque.
1586    //!
1587    //! <b>Throws</b>: If memory allocation throws or
1588    //!   T's copy constructor throws.
1589    //!
1590    //! <b>Complexity</b>: Amortized constant time.
1591    void push_front(const T &x);
1592 
1593    //! <b>Effects</b>: Constructs a new element in the front of the deque
1594    //!   and moves the resources of x to this new element.
1595    //!
1596    //! <b>Throws</b>: If memory allocation throws.
1597    //!
1598    //! <b>Complexity</b>: Amortized constant time.
1599    void push_front(T &&x);
1600    #else
1601    BOOST_MOVE_CONVERSION_AWARE_CATCH(push_front, T, void, priv_push_front)
1602    #endif
1603 
1604    #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
1605    //! <b>Effects</b>: Inserts a copy of x at the end of the deque.
1606    //!
1607    //! <b>Throws</b>: If memory allocation throws or
1608    //!   T's copy constructor throws.
1609    //!
1610    //! <b>Complexity</b>: Amortized constant time.
1611    void push_back(const T &x);
1612 
1613    //! <b>Effects</b>: Constructs a new element in the end of the deque
1614    //!   and moves the resources of x to this new element.
1615    //!
1616    //! <b>Throws</b>: If memory allocation throws.
1617    //!
1618    //! <b>Complexity</b>: Amortized constant time.
1619    void push_back(T &&x);
1620    #else
1621    BOOST_MOVE_CONVERSION_AWARE_CATCH(push_back, T, void, priv_push_back)
1622    #endif
1623 
1624    #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
1625 
1626    //! <b>Requires</b>: p must be a valid iterator of *this.
1627    //!
1628    //! <b>Effects</b>: Insert a copy of x before p.
1629    //!
1630    //! <b>Returns</b>: an iterator to the inserted element.
1631    //!
1632    //! <b>Throws</b>: If memory allocation throws or x's copy constructor throws.
1633    //!
1634    //! <b>Complexity</b>: If p is end(), amortized constant time
1635    //!   Linear time otherwise.
1636    iterator insert(const_iterator p, const T &x);
1637 
1638    //! <b>Requires</b>: p must be a valid iterator of *this.
1639    //!
1640    //! <b>Effects</b>: Insert a new element before p with x's resources.
1641    //!
1642    //! <b>Returns</b>: an iterator to the inserted element.
1643    //!
1644    //! <b>Throws</b>: If memory allocation throws.
1645    //!
1646    //! <b>Complexity</b>: If p is end(), amortized constant time
1647    //!   Linear time otherwise.
1648    iterator insert(const_iterator p, T &&x);
1649    #else
1650    BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert, T, iterator, priv_insert, const_iterator, const_iterator)
1651    #endif
1652 
1653    //! <b>Requires</b>: pos must be a valid iterator of *this.
1654    //!
1655    //! <b>Effects</b>: Insert n copies of x before pos.
1656    //!
1657    //! <b>Returns</b>: an iterator to the first inserted element or pos if n is 0.
1658    //!
1659    //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
1660    //!
1661    //! <b>Complexity</b>: Linear to n.
1662    BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator pos, size_type n, const value_type& x)
1663    {
1664       //Range check of p is done by insert()
1665       return this->insert(pos, c_it(x, n), c_it());
1666    }
1667 
1668    //! <b>Requires</b>: pos must be a valid iterator of *this.
1669    //!
1670    //! <b>Effects</b>: Insert a copy of the [first, last) range before pos.
1671    //!
1672    //! <b>Returns</b>: an iterator to the first inserted element or pos if first == last.
1673    //!
1674    //! <b>Throws</b>: If memory allocation throws, T's constructor from a
1675    //!   dereferenced InIt throws or T's copy constructor throws.
1676    //!
1677    //! <b>Complexity</b>: Linear to distance [first, last).
1678    template <class InIt>
1679    iterator insert(const_iterator pos, InIt first, InIt last
1680       #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
1681       , typename dtl::disable_if_or
1682          < void
1683          , dtl::is_convertible<InIt, size_type>
1684          , dtl::is_not_input_iterator<InIt>
1685          >::type * = 0
1686       #endif
1687       )
1688    {
1689       BOOST_ASSERT(this->priv_in_range_or_end(pos));
1690       size_type n = 0;
1691       iterator it(pos.unconst());
1692       for(;first != last; ++first, ++n){
1693          it = this->emplace(it, *first);
1694          ++it;
1695       }
1696       it -= difference_type(n);
1697       return it;
1698    }
1699 
1700 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
1701    //! <b>Requires</b>: pos must be a valid iterator of *this.
1702    //!
1703    //! <b>Effects</b>: Insert a copy of the [il.begin(), il.end()) range before pos.
1704    //!
1705    //! <b>Returns</b>: an iterator to the first inserted element or pos if il.begin() == il.end().
1706    //!
1707    //! <b>Throws</b>: If memory allocation throws, T's constructor from a
1708    //!   dereferenced std::initializer_list throws or T's copy constructor throws.
1709    //!
1710    //! <b>Complexity</b>: Linear to distance [il.begin(), il.end()).
1711    BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator pos, std::initializer_list<value_type> il)
1712    {
1713       //Range check os pos is done in insert()
1714       return insert(pos, il.begin(), il.end());
1715    }
1716 #endif
1717 
1718    #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
1719    template <class FwdIt>
1720    BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator p, FwdIt first, FwdIt last
1721       #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
1722       , typename dtl::disable_if_or
1723          < void
1724          , dtl::is_convertible<FwdIt, size_type>
1725          , dtl::is_input_iterator<FwdIt>
1726          >::type * = 0
1727       #endif
1728       )
1729    {
1730       BOOST_ASSERT(this->priv_in_range_or_end(p));
1731       dtl::insert_range_proxy<ValAllocator, FwdIt> proxy(first);
1732       return priv_insert_aux_impl(p, boost::container::iterator_udistance(first, last), proxy);
1733    }
1734    #endif
1735 
1736    //! <b>Effects</b>: Removes the first element from the deque.
1737    //!
1738    //! <b>Throws</b>: Nothing.
1739    //!
1740    //! <b>Complexity</b>: Constant time.
1741    void pop_front() BOOST_NOEXCEPT_OR_NOTHROW
1742    {
1743       BOOST_ASSERT(!this->empty());
1744       if (this->members_.m_start.m_cur != this->members_.m_start.m_last - 1) {
1745          allocator_traits_type::destroy
1746             ( this->alloc()
1747             , boost::movelib::to_raw_pointer(this->members_.m_start.m_cur)
1748             );
1749          ++this->members_.m_start.m_cur;
1750       }
1751       else
1752          this->priv_pop_front_aux();
1753    }
1754 
1755    //! <b>Effects</b>: Removes the last element from the deque.
1756    //!
1757    //! <b>Throws</b>: Nothing.
1758    //!
1759    //! <b>Complexity</b>: Constant time.
1760    void pop_back() BOOST_NOEXCEPT_OR_NOTHROW
1761    {
1762       BOOST_ASSERT(!this->empty());
1763       if (this->members_.m_finish.m_cur != this->members_.m_finish.m_first) {
1764          --this->members_.m_finish.m_cur;
1765          allocator_traits_type::destroy
1766             ( this->alloc()
1767             , boost::movelib::to_raw_pointer(this->members_.m_finish.m_cur)
1768             );
1769       }
1770       else
1771          this->priv_pop_back_aux();
1772    }
1773 
1774    //! <b>Effects</b>: Erases the element at p.
1775    //!
1776    //! <b>Throws</b>: Nothing.
1777    //!
1778    //! <b>Complexity</b>: Linear to the elements between pos and the
1779    //!   last element (if pos is near the end) or the first element
1780    //!   if(pos is near the beginning).
1781    //!   Constant if pos is the first or the last element.
1782    iterator erase(const_iterator pos) BOOST_NOEXCEPT_OR_NOTHROW
1783    {
1784       BOOST_ASSERT(this->priv_in_range(pos));
1785       iterator next = pos.unconst();
1786       ++next;
1787       size_type index = size_type(pos - this->members_.m_start);
1788       if (index < (this->size()/2)) {
1789          boost::container::move_backward(this->begin(), pos.unconst(), next);
1790          pop_front();
1791       }
1792       else {
1793          boost::container::move(next, this->end(), pos.unconst());
1794          pop_back();
1795       }
1796       return this->members_.m_start + difference_type(index);
1797    }
1798 
1799    //! <b>Effects</b>: Erases the elements pointed by [first, last).
1800    //!
1801    //! <b>Throws</b>: Nothing.
1802    //!
1803    //! <b>Complexity</b>: Linear to the distance between first and
1804    //!   last plus the elements between pos and the
1805    //!   last element (if pos is near the end) or the first element
1806    //!   if(pos is near the beginning).
1807    iterator erase(const_iterator first, const_iterator last) BOOST_NOEXCEPT_OR_NOTHROW
1808    {
1809       BOOST_ASSERT(first == last ||
1810          (first < last && this->priv_in_range(first) && this->priv_in_range_or_end(last)));
1811       if (first == this->members_.m_start && last == this->members_.m_finish) {
1812          this->clear();
1813          return this->members_.m_finish;
1814       }
1815       else {
1816          const size_type n = static_cast<size_type>(last - first);
1817          const size_type elems_before = static_cast<size_type>(first - this->members_.m_start);
1818          if (elems_before < (this->size() - n) - elems_before) {
1819             boost::container::move_backward(begin(), first.unconst(), last.unconst());
1820             iterator new_start = this->members_.m_start + difference_type(n);
1821             this->priv_destroy_range(this->members_.m_start, new_start);
1822             this->priv_destroy_nodes(this->members_.m_start.m_node, new_start.m_node);
1823             this->members_.m_start = new_start;
1824          }
1825          else {
1826             boost::container::move(last.unconst(), end(), first.unconst());
1827             iterator new_finish = this->members_.m_finish - difference_type(n);
1828             this->priv_destroy_range(new_finish, this->members_.m_finish);
1829             this->priv_destroy_nodes(new_finish.m_node + 1, this->members_.m_finish.m_node + 1);
1830             this->members_.m_finish = new_finish;
1831          }
1832          return this->members_.m_start + difference_type(elems_before);
1833       }
1834    }
1835 
1836    //! <b>Effects</b>: Swaps the contents of *this and x.
1837    //!
1838    //! <b>Throws</b>: Nothing.
1839    //!
1840    //! <b>Complexity</b>: Constant.
1841    BOOST_CONTAINER_FORCEINLINE void swap(deque &x)
1842       BOOST_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_swap::value
1843                                || allocator_traits_type::is_always_equal::value)
1844    {
1845       this->swap_members(x);
1846       dtl::bool_<allocator_traits_type::propagate_on_container_swap::value> flag;
1847       dtl::swap_alloc(this->alloc(), x.alloc(), flag);
1848       dtl::swap_alloc(this->ptr_alloc(), x.ptr_alloc(), flag);
1849    }
1850 
1851    //! <b>Effects</b>: Erases all the elements of the deque.
1852    //!
1853    //! <b>Throws</b>: Nothing.
1854    //!
1855    //! <b>Complexity</b>: Linear to the number of elements in the deque.
1856    void clear() BOOST_NOEXCEPT_OR_NOTHROW
1857    {
1858       if (this->members_.m_finish != this->members_.m_start) {
1859   
1860          for (index_pointer node = this->members_.m_start.m_node + 1;
1861                node < this->members_.m_finish.m_node;
1862                ++node) {
1863             this->priv_destroy_range(*node, *node + get_block_ssize());
1864             this->priv_deallocate_node(*node);
1865          }
1866 
1867          if (this->members_.m_start.m_node != this->members_.m_finish.m_node) {
1868             this->priv_destroy_range(this->members_.m_start.m_cur, this->members_.m_start.m_last);
1869             this->priv_destroy_range(this->members_.m_finish.m_first, this->members_.m_finish.m_cur);
1870             this->priv_deallocate_node(this->members_.m_finish.m_first);
1871          }
1872          else
1873             this->priv_destroy_range(this->members_.m_start.m_cur, this->members_.m_finish.m_cur);
1874 
1875          this->members_.m_finish = this->members_.m_start;
1876       }
1877    }
1878 
1879    //! <b>Effects</b>: Returns true if x and y are equal
1880    //!
1881    //! <b>Complexity</b>: Linear to the number of elements in the container.
1882    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1883       friend bool operator==(const deque& x, const deque& y)
1884    {  return x.size() == y.size() && ::boost::container::algo_equal(x.begin(), x.end(), y.begin());  }
1885 
1886    //! <b>Effects</b>: Returns true if x and y are unequal
1887    //!
1888    //! <b>Complexity</b>: Linear to the number of elements in the container.
1889    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1890       friend bool operator!=(const deque& x, const deque& y)
1891    {  return !(x == y); }
1892 
1893    //! <b>Effects</b>: Returns true if x is less than y
1894    //!
1895    //! <b>Complexity</b>: Linear to the number of elements in the container.
1896    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1897       friend bool operator<(const deque& x, const deque& y)
1898    {  return ::boost::container::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());  }
1899 
1900    //! <b>Effects</b>: Returns true if x is greater than y
1901    //!
1902    //! <b>Complexity</b>: Linear to the number of elements in the container.
1903    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1904       friend bool operator>(const deque& x, const deque& y)
1905    {  return y < x;  }
1906 
1907    //! <b>Effects</b>: Returns true if x is equal or less than y
1908    //!
1909    //! <b>Complexity</b>: Linear to the number of elements in the container.
1910    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1911       friend bool operator<=(const deque& x, const deque& y)
1912    {  return !(y < x);  }
1913 
1914    //! <b>Effects</b>: Returns true if x is equal or greater than y
1915    //!
1916    //! <b>Complexity</b>: Linear to the number of elements in the container.
1917    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1918       friend bool operator>=(const deque& x, const deque& y)
1919    {  return !(x < y);  }
1920 
1921    //! <b>Effects</b>: x.swap(y)
1922    //!
1923    //! <b>Complexity</b>: Constant.
1924    BOOST_CONTAINER_FORCEINLINE friend void swap(deque& x, deque& y)
1925        BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT(x.swap(y)))
1926    {  x.swap(y);  }
1927 
1928    #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
1929    private:
1930 
1931    BOOST_CONTAINER_FORCEINLINE size_type priv_index_of(const_iterator p) const
1932    {
1933       BOOST_ASSERT(this->cbegin() <= p);
1934       BOOST_ASSERT(p <= this->cend());
1935       return static_cast<size_type>(p - this->cbegin());
1936    }
1937 
1938    void priv_erase_last_n(size_type n)
1939    {
1940       if(n == this->size()) {
1941          this->clear();
1942       }
1943       else {
1944          iterator new_finish = this->members_.m_finish - difference_type(n);
1945          this->priv_destroy_range(new_finish, this->members_.m_finish);
1946          this->priv_destroy_nodes(new_finish.m_node + 1, this->members_.m_finish.m_node + 1);
1947          this->members_.m_finish = new_finish;
1948       }
1949    }
1950 
1951    void priv_throw_if_out_of_range(size_type n) const
1952    {
1953       if (n >= this->size())
1954          throw_out_of_range("deque::at out of range");
1955    }
1956 
1957    BOOST_CONTAINER_FORCEINLINE bool priv_in_range(const_iterator pos) const
1958    {
1959       return (this->begin() <= pos) && (pos < this->end());
1960    }
1961 
1962    BOOST_CONTAINER_FORCEINLINE bool priv_in_range_or_end(const_iterator pos) const
1963    {
1964       return (this->begin() <= pos) && (pos <= this->end());
1965    }
1966 
1967    template <class U>
1968    iterator priv_insert(const_iterator p, BOOST_FWD_REF(U) x)
1969    {
1970       BOOST_ASSERT(this->priv_in_range_or_end(p));
1971       if (p == cbegin()){
1972          this->push_front(::boost::forward<U>(x));
1973          return begin();
1974       }
1975       else if (p == cend()){
1976          this->push_back(::boost::forward<U>(x));
1977          return --end();
1978       }
1979       else {
1980          return priv_insert_aux_impl
1981             ( p, (size_type)1
1982             , dtl::get_insert_value_proxy<iterator, ValAllocator>(::boost::forward<U>(x)));
1983       }
1984    }
1985 
1986    template <class U>
1987    void priv_push_front(BOOST_FWD_REF(U) x)
1988    {
1989       if(this->priv_push_front_simple_available()){
1990          allocator_traits_type::construct
1991             ( this->alloc(), this->priv_push_front_simple_pos(), ::boost::forward<U>(x));
1992          this->priv_push_front_simple_commit();
1993       }
1994       else{
1995          priv_insert_aux_impl
1996             ( this->cbegin(), (size_type)1
1997             , dtl::get_insert_value_proxy<iterator, ValAllocator>(::boost::forward<U>(x)));
1998       }
1999    }
2000 
2001    template <class U>
2002    void priv_push_back(BOOST_FWD_REF(U) x)
2003    {
2004       if(this->priv_push_back_simple_available()){
2005          allocator_traits_type::construct
2006             ( this->alloc(), this->priv_push_back_simple_pos(), ::boost::forward<U>(x));
2007          this->priv_push_back_simple_commit();
2008       }
2009       else{
2010          priv_insert_aux_impl
2011             ( this->cend(), (size_type)1
2012             , dtl::get_insert_value_proxy<iterator, ValAllocator>(::boost::forward<U>(x)));
2013       }
2014    }
2015 
2016    BOOST_CONTAINER_FORCEINLINE bool priv_push_back_simple_available() const
2017    {
2018       return this->members_.m_map &&
2019          (this->members_.m_finish.m_cur != (this->members_.m_finish.m_last - 1));
2020    }
2021 
2022    BOOST_CONTAINER_FORCEINLINE T *priv_push_back_simple_pos() const
2023    {
2024       return boost::movelib::to_raw_pointer(this->members_.m_finish.m_cur);
2025    }
2026 
2027    BOOST_CONTAINER_FORCEINLINE void priv_push_back_simple_commit()
2028    {
2029       ++this->members_.m_finish.m_cur;
2030    }
2031 
2032    BOOST_CONTAINER_FORCEINLINE bool priv_push_front_simple_available() const
2033    {
2034       return this->members_.m_map &&
2035          (this->members_.m_start.m_cur != this->members_.m_start.m_first);
2036    }
2037 
2038    BOOST_CONTAINER_FORCEINLINE T *priv_push_front_simple_pos() const
2039    {  return boost::movelib::to_raw_pointer(this->members_.m_start.m_cur) - 1;  }
2040 
2041    BOOST_CONTAINER_FORCEINLINE void priv_push_front_simple_commit()
2042    {  --this->members_.m_start.m_cur;   }
2043 
2044    void priv_destroy_range(iterator p, iterator p2)
2045    {
2046       if(!Base::traits_t::trivial_dctr){
2047          for(;p != p2; ++p){
2048             allocator_traits_type::destroy(this->alloc(), boost::movelib::iterator_to_raw_pointer(p));
2049          }
2050       }
2051    }
2052 
2053    void priv_destroy_range(pointer p, pointer p2)
2054    {
2055       if(!Base::traits_t::trivial_dctr){
2056          for(;p != p2; ++p){
2057             allocator_traits_type::destroy(this->alloc(), boost::movelib::iterator_to_raw_pointer(p));
2058          }
2059       }
2060    }
2061 
2062    template<class InsertProxy>
2063    iterator priv_insert_aux_impl(const_iterator p, size_type n, InsertProxy proxy)
2064    {
2065       iterator pos(p.unconst());
2066       const size_type pos_n = size_type(p - this->cbegin());
2067       if(!this->members_.m_map){
2068          this->priv_initialize_map(0);
2069          pos = this->begin();
2070       }
2071 
2072       const size_type elemsbefore = static_cast<size_type>(pos - this->members_.m_start);
2073       const size_type length = this->size();
2074       if (elemsbefore < length / 2) {
2075          const iterator new_start = this->priv_reserve_elements_at_front(n);
2076          const iterator old_start = this->members_.m_start;
2077          if(!elemsbefore){
2078             proxy.uninitialized_copy_n_and_update(this->alloc(), new_start, n);
2079             this->members_.m_start = new_start;
2080          }
2081          else{
2082             pos = this->members_.m_start + difference_type(elemsbefore);
2083             if (elemsbefore >= n) {
2084                const iterator start_n = this->members_.m_start + difference_type(n);
2085                ::boost::container::uninitialized_move_alloc
2086                   (this->alloc(), this->members_.m_start, start_n, new_start);
2087                this->members_.m_start = new_start;
2088                boost::container::move(start_n, pos, old_start);
2089                proxy.copy_n_and_update(this->alloc(), pos - difference_type(n), n);
2090             }
2091             else {
2092                const size_type mid_count = n - elemsbefore;
2093                const iterator mid_start = old_start - difference_type(mid_count);
2094                proxy.uninitialized_copy_n_and_update(this->alloc(), mid_start, mid_count);
2095                this->members_.m_start = mid_start;
2096                ::boost::container::uninitialized_move_alloc
2097                   (this->alloc(), old_start, pos, new_start);
2098                this->members_.m_start = new_start;
2099                proxy.copy_n_and_update(this->alloc(), old_start, elemsbefore);
2100             }
2101          }
2102       }
2103       else {
2104          const iterator new_finish = this->priv_reserve_elements_at_back(n);
2105          const iterator old_finish = this->members_.m_finish;
2106          const size_type elemsafter = length - elemsbefore;
2107          if(!elemsafter){
2108             proxy.uninitialized_copy_n_and_update(this->alloc(), old_finish, n);
2109             this->members_.m_finish = new_finish;
2110          }
2111          else{
2112             pos = old_finish - difference_type(elemsafter);
2113             if (elemsafter >= n) {
2114                iterator finish_n = old_finish - difference_type(n);
2115                ::boost::container::uninitialized_move_alloc
2116                   (this->alloc(), finish_n, old_finish, old_finish);
2117                this->members_.m_finish = new_finish;
2118                boost::container::move_backward(pos, finish_n, old_finish);
2119                proxy.copy_n_and_update(this->alloc(), pos, n);
2120             }
2121             else {
2122                const size_type raw_gap = n - elemsafter;
2123                ::boost::container::uninitialized_move_alloc
2124                   (this->alloc(), pos, old_finish, old_finish + difference_type(raw_gap));
2125                BOOST_CONTAINER_TRY{
2126                   proxy.copy_n_and_update(this->alloc(), pos, elemsafter);
2127                   proxy.uninitialized_copy_n_and_update(this->alloc(), old_finish, raw_gap);
2128                }
2129                BOOST_CONTAINER_CATCH(...){
2130                   this->priv_destroy_range(old_finish, old_finish + difference_type(elemsafter));
2131                   BOOST_CONTAINER_RETHROW
2132                }
2133                BOOST_CONTAINER_CATCH_END
2134                this->members_.m_finish = new_finish;
2135             }
2136          }
2137       }
2138       return this->begin() + difference_type(pos_n);
2139    }
2140 
2141    template <class InsertProxy>
2142    iterator priv_insert_back_aux_impl(size_type n, InsertProxy proxy)
2143    {
2144       if(!this->members_.m_map){
2145          this->priv_initialize_map(0);
2146       }
2147 
2148       iterator new_finish = this->priv_reserve_elements_at_back(n);
2149       iterator old_finish = this->members_.m_finish;
2150       proxy.uninitialized_copy_n_and_update(this->alloc(), old_finish, n);
2151       this->members_.m_finish = new_finish;
2152       return iterator(this->members_.m_finish - difference_type(n));
2153    }
2154 
2155    template <class InsertProxy>
2156    iterator priv_insert_front_aux_impl(size_type n, InsertProxy proxy)
2157    {
2158       if(!this->members_.m_map){
2159          this->priv_initialize_map(0);
2160       }
2161 
2162       iterator new_start = this->priv_reserve_elements_at_front(n);
2163       proxy.uninitialized_copy_n_and_update(this->alloc(), new_start, n);
2164       this->members_.m_start = new_start;
2165       return new_start;
2166    }
2167 
2168    BOOST_CONTAINER_FORCEINLINE iterator priv_fill_insert(const_iterator pos, size_type n, const value_type& x)
2169    {
2170       return this->insert(pos, c_it(x, n), c_it());
2171    }
2172 
2173    // Precondition: this->members_.m_start and this->members_.m_finish have already been initialized,
2174    // but none of the deque's elements have yet been constructed.
2175    void priv_fill_initialize(const value_type& value)
2176    {
2177       index_pointer cur = this->members_.m_start.m_node;
2178       BOOST_CONTAINER_TRY {
2179          for ( ; cur < this->members_.m_finish.m_node; ++cur){
2180             boost::container::uninitialized_fill_alloc
2181                (this->alloc(), *cur, *cur + get_block_ssize(), value);
2182          }
2183          boost::container::uninitialized_fill_alloc
2184             (this->alloc(), this->members_.m_finish.m_first, this->members_.m_finish.m_cur, value);
2185       }
2186       BOOST_CONTAINER_CATCH(...){
2187          this->priv_destroy_range(this->members_.m_start, iterator(*cur, cur, get_block_size()));
2188          BOOST_CONTAINER_RETHROW
2189       }
2190       BOOST_CONTAINER_CATCH_END
2191    }
2192 
2193    template <class InIt>
2194    void priv_range_initialize(InIt first, InIt last, typename iterator_enable_if_tag<InIt, std::input_iterator_tag>::type* =0)
2195    {
2196       this->priv_initialize_map(0);
2197       BOOST_CONTAINER_TRY {
2198          for ( ; first != last; ++first)
2199             this->emplace_back(*first);
2200       }
2201       BOOST_CONTAINER_CATCH(...){
2202          this->clear();
2203          BOOST_CONTAINER_RETHROW
2204       }
2205       BOOST_CONTAINER_CATCH_END
2206    }
2207 
2208    template <class FwdIt>
2209    void priv_range_initialize(FwdIt first, FwdIt last, typename iterator_disable_if_tag<FwdIt, std::input_iterator_tag>::type* =0)
2210    {
2211       size_type n = 0;
2212       n = boost::container::iterator_udistance(first, last);
2213       this->priv_initialize_map(n);
2214 
2215       index_pointer cur_node = this->members_.m_start.m_node;
2216       BOOST_CONTAINER_TRY {
2217          for (; cur_node < this->members_.m_finish.m_node; ++cur_node) {
2218             FwdIt mid = first;
2219             boost::container::iterator_uadvance(mid, get_block_size());
2220             ::boost::container::uninitialized_copy_alloc(this->alloc(), first, mid, *cur_node);
2221             first = mid;
2222          }
2223          ::boost::container::uninitialized_copy_alloc(this->alloc(), first, last, this->members_.m_finish.m_first);
2224       }
2225       BOOST_CONTAINER_CATCH(...){
2226          this->priv_destroy_range(this->members_.m_start, iterator(*cur_node, cur_node, get_block_size()));
2227          BOOST_CONTAINER_RETHROW
2228       }
2229       BOOST_CONTAINER_CATCH_END
2230    }
2231 
2232    // Called only if this->members_.m_finish.m_cur == this->members_.m_finish.m_first.
2233    void priv_pop_back_aux() BOOST_NOEXCEPT_OR_NOTHROW
2234    {
2235       this->priv_deallocate_node(this->members_.m_finish.m_first);
2236       this->members_.m_finish.priv_set_node(this->members_.m_finish.m_node - 1, get_block_size());
2237       this->members_.m_finish.m_cur = this->members_.m_finish.m_last - 1;
2238       allocator_traits_type::destroy
2239          ( this->alloc()
2240          , boost::movelib::to_raw_pointer(this->members_.m_finish.m_cur)
2241          );
2242    }
2243 
2244    // Called only if this->members_.m_start.m_cur == this->members_.m_start.m_last - 1.  Note that
2245    // if the deque has at least one element (a precondition for this member
2246    // function), and if this->members_.m_start.m_cur == this->members_.m_start.m_last, then the deque
2247    // must have at least two nodes.
2248    void priv_pop_front_aux() BOOST_NOEXCEPT_OR_NOTHROW
2249    {
2250       allocator_traits_type::destroy
2251          ( this->alloc()
2252          , boost::movelib::to_raw_pointer(this->members_.m_start.m_cur)
2253          );
2254       this->priv_deallocate_node(this->members_.m_start.m_first);
2255       this->members_.m_start.priv_set_node(this->members_.m_start.m_node + 1, get_block_size());
2256       this->members_.m_start.m_cur = this->members_.m_start.m_first;
2257    }
2258 
2259    iterator priv_reserve_elements_at_front(size_type n)
2260    {
2261       size_type vacancies = size_type(this->members_.m_start.m_cur - this->members_.m_start.m_first);
2262       if (n > vacancies){
2263          size_type new_elems = n-vacancies;
2264          size_type new_nodes = (new_elems + get_block_size() - 1u) / get_block_size();
2265          size_type s = (size_type)(this->members_.m_start.m_node - this->members_.m_map);
2266          if (new_nodes > s){
2267             this->priv_reallocate_map(new_nodes, true);
2268          }
2269          size_type i = 1;
2270          BOOST_CONTAINER_TRY {
2271             for (; i <= new_nodes; ++i)
2272                *(this->members_.m_start.m_node - difference_type(i)) = this->priv_allocate_node();
2273          }
2274          BOOST_CONTAINER_CATCH(...) {
2275             for (size_type j = 1; j < i; ++j)
2276                this->priv_deallocate_node(*(this->members_.m_start.m_node - difference_type(j)));
2277             BOOST_CONTAINER_RETHROW
2278          }
2279          BOOST_CONTAINER_CATCH_END
2280       }
2281       return this->members_.m_start - difference_type(n);
2282    }
2283 
2284    iterator priv_reserve_elements_at_back(size_type n)
2285    {
2286       size_type vacancies = size_type(this->members_.m_finish.m_last - this->members_.m_finish.m_cur - 1);
2287       if (n > vacancies){
2288          size_type new_elems = size_type(n - vacancies);
2289          size_type new_nodes = size_type(new_elems + get_block_size() - 1u)/get_block_size();
2290          size_type s = (size_type)(this->members_.m_map_size - size_type(this->members_.m_finish.m_node - this->members_.m_map));
2291          if (new_nodes + 1 > s){
2292             this->priv_reallocate_map(new_nodes, false);
2293          }
2294          size_type i = 1;
2295          BOOST_CONTAINER_TRY {
2296             for (; i <= new_nodes; ++i)
2297                *(this->members_.m_finish.m_node + difference_type(i)) = this->priv_allocate_node();
2298          }
2299          BOOST_CONTAINER_CATCH(...) {
2300             for (size_type j = 1; j < i; ++j)
2301                this->priv_deallocate_node(*(this->members_.m_finish.m_node + difference_type(j)));
2302             BOOST_CONTAINER_RETHROW
2303          }
2304          BOOST_CONTAINER_CATCH_END
2305       }
2306       return this->members_.m_finish + difference_type(n);
2307    }
2308 
2309    void priv_reallocate_map(size_type nodes_to_add, bool add_at_front)
2310    {
2311       size_type old_num_nodes = size_type(this->members_.m_finish.m_node - this->members_.m_start.m_node + 1);
2312       size_type new_num_nodes = old_num_nodes + nodes_to_add;
2313 
2314       index_pointer new_nstart;
2315       if (this->members_.m_map_size > 2 * new_num_nodes) {
2316          new_nstart = this->members_.m_map + difference_type(this->members_.m_map_size - new_num_nodes) / 2
2317                            + difference_type(add_at_front ? nodes_to_add : 0u);
2318          if (new_nstart < this->members_.m_start.m_node)
2319             boost::container::move(this->members_.m_start.m_node, this->members_.m_finish.m_node + 1, new_nstart);
2320          else
2321             boost::container::move_backward
2322                (this->members_.m_start.m_node, this->members_.m_finish.m_node + 1, new_nstart + difference_type(old_num_nodes));
2323       }
2324       else {
2325          size_type new_map_size =
2326             this->members_.m_map_size + dtl::max_value(this->members_.m_map_size, nodes_to_add) + 2;
2327 
2328          index_pointer new_map = this->priv_allocate_map(new_map_size);
2329          new_nstart = new_map + difference_type(new_map_size - new_num_nodes) / 2
2330                               + difference_type(add_at_front ? nodes_to_add : 0u);
2331          boost::container::move(this->members_.m_start.m_node, this->members_.m_finish.m_node + 1, new_nstart);
2332          this->priv_deallocate_map(this->members_.m_map, this->members_.m_map_size);
2333 
2334          this->members_.m_map = new_map;
2335          this->members_.m_map_size = new_map_size;
2336       }
2337 
2338       this->members_.m_start.priv_set_node(new_nstart, get_block_size());
2339       this->members_.m_finish.priv_set_node(new_nstart + difference_type(old_num_nodes - 1u), get_block_size());
2340    }
2341    #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
2342 };
2343 
2344 #ifndef BOOST_CONTAINER_NO_CXX17_CTAD
2345 template <typename InputIterator>
2346 deque(InputIterator, InputIterator) -> deque<typename iterator_traits<InputIterator>::value_type>;
2347 template <typename InputIterator, typename Allocator>
2348 deque(InputIterator, InputIterator, Allocator const&) -> deque<typename iterator_traits<InputIterator>::value_type, Allocator>;
2349 #endif
2350 
2351 }}
2352 
2353 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
2354 
2355 namespace boost {
2356 
2357 //!has_trivial_destructor_after_move<> == true_type
2358 //!specialization for optimizations
2359 template <class T, class Allocator, class Options>
2360 struct has_trivial_destructor_after_move<boost::container::deque<T, Allocator, Options> >
2361 {
2362    typedef typename boost::container::deque<T, Allocator, Options>::allocator_type allocator_type;
2363    typedef typename ::boost::container::allocator_traits<allocator_type>::pointer pointer;
2364    static const bool value = ::boost::has_trivial_destructor_after_move<allocator_type>::value &&
2365                              ::boost::has_trivial_destructor_after_move<pointer>::value;
2366 };
2367 
2368 }
2369 
2370 #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
2371 
2372 #include <boost/container/detail/config_end.hpp>
2373 
2374 #endif //   #ifndef  BOOST_CONTAINER_DEQUE_HPP