Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /include/boost/container/deque.hpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

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 
1030    //`allocator_type::value_type` must match container's `value type`. If this
1031    //assertion fails, please review your allocator definition. 
1032    BOOST_CONTAINER_STATIC_ASSERT((dtl::is_same<value_type, typename allocator_traits<ValAllocator>::value_type>::value));
1033 
1034    BOOST_COPYABLE_AND_MOVABLE(deque)
1035    typedef typename Base::ptr_alloc_ptr index_pointer;
1036    typedef allocator_traits<ValAllocator>                  allocator_traits_type;
1037 
1038    #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
1039 
1040    using Base::get_block_ssize;
1041 
1042    public:
1043 
1044    using Base::get_block_size;
1045 
1046 
1047    //////////////////////////////////////////////
1048    //
1049    //          construct/copy/destroy
1050    //
1051    //////////////////////////////////////////////
1052 
1053    //! <b>Effects</b>: Default constructors a deque.
1054    //!
1055    //! <b>Throws</b>: If allocator_type's default constructor throws.
1056    //!
1057    //! <b>Complexity</b>: Constant.
1058    inline deque()
1059       BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible<ValAllocator>::value)
1060       : Base()
1061    {}
1062 
1063    //! <b>Effects</b>: Constructs a deque taking the allocator as parameter.
1064    //!
1065    //! <b>Throws</b>: Nothing
1066    //!
1067    //! <b>Complexity</b>: Constant.
1068    inline explicit deque(const allocator_type& a) BOOST_NOEXCEPT_OR_NOTHROW
1069       : Base(a)
1070    {}
1071 
1072    //! <b>Effects</b>: Constructs a deque
1073    //!   and inserts n value initialized values.
1074    //!
1075    //! <b>Throws</b>: If allocator_type's default constructor
1076    //!   throws or T's value initialization throws.
1077    //!
1078    //! <b>Complexity</b>: Linear to n.
1079    inline explicit deque(size_type n)
1080       : Base(n, allocator_type())
1081    {
1082       dtl::insert_value_initialized_n_proxy<ValAllocator> proxy;
1083       proxy.uninitialized_copy_n_and_update(this->alloc(), this->begin(), n);
1084       //deque_base will deallocate in case of exception...
1085    }
1086 
1087    //! <b>Effects</b>: Constructs a deque
1088    //!   and inserts n default initialized values.
1089    //!
1090    //! <b>Throws</b>: If allocator_type's default constructor
1091    //!   throws or T's default initialization or copy constructor throws.
1092    //!
1093    //! <b>Complexity</b>: Linear to n.
1094    //!
1095    //! <b>Note</b>: Non-standard extension
1096    inline deque(size_type n, default_init_t)
1097       : Base(n, allocator_type())
1098    {
1099       dtl::insert_default_initialized_n_proxy<ValAllocator> proxy;
1100       proxy.uninitialized_copy_n_and_update(this->alloc(), this->begin(), n);
1101       //deque_base will deallocate in case of exception...
1102    }
1103 
1104    //! <b>Effects</b>: Constructs a deque that will use a copy of allocator a
1105    //!   and inserts n value initialized values.
1106    //!
1107    //! <b>Throws</b>: If allocator_type's default constructor
1108    //!   throws or T's value initialization throws.
1109    //!
1110    //! <b>Complexity</b>: Linear to n.
1111    inline explicit deque(size_type n, const allocator_type &a)
1112       : Base(n, a)
1113    {
1114       dtl::insert_value_initialized_n_proxy<ValAllocator> proxy;
1115       proxy.uninitialized_copy_n_and_update(this->alloc(), this->begin(), n);
1116       //deque_base will deallocate in case of exception...
1117    }
1118 
1119    //! <b>Effects</b>: Constructs a deque that will use a copy of allocator a
1120    //!   and inserts n default initialized values.
1121    //!
1122    //! <b>Throws</b>: If allocator_type's default constructor
1123    //!   throws or T's default initialization or copy constructor throws.
1124    //!
1125    //! <b>Complexity</b>: Linear to n.
1126    //!
1127    //! <b>Note</b>: Non-standard extension
1128    inline deque(size_type n, default_init_t, const allocator_type &a)
1129       : Base(n, a)
1130    {
1131       dtl::insert_default_initialized_n_proxy<ValAllocator> proxy;
1132       proxy.uninitialized_copy_n_and_update(this->alloc(), this->begin(), n);
1133       //deque_base will deallocate in case of exception...
1134    }
1135 
1136    //! <b>Effects</b>: Constructs a deque that will use a copy of allocator a
1137    //!   and inserts n copies of value.
1138    //!
1139    //! <b>Throws</b>: If allocator_type's default constructor
1140    //!   throws or T's copy constructor throws.
1141    //!
1142    //! <b>Complexity</b>: Linear to n.
1143    inline deque(size_type n, const value_type& value)
1144       : Base(n, allocator_type())
1145    { this->priv_fill_initialize(value); }
1146 
1147    //! <b>Effects</b>: Constructs a deque that will use a copy of allocator a
1148    //!   and inserts n copies of value.
1149    //!
1150    //! <b>Throws</b>: If allocator_type's default constructor
1151    //!   throws or T's copy constructor throws.
1152    //!
1153    //! <b>Complexity</b>: Linear to n.
1154    inline deque(size_type n, const value_type& value, const allocator_type& a)
1155       : Base(n, a)
1156    { this->priv_fill_initialize(value); }
1157 
1158    //! <b>Effects</b>: Constructs a deque that will use a copy of allocator a
1159    //!   and inserts a copy of the range [first, last) in the deque.
1160    //!
1161    //! <b>Throws</b>: If allocator_type's default constructor
1162    //!   throws or T's constructor taking a dereferenced InIt throws.
1163    //!
1164    //! <b>Complexity</b>: Linear to the range [first, last).
1165    template <class InIt>
1166    inline deque(InIt first, InIt last
1167       #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
1168       , typename dtl::disable_if_convertible
1169          <InIt, size_type>::type * = 0
1170       #endif
1171       )
1172       : Base(allocator_type())
1173    {
1174       this->priv_range_initialize(first, last);
1175    }
1176 
1177    //! <b>Effects</b>: Constructs a deque that will use a copy of allocator a
1178    //!   and inserts a copy of the range [first, last) in the deque.
1179    //!
1180    //! <b>Throws</b>: If allocator_type's default constructor
1181    //!   throws or T's constructor taking a dereferenced InIt throws.
1182    //!
1183    //! <b>Complexity</b>: Linear to the range [first, last).
1184    template <class InIt>
1185    inline deque(InIt first, InIt last, const allocator_type& a
1186       #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
1187       , typename dtl::disable_if_convertible
1188          <InIt, size_type>::type * = 0
1189       #endif
1190       )
1191       : Base(a)
1192    {
1193       this->priv_range_initialize(first, last);
1194    }
1195 
1196 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
1197    //! <b>Effects</b>: Constructs a deque that will use a copy of allocator a
1198    //!   and inserts a copy of the range [il.begin(), il.end()) in the deque.
1199    //!
1200    //! <b>Throws</b>: If allocator_type's default constructor
1201    //!   throws or T's constructor taking a dereferenced std::initializer_list iterator throws.
1202    //!
1203    //! <b>Complexity</b>: Linear to the range [il.begin(), il.end()).
1204    inline deque(std::initializer_list<value_type> il, const allocator_type& a = allocator_type())
1205       : Base(a)
1206    {
1207       this->priv_range_initialize(il.begin(), il.end());
1208    }
1209 #endif
1210 
1211    //! <b>Effects</b>: Copy constructs a deque.
1212    //!
1213    //! <b>Postcondition</b>: x == *this.
1214    //!
1215    //! <b>Complexity</b>: Linear to the elements x contains.
1216    inline deque(const deque& x)
1217       :  Base(allocator_traits_type::select_on_container_copy_construction(x.alloc()))
1218    {
1219       if(x.size()){
1220          this->priv_initialize_map(x.size());
1221          boost::container::uninitialized_copy_alloc
1222             (this->alloc(), x.begin(), x.end(), this->members_.m_start);
1223       }
1224    }
1225 
1226    //! <b>Effects</b>: Move constructor. Moves x's resources to *this.
1227    //!
1228    //! <b>Throws</b>: If allocator_type's copy constructor throws.
1229    //!
1230    //! <b>Complexity</b>: Constant.
1231    inline deque(BOOST_RV_REF(deque) x) BOOST_NOEXCEPT_OR_NOTHROW
1232       :  Base(BOOST_MOVE_BASE(Base, x))
1233    {  this->swap_members(x);   }
1234 
1235    //! <b>Effects</b>: Copy constructs a vector using the specified allocator.
1236    //!
1237    //! <b>Postcondition</b>: x == *this.
1238    //!
1239    //! <b>Throws</b>: If allocation
1240    //!   throws or T's copy constructor throws.
1241    //!
1242    //! <b>Complexity</b>: Linear to the elements x contains.
1243    deque(const deque& x, const allocator_type &a)
1244       :  Base(a)
1245    {
1246       if(x.size()){
1247          this->priv_initialize_map(x.size());
1248          boost::container::uninitialized_copy_alloc
1249             (this->alloc(), x.begin(), x.end(), this->members_.m_start);
1250       }
1251    }
1252 
1253    //! <b>Effects</b>: Move constructor using the specified allocator.
1254    //!                 Moves x's resources to *this if a == allocator_type().
1255    //!                 Otherwise copies values from x to *this.
1256    //!
1257    //! <b>Throws</b>: If allocation or T's copy constructor throws.
1258    //!
1259    //! <b>Complexity</b>: Constant if a == x.get_allocator(), linear otherwise.
1260    deque(BOOST_RV_REF(deque) x, const allocator_type &a)
1261       :  Base(a)
1262    {
1263       if(x.alloc() == a){
1264          this->swap_members(x);
1265       }
1266       else{
1267          if(x.size()){
1268             this->priv_initialize_map(x.size());
1269             boost::container::uninitialized_copy_alloc
1270                ( this->alloc(), boost::make_move_iterator(x.begin())
1271                , boost::make_move_iterator(x.end()), this->members_.m_start);
1272          }
1273       }
1274    }
1275 
1276    //! <b>Effects</b>: Destroys the deque. All stored values are destroyed
1277    //!   and used memory is deallocated.
1278    //!
1279    //! <b>Throws</b>: Nothing.
1280    //!
1281    //! <b>Complexity</b>: Linear to the number of elements.
1282    inline ~deque() BOOST_NOEXCEPT_OR_NOTHROW
1283    {
1284       this->priv_destroy_range(this->members_.m_start, this->members_.m_finish);
1285    }
1286 
1287    //! <b>Effects</b>: Makes *this contain the same elements as x.
1288    //!
1289    //! <b>Postcondition</b>: this->size() == x.size(). *this contains a copy
1290    //! of each of x's elements.
1291    //!
1292    //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
1293    //!
1294    //! <b>Complexity</b>: Linear to the number of elements in x.
1295    deque& operator= (BOOST_COPY_ASSIGN_REF(deque) x)
1296    {
1297       if (BOOST_LIKELY(&x != this)){
1298          allocator_type &this_alloc     = this->alloc();
1299          const allocator_type &x_alloc  = x.alloc();
1300          dtl::bool_<allocator_traits_type::
1301             propagate_on_container_copy_assignment::value> flag;
1302          if(flag && this_alloc != x_alloc){
1303             this->clear();
1304             this->shrink_to_fit();
1305          }
1306          dtl::assign_alloc(this->alloc(), x.alloc(), flag);
1307          dtl::assign_alloc(this->ptr_alloc(), x.ptr_alloc(), flag);
1308          this->assign(x.cbegin(), x.cend());
1309       }
1310       return *this;
1311    }
1312 
1313    //! <b>Effects</b>: Move assignment. All x's values are transferred to *this.
1314    //!
1315    //! <b>Throws</b>: If allocator_traits_type::propagate_on_container_move_assignment
1316    //!   is false and (allocation throws or value_type's move constructor throws)
1317    //!
1318    //! <b>Complexity</b>: Constant if allocator_traits_type::
1319    //!   propagate_on_container_move_assignment is true or
1320    //!   this->get>allocator() == x.get_allocator(). Linear otherwise.
1321    deque& operator= (BOOST_RV_REF(deque) x)
1322       BOOST_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_move_assignment::value
1323                                   || allocator_traits_type::is_always_equal::value)
1324    {
1325       if (BOOST_LIKELY(this != &x)) {
1326          //We know resources can be transferred at comiple time if both allocators are
1327          //always equal or the allocator is going to be propagated
1328          const bool can_steal_resources_alloc
1329             =  allocator_traits_type::propagate_on_container_move_assignment::value
1330             || allocator_traits_type::is_always_equal::value;
1331          dtl::bool_<can_steal_resources_alloc> flag;
1332          this->priv_move_assign(boost::move(x), flag);
1333       }
1334       return *this;
1335    }
1336 
1337 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
1338    //! <b>Effects</b>: Makes *this contain the same elements as il.
1339    //!
1340    //! <b>Postcondition</b>: this->size() == il.size(). *this contains a copy
1341    //! of each of x's elements.
1342    //!
1343    //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
1344    //!
1345    //! <b>Complexity</b>: Linear to the number of elements in il.
1346    inline deque& operator=(std::initializer_list<value_type> il)
1347    {
1348       this->assign(il.begin(), il.end());
1349       return *this;
1350    }
1351 #endif
1352 
1353    //! <b>Effects</b>: Assigns the n copies of val to *this.
1354    //!
1355    //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
1356    //!
1357    //! <b>Complexity</b>: Linear to n.
1358    inline void assign(size_type n, const T& val)
1359    {
1360       this->assign(c_it(val, n), c_it());
1361    }
1362 
1363    //! <b>Effects</b>: Assigns the the range [first, last) to *this.
1364    //!
1365    //! <b>Throws</b>: If memory allocation throws or
1366    //!   T's constructor from dereferencing InIt throws.
1367    //!
1368    //! <b>Complexity</b>: Linear to n.
1369    template <class InIt>
1370    void assign(InIt first, InIt last
1371       #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
1372       , typename dtl::disable_if_or
1373          < void
1374          , dtl::is_convertible<InIt, size_type>
1375          , dtl::is_not_input_iterator<InIt>
1376          >::type * = 0
1377       #endif
1378       )
1379    {
1380       iterator cur = this->begin();
1381       for ( ; first != last && cur != end(); ++cur, ++first){
1382          *cur = *first;
1383       }
1384       if (first == last){
1385          this->erase(cur, this->cend());
1386       }
1387       else{
1388          this->insert(this->cend(), first, last);
1389       }
1390    }
1391 
1392    #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
1393    template <class FwdIt>
1394    void assign(FwdIt first, FwdIt last
1395       , typename dtl::disable_if_or
1396          < void
1397          , dtl::is_convertible<FwdIt, size_type>
1398          , dtl::is_input_iterator<FwdIt>
1399          >::type * = 0
1400       )
1401    {
1402       const size_type len = boost::container::iterator_udistance(first, last);
1403       if (len > size()) {
1404          FwdIt mid = first;
1405          boost::container::iterator_uadvance(mid, this->size());
1406          boost::container::copy(first, mid, begin());
1407          this->insert(this->cend(), mid, last);
1408       }
1409       else{
1410          this->erase(boost::container::copy(first, last, this->begin()), cend());
1411       }
1412    }
1413    #endif
1414 
1415 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
1416    //! <b>Effects</b>: Assigns the the range [il.begin(), il.end()) to *this.
1417    //!
1418    //! <b>Throws</b>: If memory allocation throws or
1419    //!   T's constructor from dereferencing std::initializer_list iterator throws.
1420    //!
1421    //! <b>Complexity</b>: Linear to il.size().
1422    inline void assign(std::initializer_list<value_type> il)
1423    {   this->assign(il.begin(), il.end());   }
1424 #endif
1425 
1426    //! <b>Effects</b>: Returns a copy of the internal allocator.
1427    //!
1428    //! <b>Throws</b>: If allocator's copy constructor throws.
1429    //!
1430    //! <b>Complexity</b>: Constant.
1431    BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
1432       allocator_type get_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
1433    { return Base::alloc(); }
1434 
1435    //! <b>Effects</b>: Returns a reference to the internal allocator.
1436    //!
1437    //! <b>Throws</b>: Nothing
1438    //!
1439    //! <b>Complexity</b>: Constant.
1440    //!
1441    //! <b>Note</b>: Non-standard extension.
1442    BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
1443       const stored_allocator_type &get_stored_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
1444    {  return Base::alloc(); }
1445 
1446    //////////////////////////////////////////////
1447    //
1448    //                iterators
1449    //
1450    //////////////////////////////////////////////
1451 
1452    //! <b>Effects</b>: Returns a reference to the internal allocator.
1453    //!
1454    //! <b>Throws</b>: Nothing
1455    //!
1456    //! <b>Complexity</b>: Constant.
1457    //!
1458    //! <b>Note</b>: Non-standard extension.
1459    BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
1460       stored_allocator_type &get_stored_allocator() BOOST_NOEXCEPT_OR_NOTHROW
1461    {  return Base::alloc(); }
1462 
1463    //! <b>Effects</b>: Returns an iterator to the first element contained in the deque.
1464    //!
1465    //! <b>Throws</b>: Nothing.
1466    //!
1467    //! <b>Complexity</b>: Constant.
1468    BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
1469       iterator begin() BOOST_NOEXCEPT_OR_NOTHROW
1470       { return this->members_.m_start; }
1471 
1472    //! <b>Effects</b>: Returns a const_iterator to the first element contained in the deque.
1473    //!
1474    //! <b>Throws</b>: Nothing.
1475    //!
1476    //! <b>Complexity</b>: Constant.
1477    BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
1478       const_iterator begin() const BOOST_NOEXCEPT_OR_NOTHROW
1479       { return this->members_.m_start; }
1480 
1481    //! <b>Effects</b>: Returns an iterator to the end of the deque.
1482    //!
1483    //! <b>Throws</b>: Nothing.
1484    //!
1485    //! <b>Complexity</b>: Constant.
1486    BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
1487       iterator end() BOOST_NOEXCEPT_OR_NOTHROW
1488       { return this->members_.m_finish; }
1489 
1490    //! <b>Effects</b>: Returns a const_iterator to the end of the deque.
1491    //!
1492    //! <b>Throws</b>: Nothing.
1493    //!
1494    //! <b>Complexity</b>: Constant.
1495    BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
1496       const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW
1497       { return this->members_.m_finish; }
1498 
1499    //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
1500    //! of the reversed deque.
1501    //!
1502    //! <b>Throws</b>: Nothing.
1503    //!
1504    //! <b>Complexity</b>: Constant.
1505    BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
1506       reverse_iterator rbegin() BOOST_NOEXCEPT_OR_NOTHROW
1507       { return reverse_iterator(this->members_.m_finish); }
1508 
1509    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
1510    //! of the reversed deque.
1511    //!
1512    //! <b>Throws</b>: Nothing.
1513    //!
1514    //! <b>Complexity</b>: Constant.
1515    BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
1516       const_reverse_iterator rbegin() const BOOST_NOEXCEPT_OR_NOTHROW
1517       { return const_reverse_iterator(this->members_.m_finish); }
1518 
1519    //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
1520    //! of the reversed deque.
1521    //!
1522    //! <b>Throws</b>: Nothing.
1523    //!
1524    //! <b>Complexity</b>: Constant.
1525    BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
1526       reverse_iterator rend() BOOST_NOEXCEPT_OR_NOTHROW
1527       { return reverse_iterator(this->members_.m_start); }
1528 
1529    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
1530    //! of the reversed deque.
1531    //!
1532    //! <b>Throws</b>: Nothing.
1533    //!
1534    //! <b>Complexity</b>: Constant.
1535    BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
1536       const_reverse_iterator rend() const BOOST_NOEXCEPT_OR_NOTHROW
1537       { return const_reverse_iterator(this->members_.m_start); }
1538 
1539    //! <b>Effects</b>: Returns a const_iterator to the first element contained in the deque.
1540    //!
1541    //! <b>Throws</b>: Nothing.
1542    //!
1543    //! <b>Complexity</b>: Constant.
1544    BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
1545       const_iterator cbegin() const BOOST_NOEXCEPT_OR_NOTHROW
1546       { return this->members_.m_start; }
1547 
1548    //! <b>Effects</b>: Returns a const_iterator to the end of the deque.
1549    //!
1550    //! <b>Throws</b>: Nothing.
1551    //!
1552    //! <b>Complexity</b>: Constant.
1553    BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
1554       const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW
1555       { return this->members_.m_finish; }
1556 
1557    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
1558    //! of the reversed deque.
1559    //!
1560    //! <b>Throws</b>: Nothing.
1561    //!
1562    //! <b>Complexity</b>: Constant.
1563    BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
1564       const_reverse_iterator crbegin() const BOOST_NOEXCEPT_OR_NOTHROW
1565       { return const_reverse_iterator(this->members_.m_finish); }
1566 
1567    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
1568    //! of the reversed deque.
1569    //!
1570    //! <b>Throws</b>: Nothing.
1571    //!
1572    //! <b>Complexity</b>: Constant.
1573    BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
1574       const_reverse_iterator crend() const BOOST_NOEXCEPT_OR_NOTHROW
1575       { return const_reverse_iterator(this->members_.m_start); }
1576 
1577    //////////////////////////////////////////////
1578    //
1579    //                capacity
1580    //
1581    //////////////////////////////////////////////
1582 
1583    //! <b>Effects</b>: Returns true if the deque contains no elements.
1584    //!
1585    //! <b>Throws</b>: Nothing.
1586    //!
1587    //! <b>Complexity</b>: Constant.
1588    BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
1589       bool empty() const BOOST_NOEXCEPT_OR_NOTHROW
1590    { return this->members_.m_finish == this->members_.m_start; }
1591 
1592    //! <b>Effects</b>: Returns the number of the elements contained in the deque.
1593    //!
1594    //! <b>Throws</b>: Nothing.
1595    //!
1596    //! <b>Complexity</b>: Constant.
1597    BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
1598       size_type size() const BOOST_NOEXCEPT_OR_NOTHROW
1599       { return size_type(this->members_.m_finish - this->members_.m_start); }
1600 
1601    //! <b>Effects</b>: Returns the largest possible size of the deque.
1602    //!
1603    //! <b>Throws</b>: Nothing.
1604    //!
1605    //! <b>Complexity</b>: Constant.
1606    BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
1607       size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW
1608       { return allocator_traits_type::max_size(this->alloc()); }
1609 
1610    //! <b>Effects</b>: Inserts or erases elements at the end such that
1611    //!   the size becomes n. New elements are value initialized.
1612    //!
1613    //! <b>Throws</b>: If memory allocation throws, or T's constructor throws.
1614    //!
1615    //! <b>Complexity</b>: Linear to the difference between size() and new_size.
1616    void resize(size_type new_size)
1617    {
1618       const size_type len = size();
1619       if (new_size < len)
1620          this->priv_erase_last_n(len - new_size);
1621       else{
1622          const size_type n = new_size - this->size();
1623          dtl::insert_value_initialized_n_proxy<ValAllocator> proxy;
1624          priv_insert_back_aux_impl(n, proxy);
1625       }
1626    }
1627 
1628    //! <b>Effects</b>: Inserts or erases elements at the end such that
1629    //!   the size becomes n. New elements are default initialized.
1630    //!
1631    //! <b>Throws</b>: If memory allocation throws, or T's constructor throws.
1632    //!
1633    //! <b>Complexity</b>: Linear to the difference between size() and new_size.
1634    //!
1635    //! <b>Note</b>: Non-standard extension
1636    void resize(size_type new_size, default_init_t)
1637    {
1638       const size_type len = size();
1639       if (new_size < len)
1640          this->priv_erase_last_n(len - new_size);
1641       else{
1642          const size_type n = new_size - this->size();
1643          dtl::insert_default_initialized_n_proxy<ValAllocator> proxy;
1644          priv_insert_back_aux_impl(n, proxy);
1645       }
1646    }
1647 
1648    //! <b>Effects</b>: Inserts or erases elements at the end such that
1649    //!   the size becomes n. New elements are copy constructed from x.
1650    //!
1651    //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
1652    //!
1653    //! <b>Complexity</b>: Linear to the difference between size() and new_size.
1654    void resize(size_type new_size, const value_type& x)
1655    {
1656       const size_type len = size();
1657       if (new_size < len)
1658          this->erase(this->members_.m_start + difference_type(new_size), this->members_.m_finish);
1659       else
1660          this->insert(this->members_.m_finish, new_size - len, x);
1661    }
1662 
1663    //! <b>Effects</b>: Tries to deallocate the excess of memory created
1664    //!   with previous allocations. The size of the deque is unchanged
1665    //!
1666    //! <b>Throws</b>: If memory allocation throws.
1667    //!
1668    //! <b>Complexity</b>: Constant.
1669    void shrink_to_fit()
1670    {
1671       //This deque implementation already
1672       //deallocates excess nodes when erasing
1673       //so there is nothing to do except for
1674       //empty deque
1675       if(this->empty()){
1676          this->priv_clear_map();
1677       }
1678    }
1679 
1680    //////////////////////////////////////////////
1681    //
1682    //               element access
1683    //
1684    //////////////////////////////////////////////
1685 
1686    //! <b>Requires</b>: !empty()
1687    //!
1688    //! <b>Effects</b>: Returns a reference to the first
1689    //!   element of the container.
1690    //!
1691    //! <b>Throws</b>: Nothing.
1692    //!
1693    //! <b>Complexity</b>: Constant.
1694    BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
1695       reference front() BOOST_NOEXCEPT_OR_NOTHROW
1696    {
1697       BOOST_ASSERT(!this->empty());
1698       return *this->members_.m_start;
1699    }
1700 
1701    //! <b>Requires</b>: !empty()
1702    //!
1703    //! <b>Effects</b>: Returns a const reference to the first element
1704    //!   from the beginning of the container.
1705    //!
1706    //! <b>Throws</b>: Nothing.
1707    //!
1708    //! <b>Complexity</b>: Constant.
1709    BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
1710       const_reference front() const BOOST_NOEXCEPT_OR_NOTHROW
1711    {
1712       BOOST_ASSERT(!this->empty());
1713       return *this->members_.m_start;
1714    }
1715 
1716    //! <b>Requires</b>: !empty()
1717    //!
1718    //! <b>Effects</b>: Returns a reference to the last
1719    //!   element of the container.
1720    //!
1721    //! <b>Throws</b>: Nothing.
1722    //!
1723    //! <b>Complexity</b>: Constant.
1724    BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
1725       reference back() BOOST_NOEXCEPT_OR_NOTHROW
1726    {
1727       BOOST_ASSERT(!this->empty());
1728       return *(end()-1);
1729    }
1730 
1731    //! <b>Requires</b>: !empty()
1732    //!
1733    //! <b>Effects</b>: Returns a const reference to the last
1734    //!   element of the container.
1735    //!
1736    //! <b>Throws</b>: Nothing.
1737    //!
1738    //! <b>Complexity</b>: Constant.
1739    BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
1740       const_reference back() const BOOST_NOEXCEPT_OR_NOTHROW
1741    {
1742       BOOST_ASSERT(!this->empty());
1743       return *(cend()-1);
1744    }
1745 
1746    //! <b>Requires</b>: size() > n.
1747    //!
1748    //! <b>Effects</b>: Returns a reference to the nth element
1749    //!   from the beginning of the container.
1750    //!
1751    //! <b>Throws</b>: Nothing.
1752    //!
1753    //! <b>Complexity</b>: Constant.
1754    BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
1755       reference operator[](size_type n) BOOST_NOEXCEPT_OR_NOTHROW
1756    {
1757       BOOST_ASSERT(this->size() > n);
1758       return this->members_.m_start[difference_type(n)];
1759    }
1760 
1761    //! <b>Requires</b>: size() > n.
1762    //!
1763    //! <b>Effects</b>: Returns a const reference to the nth element
1764    //!   from the beginning of the container.
1765    //!
1766    //! <b>Throws</b>: Nothing.
1767    //!
1768    //! <b>Complexity</b>: Constant.
1769    BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
1770       const_reference operator[](size_type n) const BOOST_NOEXCEPT_OR_NOTHROW
1771    {
1772       BOOST_ASSERT(this->size() > n);
1773       return this->members_.m_start[difference_type(n)];
1774    }
1775 
1776    //! <b>Requires</b>: size() >= n.
1777    //!
1778    //! <b>Effects</b>: Returns an iterator to the nth element
1779    //!   from the beginning of the container. Returns end()
1780    //!   if n == size().
1781    //!
1782    //! <b>Throws</b>: Nothing.
1783    //!
1784    //! <b>Complexity</b>: Constant.
1785    //!
1786    //! <b>Note</b>: Non-standard extension
1787    BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
1788       iterator nth(size_type n) BOOST_NOEXCEPT_OR_NOTHROW
1789    {
1790       BOOST_ASSERT(this->size() >= n);
1791       return iterator(this->begin()+difference_type(n));
1792    }
1793 
1794    //! <b>Requires</b>: size() >= n.
1795    //!
1796    //! <b>Effects</b>: Returns a const_iterator to the nth element
1797    //!   from the beginning of the container. Returns end()
1798    //!   if n == size().
1799    //!
1800    //! <b>Throws</b>: Nothing.
1801    //!
1802    //! <b>Complexity</b>: Constant.
1803    //!
1804    //! <b>Note</b>: Non-standard extension
1805    BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
1806       const_iterator nth(size_type n) const BOOST_NOEXCEPT_OR_NOTHROW
1807    {
1808       BOOST_ASSERT(this->size() >= n);
1809       return const_iterator(this->cbegin()+difference_type(n));
1810    }
1811 
1812    //! <b>Requires</b>: begin() <= p <= end().
1813    //!
1814    //! <b>Effects</b>: Returns the index of the element pointed by p
1815    //!   and size() if p == end().
1816    //!
1817    //! <b>Throws</b>: Nothing.
1818    //!
1819    //! <b>Complexity</b>: Constant.
1820    //!
1821    //! <b>Note</b>: Non-standard extension
1822    BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
1823       size_type index_of(iterator p) BOOST_NOEXCEPT_OR_NOTHROW
1824    {
1825       //Range checked priv_index_of
1826       return this->priv_index_of(p);
1827    }
1828 
1829    //! <b>Requires</b>: begin() <= p <= end().
1830    //!
1831    //! <b>Effects</b>: Returns the index of the element pointed by p
1832    //!   and size() if p == end().
1833    //!
1834    //! <b>Throws</b>: Nothing.
1835    //!
1836    //! <b>Complexity</b>: Constant.
1837    //!
1838    //! <b>Note</b>: Non-standard extension
1839    BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
1840       size_type index_of(const_iterator p) const BOOST_NOEXCEPT_OR_NOTHROW
1841    {
1842       //Range checked priv_index_of
1843       return this->priv_index_of(p);
1844    }
1845 
1846    //! <b>Requires</b>: size() > n.
1847    //!
1848    //! <b>Effects</b>: Returns a reference to the nth element
1849    //!   from the beginning of the container.
1850    //!
1851    //! <b>Throws</b>: range_error if n >= size()
1852    //!
1853    //! <b>Complexity</b>: Constant.
1854    BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
1855       reference at(size_type n)
1856    {
1857       this->priv_throw_if_out_of_range(n);
1858       return (*this)[n];
1859    }
1860 
1861    //! <b>Requires</b>: size() > n.
1862    //!
1863    //! <b>Effects</b>: Returns a const reference to the nth element
1864    //!   from the beginning of the container.
1865    //!
1866    //! <b>Throws</b>: range_error if n >= size()
1867    //!
1868    //! <b>Complexity</b>: Constant.
1869    BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
1870       const_reference at(size_type n) const
1871    {
1872       this->priv_throw_if_out_of_range(n);
1873       return (*this)[n];
1874    }
1875 
1876    //////////////////////////////////////////////
1877    //
1878    //                modifiers
1879    //
1880    //////////////////////////////////////////////
1881 
1882    #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
1883 
1884    //! <b>Effects</b>: Inserts an object of type T constructed with
1885    //!   std::forward<Args>(args)... in the beginning of the deque.
1886    //!
1887    //! <b>Returns</b>: A reference to the created object.
1888    //!
1889    //! <b>Throws</b>: If memory allocation throws or the in-place constructor throws.
1890    //!
1891    //! <b>Complexity</b>: Amortized constant time
1892    template <class... Args>
1893    reference emplace_front(BOOST_FWD_REF(Args)... args)
1894    {
1895       if(this->priv_push_front_simple_available()){
1896          reference r = *this->priv_push_front_simple_pos();
1897          allocator_traits_type::construct
1898             ( this->alloc()
1899             , this->priv_push_front_simple_pos()
1900             , boost::forward<Args>(args)...);
1901          this->priv_push_front_simple_commit();
1902          return r;
1903       }
1904       else{
1905          typedef dtl::insert_nonmovable_emplace_proxy<ValAllocator, Args...> type;
1906          return *this->priv_insert_front_aux_impl(1, type(boost::forward<Args>(args)...));
1907       }
1908    }
1909 
1910    //! <b>Effects</b>: Inserts an object of type T constructed with
1911    //!   std::forward<Args>(args)... in the end of the deque.
1912    //!
1913    //! <b>Returns</b>: A reference to the created object.
1914    //!
1915    //! <b>Throws</b>: If memory allocation throws or the in-place constructor throws.
1916    //!
1917    //! <b>Complexity</b>: Amortized constant time
1918    template <class... Args>
1919    reference emplace_back(BOOST_FWD_REF(Args)... args)
1920    {
1921       if(this->priv_push_back_simple_available()){
1922          reference r = *this->priv_push_back_simple_pos();
1923          allocator_traits_type::construct
1924             ( this->alloc()
1925             , this->priv_push_back_simple_pos()
1926             , boost::forward<Args>(args)...);
1927          this->priv_push_back_simple_commit();
1928          return r;
1929       }
1930       else{
1931          typedef dtl::insert_nonmovable_emplace_proxy<ValAllocator, Args...> type;
1932          return *this->priv_insert_back_aux_impl(1, type(boost::forward<Args>(args)...));
1933       }
1934    }
1935 
1936    //! <b>Requires</b>: p must be a valid iterator of *this.
1937    //!
1938    //! <b>Effects</b>: Inserts an object of type T constructed with
1939    //!   std::forward<Args>(args)... before p
1940    //!
1941    //! <b>Throws</b>: If memory allocation throws or the in-place constructor throws.
1942    //!
1943    //! <b>Complexity</b>: If p is end(), amortized constant time
1944    //!   Linear time otherwise.
1945    template <class... Args>
1946    iterator emplace(const_iterator p, BOOST_FWD_REF(Args)... args)
1947    {
1948       BOOST_ASSERT(this->priv_in_range_or_end(p));
1949       if(p == this->cbegin()){
1950          this->emplace_front(boost::forward<Args>(args)...);
1951          return this->begin();
1952       }
1953       else if(p == this->cend()){
1954          this->emplace_back(boost::forward<Args>(args)...);
1955          return (this->end()-1);
1956       }
1957       else{
1958          typedef dtl::insert_emplace_proxy<ValAllocator, Args...> type;
1959          return this->priv_insert_aux_impl(p, 1, type(boost::forward<Args>(args)...));
1960       }
1961    }
1962 
1963    #else //!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
1964 
1965    #define BOOST_CONTAINER_DEQUE_EMPLACE_CODE(N) \
1966    BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N\
1967    reference emplace_front(BOOST_MOVE_UREF##N)\
1968    {\
1969       if(priv_push_front_simple_available()){\
1970          reference r = *this->priv_push_front_simple_pos();\
1971          allocator_traits_type::construct\
1972             ( this->alloc(), this->priv_push_front_simple_pos() BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
1973          priv_push_front_simple_commit();\
1974          return r;\
1975       }\
1976       else{\
1977          typedef dtl::insert_nonmovable_emplace_proxy##N\
1978                <ValAllocator BOOST_MOVE_I##N BOOST_MOVE_TARG##N> type;\
1979          return *priv_insert_front_aux_impl(1, type(BOOST_MOVE_FWD##N));\
1980       }\
1981    }\
1982    \
1983    BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N\
1984    reference emplace_back(BOOST_MOVE_UREF##N)\
1985    {\
1986       if(priv_push_back_simple_available()){\
1987          reference r = *this->priv_push_back_simple_pos();\
1988          allocator_traits_type::construct\
1989             ( this->alloc(), this->priv_push_back_simple_pos() BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
1990          priv_push_back_simple_commit();\
1991          return r;\
1992       }\
1993       else{\
1994          typedef dtl::insert_nonmovable_emplace_proxy##N\
1995                <ValAllocator BOOST_MOVE_I##N BOOST_MOVE_TARG##N> type;\
1996          return *priv_insert_back_aux_impl(1, type(BOOST_MOVE_FWD##N));\
1997       }\
1998    }\
1999    \
2000    BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N\
2001    iterator emplace(const_iterator p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
2002    {\
2003       BOOST_ASSERT(this->priv_in_range_or_end(p));\
2004       if(p == this->cbegin()){\
2005          this->emplace_front(BOOST_MOVE_FWD##N);\
2006          return this->begin();\
2007       }\
2008       else if(p == cend()){\
2009          this->emplace_back(BOOST_MOVE_FWD##N);\
2010          return (--this->end());\
2011       }\
2012       else{\
2013          typedef dtl::insert_emplace_proxy_arg##N\
2014                <ValAllocator BOOST_MOVE_I##N BOOST_MOVE_TARG##N> type;\
2015          return this->priv_insert_aux_impl(p, 1, type(BOOST_MOVE_FWD##N));\
2016       }\
2017    }
2018    //
2019    BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_DEQUE_EMPLACE_CODE)
2020    #undef BOOST_CONTAINER_DEQUE_EMPLACE_CODE
2021 
2022    #endif   // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
2023 
2024    #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
2025    //! <b>Effects</b>: Inserts a copy of x at the front of the deque.
2026    //!
2027    //! <b>Throws</b>: If memory allocation throws or
2028    //!   T's copy constructor throws.
2029    //!
2030    //! <b>Complexity</b>: Amortized constant time.
2031    void push_front(const T &x);
2032 
2033    //! <b>Effects</b>: Constructs a new element in the front of the deque
2034    //!   and moves the resources of x to this new element.
2035    //!
2036    //! <b>Throws</b>: If memory allocation throws.
2037    //!
2038    //! <b>Complexity</b>: Amortized constant time.
2039    void push_front(T &&x);
2040    #else
2041    BOOST_MOVE_CONVERSION_AWARE_CATCH(push_front, T, void, priv_push_front)
2042    #endif
2043 
2044    #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
2045    //! <b>Effects</b>: Inserts a copy of x at the end of the deque.
2046    //!
2047    //! <b>Throws</b>: If memory allocation throws or
2048    //!   T's copy constructor throws.
2049    //!
2050    //! <b>Complexity</b>: Amortized constant time.
2051    void push_back(const T &x);
2052 
2053    //! <b>Effects</b>: Constructs a new element in the end of the deque
2054    //!   and moves the resources of x to this new element.
2055    //!
2056    //! <b>Throws</b>: If memory allocation throws.
2057    //!
2058    //! <b>Complexity</b>: Amortized constant time.
2059    void push_back(T &&x);
2060    #else
2061    BOOST_MOVE_CONVERSION_AWARE_CATCH(push_back, T, void, priv_push_back)
2062    #endif
2063 
2064    #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
2065 
2066    //! <b>Requires</b>: p must be a valid iterator of *this.
2067    //!
2068    //! <b>Effects</b>: Insert a copy of x before p.
2069    //!
2070    //! <b>Returns</b>: an iterator to the inserted element.
2071    //!
2072    //! <b>Throws</b>: If memory allocation throws or x's copy constructor throws.
2073    //!
2074    //! <b>Complexity</b>: If p is end(), amortized constant time
2075    //!   Linear time otherwise.
2076    iterator insert(const_iterator p, const T &x);
2077 
2078    //! <b>Requires</b>: p must be a valid iterator of *this.
2079    //!
2080    //! <b>Effects</b>: Insert a new element before p with x's resources.
2081    //!
2082    //! <b>Returns</b>: an iterator to the inserted element.
2083    //!
2084    //! <b>Throws</b>: If memory allocation throws.
2085    //!
2086    //! <b>Complexity</b>: If p is end(), amortized constant time
2087    //!   Linear time otherwise.
2088    iterator insert(const_iterator p, T &&x);
2089    #else
2090    BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert, T, iterator, priv_insert, const_iterator, const_iterator)
2091    #endif
2092 
2093    //! <b>Requires</b>: pos must be a valid iterator of *this.
2094    //!
2095    //! <b>Effects</b>: Insert n copies of x before pos.
2096    //!
2097    //! <b>Returns</b>: an iterator to the first inserted element or pos if n is 0.
2098    //!
2099    //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
2100    //!
2101    //! <b>Complexity</b>: Linear to n.
2102    inline iterator insert(const_iterator pos, size_type n, const value_type& x)
2103    {
2104       //Range check of p is done by insert()
2105       return this->insert(pos, c_it(x, n), c_it());
2106    }
2107 
2108    //! <b>Requires</b>: pos must be a valid iterator of *this.
2109    //!
2110    //! <b>Effects</b>: Insert a copy of the [first, last) range before pos.
2111    //!
2112    //! <b>Returns</b>: an iterator to the first inserted element or pos if first == last.
2113    //!
2114    //! <b>Throws</b>: If memory allocation throws, T's constructor from a
2115    //!   dereferenced InIt throws or T's copy constructor throws.
2116    //!
2117    //! <b>Complexity</b>: Linear to distance [first, last).
2118    template <class InIt>
2119    iterator insert(const_iterator pos, InIt first, InIt last
2120       #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
2121       , typename dtl::disable_if_or
2122          < void
2123          , dtl::is_convertible<InIt, size_type>
2124          , dtl::is_not_input_iterator<InIt>
2125          >::type * = 0
2126       #endif
2127       )
2128    {
2129       BOOST_ASSERT(this->priv_in_range_or_end(pos));
2130       size_type n = 0;
2131       iterator it(pos.unconst());
2132       for(;first != last; ++first, ++n){
2133          it = this->emplace(it, *first);
2134          ++it;
2135       }
2136       it -= difference_type(n);
2137       return it;
2138    }
2139 
2140 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
2141    //! <b>Requires</b>: pos must be a valid iterator of *this.
2142    //!
2143    //! <b>Effects</b>: Insert a copy of the [il.begin(), il.end()) range before pos.
2144    //!
2145    //! <b>Returns</b>: an iterator to the first inserted element or pos if il.begin() == il.end().
2146    //!
2147    //! <b>Throws</b>: If memory allocation throws, T's constructor from a
2148    //!   dereferenced std::initializer_list throws or T's copy constructor throws.
2149    //!
2150    //! <b>Complexity</b>: Linear to distance [il.begin(), il.end()).
2151    inline iterator insert(const_iterator pos, std::initializer_list<value_type> il)
2152    {
2153       //Range check os pos is done in insert()
2154       return insert(pos, il.begin(), il.end());
2155    }
2156 #endif
2157 
2158    #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
2159    template <class FwdIt>
2160    inline iterator insert(const_iterator p, FwdIt first, FwdIt last
2161       #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
2162       , typename dtl::disable_if_or
2163          < void
2164          , dtl::is_convertible<FwdIt, size_type>
2165          , dtl::is_input_iterator<FwdIt>
2166          >::type * = 0
2167       #endif
2168       )
2169    {
2170       BOOST_ASSERT(this->priv_in_range_or_end(p));
2171       dtl::insert_range_proxy<ValAllocator, FwdIt> proxy(first);
2172       return priv_insert_aux_impl(p, boost::container::iterator_udistance(first, last), proxy);
2173    }
2174    #endif
2175 
2176    //! <b>Effects</b>: Removes the first element from the deque.
2177    //!
2178    //! <b>Throws</b>: Nothing.
2179    //!
2180    //! <b>Complexity</b>: Constant time.
2181    void pop_front() BOOST_NOEXCEPT_OR_NOTHROW
2182    {
2183       BOOST_ASSERT(!this->empty());
2184       if (this->members_.m_start.m_cur != this->members_.m_start.get_last() - 1) {
2185          allocator_traits_type::destroy
2186             ( this->alloc()
2187             , boost::movelib::to_raw_pointer(this->members_.m_start.m_cur)
2188             );
2189          ++this->members_.m_start.m_cur;
2190       }
2191       else
2192          this->priv_pop_front_aux();
2193    }
2194 
2195    //! <b>Effects</b>: Removes the last element from the deque.
2196    //!
2197    //! <b>Throws</b>: Nothing.
2198    //!
2199    //! <b>Complexity</b>: Constant time.
2200    void pop_back() BOOST_NOEXCEPT_OR_NOTHROW
2201    {
2202       BOOST_ASSERT(!this->empty());
2203       if (this->members_.m_finish.m_cur != this->members_.m_finish.get_first()) {
2204          --this->members_.m_finish.m_cur;
2205          allocator_traits_type::destroy
2206             ( this->alloc()
2207             , boost::movelib::to_raw_pointer(this->members_.m_finish.m_cur)
2208             );
2209       }
2210       else
2211          this->priv_pop_back_aux();
2212    }
2213 
2214    //! <b>Effects</b>: Erases the element at p.
2215    //!
2216    //! <b>Throws</b>: Nothing.
2217    //!
2218    //! <b>Complexity</b>: Linear to the elements between pos and the
2219    //!   last element (if pos is near the end) or the first element
2220    //!   if(pos is near the beginning).
2221    //!   Constant if pos is the first or the last element.
2222    iterator erase(const_iterator pos) BOOST_NOEXCEPT_OR_NOTHROW
2223    {
2224       BOOST_ASSERT(this->priv_in_range(pos));
2225       iterator next = pos.unconst();
2226       ++next;
2227       size_type index = size_type(pos - this->members_.m_start);
2228       if (index < (this->size()/2)) {
2229          boost::container::move_backward(this->begin(), pos.unconst(), next);
2230          pop_front();
2231       }
2232       else {
2233          boost::container::move(next, this->end(), pos.unconst());
2234          pop_back();
2235       }
2236       return this->members_.m_start + difference_type(index);
2237    }
2238 
2239    //! <b>Effects</b>: Erases the elements pointed by [first, last).
2240    //!
2241    //! <b>Throws</b>: Nothing.
2242    //!
2243    //! <b>Complexity</b>: Linear to the distance between first and
2244    //!   last plus the elements between pos and the
2245    //!   last element (if pos is near the end) or the first element
2246    //!   if(pos is near the beginning).
2247    iterator erase(const_iterator first, const_iterator last) BOOST_NOEXCEPT_OR_NOTHROW
2248    {
2249       BOOST_ASSERT(first == last ||
2250          (first < last && this->priv_in_range(first) && this->priv_in_range_or_end(last)));
2251       if (first == this->members_.m_start && last == this->members_.m_finish) {
2252          this->clear();
2253          return this->members_.m_finish;
2254       }
2255       else {
2256          const size_type n = static_cast<size_type>(last - first);
2257          const size_type elems_before = static_cast<size_type>(first - this->members_.m_start);
2258          if (elems_before < (this->size() - n) - elems_before) {
2259             boost::container::move_backward(begin(), first.unconst(), last.unconst());
2260             iterator new_start = this->members_.m_start + difference_type(n);
2261             this->priv_destroy_range(this->members_.m_start, new_start);
2262             this->priv_destroy_nodes(this->members_.m_start.m_node, new_start.m_node);
2263             this->members_.m_start = new_start;
2264          }
2265          else {
2266             boost::container::move(last.unconst(), end(), first.unconst());
2267             iterator new_finish = this->members_.m_finish - difference_type(n);
2268             this->priv_destroy_range(new_finish, this->members_.m_finish);
2269             this->priv_destroy_nodes(new_finish.m_node + 1, this->members_.m_finish.m_node + 1);
2270             this->members_.m_finish = new_finish;
2271          }
2272          return this->members_.m_start + difference_type(elems_before);
2273       }
2274    }
2275 
2276    //! <b>Effects</b>: Swaps the contents of *this and x.
2277    //!
2278    //! <b>Throws</b>: Nothing.
2279    //!
2280    //! <b>Complexity</b>: Constant.
2281    inline void swap(deque &x)
2282       BOOST_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_swap::value
2283                                || allocator_traits_type::is_always_equal::value)
2284    {
2285       this->swap_members(x);
2286       dtl::bool_<allocator_traits_type::propagate_on_container_swap::value> flag;
2287       dtl::swap_alloc(this->alloc(), x.alloc(), flag);
2288       dtl::swap_alloc(this->ptr_alloc(), x.ptr_alloc(), flag);
2289    }
2290 
2291    //! <b>Effects</b>: Erases all the elements of the deque.
2292    //!
2293    //! <b>Throws</b>: Nothing.
2294    //!
2295    //! <b>Complexity</b>: Linear to the number of elements in the deque.
2296    void clear() BOOST_NOEXCEPT_OR_NOTHROW
2297    {
2298       if (this->members_.m_finish != this->members_.m_start) {
2299   
2300          for (index_pointer node = this->members_.m_start.m_node + 1;
2301                node < this->members_.m_finish.m_node;
2302                ++node) {
2303             this->priv_destroy_range(*node, *node + get_block_ssize());
2304             this->priv_deallocate_node(*node);
2305          }
2306 
2307          if (this->members_.m_start.m_node != this->members_.m_finish.m_node) {
2308             this->priv_destroy_range(this->members_.m_start.m_cur, this->members_.m_start.get_last());
2309             this->priv_destroy_range(this->members_.m_finish.get_first(), this->members_.m_finish.m_cur);
2310             this->priv_deallocate_node(this->members_.m_finish.get_first());
2311          }
2312          else
2313             this->priv_destroy_range(this->members_.m_start.m_cur, this->members_.m_finish.m_cur);
2314 
2315          this->members_.m_finish = this->members_.m_start;
2316       }
2317    }
2318 
2319    //! <b>Effects</b>: Returns true if x and y are equal
2320    //!
2321    //! <b>Complexity</b>: Linear to the number of elements in the container.
2322    BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
2323       friend bool operator==(const deque& x, const deque& y)
2324    {  return x.size() == y.size() && ::boost::container::algo_equal(x.begin(), x.end(), y.begin());  }
2325 
2326    //! <b>Effects</b>: Returns true if x and y are unequal
2327    //!
2328    //! <b>Complexity</b>: Linear to the number of elements in the container.
2329    BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
2330       friend bool operator!=(const deque& x, const deque& y)
2331    {  return !(x == y); }
2332 
2333    //! <b>Effects</b>: Returns true if x is less than y
2334    //!
2335    //! <b>Complexity</b>: Linear to the number of elements in the container.
2336    BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
2337       friend bool operator<(const deque& x, const deque& y)
2338    {  return ::boost::container::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());  }
2339 
2340    //! <b>Effects</b>: Returns true if x is greater than y
2341    //!
2342    //! <b>Complexity</b>: Linear to the number of elements in the container.
2343    BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
2344       friend bool operator>(const deque& x, const deque& y)
2345    {  return y < x;  }
2346 
2347    //! <b>Effects</b>: Returns true if x is equal or less than y
2348    //!
2349    //! <b>Complexity</b>: Linear to the number of elements in the container.
2350    BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
2351       friend bool operator<=(const deque& x, const deque& y)
2352    {  return !(y < x);  }
2353 
2354    //! <b>Effects</b>: Returns true if x is equal or greater than y
2355    //!
2356    //! <b>Complexity</b>: Linear to the number of elements in the container.
2357    BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
2358       friend bool operator>=(const deque& x, const deque& y)
2359    {  return !(x < y);  }
2360 
2361    //! <b>Effects</b>: x.swap(y)
2362    //!
2363    //! <b>Complexity</b>: Constant.
2364    inline friend void swap(deque& x, deque& y)
2365        BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT(x.swap(y)))
2366    {  x.swap(y);  }
2367 
2368    #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
2369    private:
2370 
2371    void priv_move_assign(BOOST_RV_REF(deque) x, dtl::bool_<true> /*steal_resources*/)
2372    {
2373       //Destroy objects but retain memory in case x reuses it in the future
2374       this->clear();
2375       //Move allocator if needed
2376       dtl::bool_<allocator_traits_type::propagate_on_container_move_assignment::value> flag;
2377       dtl::move_alloc(this->alloc(), x.alloc(), flag);
2378       dtl::move_alloc(this->ptr_alloc(), x.ptr_alloc(), flag);
2379       //Nothrow swap
2380       this->swap_members(x);
2381    }
2382 
2383    void priv_move_assign(BOOST_RV_REF(deque) x, dtl::bool_<false> /*steal_resources*/)
2384    {
2385       //We can't guarantee a compile-time equal allocator or propagation so fallback to runtime
2386       //Resources can be transferred if both allocators are equal
2387       if (this->alloc() == x.alloc()) {
2388          this->priv_move_assign(boost::move(x), dtl::true_());
2389       }
2390       else {
2391          this->assign(boost::make_move_iterator(x.begin()), boost::make_move_iterator(x.end()));
2392       }
2393    }
2394 
2395    inline size_type priv_index_of(const_iterator p) const
2396    {
2397       BOOST_ASSERT(this->cbegin() <= p);
2398       BOOST_ASSERT(p <= this->cend());
2399       return static_cast<size_type>(p - this->cbegin());
2400    }
2401 
2402    void priv_erase_last_n(size_type n)
2403    {
2404       if(n == this->size()) {
2405          this->clear();
2406       }
2407       else {
2408          iterator new_finish = this->members_.m_finish - difference_type(n);
2409          this->priv_destroy_range(new_finish, this->members_.m_finish);
2410          this->priv_destroy_nodes(new_finish.m_node + 1, this->members_.m_finish.m_node + 1);
2411          this->members_.m_finish = new_finish;
2412       }
2413    }
2414 
2415    void priv_throw_if_out_of_range(size_type n) const
2416    {
2417       if (n >= this->size())
2418          throw_out_of_range("deque::at out of range");
2419    }
2420 
2421    inline bool priv_in_range(const_iterator pos) const
2422    {
2423       return (this->begin() <= pos) && (pos < this->end());
2424    }
2425 
2426    inline bool priv_in_range_or_end(const_iterator pos) const
2427    {
2428       return (this->begin() <= pos) && (pos <= this->end());
2429    }
2430 
2431    template <class U>
2432    iterator priv_insert(const_iterator p, BOOST_FWD_REF(U) x)
2433    {
2434       BOOST_ASSERT(this->priv_in_range_or_end(p));
2435       if (p == cbegin()){
2436          this->push_front(::boost::forward<U>(x));
2437          return begin();
2438       }
2439       else if (p == cend()){
2440          this->push_back(::boost::forward<U>(x));
2441          return --end();
2442       }
2443       else {
2444          return priv_insert_aux_impl
2445             ( p, (size_type)1
2446             , dtl::get_insert_value_proxy<iterator, ValAllocator>(::boost::forward<U>(x)));
2447       }
2448    }
2449 
2450    template <class U>
2451    void priv_push_front(BOOST_FWD_REF(U) x)
2452    {
2453       if(this->priv_push_front_simple_available()){
2454          allocator_traits_type::construct
2455             ( this->alloc(), this->priv_push_front_simple_pos(), ::boost::forward<U>(x));
2456          this->priv_push_front_simple_commit();
2457       }
2458       else{
2459          priv_insert_aux_impl
2460             ( this->cbegin(), (size_type)1
2461             , dtl::get_insert_value_proxy<iterator, ValAllocator>(::boost::forward<U>(x)));
2462       }
2463    }
2464 
2465    template <class U>
2466    void priv_push_back(BOOST_FWD_REF(U) x)
2467    {
2468       if(this->priv_push_back_simple_available()){
2469          allocator_traits_type::construct
2470             ( this->alloc(), this->priv_push_back_simple_pos(), ::boost::forward<U>(x));
2471          this->priv_push_back_simple_commit();
2472       }
2473       else{
2474          priv_insert_aux_impl
2475             ( this->cend(), (size_type)1
2476             , dtl::get_insert_value_proxy<iterator, ValAllocator>(::boost::forward<U>(x)));
2477       }
2478    }
2479 
2480    inline bool priv_push_back_simple_available() const
2481    {
2482       return this->members_.m_map &&
2483          (this->members_.m_finish.m_cur != (this->members_.m_finish.get_last() - 1));
2484    }
2485 
2486    inline T *priv_push_back_simple_pos() const
2487    {
2488       return boost::movelib::to_raw_pointer(this->members_.m_finish.m_cur);
2489    }
2490 
2491    inline void priv_push_back_simple_commit()
2492    {
2493       ++this->members_.m_finish.m_cur;
2494    }
2495 
2496    inline bool priv_push_front_simple_available() const
2497    {
2498       return this->members_.m_map &&
2499          (this->members_.m_start.m_cur != this->members_.m_start.get_first());
2500    }
2501 
2502    inline T *priv_push_front_simple_pos() const
2503    {  return boost::movelib::to_raw_pointer(this->members_.m_start.m_cur) - 1;  }
2504 
2505    inline void priv_push_front_simple_commit()
2506    {  --this->members_.m_start.m_cur;   }
2507 
2508    void priv_destroy_range(iterator p, iterator p2)
2509    {
2510       (void)p; (void)p2;
2511       BOOST_IF_CONSTEXPR(!Base::traits_t::trivial_dctr){
2512          for(;p != p2; ++p){
2513             allocator_traits_type::destroy(this->alloc(), boost::movelib::iterator_to_raw_pointer(p));
2514          }
2515       }
2516    }
2517 
2518    void priv_destroy_range(pointer p, pointer p2)
2519    {
2520       (void)p; (void)p2;
2521       BOOST_IF_CONSTEXPR(!Base::traits_t::trivial_dctr){
2522          for(;p != p2; ++p){
2523             allocator_traits_type::destroy(this->alloc(), boost::movelib::iterator_to_raw_pointer(p));
2524          }
2525       }
2526    }
2527 
2528    template<class InsertProxy>
2529    iterator priv_insert_middle_aux_impl(const_iterator p, const size_type elemsbefore, const size_type length, const size_type n, InsertProxy proxy)
2530    {
2531       if (!this->members_.m_map) {
2532          this->priv_initialize_map(0);
2533          p = this->cbegin();
2534       }
2535 
2536       iterator pos(p.unconst());
2537       const size_type pos_n = size_type(p - this->cbegin());
2538 
2539       if (elemsbefore < length / 2) {
2540          const iterator new_start = this->priv_reserve_elements_at_front(n);
2541          const iterator old_start = this->members_.m_start;
2542          pos = this->members_.m_start + difference_type(elemsbefore);
2543          if (elemsbefore >= n) {
2544             const iterator start_n = this->members_.m_start + difference_type(n);
2545             BOOST_CONTAINER_TRY {
2546                ::boost::container::uninitialized_move_alloc
2547                   (this->alloc(), this->members_.m_start, start_n, new_start);
2548             }
2549             BOOST_CONTAINER_CATCH(...) {
2550                this->priv_destroy_nodes(new_start.m_node, this->members_.m_start.m_node);
2551                BOOST_CONTAINER_RETHROW
2552             }
2553             BOOST_CONTAINER_CATCH_END
2554             this->members_.m_start = new_start;
2555             boost::container::move(start_n, pos, old_start);
2556             proxy.copy_n_and_update(this->alloc(), pos - difference_type(n), n);
2557          }
2558          else {
2559             const size_type mid_count = n - elemsbefore;
2560             const iterator mid_start = old_start - difference_type(mid_count);
2561             BOOST_CONTAINER_TRY {
2562                proxy.uninitialized_copy_n_and_update(this->alloc(), mid_start, mid_count);
2563                this->members_.m_start = mid_start;
2564                ::boost::container::uninitialized_move_alloc(this->alloc(), old_start, pos, new_start);
2565             }
2566             BOOST_CONTAINER_CATCH(...) {
2567                this->priv_destroy_nodes(new_start.m_node, this->members_.m_start.m_node);
2568                BOOST_CONTAINER_RETHROW
2569             }
2570             BOOST_CONTAINER_CATCH_END
2571             this->members_.m_start = new_start;
2572             proxy.copy_n_and_update(this->alloc(), old_start, elemsbefore);
2573          }
2574       }
2575       else {
2576          const iterator new_finish = this->priv_reserve_elements_at_back(n);
2577          const iterator old_finish = this->members_.m_finish;
2578          const size_type elemsafter = length - elemsbefore;
2579 
2580          pos = old_finish - difference_type(elemsafter);
2581          if (elemsafter >= n) {
2582             iterator finish_n = old_finish - difference_type(n);
2583             BOOST_CONTAINER_TRY {
2584                ::boost::container::uninitialized_move_alloc(this->alloc(), finish_n, old_finish, old_finish);
2585             }
2586             BOOST_CONTAINER_CATCH(...) {
2587                this->priv_destroy_nodes(this->members_.m_finish.m_node + 1, new_finish.m_node + 1);
2588                BOOST_CONTAINER_RETHROW
2589             }
2590             BOOST_CONTAINER_CATCH_END
2591 
2592             this->members_.m_finish = new_finish;
2593             boost::container::move_backward(pos, finish_n, old_finish);
2594             proxy.copy_n_and_update(this->alloc(), pos, n);
2595          }
2596          else {
2597             const size_type raw_gap = n - elemsafter;
2598             BOOST_CONTAINER_TRY{
2599                ::boost::container::uninitialized_move_alloc
2600                   (this->alloc(), pos, old_finish, old_finish + difference_type(raw_gap));
2601                BOOST_CONTAINER_TRY{
2602                   proxy.copy_n_and_update(this->alloc(), pos, elemsafter);
2603                   proxy.uninitialized_copy_n_and_update(this->alloc(), old_finish, raw_gap);
2604                }
2605                BOOST_CONTAINER_CATCH(...) {
2606                   this->priv_destroy_range(old_finish, old_finish + difference_type(elemsafter));
2607                   BOOST_CONTAINER_RETHROW
2608                }
2609                BOOST_CONTAINER_CATCH_END
2610             }
2611             BOOST_CONTAINER_CATCH(...) {
2612                this->priv_destroy_nodes(this->members_.m_finish.m_node + 1, new_finish.m_node + 1);
2613                BOOST_CONTAINER_RETHROW
2614             }
2615             BOOST_CONTAINER_CATCH_END
2616             this->members_.m_finish = new_finish;
2617          }
2618       }
2619       return this->begin() + difference_type(pos_n);
2620    }
2621 
2622    template<class InsertProxy>
2623    iterator priv_insert_aux_impl(const_iterator p, size_type n, InsertProxy proxy)
2624    {
2625       iterator pos(p.unconst());
2626       const size_type elemsbefore = static_cast<size_type>(pos - this->members_.m_start);
2627       const size_type length = this->size();
2628 
2629       if (!elemsbefore) {
2630          return this->priv_insert_front_aux_impl(n, proxy);
2631       }
2632       else if (elemsbefore == length) {
2633          return this->priv_insert_back_aux_impl(n, proxy);
2634       }
2635       else {
2636          return this->priv_insert_middle_aux_impl(p, elemsbefore, length, n, proxy);
2637       }
2638    }
2639 
2640    template <class InsertProxy>
2641    iterator priv_insert_back_aux_impl(size_type n, InsertProxy proxy)
2642    {
2643       if(!this->members_.m_map){
2644          this->priv_initialize_map(0);
2645       }
2646 
2647       iterator new_finish = this->priv_reserve_elements_at_back(n);
2648       BOOST_CONTAINER_TRY{
2649          proxy.uninitialized_copy_n_and_update(this->alloc(), this->members_.m_finish, n);
2650       }
2651       BOOST_CONTAINER_CATCH(...) {
2652          this->priv_destroy_nodes(this->members_.m_finish.m_node + 1, new_finish.m_node + 1);
2653          BOOST_CONTAINER_RETHROW
2654       }
2655       BOOST_CONTAINER_CATCH_END
2656       this->members_.m_finish = new_finish;
2657       return iterator(this->members_.m_finish - difference_type(n));
2658    }
2659 
2660    template <class InsertProxy>
2661    iterator priv_insert_front_aux_impl(size_type n, InsertProxy proxy)
2662    {
2663       if(!this->members_.m_map){
2664          this->priv_initialize_map(0);
2665       }
2666 
2667       iterator new_start = this->priv_reserve_elements_at_front(n);
2668       BOOST_CONTAINER_TRY{
2669          proxy.uninitialized_copy_n_and_update(this->alloc(), new_start, n);
2670       }
2671       BOOST_CONTAINER_CATCH(...) {
2672          this->priv_destroy_nodes(new_start.m_node, this->members_.m_start.m_node);
2673          BOOST_CONTAINER_RETHROW
2674       }
2675       BOOST_CONTAINER_CATCH_END
2676 
2677       this->members_.m_start = new_start;
2678       return new_start;
2679    }
2680 
2681    inline iterator priv_fill_insert(const_iterator pos, size_type n, const value_type& x)
2682    {
2683       return this->insert(pos, c_it(x, n), c_it());
2684    }
2685 
2686    // Precondition: this->members_.m_start and this->members_.m_finish have already been initialized,
2687    // but none of the deque's elements have yet been constructed.
2688    void priv_fill_initialize(const value_type& value)
2689    {
2690       index_pointer cur = this->members_.m_start.m_node;
2691       BOOST_CONTAINER_TRY {
2692          for ( ; cur < this->members_.m_finish.m_node; ++cur){
2693             boost::container::uninitialized_fill_alloc
2694                (this->alloc(), *cur, *cur + get_block_ssize(), value);
2695          }
2696          boost::container::uninitialized_fill_alloc
2697             (this->alloc(), this->members_.m_finish.get_first(), this->members_.m_finish.m_cur, value);
2698       }
2699       BOOST_CONTAINER_CATCH(...){
2700          this->priv_destroy_range(this->members_.m_start, iterator(*cur, cur, get_block_size()));
2701          BOOST_CONTAINER_RETHROW
2702       }
2703       BOOST_CONTAINER_CATCH_END
2704    }
2705 
2706    template <class InIt>
2707    void priv_range_initialize(InIt first, InIt last, typename iterator_enable_if_tag<InIt, std::input_iterator_tag>::type* =0)
2708    {
2709       this->priv_initialize_map(0);
2710       BOOST_CONTAINER_TRY {
2711          for ( ; first != last; ++first)
2712             this->emplace_back(*first);
2713       }
2714       BOOST_CONTAINER_CATCH(...){
2715          this->clear();
2716          BOOST_CONTAINER_RETHROW
2717       }
2718       BOOST_CONTAINER_CATCH_END
2719    }
2720 
2721    template <class FwdIt>
2722    void priv_range_initialize(FwdIt first, FwdIt last, typename iterator_disable_if_tag<FwdIt, std::input_iterator_tag>::type* =0)
2723    {
2724       size_type n = 0;
2725       n = boost::container::iterator_udistance(first, last);
2726       this->priv_initialize_map(n);
2727 
2728       index_pointer cur_node = this->members_.m_start.m_node;
2729       BOOST_CONTAINER_TRY {
2730          for (; cur_node < this->members_.m_finish.m_node; ++cur_node) {
2731             FwdIt mid = first;
2732             boost::container::iterator_uadvance(mid, get_block_size());
2733             ::boost::container::uninitialized_copy_alloc(this->alloc(), first, mid, *cur_node);
2734             first = mid;
2735          }
2736          ::boost::container::uninitialized_copy_alloc(this->alloc(), first, last, this->members_.m_finish.get_first());
2737       }
2738       BOOST_CONTAINER_CATCH(...){
2739          this->priv_destroy_range(this->members_.m_start, iterator(*cur_node, cur_node, get_block_size()));
2740          BOOST_CONTAINER_RETHROW
2741       }
2742       BOOST_CONTAINER_CATCH_END
2743    }
2744 
2745    // Called only if this->members_.m_finish.m_cur == this->members_.m_finish.get_first().
2746    void priv_pop_back_aux() BOOST_NOEXCEPT_OR_NOTHROW
2747    {
2748       this->priv_deallocate_node(this->members_.m_finish.get_first());
2749       this->members_.m_finish.priv_set_node(this->members_.m_finish.m_node - 1, get_block_size());
2750       this->members_.m_finish.m_cur = this->members_.m_finish.get_last() - 1;
2751       allocator_traits_type::destroy
2752          ( this->alloc()
2753          , boost::movelib::to_raw_pointer(this->members_.m_finish.m_cur)
2754          );
2755    }
2756 
2757    // Called only if this->members_.m_start.m_cur == this->members_.m_start.get_last() - 1.  Note that
2758    // if the deque has at least one element (a precondition for this member
2759    // function), and if this->members_.m_start.m_cur == this->members_.m_start.get_last(), then the deque
2760    // must have at least two nodes.
2761    void priv_pop_front_aux() BOOST_NOEXCEPT_OR_NOTHROW
2762    {
2763       allocator_traits_type::destroy
2764          ( this->alloc()
2765          , boost::movelib::to_raw_pointer(this->members_.m_start.m_cur)
2766          );
2767       this->priv_deallocate_node(this->members_.m_start.get_first());
2768       this->members_.m_start.priv_set_node(this->members_.m_start.m_node + 1, get_block_size());
2769       this->members_.m_start.m_cur = this->members_.m_start.get_first();
2770    }
2771 
2772    iterator priv_reserve_elements_at_front(size_type n)
2773    {
2774       size_type vacancies = size_type(this->members_.m_start.m_cur - this->members_.m_start.get_first());
2775       if (n > vacancies){
2776          size_type new_elems = n-vacancies;
2777          size_type new_nodes = (new_elems + get_block_size() - 1u) / get_block_size();
2778          size_type s = (size_type)(this->members_.m_start.m_node - this->members_.m_map);
2779          if (new_nodes > s){
2780             this->priv_reallocate_map(new_nodes, true);
2781          }
2782          size_type i = 1;
2783          BOOST_CONTAINER_TRY {
2784             for (; i <= new_nodes; ++i)
2785                *(this->members_.m_start.m_node - difference_type(i)) = this->priv_allocate_node();
2786          }
2787          BOOST_CONTAINER_CATCH(...) {
2788             for (size_type j = 1; j < i; ++j)
2789                this->priv_deallocate_node(*(this->members_.m_start.m_node - difference_type(j)));
2790             BOOST_CONTAINER_RETHROW
2791          }
2792          BOOST_CONTAINER_CATCH_END
2793       }
2794       return this->members_.m_start - difference_type(n);
2795    }
2796 
2797    iterator priv_reserve_elements_at_back(size_type n)
2798    {
2799       size_type vacancies = size_type(this->members_.m_finish.get_last() - this->members_.m_finish.m_cur - 1);
2800       if (n > vacancies){
2801          size_type new_elems = size_type(n - vacancies);
2802          size_type new_nodes = size_type(new_elems + get_block_size() - 1u)/get_block_size();
2803          size_type s = (size_type)(this->members_.m_map_size - size_type(this->members_.m_finish.m_node - this->members_.m_map));
2804          if (new_nodes + 1 > s){
2805             this->priv_reallocate_map(new_nodes, false);
2806          }
2807          size_type i = 1;
2808          BOOST_CONTAINER_TRY {
2809             for (; i <= new_nodes; ++i)
2810                *(this->members_.m_finish.m_node + difference_type(i)) = this->priv_allocate_node();
2811          }
2812          BOOST_CONTAINER_CATCH(...) {
2813             for (size_type j = 1; j < i; ++j)
2814                this->priv_deallocate_node(*(this->members_.m_finish.m_node + difference_type(j)));
2815             BOOST_CONTAINER_RETHROW
2816          }
2817          BOOST_CONTAINER_CATCH_END
2818       }
2819       return this->members_.m_finish + difference_type(n);
2820    }
2821 
2822    void priv_reallocate_map(size_type nodes_to_add, bool add_at_front)
2823    {
2824       size_type old_num_nodes = size_type(this->members_.m_finish.m_node - this->members_.m_start.m_node + 1);
2825       size_type new_num_nodes = old_num_nodes + nodes_to_add;
2826 
2827       index_pointer new_nstart;
2828       if (this->members_.m_map_size > 2 * new_num_nodes) {
2829          new_nstart = this->members_.m_map + difference_type(this->members_.m_map_size - new_num_nodes) / 2
2830                            + difference_type(add_at_front ? nodes_to_add : 0u);
2831          if (new_nstart < this->members_.m_start.m_node)
2832             boost::container::move(this->members_.m_start.m_node, this->members_.m_finish.m_node + 1, new_nstart);
2833          else
2834             boost::container::move_backward
2835                (this->members_.m_start.m_node, this->members_.m_finish.m_node + 1, new_nstart + difference_type(old_num_nodes));
2836       }
2837       else {
2838          size_type new_map_size =
2839             this->members_.m_map_size + dtl::max_value(this->members_.m_map_size, nodes_to_add) + 2;
2840 
2841          index_pointer new_map = this->priv_allocate_map(new_map_size);
2842          new_nstart = new_map + difference_type(new_map_size - new_num_nodes) / 2
2843                               + difference_type(add_at_front ? nodes_to_add : 0u);
2844          boost::container::move(this->members_.m_start.m_node, this->members_.m_finish.m_node + 1, new_nstart);
2845          this->priv_deallocate_map(this->members_.m_map, this->members_.m_map_size);
2846 
2847          this->members_.m_map = new_map;
2848          this->members_.m_map_size = new_map_size;
2849       }
2850 
2851       this->members_.m_start.priv_set_node(new_nstart, get_block_size());
2852       this->members_.m_finish.priv_set_node(new_nstart + difference_type(old_num_nodes - 1u), get_block_size());
2853    }
2854    #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
2855 };
2856 
2857 #ifndef BOOST_CONTAINER_NO_CXX17_CTAD
2858 template <typename InputIterator>
2859 deque(InputIterator, InputIterator) -> deque<typename iterator_traits<InputIterator>::value_type>;
2860 template <typename InputIterator, typename Allocator>
2861 deque(InputIterator, InputIterator, Allocator const&) -> deque<typename iterator_traits<InputIterator>::value_type, Allocator>;
2862 #endif
2863 
2864 }  //namespace container
2865 }  //namespace boost
2866 
2867 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
2868 
2869 namespace boost {
2870 
2871 //!has_trivial_destructor_after_move<> == true_type
2872 //!specialization for optimizations
2873 template <class T, class Allocator, class Options>
2874 struct has_trivial_destructor_after_move<boost::container::deque<T, Allocator, Options> >
2875 {
2876    typedef typename boost::container::deque<T, Allocator, Options>::allocator_type allocator_type;
2877    typedef typename ::boost::container::allocator_traits<allocator_type>::pointer pointer;
2878    BOOST_STATIC_CONSTEXPR bool value = ::boost::has_trivial_destructor_after_move<allocator_type>::value &&
2879                              ::boost::has_trivial_destructor_after_move<pointer>::value;
2880 };
2881 
2882 }
2883 
2884 #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
2885 
2886 #include <boost/container/detail/config_end.hpp>
2887 
2888 #endif //   #ifndef  BOOST_CONTAINER_DEQUE_HPP