Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-14 08:27:33

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