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