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
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
1030
1031
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
1039
1040 using Base::get_block_ssize;
1041
1042 public:
1043
1044 using Base::get_block_size;
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058 inline deque()
1059 BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible<ValAllocator>::value)
1060 : Base()
1061 {}
1062
1063
1064
1065
1066
1067
1068 inline explicit deque(const allocator_type& a) BOOST_NOEXCEPT_OR_NOTHROW
1069 : Base(a)
1070 {}
1071
1072
1073
1074
1075
1076
1077
1078
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
1085 }
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
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
1102 }
1103
1104
1105
1106
1107
1108
1109
1110
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
1117 }
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
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
1134 }
1135
1136
1137
1138
1139
1140
1141
1142
1143 inline deque(size_type n, const value_type& value)
1144 : Base(n, allocator_type())
1145 { this->priv_fill_initialize(value); }
1146
1147
1148
1149
1150
1151
1152
1153
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
1159
1160
1161
1162
1163
1164
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
1178
1179
1180
1181
1182
1183
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
1198
1199
1200
1201
1202
1203
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
1212
1213
1214
1215
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
1227
1228
1229
1230
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
1236
1237
1238
1239
1240
1241
1242
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
1254
1255
1256
1257
1258
1259
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
1277
1278
1279
1280
1281
1282 inline ~deque() BOOST_NOEXCEPT_OR_NOTHROW
1283 {
1284 this->priv_destroy_range(this->members_.m_start, this->members_.m_finish);
1285 }
1286
1287
1288
1289
1290
1291
1292
1293
1294
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
1314
1315
1316
1317
1318
1319
1320
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
1327
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
1339
1340
1341
1342
1343
1344
1345
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
1354
1355
1356
1357
1358 inline void assign(size_type n, const T& val)
1359 {
1360 this->assign(c_it(val, n), c_it());
1361 }
1362
1363
1364
1365
1366
1367
1368
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
1417
1418
1419
1420
1421
1422 inline void assign(std::initializer_list<value_type> il)
1423 { this->assign(il.begin(), il.end()); }
1424 #endif
1425
1426
1427
1428
1429
1430
1431 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
1432 allocator_type get_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
1433 { return Base::alloc(); }
1434
1435
1436
1437
1438
1439
1440
1441
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
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
1460 stored_allocator_type &get_stored_allocator() BOOST_NOEXCEPT_OR_NOTHROW
1461 { return Base::alloc(); }
1462
1463
1464
1465
1466
1467
1468 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
1469 iterator begin() BOOST_NOEXCEPT_OR_NOTHROW
1470 { return this->members_.m_start; }
1471
1472
1473
1474
1475
1476
1477 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
1478 const_iterator begin() const BOOST_NOEXCEPT_OR_NOTHROW
1479 { return this->members_.m_start; }
1480
1481
1482
1483
1484
1485
1486 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
1487 iterator end() BOOST_NOEXCEPT_OR_NOTHROW
1488 { return this->members_.m_finish; }
1489
1490
1491
1492
1493
1494
1495 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
1496 const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW
1497 { return this->members_.m_finish; }
1498
1499
1500
1501
1502
1503
1504
1505 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
1506 reverse_iterator rbegin() BOOST_NOEXCEPT_OR_NOTHROW
1507 { return reverse_iterator(this->members_.m_finish); }
1508
1509
1510
1511
1512
1513
1514
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
1520
1521
1522
1523
1524
1525 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
1526 reverse_iterator rend() BOOST_NOEXCEPT_OR_NOTHROW
1527 { return reverse_iterator(this->members_.m_start); }
1528
1529
1530
1531
1532
1533
1534
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
1540
1541
1542
1543
1544 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
1545 const_iterator cbegin() const BOOST_NOEXCEPT_OR_NOTHROW
1546 { return this->members_.m_start; }
1547
1548
1549
1550
1551
1552
1553 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
1554 const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW
1555 { return this->members_.m_finish; }
1556
1557
1558
1559
1560
1561
1562
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
1568
1569
1570
1571
1572
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
1580
1581
1582
1583
1584
1585
1586
1587
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
1593
1594
1595
1596
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
1602
1603
1604
1605
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
1611
1612
1613
1614
1615
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
1629
1630
1631
1632
1633
1634
1635
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
1649
1650
1651
1652
1653
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
1664
1665
1666
1667
1668
1669 void shrink_to_fit()
1670 {
1671
1672
1673
1674
1675 if(this->empty()){
1676 this->priv_clear_map();
1677 }
1678 }
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
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
1702
1703
1704
1705
1706
1707
1708
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
1717
1718
1719
1720
1721
1722
1723
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
1732
1733
1734
1735
1736
1737
1738
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
1747
1748
1749
1750
1751
1752
1753
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
1762
1763
1764
1765
1766
1767
1768
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
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
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
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
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
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
1823 size_type index_of(iterator p) BOOST_NOEXCEPT_OR_NOTHROW
1824 {
1825
1826 return this->priv_index_of(p);
1827 }
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
1840 size_type index_of(const_iterator p) const BOOST_NOEXCEPT_OR_NOTHROW
1841 {
1842
1843 return this->priv_index_of(p);
1844 }
1845
1846
1847
1848
1849
1850
1851
1852
1853
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
1862
1863
1864
1865
1866
1867
1868
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
1879
1880
1881
1882 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
1883
1884
1885
1886
1887
1888
1889
1890
1891
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
1911
1912
1913
1914
1915
1916
1917
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
1937
1938
1939
1940
1941
1942
1943
1944
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
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
2023
2024 #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
2025
2026
2027
2028
2029
2030
2031 void push_front(const T &x);
2032
2033
2034
2035
2036
2037
2038
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
2046
2047
2048
2049
2050
2051 void push_back(const T &x);
2052
2053
2054
2055
2056
2057
2058
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
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076 iterator insert(const_iterator p, const T &x);
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
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
2094
2095
2096
2097
2098
2099
2100
2101
2102 inline iterator insert(const_iterator pos, size_type n, const value_type& x)
2103 {
2104
2105 return this->insert(pos, c_it(x, n), c_it());
2106 }
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
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
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151 inline iterator insert(const_iterator pos, std::initializer_list<value_type> il)
2152 {
2153
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
2177
2178
2179
2180
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
2196
2197
2198
2199
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
2215
2216
2217
2218
2219
2220
2221
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
2240
2241
2242
2243
2244
2245
2246
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
2277
2278
2279
2280
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
2292
2293
2294
2295
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
2320
2321
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
2327
2328
2329 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
2330 friend bool operator!=(const deque& x, const deque& y)
2331 { return !(x == y); }
2332
2333
2334
2335
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
2341
2342
2343 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
2344 friend bool operator>(const deque& x, const deque& y)
2345 { return y < x; }
2346
2347
2348
2349
2350 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
2351 friend bool operator<=(const deque& x, const deque& y)
2352 { return !(y < x); }
2353
2354
2355
2356
2357 BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
2358 friend bool operator>=(const deque& x, const deque& y)
2359 { return !(x < y); }
2360
2361
2362
2363
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> )
2372 {
2373
2374 this->clear();
2375
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
2380 this->swap_members(x);
2381 }
2382
2383 void priv_move_assign(BOOST_RV_REF(deque) x, dtl::bool_<false> )
2384 {
2385
2386
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
2687
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
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
2758
2759
2760
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
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 }
2865 }
2866
2867 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
2868
2869 namespace boost {
2870
2871
2872
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
2885
2886 #include <boost/container/detail/config_end.hpp>
2887
2888 #endif