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