annotate DEPENDENCIES/generic/include/boost/container/deque.hpp @ 16:2665513ce2d3

Add boost headers
author Chris Cannam
date Tue, 05 Aug 2014 11:11:38 +0100
parents
children c530137014c0
rev   line source
Chris@16 1 //////////////////////////////////////////////////////////////////////////////
Chris@16 2 //
Chris@16 3 // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
Chris@16 4 // Software License, Version 1.0. (See accompanying file
Chris@16 5 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Chris@16 6 //
Chris@16 7 // See http://www.boost.org/libs/container for documentation.
Chris@16 8 //
Chris@16 9 //////////////////////////////////////////////////////////////////////////////
Chris@16 10
Chris@16 11 #ifndef BOOST_CONTAINER_DEQUE_HPP
Chris@16 12 #define BOOST_CONTAINER_DEQUE_HPP
Chris@16 13
Chris@16 14 #if defined(_MSC_VER)
Chris@16 15 # pragma once
Chris@16 16 #endif
Chris@16 17
Chris@16 18 #include <boost/container/detail/config_begin.hpp>
Chris@16 19 #include <boost/container/detail/workaround.hpp>
Chris@16 20
Chris@16 21 #include <boost/container/detail/utilities.hpp>
Chris@16 22 #include <boost/container/detail/iterators.hpp>
Chris@16 23 #include <boost/container/detail/algorithms.hpp>
Chris@16 24 #include <boost/container/detail/mpl.hpp>
Chris@16 25 #include <boost/container/allocator_traits.hpp>
Chris@16 26 #include <boost/container/container_fwd.hpp>
Chris@16 27 #include <boost/container/throw_exception.hpp>
Chris@16 28 #include <cstddef>
Chris@16 29 #include <iterator>
Chris@16 30 #include <boost/assert.hpp>
Chris@16 31 #include <memory>
Chris@16 32 #include <algorithm>
Chris@16 33 #include <boost/detail/no_exceptions_support.hpp>
Chris@16 34 #include <boost/type_traits/has_trivial_destructor.hpp>
Chris@16 35 #include <boost/type_traits/has_trivial_copy.hpp>
Chris@16 36 #include <boost/type_traits/has_trivial_assign.hpp>
Chris@16 37 #include <boost/type_traits/has_nothrow_copy.hpp>
Chris@16 38 #include <boost/type_traits/has_nothrow_assign.hpp>
Chris@16 39 #include <boost/move/utility.hpp>
Chris@16 40 #include <boost/move/iterator.hpp>
Chris@16 41 #include <boost/move/detail/move_helpers.hpp>
Chris@16 42 #include <boost/container/detail/advanced_insert_int.hpp>
Chris@16 43 #include <boost/detail/no_exceptions_support.hpp>
Chris@16 44
Chris@16 45 namespace boost {
Chris@16 46 namespace container {
Chris@16 47
Chris@16 48 /// @cond
Chris@16 49 #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
Chris@16 50 template <class T, class Allocator = std::allocator<T> >
Chris@16 51 #else
Chris@16 52 template <class T, class Allocator>
Chris@16 53 #endif
Chris@16 54 class deque;
Chris@16 55
Chris@16 56 template <class T>
Chris@16 57 struct deque_value_traits
Chris@16 58 {
Chris@16 59 typedef T value_type;
Chris@16 60 static const bool trivial_dctr = boost::has_trivial_destructor<value_type>::value;
Chris@16 61 static const bool trivial_dctr_after_move = ::boost::has_trivial_destructor_after_move<value_type>::value;
Chris@16 62 static const bool trivial_copy = has_trivial_copy<value_type>::value;
Chris@16 63 static const bool nothrow_copy = has_nothrow_copy<value_type>::value;
Chris@16 64 static const bool trivial_assign = has_trivial_assign<value_type>::value;
Chris@16 65 //static const bool nothrow_assign = has_nothrow_assign<value_type>::value;
Chris@16 66 static const bool nothrow_assign = false;
Chris@16 67 };
Chris@16 68
Chris@16 69 // Note: this function is simply a kludge to work around several compilers'
Chris@16 70 // bugs in handling constant expressions.
Chris@16 71 template<class T>
Chris@16 72 struct deque_buf_size
Chris@16 73 {
Chris@16 74 static const std::size_t min_size = 512u;
Chris@16 75 static const std::size_t sizeof_t = sizeof(T);
Chris@16 76 static const std::size_t value = sizeof_t < min_size ? (min_size/sizeof_t) : std::size_t(1);
Chris@16 77 };
Chris@16 78
Chris@16 79 namespace container_detail {
Chris@16 80
Chris@16 81 // Class invariants:
Chris@16 82 // For any nonsingular iterator i:
Chris@16 83 // i.node is the address of an element in the map array. The
Chris@16 84 // contents of i.node is a pointer to the beginning of a node.
Chris@16 85 // i.first == //(i.node)
Chris@16 86 // i.last == i.first + node_size
Chris@16 87 // i.cur is a pointer in the range [i.first, i.last). NOTE:
Chris@16 88 // the implication of this is that i.cur is always a dereferenceable
Chris@16 89 // pointer, even if i is a past-the-end iterator.
Chris@16 90 // Start and Finish are always nonsingular iterators. NOTE: this means
Chris@16 91 // that an empty deque must have one node, and that a deque
Chris@16 92 // with N elements, where N is the buffer size, must have two nodes.
Chris@16 93 // For every node other than start.node and finish.node, every element
Chris@16 94 // in the node is an initialized object. If start.node == finish.node,
Chris@16 95 // then [start.cur, finish.cur) are initialized objects, and
Chris@16 96 // the elements outside that range are uninitialized storage. Otherwise,
Chris@16 97 // [start.cur, start.last) and [finish.first, finish.cur) are initialized
Chris@16 98 // objects, and [start.first, start.cur) and [finish.cur, finish.last)
Chris@16 99 // are uninitialized storage.
Chris@16 100 // [map, map + map_size) is a valid, non-empty range.
Chris@16 101 // [start.node, finish.node] is a valid range contained within
Chris@16 102 // [map, map + map_size).
Chris@16 103 // Allocator pointer in the range [map, map + map_size) points to an allocated node
Chris@16 104 // if and only if the pointer is in the range [start.node, finish.node].
Chris@16 105 template<class Pointer, bool IsConst>
Chris@16 106 class deque_iterator
Chris@16 107 {
Chris@16 108 public:
Chris@16 109 typedef std::random_access_iterator_tag iterator_category;
Chris@16 110 typedef typename boost::intrusive::pointer_traits<Pointer>::element_type value_type;
Chris@16 111 typedef typename boost::intrusive::pointer_traits<Pointer>::difference_type difference_type;
Chris@16 112 typedef typename if_c
Chris@16 113 < IsConst
Chris@16 114 , typename boost::intrusive::pointer_traits<Pointer>::template
Chris@16 115 rebind_pointer<const value_type>::type
Chris@16 116 , Pointer
Chris@16 117 >::type pointer;
Chris@16 118 typedef typename if_c
Chris@16 119 < IsConst
Chris@16 120 , const value_type&
Chris@16 121 , value_type&
Chris@16 122 >::type reference;
Chris@16 123
Chris@16 124 static std::size_t s_buffer_size()
Chris@16 125 { return deque_buf_size<value_type>::value; }
Chris@16 126
Chris@16 127 typedef Pointer val_alloc_ptr;
Chris@16 128 typedef typename boost::intrusive::pointer_traits<Pointer>::
Chris@16 129 template rebind_pointer<Pointer>::type index_pointer;
Chris@16 130
Chris@16 131 Pointer m_cur;
Chris@16 132 Pointer m_first;
Chris@16 133 Pointer m_last;
Chris@16 134 index_pointer m_node;
Chris@16 135
Chris@16 136 public:
Chris@16 137
Chris@16 138 Pointer get_cur() const { return m_cur; }
Chris@16 139 Pointer get_first() const { return m_first; }
Chris@16 140 Pointer get_last() const { return m_last; }
Chris@16 141 index_pointer get_node() const { return m_node; }
Chris@16 142
Chris@16 143 deque_iterator(val_alloc_ptr x, index_pointer y) BOOST_CONTAINER_NOEXCEPT
Chris@16 144 : m_cur(x), m_first(*y), m_last(*y + s_buffer_size()), m_node(y)
Chris@16 145 {}
Chris@16 146
Chris@16 147 deque_iterator() BOOST_CONTAINER_NOEXCEPT
Chris@16 148 : m_cur(), m_first(), m_last(), m_node()
Chris@16 149 {}
Chris@16 150
Chris@16 151 deque_iterator(deque_iterator<Pointer, false> const& x) BOOST_CONTAINER_NOEXCEPT
Chris@16 152 : m_cur(x.get_cur()), m_first(x.get_first()), m_last(x.get_last()), m_node(x.get_node())
Chris@16 153 {}
Chris@16 154
Chris@16 155 deque_iterator(Pointer cur, Pointer first, Pointer last, index_pointer node) BOOST_CONTAINER_NOEXCEPT
Chris@16 156 : m_cur(cur), m_first(first), m_last(last), m_node(node)
Chris@16 157 {}
Chris@16 158
Chris@16 159 deque_iterator<Pointer, false> unconst() const BOOST_CONTAINER_NOEXCEPT
Chris@16 160 {
Chris@16 161 return deque_iterator<Pointer, false>(this->get_cur(), this->get_first(), this->get_last(), this->get_node());
Chris@16 162 }
Chris@16 163
Chris@16 164 reference operator*() const BOOST_CONTAINER_NOEXCEPT
Chris@16 165 { return *this->m_cur; }
Chris@16 166
Chris@16 167 pointer operator->() const BOOST_CONTAINER_NOEXCEPT
Chris@16 168 { return this->m_cur; }
Chris@16 169
Chris@16 170 difference_type operator-(const deque_iterator& x) const BOOST_CONTAINER_NOEXCEPT
Chris@16 171 {
Chris@16 172 if(!this->m_cur && !x.m_cur){
Chris@16 173 return 0;
Chris@16 174 }
Chris@16 175 return difference_type(this->s_buffer_size()) * (this->m_node - x.m_node - 1) +
Chris@16 176 (this->m_cur - this->m_first) + (x.m_last - x.m_cur);
Chris@16 177 }
Chris@16 178
Chris@16 179 deque_iterator& operator++() BOOST_CONTAINER_NOEXCEPT
Chris@16 180 {
Chris@16 181 ++this->m_cur;
Chris@16 182 if (this->m_cur == this->m_last) {
Chris@16 183 this->priv_set_node(this->m_node + 1);
Chris@16 184 this->m_cur = this->m_first;
Chris@16 185 }
Chris@16 186 return *this;
Chris@16 187 }
Chris@16 188
Chris@16 189 deque_iterator operator++(int) BOOST_CONTAINER_NOEXCEPT
Chris@16 190 {
Chris@16 191 deque_iterator tmp(*this);
Chris@16 192 ++*this;
Chris@16 193 return tmp;
Chris@16 194 }
Chris@16 195
Chris@16 196 deque_iterator& operator--() BOOST_CONTAINER_NOEXCEPT
Chris@16 197 {
Chris@16 198 if (this->m_cur == this->m_first) {
Chris@16 199 this->priv_set_node(this->m_node - 1);
Chris@16 200 this->m_cur = this->m_last;
Chris@16 201 }
Chris@16 202 --this->m_cur;
Chris@16 203 return *this;
Chris@16 204 }
Chris@16 205
Chris@16 206 deque_iterator operator--(int) BOOST_CONTAINER_NOEXCEPT
Chris@16 207 {
Chris@16 208 deque_iterator tmp(*this);
Chris@16 209 --*this;
Chris@16 210 return tmp;
Chris@16 211 }
Chris@16 212
Chris@16 213 deque_iterator& operator+=(difference_type n) BOOST_CONTAINER_NOEXCEPT
Chris@16 214 {
Chris@16 215 difference_type offset = n + (this->m_cur - this->m_first);
Chris@16 216 if (offset >= 0 && offset < difference_type(this->s_buffer_size()))
Chris@16 217 this->m_cur += n;
Chris@16 218 else {
Chris@16 219 difference_type node_offset =
Chris@16 220 offset > 0 ? offset / difference_type(this->s_buffer_size())
Chris@16 221 : -difference_type((-offset - 1) / this->s_buffer_size()) - 1;
Chris@16 222 this->priv_set_node(this->m_node + node_offset);
Chris@16 223 this->m_cur = this->m_first +
Chris@16 224 (offset - node_offset * difference_type(this->s_buffer_size()));
Chris@16 225 }
Chris@16 226 return *this;
Chris@16 227 }
Chris@16 228
Chris@16 229 deque_iterator operator+(difference_type n) const BOOST_CONTAINER_NOEXCEPT
Chris@16 230 { deque_iterator tmp(*this); return tmp += n; }
Chris@16 231
Chris@16 232 deque_iterator& operator-=(difference_type n) BOOST_CONTAINER_NOEXCEPT
Chris@16 233 { return *this += -n; }
Chris@16 234
Chris@16 235 deque_iterator operator-(difference_type n) const BOOST_CONTAINER_NOEXCEPT
Chris@16 236 { deque_iterator tmp(*this); return tmp -= n; }
Chris@16 237
Chris@16 238 reference operator[](difference_type n) const BOOST_CONTAINER_NOEXCEPT
Chris@16 239 { return *(*this + n); }
Chris@16 240
Chris@16 241 friend bool operator==(const deque_iterator& l, const deque_iterator& r) BOOST_CONTAINER_NOEXCEPT
Chris@16 242 { return l.m_cur == r.m_cur; }
Chris@16 243
Chris@16 244 friend bool operator!=(const deque_iterator& l, const deque_iterator& r) BOOST_CONTAINER_NOEXCEPT
Chris@16 245 { return l.m_cur != r.m_cur; }
Chris@16 246
Chris@16 247 friend bool operator<(const deque_iterator& l, const deque_iterator& r) BOOST_CONTAINER_NOEXCEPT
Chris@16 248 { return (l.m_node == r.m_node) ? (l.m_cur < r.m_cur) : (l.m_node < r.m_node); }
Chris@16 249
Chris@16 250 friend bool operator>(const deque_iterator& l, const deque_iterator& r) BOOST_CONTAINER_NOEXCEPT
Chris@16 251 { return r < l; }
Chris@16 252
Chris@16 253 friend bool operator<=(const deque_iterator& l, const deque_iterator& r) BOOST_CONTAINER_NOEXCEPT
Chris@16 254 { return !(r < l); }
Chris@16 255
Chris@16 256 friend bool operator>=(const deque_iterator& l, const deque_iterator& r) BOOST_CONTAINER_NOEXCEPT
Chris@16 257 { return !(l < r); }
Chris@16 258
Chris@16 259 void priv_set_node(index_pointer new_node) BOOST_CONTAINER_NOEXCEPT
Chris@16 260 {
Chris@16 261 this->m_node = new_node;
Chris@16 262 this->m_first = *new_node;
Chris@16 263 this->m_last = this->m_first + this->s_buffer_size();
Chris@16 264 }
Chris@16 265
Chris@16 266 friend deque_iterator operator+(difference_type n, deque_iterator x) BOOST_CONTAINER_NOEXCEPT
Chris@16 267 { return x += n; }
Chris@16 268 };
Chris@16 269
Chris@16 270 } //namespace container_detail {
Chris@16 271
Chris@16 272 // Deque base class. It has two purposes. First, its constructor
Chris@16 273 // and destructor allocate (but don't initialize) storage. This makes
Chris@16 274 // exception safety easier.
Chris@16 275 template <class Allocator>
Chris@16 276 class deque_base
Chris@16 277 {
Chris@16 278 BOOST_COPYABLE_AND_MOVABLE(deque_base)
Chris@16 279 public:
Chris@16 280 typedef allocator_traits<Allocator> val_alloc_traits_type;
Chris@16 281 typedef typename val_alloc_traits_type::value_type val_alloc_val;
Chris@16 282 typedef typename val_alloc_traits_type::pointer val_alloc_ptr;
Chris@16 283 typedef typename val_alloc_traits_type::const_pointer val_alloc_cptr;
Chris@16 284 typedef typename val_alloc_traits_type::reference val_alloc_ref;
Chris@16 285 typedef typename val_alloc_traits_type::const_reference val_alloc_cref;
Chris@16 286 typedef typename val_alloc_traits_type::difference_type val_alloc_diff;
Chris@16 287 typedef typename val_alloc_traits_type::size_type val_alloc_size;
Chris@16 288 typedef typename val_alloc_traits_type::template
Chris@16 289 portable_rebind_alloc<val_alloc_ptr>::type ptr_alloc_t;
Chris@16 290 typedef allocator_traits<ptr_alloc_t> ptr_alloc_traits_type;
Chris@16 291 typedef typename ptr_alloc_traits_type::value_type ptr_alloc_val;
Chris@16 292 typedef typename ptr_alloc_traits_type::pointer ptr_alloc_ptr;
Chris@16 293 typedef typename ptr_alloc_traits_type::const_pointer ptr_alloc_cptr;
Chris@16 294 typedef typename ptr_alloc_traits_type::reference ptr_alloc_ref;
Chris@16 295 typedef typename ptr_alloc_traits_type::const_reference ptr_alloc_cref;
Chris@16 296 typedef Allocator allocator_type;
Chris@16 297 typedef allocator_type stored_allocator_type;
Chris@16 298 typedef val_alloc_size size_type;
Chris@16 299
Chris@16 300 protected:
Chris@16 301
Chris@16 302 typedef deque_value_traits<val_alloc_val> traits_t;
Chris@16 303 typedef ptr_alloc_t map_allocator_type;
Chris@16 304
Chris@16 305 static size_type s_buffer_size() BOOST_CONTAINER_NOEXCEPT
Chris@16 306 { return deque_buf_size<val_alloc_val>::value; }
Chris@16 307
Chris@16 308 val_alloc_ptr priv_allocate_node()
Chris@16 309 { return this->alloc().allocate(s_buffer_size()); }
Chris@16 310
Chris@16 311 void priv_deallocate_node(val_alloc_ptr p) BOOST_CONTAINER_NOEXCEPT
Chris@16 312 { this->alloc().deallocate(p, s_buffer_size()); }
Chris@16 313
Chris@16 314 ptr_alloc_ptr priv_allocate_map(size_type n)
Chris@16 315 { return this->ptr_alloc().allocate(n); }
Chris@16 316
Chris@16 317 void priv_deallocate_map(ptr_alloc_ptr p, size_type n) BOOST_CONTAINER_NOEXCEPT
Chris@16 318 { this->ptr_alloc().deallocate(p, n); }
Chris@16 319
Chris@16 320 typedef container_detail::deque_iterator<val_alloc_ptr, false> iterator;
Chris@16 321 typedef container_detail::deque_iterator<val_alloc_ptr, true > const_iterator;
Chris@16 322
Chris@16 323 deque_base(size_type num_elements, const allocator_type& a)
Chris@16 324 : members_(a)
Chris@16 325 { this->priv_initialize_map(num_elements); }
Chris@16 326
Chris@16 327 explicit deque_base(const allocator_type& a)
Chris@16 328 : members_(a)
Chris@16 329 {}
Chris@16 330
Chris@16 331 deque_base()
Chris@16 332 : members_()
Chris@16 333 {}
Chris@16 334
Chris@16 335 explicit deque_base(BOOST_RV_REF(deque_base) x)
Chris@16 336 : members_( boost::move(x.ptr_alloc())
Chris@16 337 , boost::move(x.alloc()) )
Chris@16 338 {}
Chris@16 339
Chris@16 340 ~deque_base()
Chris@16 341 {
Chris@16 342 if (this->members_.m_map) {
Chris@16 343 this->priv_destroy_nodes(this->members_.m_start.m_node, this->members_.m_finish.m_node + 1);
Chris@16 344 this->priv_deallocate_map(this->members_.m_map, this->members_.m_map_size);
Chris@16 345 }
Chris@16 346 }
Chris@16 347
Chris@16 348 private:
Chris@16 349 deque_base(const deque_base&);
Chris@16 350
Chris@16 351 protected:
Chris@16 352
Chris@16 353 void swap_members(deque_base &x) BOOST_CONTAINER_NOEXCEPT
Chris@16 354 {
Chris@16 355 std::swap(this->members_.m_start, x.members_.m_start);
Chris@16 356 std::swap(this->members_.m_finish, x.members_.m_finish);
Chris@16 357 std::swap(this->members_.m_map, x.members_.m_map);
Chris@16 358 std::swap(this->members_.m_map_size, x.members_.m_map_size);
Chris@16 359 }
Chris@16 360
Chris@16 361 void priv_initialize_map(size_type num_elements)
Chris@16 362 {
Chris@16 363 // if(num_elements){
Chris@16 364 size_type num_nodes = num_elements / s_buffer_size() + 1;
Chris@16 365
Chris@16 366 this->members_.m_map_size = container_detail::max_value((size_type) InitialMapSize, num_nodes + 2);
Chris@16 367 this->members_.m_map = this->priv_allocate_map(this->members_.m_map_size);
Chris@16 368
Chris@16 369 ptr_alloc_ptr nstart = this->members_.m_map + (this->members_.m_map_size - num_nodes) / 2;
Chris@16 370 ptr_alloc_ptr nfinish = nstart + num_nodes;
Chris@16 371
Chris@16 372 BOOST_TRY {
Chris@16 373 this->priv_create_nodes(nstart, nfinish);
Chris@16 374 }
Chris@16 375 BOOST_CATCH(...){
Chris@16 376 this->priv_deallocate_map(this->members_.m_map, this->members_.m_map_size);
Chris@16 377 this->members_.m_map = 0;
Chris@16 378 this->members_.m_map_size = 0;
Chris@16 379 BOOST_RETHROW
Chris@16 380 }
Chris@16 381 BOOST_CATCH_END
Chris@16 382
Chris@16 383 this->members_.m_start.priv_set_node(nstart);
Chris@16 384 this->members_.m_finish.priv_set_node(nfinish - 1);
Chris@16 385 this->members_.m_start.m_cur = this->members_.m_start.m_first;
Chris@16 386 this->members_.m_finish.m_cur = this->members_.m_finish.m_first +
Chris@16 387 num_elements % s_buffer_size();
Chris@16 388 // }
Chris@16 389 }
Chris@16 390
Chris@16 391 void priv_create_nodes(ptr_alloc_ptr nstart, ptr_alloc_ptr nfinish)
Chris@16 392 {
Chris@16 393 ptr_alloc_ptr cur;
Chris@16 394 BOOST_TRY {
Chris@16 395 for (cur = nstart; cur < nfinish; ++cur)
Chris@16 396 *cur = this->priv_allocate_node();
Chris@16 397 }
Chris@16 398 BOOST_CATCH(...){
Chris@16 399 this->priv_destroy_nodes(nstart, cur);
Chris@16 400 BOOST_RETHROW
Chris@16 401 }
Chris@16 402 BOOST_CATCH_END
Chris@16 403 }
Chris@16 404
Chris@16 405 void priv_destroy_nodes(ptr_alloc_ptr nstart, ptr_alloc_ptr nfinish) BOOST_CONTAINER_NOEXCEPT
Chris@16 406 {
Chris@16 407 for (ptr_alloc_ptr n = nstart; n < nfinish; ++n)
Chris@16 408 this->priv_deallocate_node(*n);
Chris@16 409 }
Chris@16 410
Chris@16 411 void priv_clear_map() BOOST_CONTAINER_NOEXCEPT
Chris@16 412 {
Chris@16 413 if (this->members_.m_map) {
Chris@16 414 this->priv_destroy_nodes(this->members_.m_start.m_node, this->members_.m_finish.m_node + 1);
Chris@16 415 this->priv_deallocate_map(this->members_.m_map, this->members_.m_map_size);
Chris@16 416 this->members_.m_map = 0;
Chris@16 417 this->members_.m_map_size = 0;
Chris@16 418 this->members_.m_start = iterator();
Chris@16 419 this->members_.m_finish = this->members_.m_start;
Chris@16 420 }
Chris@16 421 }
Chris@16 422
Chris@16 423 enum { InitialMapSize = 8 };
Chris@16 424
Chris@16 425 protected:
Chris@16 426 struct members_holder
Chris@16 427 : public ptr_alloc_t
Chris@16 428 , public allocator_type
Chris@16 429 {
Chris@16 430 members_holder()
Chris@16 431 : map_allocator_type(), allocator_type()
Chris@16 432 , m_map(0), m_map_size(0)
Chris@16 433 , m_start(), m_finish(m_start)
Chris@16 434 {}
Chris@16 435
Chris@16 436 explicit members_holder(const allocator_type &a)
Chris@16 437 : map_allocator_type(a), allocator_type(a)
Chris@16 438 , m_map(0), m_map_size(0)
Chris@16 439 , m_start(), m_finish(m_start)
Chris@16 440 {}
Chris@16 441
Chris@16 442 template<class ValAllocConvertible, class PtrAllocConvertible>
Chris@16 443 members_holder(BOOST_FWD_REF(PtrAllocConvertible) pa, BOOST_FWD_REF(ValAllocConvertible) va)
Chris@16 444 : map_allocator_type(boost::forward<PtrAllocConvertible>(pa))
Chris@16 445 , allocator_type (boost::forward<ValAllocConvertible>(va))
Chris@16 446 , m_map(0), m_map_size(0)
Chris@16 447 , m_start(), m_finish(m_start)
Chris@16 448 {}
Chris@16 449
Chris@16 450 ptr_alloc_ptr m_map;
Chris@16 451 val_alloc_size m_map_size;
Chris@16 452 iterator m_start;
Chris@16 453 iterator m_finish;
Chris@16 454 } members_;
Chris@16 455
Chris@16 456 ptr_alloc_t &ptr_alloc() BOOST_CONTAINER_NOEXCEPT
Chris@16 457 { return members_; }
Chris@16 458
Chris@16 459 const ptr_alloc_t &ptr_alloc() const BOOST_CONTAINER_NOEXCEPT
Chris@16 460 { return members_; }
Chris@16 461
Chris@16 462 allocator_type &alloc() BOOST_CONTAINER_NOEXCEPT
Chris@16 463 { return members_; }
Chris@16 464
Chris@16 465 const allocator_type &alloc() const BOOST_CONTAINER_NOEXCEPT
Chris@16 466 { return members_; }
Chris@16 467 };
Chris@16 468 /// @endcond
Chris@16 469
Chris@16 470 //! Deque class
Chris@16 471 //!
Chris@16 472 #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
Chris@16 473 template <class T, class Allocator = std::allocator<T> >
Chris@16 474 #else
Chris@16 475 template <class T, class Allocator>
Chris@16 476 #endif
Chris@16 477 class deque : protected deque_base<Allocator>
Chris@16 478 {
Chris@16 479 /// @cond
Chris@16 480 private:
Chris@16 481 typedef deque_base<Allocator> Base;
Chris@16 482 /// @endcond
Chris@16 483
Chris@16 484 public:
Chris@16 485
Chris@16 486 //////////////////////////////////////////////
Chris@16 487 //
Chris@16 488 // types
Chris@16 489 //
Chris@16 490 //////////////////////////////////////////////
Chris@16 491
Chris@16 492 typedef T value_type;
Chris@16 493 typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
Chris@16 494 typedef typename ::boost::container::allocator_traits<Allocator>::const_pointer const_pointer;
Chris@16 495 typedef typename ::boost::container::allocator_traits<Allocator>::reference reference;
Chris@16 496 typedef typename ::boost::container::allocator_traits<Allocator>::const_reference const_reference;
Chris@16 497 typedef typename ::boost::container::allocator_traits<Allocator>::size_type size_type;
Chris@16 498 typedef typename ::boost::container::allocator_traits<Allocator>::difference_type difference_type;
Chris@16 499 typedef Allocator allocator_type;
Chris@16 500 typedef BOOST_CONTAINER_IMPDEF(allocator_type) stored_allocator_type;
Chris@16 501 typedef BOOST_CONTAINER_IMPDEF(typename Base::iterator) iterator;
Chris@16 502 typedef BOOST_CONTAINER_IMPDEF(typename Base::const_iterator) const_iterator;
Chris@16 503 typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator<iterator>) reverse_iterator;
Chris@16 504 typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator<const_iterator>) const_reverse_iterator;
Chris@16 505
Chris@16 506 /// @cond
Chris@16 507
Chris@16 508 private: // Internal typedefs
Chris@16 509 BOOST_COPYABLE_AND_MOVABLE(deque)
Chris@16 510 typedef typename Base::ptr_alloc_ptr index_pointer;
Chris@16 511 static size_type s_buffer_size()
Chris@16 512 { return Base::s_buffer_size(); }
Chris@16 513 typedef allocator_traits<Allocator> allocator_traits_type;
Chris@16 514
Chris@16 515 /// @endcond
Chris@16 516
Chris@16 517 public:
Chris@16 518 //////////////////////////////////////////////
Chris@16 519 //
Chris@16 520 // construct/copy/destroy
Chris@16 521 //
Chris@16 522 //////////////////////////////////////////////
Chris@16 523
Chris@16 524 //! <b>Effects</b>: Default constructors a deque.
Chris@16 525 //!
Chris@16 526 //! <b>Throws</b>: If allocator_type's default constructor throws.
Chris@16 527 //!
Chris@16 528 //! <b>Complexity</b>: Constant.
Chris@16 529 deque()
Chris@16 530 : Base()
Chris@16 531 {}
Chris@16 532
Chris@16 533 //! <b>Effects</b>: Constructs a deque taking the allocator as parameter.
Chris@16 534 //!
Chris@16 535 //! <b>Throws</b>: Nothing
Chris@16 536 //!
Chris@16 537 //! <b>Complexity</b>: Constant.
Chris@16 538 explicit deque(const allocator_type& a) BOOST_CONTAINER_NOEXCEPT
Chris@16 539 : Base(a)
Chris@16 540 {}
Chris@16 541
Chris@16 542 //! <b>Effects</b>: Constructs a deque that will use a copy of allocator a
Chris@16 543 //! and inserts n value initialized values.
Chris@16 544 //!
Chris@16 545 //! <b>Throws</b>: If allocator_type's default constructor or copy constructor
Chris@16 546 //! throws or T's default or copy constructor throws.
Chris@16 547 //!
Chris@16 548 //! <b>Complexity</b>: Linear to n.
Chris@16 549 explicit deque(size_type n)
Chris@16 550 : Base(n, allocator_type())
Chris@16 551 {
Chris@16 552 container_detail::insert_value_initialized_n_proxy<Allocator, iterator> proxy(this->alloc());
Chris@16 553 proxy.uninitialized_copy_n_and_update(this->begin(), n);
Chris@16 554 //deque_base will deallocate in case of exception...
Chris@16 555 }
Chris@16 556
Chris@16 557 //! <b>Effects</b>: Constructs a deque that will use a copy of allocator a
Chris@16 558 //! and inserts n default initialized values.
Chris@16 559 //!
Chris@16 560 //! <b>Throws</b>: If allocator_type's default constructor or copy constructor
Chris@16 561 //! throws or T's default or copy constructor throws.
Chris@16 562 //!
Chris@16 563 //! <b>Complexity</b>: Linear to n.
Chris@16 564 //!
Chris@16 565 //! <b>Note</b>: Non-standard extension
Chris@16 566 deque(size_type n, default_init_t)
Chris@16 567 : Base(n, allocator_type())
Chris@16 568 {
Chris@16 569 container_detail::insert_default_initialized_n_proxy<Allocator, iterator> proxy(this->alloc());
Chris@16 570 proxy.uninitialized_copy_n_and_update(this->begin(), n);
Chris@16 571 //deque_base will deallocate in case of exception...
Chris@16 572 }
Chris@16 573
Chris@16 574 //! <b>Effects</b>: Constructs a deque that will use a copy of allocator a
Chris@16 575 //! and inserts n copies of value.
Chris@16 576 //!
Chris@16 577 //! <b>Throws</b>: If allocator_type's default constructor or copy constructor
Chris@16 578 //! throws or T's default or copy constructor throws.
Chris@16 579 //!
Chris@16 580 //! <b>Complexity</b>: Linear to n.
Chris@16 581 deque(size_type n, const value_type& value,
Chris@16 582 const allocator_type& a = allocator_type())
Chris@16 583 : Base(n, a)
Chris@16 584 { this->priv_fill_initialize(value); }
Chris@16 585
Chris@16 586 //! <b>Effects</b>: Constructs a deque that will use a copy of allocator a
Chris@16 587 //! and inserts a copy of the range [first, last) in the deque.
Chris@16 588 //!
Chris@16 589 //! <b>Throws</b>: If allocator_type's default constructor or copy constructor
Chris@16 590 //! throws or T's constructor taking an dereferenced InIt throws.
Chris@16 591 //!
Chris@16 592 //! <b>Complexity</b>: Linear to the range [first, last).
Chris@16 593 template <class InIt>
Chris@16 594 deque(InIt first, InIt last, const allocator_type& a = allocator_type()
Chris@16 595 #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
Chris@16 596 , typename container_detail::enable_if_c
Chris@16 597 < !container_detail::is_convertible<InIt, size_type>::value
Chris@16 598 >::type * = 0
Chris@16 599 #endif
Chris@16 600 )
Chris@16 601 : Base(a)
Chris@16 602 {
Chris@16 603 typedef typename std::iterator_traits<InIt>::iterator_category ItCat;
Chris@16 604 this->priv_range_initialize(first, last, ItCat());
Chris@16 605 }
Chris@16 606
Chris@16 607 //! <b>Effects</b>: Copy constructs a deque.
Chris@16 608 //!
Chris@16 609 //! <b>Postcondition</b>: x == *this.
Chris@16 610 //!
Chris@16 611 //! <b>Complexity</b>: Linear to the elements x contains.
Chris@16 612 deque(const deque& x)
Chris@16 613 : Base(allocator_traits_type::select_on_container_copy_construction(x.alloc()))
Chris@16 614 {
Chris@16 615 if(x.size()){
Chris@16 616 this->priv_initialize_map(x.size());
Chris@16 617 boost::container::uninitialized_copy_alloc
Chris@16 618 (this->alloc(), x.begin(), x.end(), this->members_.m_start);
Chris@16 619 }
Chris@16 620 }
Chris@16 621
Chris@16 622 //! <b>Effects</b>: Move constructor. Moves mx's resources to *this.
Chris@16 623 //!
Chris@16 624 //! <b>Throws</b>: If allocator_type's copy constructor throws.
Chris@16 625 //!
Chris@16 626 //! <b>Complexity</b>: Constant.
Chris@16 627 deque(BOOST_RV_REF(deque) x)
Chris@16 628 : Base(boost::move(static_cast<Base&>(x)))
Chris@16 629 { this->swap_members(x); }
Chris@16 630
Chris@16 631 //! <b>Effects</b>: Copy constructs a vector using the specified allocator.
Chris@16 632 //!
Chris@16 633 //! <b>Postcondition</b>: x == *this.
Chris@16 634 //!
Chris@16 635 //! <b>Throws</b>: If allocation
Chris@16 636 //! throws or T's copy constructor throws.
Chris@16 637 //!
Chris@16 638 //! <b>Complexity</b>: Linear to the elements x contains.
Chris@16 639 deque(const deque& x, const allocator_type &a)
Chris@16 640 : Base(a)
Chris@16 641 {
Chris@16 642 if(x.size()){
Chris@16 643 this->priv_initialize_map(x.size());
Chris@16 644 boost::container::uninitialized_copy_alloc
Chris@16 645 (this->alloc(), x.begin(), x.end(), this->members_.m_start);
Chris@16 646 }
Chris@16 647 }
Chris@16 648
Chris@16 649 //! <b>Effects</b>: Move constructor using the specified allocator.
Chris@16 650 //! Moves mx's resources to *this if a == allocator_type().
Chris@16 651 //! Otherwise copies values from x to *this.
Chris@16 652 //!
Chris@16 653 //! <b>Throws</b>: If allocation or T's copy constructor throws.
Chris@16 654 //!
Chris@16 655 //! <b>Complexity</b>: Constant if a == mx.get_allocator(), linear otherwise.
Chris@16 656 deque(BOOST_RV_REF(deque) mx, const allocator_type &a)
Chris@16 657 : Base(a)
Chris@16 658 {
Chris@16 659 if(mx.alloc() == a){
Chris@16 660 this->swap_members(mx);
Chris@16 661 }
Chris@16 662 else{
Chris@16 663 if(mx.size()){
Chris@16 664 this->priv_initialize_map(mx.size());
Chris@16 665 boost::container::uninitialized_copy_alloc
Chris@16 666 (this->alloc(), mx.begin(), mx.end(), this->members_.m_start);
Chris@16 667 }
Chris@16 668 }
Chris@16 669 }
Chris@16 670
Chris@16 671 //! <b>Effects</b>: Destroys the deque. All stored values are destroyed
Chris@16 672 //! and used memory is deallocated.
Chris@16 673 //!
Chris@16 674 //! <b>Throws</b>: Nothing.
Chris@16 675 //!
Chris@16 676 //! <b>Complexity</b>: Linear to the number of elements.
Chris@16 677 ~deque() BOOST_CONTAINER_NOEXCEPT
Chris@16 678 {
Chris@16 679 this->priv_destroy_range(this->members_.m_start, this->members_.m_finish);
Chris@16 680 }
Chris@16 681
Chris@16 682 //! <b>Effects</b>: Makes *this contain the same elements as x.
Chris@16 683 //!
Chris@16 684 //! <b>Postcondition</b>: this->size() == x.size(). *this contains a copy
Chris@16 685 //! of each of x's elements.
Chris@16 686 //!
Chris@16 687 //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
Chris@16 688 //!
Chris@16 689 //! <b>Complexity</b>: Linear to the number of elements in x.
Chris@16 690 deque& operator= (BOOST_COPY_ASSIGN_REF(deque) x)
Chris@16 691 {
Chris@16 692 if (&x != this){
Chris@16 693 allocator_type &this_alloc = this->alloc();
Chris@16 694 const allocator_type &x_alloc = x.alloc();
Chris@16 695 container_detail::bool_<allocator_traits_type::
Chris@16 696 propagate_on_container_copy_assignment::value> flag;
Chris@16 697 if(flag && this_alloc != x_alloc){
Chris@16 698 this->clear();
Chris@16 699 this->shrink_to_fit();
Chris@16 700 }
Chris@16 701 container_detail::assign_alloc(this->alloc(), x.alloc(), flag);
Chris@16 702 container_detail::assign_alloc(this->ptr_alloc(), x.ptr_alloc(), flag);
Chris@16 703 this->assign(x.cbegin(), x.cend());
Chris@16 704 }
Chris@16 705 return *this;
Chris@16 706 }
Chris@16 707
Chris@16 708 //! <b>Effects</b>: Move assignment. All mx's values are transferred to *this.
Chris@16 709 //!
Chris@16 710 //! <b>Postcondition</b>: x.empty(). *this contains a the elements x had
Chris@16 711 //! before the function.
Chris@16 712 //!
Chris@16 713 //! <b>Throws</b>: If allocator_type's copy constructor throws.
Chris@16 714 //!
Chris@16 715 //! <b>Complexity</b>: Linear.
Chris@16 716 deque& operator= (BOOST_RV_REF(deque) x)
Chris@16 717 {
Chris@16 718 if (&x != this){
Chris@16 719 allocator_type &this_alloc = this->alloc();
Chris@16 720 allocator_type &x_alloc = x.alloc();
Chris@16 721 //If allocators are equal we can just swap pointers
Chris@16 722 if(this_alloc == x_alloc){
Chris@16 723 //Destroy objects but retain memory in case x reuses it in the future
Chris@16 724 this->clear();
Chris@16 725 this->swap_members(x);
Chris@16 726 //Move allocator if needed
Chris@16 727 container_detail::bool_<allocator_traits_type::
Chris@16 728 propagate_on_container_move_assignment::value> flag;
Chris@16 729 container_detail::move_alloc(this_alloc, x_alloc, flag);
Chris@16 730 container_detail::move_alloc(this->ptr_alloc(), x.ptr_alloc(), flag);
Chris@16 731 }
Chris@16 732 //If unequal allocators, then do a one by one move
Chris@16 733 else{
Chris@16 734 this->assign( boost::make_move_iterator(x.begin())
Chris@16 735 , boost::make_move_iterator(x.end()));
Chris@16 736 }
Chris@16 737 }
Chris@16 738 return *this;
Chris@16 739 }
Chris@16 740
Chris@16 741 //! <b>Effects</b>: Assigns the n copies of val to *this.
Chris@16 742 //!
Chris@16 743 //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
Chris@16 744 //!
Chris@16 745 //! <b>Complexity</b>: Linear to n.
Chris@16 746 void assign(size_type n, const T& val)
Chris@16 747 {
Chris@16 748 typedef constant_iterator<value_type, difference_type> c_it;
Chris@16 749 this->assign(c_it(val, n), c_it());
Chris@16 750 }
Chris@16 751
Chris@16 752 //! <b>Effects</b>: Assigns the the range [first, last) to *this.
Chris@16 753 //!
Chris@16 754 //! <b>Throws</b>: If memory allocation throws or
Chris@16 755 //! T's constructor from dereferencing InIt throws.
Chris@16 756 //!
Chris@16 757 //! <b>Complexity</b>: Linear to n.
Chris@16 758 template <class InIt>
Chris@16 759 void assign(InIt first, InIt last
Chris@16 760 #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
Chris@16 761 , typename container_detail::enable_if_c
Chris@16 762 < !container_detail::is_convertible<InIt, size_type>::value
Chris@16 763 && container_detail::is_input_iterator<InIt>::value
Chris@16 764 >::type * = 0
Chris@16 765 #endif
Chris@16 766 )
Chris@16 767 {
Chris@16 768 iterator cur = this->begin();
Chris@16 769 for ( ; first != last && cur != end(); ++cur, ++first){
Chris@16 770 *cur = *first;
Chris@16 771 }
Chris@16 772 if (first == last){
Chris@16 773 this->erase(cur, this->cend());
Chris@16 774 }
Chris@16 775 else{
Chris@16 776 this->insert(this->cend(), first, last);
Chris@16 777 }
Chris@16 778 }
Chris@16 779
Chris@16 780 #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
Chris@16 781 template <class FwdIt>
Chris@16 782 void assign(FwdIt first, FwdIt last
Chris@16 783 , typename container_detail::enable_if_c
Chris@16 784 < !container_detail::is_convertible<FwdIt, size_type>::value
Chris@16 785 && !container_detail::is_input_iterator<FwdIt>::value
Chris@16 786 >::type * = 0
Chris@16 787 )
Chris@16 788 {
Chris@16 789 const size_type len = std::distance(first, last);
Chris@16 790 if (len > size()) {
Chris@16 791 FwdIt mid = first;
Chris@16 792 std::advance(mid, this->size());
Chris@16 793 boost::container::copy(first, mid, begin());
Chris@16 794 this->insert(this->cend(), mid, last);
Chris@16 795 }
Chris@16 796 else{
Chris@16 797 this->erase(boost::container::copy(first, last, this->begin()), cend());
Chris@16 798 }
Chris@16 799 }
Chris@16 800 #endif
Chris@16 801
Chris@16 802 //! <b>Effects</b>: Returns a copy of the internal allocator.
Chris@16 803 //!
Chris@16 804 //! <b>Throws</b>: If allocator's copy constructor throws.
Chris@16 805 //!
Chris@16 806 //! <b>Complexity</b>: Constant.
Chris@16 807 allocator_type get_allocator() const BOOST_CONTAINER_NOEXCEPT
Chris@16 808 { return Base::alloc(); }
Chris@16 809
Chris@16 810 //! <b>Effects</b>: Returns a reference to the internal allocator.
Chris@16 811 //!
Chris@16 812 //! <b>Throws</b>: Nothing
Chris@16 813 //!
Chris@16 814 //! <b>Complexity</b>: Constant.
Chris@16 815 //!
Chris@16 816 //! <b>Note</b>: Non-standard extension.
Chris@16 817 const stored_allocator_type &get_stored_allocator() const BOOST_CONTAINER_NOEXCEPT
Chris@16 818 { return Base::alloc(); }
Chris@16 819
Chris@16 820 //////////////////////////////////////////////
Chris@16 821 //
Chris@16 822 // iterators
Chris@16 823 //
Chris@16 824 //////////////////////////////////////////////
Chris@16 825
Chris@16 826 //! <b>Effects</b>: Returns a reference to the internal allocator.
Chris@16 827 //!
Chris@16 828 //! <b>Throws</b>: Nothing
Chris@16 829 //!
Chris@16 830 //! <b>Complexity</b>: Constant.
Chris@16 831 //!
Chris@16 832 //! <b>Note</b>: Non-standard extension.
Chris@16 833 stored_allocator_type &get_stored_allocator() BOOST_CONTAINER_NOEXCEPT
Chris@16 834 { return Base::alloc(); }
Chris@16 835
Chris@16 836 //! <b>Effects</b>: Returns an iterator to the first element contained in the deque.
Chris@16 837 //!
Chris@16 838 //! <b>Throws</b>: Nothing.
Chris@16 839 //!
Chris@16 840 //! <b>Complexity</b>: Constant.
Chris@16 841 iterator begin() BOOST_CONTAINER_NOEXCEPT
Chris@16 842 { return this->members_.m_start; }
Chris@16 843
Chris@16 844 //! <b>Effects</b>: Returns a const_iterator to the first element contained in the deque.
Chris@16 845 //!
Chris@16 846 //! <b>Throws</b>: Nothing.
Chris@16 847 //!
Chris@16 848 //! <b>Complexity</b>: Constant.
Chris@16 849 const_iterator begin() const BOOST_CONTAINER_NOEXCEPT
Chris@16 850 { return this->members_.m_start; }
Chris@16 851
Chris@16 852 //! <b>Effects</b>: Returns an iterator to the end of the deque.
Chris@16 853 //!
Chris@16 854 //! <b>Throws</b>: Nothing.
Chris@16 855 //!
Chris@16 856 //! <b>Complexity</b>: Constant.
Chris@16 857 iterator end() BOOST_CONTAINER_NOEXCEPT
Chris@16 858 { return this->members_.m_finish; }
Chris@16 859
Chris@16 860 //! <b>Effects</b>: Returns a const_iterator to the end of the deque.
Chris@16 861 //!
Chris@16 862 //! <b>Throws</b>: Nothing.
Chris@16 863 //!
Chris@16 864 //! <b>Complexity</b>: Constant.
Chris@16 865 const_iterator end() const BOOST_CONTAINER_NOEXCEPT
Chris@16 866 { return this->members_.m_finish; }
Chris@16 867
Chris@16 868 //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
Chris@16 869 //! of the reversed deque.
Chris@16 870 //!
Chris@16 871 //! <b>Throws</b>: Nothing.
Chris@16 872 //!
Chris@16 873 //! <b>Complexity</b>: Constant.
Chris@16 874 reverse_iterator rbegin() BOOST_CONTAINER_NOEXCEPT
Chris@16 875 { return reverse_iterator(this->members_.m_finish); }
Chris@16 876
Chris@16 877 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
Chris@16 878 //! of the reversed deque.
Chris@16 879 //!
Chris@16 880 //! <b>Throws</b>: Nothing.
Chris@16 881 //!
Chris@16 882 //! <b>Complexity</b>: Constant.
Chris@16 883 const_reverse_iterator rbegin() const BOOST_CONTAINER_NOEXCEPT
Chris@16 884 { return const_reverse_iterator(this->members_.m_finish); }
Chris@16 885
Chris@16 886 //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
Chris@16 887 //! of the reversed deque.
Chris@16 888 //!
Chris@16 889 //! <b>Throws</b>: Nothing.
Chris@16 890 //!
Chris@16 891 //! <b>Complexity</b>: Constant.
Chris@16 892 reverse_iterator rend() BOOST_CONTAINER_NOEXCEPT
Chris@16 893 { return reverse_iterator(this->members_.m_start); }
Chris@16 894
Chris@16 895 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
Chris@16 896 //! of the reversed deque.
Chris@16 897 //!
Chris@16 898 //! <b>Throws</b>: Nothing.
Chris@16 899 //!
Chris@16 900 //! <b>Complexity</b>: Constant.
Chris@16 901 const_reverse_iterator rend() const BOOST_CONTAINER_NOEXCEPT
Chris@16 902 { return const_reverse_iterator(this->members_.m_start); }
Chris@16 903
Chris@16 904 //! <b>Effects</b>: Returns a const_iterator to the first element contained in the deque.
Chris@16 905 //!
Chris@16 906 //! <b>Throws</b>: Nothing.
Chris@16 907 //!
Chris@16 908 //! <b>Complexity</b>: Constant.
Chris@16 909 const_iterator cbegin() const BOOST_CONTAINER_NOEXCEPT
Chris@16 910 { return this->members_.m_start; }
Chris@16 911
Chris@16 912 //! <b>Effects</b>: Returns a const_iterator to the end of the deque.
Chris@16 913 //!
Chris@16 914 //! <b>Throws</b>: Nothing.
Chris@16 915 //!
Chris@16 916 //! <b>Complexity</b>: Constant.
Chris@16 917 const_iterator cend() const BOOST_CONTAINER_NOEXCEPT
Chris@16 918 { return this->members_.m_finish; }
Chris@16 919
Chris@16 920 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
Chris@16 921 //! of the reversed deque.
Chris@16 922 //!
Chris@16 923 //! <b>Throws</b>: Nothing.
Chris@16 924 //!
Chris@16 925 //! <b>Complexity</b>: Constant.
Chris@16 926 const_reverse_iterator crbegin() const BOOST_CONTAINER_NOEXCEPT
Chris@16 927 { return const_reverse_iterator(this->members_.m_finish); }
Chris@16 928
Chris@16 929 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
Chris@16 930 //! of the reversed deque.
Chris@16 931 //!
Chris@16 932 //! <b>Throws</b>: Nothing.
Chris@16 933 //!
Chris@16 934 //! <b>Complexity</b>: Constant.
Chris@16 935 const_reverse_iterator crend() const BOOST_CONTAINER_NOEXCEPT
Chris@16 936 { return const_reverse_iterator(this->members_.m_start); }
Chris@16 937
Chris@16 938 //////////////////////////////////////////////
Chris@16 939 //
Chris@16 940 // capacity
Chris@16 941 //
Chris@16 942 //////////////////////////////////////////////
Chris@16 943
Chris@16 944 //! <b>Effects</b>: Returns true if the deque contains no elements.
Chris@16 945 //!
Chris@16 946 //! <b>Throws</b>: Nothing.
Chris@16 947 //!
Chris@16 948 //! <b>Complexity</b>: Constant.
Chris@16 949 bool empty() const BOOST_CONTAINER_NOEXCEPT
Chris@16 950 { return this->members_.m_finish == this->members_.m_start; }
Chris@16 951
Chris@16 952 //! <b>Effects</b>: Returns the number of the elements contained in the deque.
Chris@16 953 //!
Chris@16 954 //! <b>Throws</b>: Nothing.
Chris@16 955 //!
Chris@16 956 //! <b>Complexity</b>: Constant.
Chris@16 957 size_type size() const BOOST_CONTAINER_NOEXCEPT
Chris@16 958 { return this->members_.m_finish - this->members_.m_start; }
Chris@16 959
Chris@16 960 //! <b>Effects</b>: Returns the largest possible size of the deque.
Chris@16 961 //!
Chris@16 962 //! <b>Throws</b>: Nothing.
Chris@16 963 //!
Chris@16 964 //! <b>Complexity</b>: Constant.
Chris@16 965 size_type max_size() const BOOST_CONTAINER_NOEXCEPT
Chris@16 966 { return allocator_traits_type::max_size(this->alloc()); }
Chris@16 967
Chris@16 968 //! <b>Effects</b>: Inserts or erases elements at the end such that
Chris@16 969 //! the size becomes n. New elements are value initialized.
Chris@16 970 //!
Chris@16 971 //! <b>Throws</b>: If memory allocation throws, or T's constructor throws.
Chris@16 972 //!
Chris@16 973 //! <b>Complexity</b>: Linear to the difference between size() and new_size.
Chris@16 974 void resize(size_type new_size)
Chris@16 975 {
Chris@16 976 const size_type len = size();
Chris@16 977 if (new_size < len)
Chris@16 978 this->priv_erase_last_n(len - new_size);
Chris@16 979 else{
Chris@16 980 const size_type n = new_size - this->size();
Chris@16 981 container_detail::insert_value_initialized_n_proxy<Allocator, iterator> proxy(this->alloc());
Chris@16 982 priv_insert_back_aux_impl(n, proxy);
Chris@16 983 }
Chris@16 984 }
Chris@16 985
Chris@16 986 //! <b>Effects</b>: Inserts or erases elements at the end such that
Chris@16 987 //! the size becomes n. New elements are default initialized.
Chris@16 988 //!
Chris@16 989 //! <b>Throws</b>: If memory allocation throws, or T's constructor throws.
Chris@16 990 //!
Chris@16 991 //! <b>Complexity</b>: Linear to the difference between size() and new_size.
Chris@16 992 //!
Chris@16 993 //! <b>Note</b>: Non-standard extension
Chris@16 994 void resize(size_type new_size, default_init_t)
Chris@16 995 {
Chris@16 996 const size_type len = size();
Chris@16 997 if (new_size < len)
Chris@16 998 this->priv_erase_last_n(len - new_size);
Chris@16 999 else{
Chris@16 1000 const size_type n = new_size - this->size();
Chris@16 1001 container_detail::insert_default_initialized_n_proxy<Allocator, iterator> proxy(this->alloc());
Chris@16 1002 priv_insert_back_aux_impl(n, proxy);
Chris@16 1003 }
Chris@16 1004 }
Chris@16 1005
Chris@16 1006 //! <b>Effects</b>: Inserts or erases elements at the end such that
Chris@16 1007 //! the size becomes n. New elements are copy constructed from x.
Chris@16 1008 //!
Chris@16 1009 //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
Chris@16 1010 //!
Chris@16 1011 //! <b>Complexity</b>: Linear to the difference between size() and new_size.
Chris@16 1012 void resize(size_type new_size, const value_type& x)
Chris@16 1013 {
Chris@16 1014 const size_type len = size();
Chris@16 1015 if (new_size < len)
Chris@16 1016 this->erase(this->members_.m_start + new_size, this->members_.m_finish);
Chris@16 1017 else
Chris@16 1018 this->insert(this->members_.m_finish, new_size - len, x);
Chris@16 1019 }
Chris@16 1020
Chris@16 1021 //! <b>Effects</b>: Tries to deallocate the excess of memory created
Chris@16 1022 //! with previous allocations. The size of the deque is unchanged
Chris@16 1023 //!
Chris@16 1024 //! <b>Throws</b>: If memory allocation throws.
Chris@16 1025 //!
Chris@16 1026 //! <b>Complexity</b>: Constant.
Chris@16 1027 void shrink_to_fit()
Chris@16 1028 {
Chris@16 1029 //This deque implementation already
Chris@16 1030 //deallocates excess nodes when erasing
Chris@16 1031 //so there is nothing to do except for
Chris@16 1032 //empty deque
Chris@16 1033 if(this->empty()){
Chris@16 1034 this->priv_clear_map();
Chris@16 1035 }
Chris@16 1036 }
Chris@16 1037
Chris@16 1038 //////////////////////////////////////////////
Chris@16 1039 //
Chris@16 1040 // element access
Chris@16 1041 //
Chris@16 1042 //////////////////////////////////////////////
Chris@16 1043
Chris@16 1044 //! <b>Requires</b>: !empty()
Chris@16 1045 //!
Chris@16 1046 //! <b>Effects</b>: Returns a reference to the first
Chris@16 1047 //! element of the container.
Chris@16 1048 //!
Chris@16 1049 //! <b>Throws</b>: Nothing.
Chris@16 1050 //!
Chris@16 1051 //! <b>Complexity</b>: Constant.
Chris@16 1052 reference front() BOOST_CONTAINER_NOEXCEPT
Chris@16 1053 { return *this->members_.m_start; }
Chris@16 1054
Chris@16 1055 //! <b>Requires</b>: !empty()
Chris@16 1056 //!
Chris@16 1057 //! <b>Effects</b>: Returns a const reference to the first element
Chris@16 1058 //! from the beginning of the container.
Chris@16 1059 //!
Chris@16 1060 //! <b>Throws</b>: Nothing.
Chris@16 1061 //!
Chris@16 1062 //! <b>Complexity</b>: Constant.
Chris@16 1063 const_reference front() const BOOST_CONTAINER_NOEXCEPT
Chris@16 1064 { return *this->members_.m_start; }
Chris@16 1065
Chris@16 1066 //! <b>Requires</b>: !empty()
Chris@16 1067 //!
Chris@16 1068 //! <b>Effects</b>: Returns a reference to the last
Chris@16 1069 //! element of the container.
Chris@16 1070 //!
Chris@16 1071 //! <b>Throws</b>: Nothing.
Chris@16 1072 //!
Chris@16 1073 //! <b>Complexity</b>: Constant.
Chris@16 1074 reference back() BOOST_CONTAINER_NOEXCEPT
Chris@16 1075 { return *(end()-1); }
Chris@16 1076
Chris@16 1077 //! <b>Requires</b>: !empty()
Chris@16 1078 //!
Chris@16 1079 //! <b>Effects</b>: Returns a const reference to the last
Chris@16 1080 //! element of the container.
Chris@16 1081 //!
Chris@16 1082 //! <b>Throws</b>: Nothing.
Chris@16 1083 //!
Chris@16 1084 //! <b>Complexity</b>: Constant.
Chris@16 1085 const_reference back() const BOOST_CONTAINER_NOEXCEPT
Chris@16 1086 { return *(cend()-1); }
Chris@16 1087
Chris@16 1088 //! <b>Requires</b>: size() > n.
Chris@16 1089 //!
Chris@16 1090 //! <b>Effects</b>: Returns a reference to the nth element
Chris@16 1091 //! from the beginning of the container.
Chris@16 1092 //!
Chris@16 1093 //! <b>Throws</b>: Nothing.
Chris@16 1094 //!
Chris@16 1095 //! <b>Complexity</b>: Constant.
Chris@16 1096 reference operator[](size_type n) BOOST_CONTAINER_NOEXCEPT
Chris@16 1097 { return this->members_.m_start[difference_type(n)]; }
Chris@16 1098
Chris@16 1099 //! <b>Requires</b>: size() > n.
Chris@16 1100 //!
Chris@16 1101 //! <b>Effects</b>: Returns a const reference to the nth element
Chris@16 1102 //! from the beginning of the container.
Chris@16 1103 //!
Chris@16 1104 //! <b>Throws</b>: Nothing.
Chris@16 1105 //!
Chris@16 1106 //! <b>Complexity</b>: Constant.
Chris@16 1107 const_reference operator[](size_type n) const BOOST_CONTAINER_NOEXCEPT
Chris@16 1108 { return this->members_.m_start[difference_type(n)]; }
Chris@16 1109
Chris@16 1110 //! <b>Requires</b>: size() > n.
Chris@16 1111 //!
Chris@16 1112 //! <b>Effects</b>: Returns a reference to the nth element
Chris@16 1113 //! from the beginning of the container.
Chris@16 1114 //!
Chris@16 1115 //! <b>Throws</b>: std::range_error if n >= size()
Chris@16 1116 //!
Chris@16 1117 //! <b>Complexity</b>: Constant.
Chris@16 1118 reference at(size_type n)
Chris@16 1119 { this->priv_range_check(n); return (*this)[n]; }
Chris@16 1120
Chris@16 1121 //! <b>Requires</b>: size() > n.
Chris@16 1122 //!
Chris@16 1123 //! <b>Effects</b>: Returns a const reference to the nth element
Chris@16 1124 //! from the beginning of the container.
Chris@16 1125 //!
Chris@16 1126 //! <b>Throws</b>: std::range_error if n >= size()
Chris@16 1127 //!
Chris@16 1128 //! <b>Complexity</b>: Constant.
Chris@16 1129 const_reference at(size_type n) const
Chris@16 1130 { this->priv_range_check(n); return (*this)[n]; }
Chris@16 1131
Chris@16 1132 //////////////////////////////////////////////
Chris@16 1133 //
Chris@16 1134 // modifiers
Chris@16 1135 //
Chris@16 1136 //////////////////////////////////////////////
Chris@16 1137
Chris@16 1138 #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
Chris@16 1139
Chris@16 1140 //! <b>Effects</b>: Inserts an object of type T constructed with
Chris@16 1141 //! std::forward<Args>(args)... in the beginning of the deque.
Chris@16 1142 //!
Chris@16 1143 //! <b>Throws</b>: If memory allocation throws or the in-place constructor throws.
Chris@16 1144 //!
Chris@16 1145 //! <b>Complexity</b>: Amortized constant time
Chris@16 1146 template <class... Args>
Chris@16 1147 void emplace_front(Args&&... args)
Chris@16 1148 {
Chris@16 1149 if(this->priv_push_front_simple_available()){
Chris@16 1150 allocator_traits_type::construct
Chris@16 1151 ( this->alloc()
Chris@16 1152 , this->priv_push_front_simple_pos()
Chris@16 1153 , boost::forward<Args>(args)...);
Chris@16 1154 this->priv_push_front_simple_commit();
Chris@16 1155 }
Chris@16 1156 else{
Chris@16 1157 typedef container_detail::insert_non_movable_emplace_proxy<Allocator, iterator, Args...> type;
Chris@16 1158 this->priv_insert_front_aux_impl(1, type(this->alloc(), boost::forward<Args>(args)...));
Chris@16 1159 }
Chris@16 1160 }
Chris@16 1161
Chris@16 1162 //! <b>Effects</b>: Inserts an object of type T constructed with
Chris@16 1163 //! std::forward<Args>(args)... in the end of the deque.
Chris@16 1164 //!
Chris@16 1165 //! <b>Throws</b>: If memory allocation throws or the in-place constructor throws.
Chris@16 1166 //!
Chris@16 1167 //! <b>Complexity</b>: Amortized constant time
Chris@16 1168 template <class... Args>
Chris@16 1169 void emplace_back(Args&&... args)
Chris@16 1170 {
Chris@16 1171 if(this->priv_push_back_simple_available()){
Chris@16 1172 allocator_traits_type::construct
Chris@16 1173 ( this->alloc()
Chris@16 1174 , this->priv_push_back_simple_pos()
Chris@16 1175 , boost::forward<Args>(args)...);
Chris@16 1176 this->priv_push_back_simple_commit();
Chris@16 1177 }
Chris@16 1178 else{
Chris@16 1179 typedef container_detail::insert_non_movable_emplace_proxy<Allocator, iterator, Args...> type;
Chris@16 1180 this->priv_insert_back_aux_impl(1, type(this->alloc(), boost::forward<Args>(args)...));
Chris@16 1181 }
Chris@16 1182 }
Chris@16 1183
Chris@16 1184 //! <b>Requires</b>: position must be a valid iterator of *this.
Chris@16 1185 //!
Chris@16 1186 //! <b>Effects</b>: Inserts an object of type T constructed with
Chris@16 1187 //! std::forward<Args>(args)... before position
Chris@16 1188 //!
Chris@16 1189 //! <b>Throws</b>: If memory allocation throws or the in-place constructor throws.
Chris@16 1190 //!
Chris@16 1191 //! <b>Complexity</b>: If position is end(), amortized constant time
Chris@16 1192 //! Linear time otherwise.
Chris@16 1193 template <class... Args>
Chris@16 1194 iterator emplace(const_iterator p, Args&&... args)
Chris@16 1195 {
Chris@16 1196 if(p == this->cbegin()){
Chris@16 1197 this->emplace_front(boost::forward<Args>(args)...);
Chris@16 1198 return this->begin();
Chris@16 1199 }
Chris@16 1200 else if(p == this->cend()){
Chris@16 1201 this->emplace_back(boost::forward<Args>(args)...);
Chris@16 1202 return (this->end()-1);
Chris@16 1203 }
Chris@16 1204 else{
Chris@16 1205 typedef container_detail::insert_emplace_proxy<Allocator, iterator, Args...> type;
Chris@16 1206 return this->priv_insert_aux_impl(p, 1, type(this->alloc(), boost::forward<Args>(args)...));
Chris@16 1207 }
Chris@16 1208 }
Chris@16 1209
Chris@16 1210 #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
Chris@16 1211
Chris@16 1212 //advanced_insert_int.hpp includes all necessary preprocessor machinery...
Chris@16 1213 #define BOOST_PP_LOCAL_MACRO(n) \
Chris@16 1214 BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, > ) \
Chris@16 1215 void emplace_front(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
Chris@16 1216 { \
Chris@16 1217 if(priv_push_front_simple_available()){ \
Chris@16 1218 allocator_traits_type::construct \
Chris@16 1219 ( this->alloc() \
Chris@16 1220 , this->priv_push_front_simple_pos() \
Chris@16 1221 BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
Chris@16 1222 priv_push_front_simple_commit(); \
Chris@16 1223 } \
Chris@16 1224 else{ \
Chris@16 1225 container_detail::BOOST_PP_CAT(insert_non_movable_emplace_proxy_arg, n) \
Chris@16 1226 <Allocator, iterator BOOST_PP_ENUM_TRAILING_PARAMS(n, P)> proxy \
Chris@16 1227 (this->alloc() BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
Chris@16 1228 priv_insert_front_aux_impl(1, proxy); \
Chris@16 1229 } \
Chris@16 1230 } \
Chris@16 1231 \
Chris@16 1232 BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
Chris@16 1233 void emplace_back(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
Chris@16 1234 { \
Chris@16 1235 if(priv_push_back_simple_available()){ \
Chris@16 1236 allocator_traits_type::construct \
Chris@16 1237 ( this->alloc() \
Chris@16 1238 , this->priv_push_back_simple_pos() \
Chris@16 1239 BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
Chris@16 1240 priv_push_back_simple_commit(); \
Chris@16 1241 } \
Chris@16 1242 else{ \
Chris@16 1243 container_detail::BOOST_PP_CAT(insert_non_movable_emplace_proxy_arg, n) \
Chris@16 1244 <Allocator, iterator BOOST_PP_ENUM_TRAILING_PARAMS(n, P)> proxy \
Chris@16 1245 (this->alloc() BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
Chris@16 1246 priv_insert_back_aux_impl(1, proxy); \
Chris@16 1247 } \
Chris@16 1248 } \
Chris@16 1249 \
Chris@16 1250 BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
Chris@16 1251 iterator emplace(const_iterator p \
Chris@16 1252 BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
Chris@16 1253 { \
Chris@16 1254 if(p == this->cbegin()){ \
Chris@16 1255 this->emplace_front(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
Chris@16 1256 return this->begin(); \
Chris@16 1257 } \
Chris@16 1258 else if(p == cend()){ \
Chris@16 1259 this->emplace_back(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
Chris@16 1260 return (this->end()-1); \
Chris@16 1261 } \
Chris@16 1262 else{ \
Chris@16 1263 container_detail::BOOST_PP_CAT(insert_emplace_proxy_arg, n) \
Chris@16 1264 <Allocator, iterator BOOST_PP_ENUM_TRAILING_PARAMS(n, P)> proxy \
Chris@16 1265 (this->alloc() BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
Chris@16 1266 return this->priv_insert_aux_impl(p, 1, proxy); \
Chris@16 1267 } \
Chris@16 1268 } \
Chris@16 1269 //!
Chris@16 1270 #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
Chris@16 1271 #include BOOST_PP_LOCAL_ITERATE()
Chris@16 1272
Chris@16 1273 #endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
Chris@16 1274
Chris@16 1275 #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
Chris@16 1276 //! <b>Effects</b>: Inserts a copy of x at the front of the deque.
Chris@16 1277 //!
Chris@16 1278 //! <b>Throws</b>: If memory allocation throws or
Chris@16 1279 //! T's copy constructor throws.
Chris@16 1280 //!
Chris@16 1281 //! <b>Complexity</b>: Amortized constant time.
Chris@16 1282 void push_front(const T &x);
Chris@16 1283
Chris@16 1284 //! <b>Effects</b>: Constructs a new element in the front of the deque
Chris@16 1285 //! and moves the resources of mx to this new element.
Chris@16 1286 //!
Chris@16 1287 //! <b>Throws</b>: If memory allocation throws.
Chris@16 1288 //!
Chris@16 1289 //! <b>Complexity</b>: Amortized constant time.
Chris@16 1290 void push_front(T &&x);
Chris@16 1291 #else
Chris@16 1292 BOOST_MOVE_CONVERSION_AWARE_CATCH(push_front, T, void, priv_push_front)
Chris@16 1293 #endif
Chris@16 1294
Chris@16 1295 #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
Chris@16 1296 //! <b>Effects</b>: Inserts a copy of x at the end of the deque.
Chris@16 1297 //!
Chris@16 1298 //! <b>Throws</b>: If memory allocation throws or
Chris@16 1299 //! T's copy constructor throws.
Chris@16 1300 //!
Chris@16 1301 //! <b>Complexity</b>: Amortized constant time.
Chris@16 1302 void push_back(const T &x);
Chris@16 1303
Chris@16 1304 //! <b>Effects</b>: Constructs a new element in the end of the deque
Chris@16 1305 //! and moves the resources of mx to this new element.
Chris@16 1306 //!
Chris@16 1307 //! <b>Throws</b>: If memory allocation throws.
Chris@16 1308 //!
Chris@16 1309 //! <b>Complexity</b>: Amortized constant time.
Chris@16 1310 void push_back(T &&x);
Chris@16 1311 #else
Chris@16 1312 BOOST_MOVE_CONVERSION_AWARE_CATCH(push_back, T, void, priv_push_back)
Chris@16 1313 #endif
Chris@16 1314
Chris@16 1315 #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
Chris@16 1316
Chris@16 1317 //! <b>Requires</b>: position must be a valid iterator of *this.
Chris@16 1318 //!
Chris@16 1319 //! <b>Effects</b>: Insert a copy of x before position.
Chris@16 1320 //!
Chris@16 1321 //! <b>Returns</b>: an iterator to the inserted element.
Chris@16 1322 //!
Chris@16 1323 //! <b>Throws</b>: If memory allocation throws or x's copy constructor throws.
Chris@16 1324 //!
Chris@16 1325 //! <b>Complexity</b>: If position is end(), amortized constant time
Chris@16 1326 //! Linear time otherwise.
Chris@16 1327 iterator insert(const_iterator position, const T &x);
Chris@16 1328
Chris@16 1329 //! <b>Requires</b>: position must be a valid iterator of *this.
Chris@16 1330 //!
Chris@16 1331 //! <b>Effects</b>: Insert a new element before position with mx's resources.
Chris@16 1332 //!
Chris@16 1333 //! <b>Returns</b>: an iterator to the inserted element.
Chris@16 1334 //!
Chris@16 1335 //! <b>Throws</b>: If memory allocation throws.
Chris@16 1336 //!
Chris@16 1337 //! <b>Complexity</b>: If position is end(), amortized constant time
Chris@16 1338 //! Linear time otherwise.
Chris@16 1339 iterator insert(const_iterator position, T &&x);
Chris@16 1340 #else
Chris@16 1341 BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert, T, iterator, priv_insert, const_iterator, const_iterator)
Chris@16 1342 #endif
Chris@16 1343
Chris@16 1344 //! <b>Requires</b>: pos must be a valid iterator of *this.
Chris@16 1345 //!
Chris@16 1346 //! <b>Effects</b>: Insert n copies of x before pos.
Chris@16 1347 //!
Chris@16 1348 //! <b>Returns</b>: an iterator to the first inserted element or pos if n is 0.
Chris@16 1349 //!
Chris@16 1350 //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
Chris@16 1351 //!
Chris@16 1352 //! <b>Complexity</b>: Linear to n.
Chris@16 1353 iterator insert(const_iterator pos, size_type n, const value_type& x)
Chris@16 1354 {
Chris@16 1355 typedef constant_iterator<value_type, difference_type> c_it;
Chris@16 1356 return this->insert(pos, c_it(x, n), c_it());
Chris@16 1357 }
Chris@16 1358
Chris@16 1359 //! <b>Requires</b>: pos must be a valid iterator of *this.
Chris@16 1360 //!
Chris@16 1361 //! <b>Effects</b>: Insert a copy of the [first, last) range before pos.
Chris@16 1362 //!
Chris@16 1363 //! <b>Returns</b>: an iterator to the first inserted element or pos if first == last.
Chris@16 1364 //!
Chris@16 1365 //! <b>Throws</b>: If memory allocation throws, T's constructor from a
Chris@16 1366 //! dereferenced InIt throws or T's copy constructor throws.
Chris@16 1367 //!
Chris@16 1368 //! <b>Complexity</b>: Linear to std::distance [first, last).
Chris@16 1369 template <class InIt>
Chris@16 1370 iterator insert(const_iterator pos, InIt first, InIt last
Chris@16 1371 #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
Chris@16 1372 , typename container_detail::enable_if_c
Chris@16 1373 < !container_detail::is_convertible<InIt, size_type>::value
Chris@16 1374 && container_detail::is_input_iterator<InIt>::value
Chris@16 1375 >::type * = 0
Chris@16 1376 #endif
Chris@16 1377 )
Chris@16 1378 {
Chris@16 1379 size_type n = 0;
Chris@16 1380 iterator it(pos.unconst());
Chris@16 1381 for(;first != last; ++first, ++n){
Chris@16 1382 it = this->emplace(it, *first);
Chris@16 1383 ++it;
Chris@16 1384 }
Chris@16 1385 it -= n;
Chris@16 1386 return it;
Chris@16 1387 }
Chris@16 1388
Chris@16 1389 #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
Chris@16 1390 template <class FwdIt>
Chris@16 1391 iterator insert(const_iterator p, FwdIt first, FwdIt last
Chris@16 1392 #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
Chris@16 1393 , typename container_detail::enable_if_c
Chris@16 1394 < !container_detail::is_convertible<FwdIt, size_type>::value
Chris@16 1395 && !container_detail::is_input_iterator<FwdIt>::value
Chris@16 1396 >::type * = 0
Chris@16 1397 #endif
Chris@16 1398 )
Chris@16 1399 {
Chris@16 1400 container_detail::insert_range_proxy<Allocator, FwdIt, iterator> proxy(this->alloc(), first);
Chris@16 1401 return priv_insert_aux_impl(p, (size_type)std::distance(first, last), proxy);
Chris@16 1402 }
Chris@16 1403 #endif
Chris@16 1404
Chris@16 1405 //! <b>Effects</b>: Removes the first element from the deque.
Chris@16 1406 //!
Chris@16 1407 //! <b>Throws</b>: Nothing.
Chris@16 1408 //!
Chris@16 1409 //! <b>Complexity</b>: Constant time.
Chris@16 1410 void pop_front() BOOST_CONTAINER_NOEXCEPT
Chris@16 1411 {
Chris@16 1412 if (this->members_.m_start.m_cur != this->members_.m_start.m_last - 1) {
Chris@16 1413 allocator_traits_type::destroy
Chris@16 1414 ( this->alloc()
Chris@16 1415 , container_detail::to_raw_pointer(this->members_.m_start.m_cur)
Chris@16 1416 );
Chris@16 1417 ++this->members_.m_start.m_cur;
Chris@16 1418 }
Chris@16 1419 else
Chris@16 1420 this->priv_pop_front_aux();
Chris@16 1421 }
Chris@16 1422
Chris@16 1423 //! <b>Effects</b>: Removes the last element from the deque.
Chris@16 1424 //!
Chris@16 1425 //! <b>Throws</b>: Nothing.
Chris@16 1426 //!
Chris@16 1427 //! <b>Complexity</b>: Constant time.
Chris@16 1428 void pop_back() BOOST_CONTAINER_NOEXCEPT
Chris@16 1429 {
Chris@16 1430 if (this->members_.m_finish.m_cur != this->members_.m_finish.m_first) {
Chris@16 1431 --this->members_.m_finish.m_cur;
Chris@16 1432 allocator_traits_type::destroy
Chris@16 1433 ( this->alloc()
Chris@16 1434 , container_detail::to_raw_pointer(this->members_.m_finish.m_cur)
Chris@16 1435 );
Chris@16 1436 }
Chris@16 1437 else
Chris@16 1438 this->priv_pop_back_aux();
Chris@16 1439 }
Chris@16 1440
Chris@16 1441 //! <b>Effects</b>: Erases the element at position pos.
Chris@16 1442 //!
Chris@16 1443 //! <b>Throws</b>: Nothing.
Chris@16 1444 //!
Chris@16 1445 //! <b>Complexity</b>: Linear to the elements between pos and the
Chris@16 1446 //! last element (if pos is near the end) or the first element
Chris@16 1447 //! if(pos is near the beginning).
Chris@16 1448 //! Constant if pos is the first or the last element.
Chris@16 1449 iterator erase(const_iterator pos) BOOST_CONTAINER_NOEXCEPT
Chris@16 1450 {
Chris@16 1451 iterator next = pos.unconst();
Chris@16 1452 ++next;
Chris@16 1453 size_type index = pos - this->members_.m_start;
Chris@16 1454 if (index < (this->size()/2)) {
Chris@16 1455 boost::move_backward(this->begin(), pos.unconst(), next);
Chris@16 1456 pop_front();
Chris@16 1457 }
Chris@16 1458 else {
Chris@16 1459 boost::move(next, this->end(), pos.unconst());
Chris@16 1460 pop_back();
Chris@16 1461 }
Chris@16 1462 return this->members_.m_start + index;
Chris@16 1463 }
Chris@16 1464
Chris@16 1465 //! <b>Effects</b>: Erases the elements pointed by [first, last).
Chris@16 1466 //!
Chris@16 1467 //! <b>Throws</b>: Nothing.
Chris@16 1468 //!
Chris@16 1469 //! <b>Complexity</b>: Linear to the distance between first and
Chris@16 1470 //! last plus the elements between pos and the
Chris@16 1471 //! last element (if pos is near the end) or the first element
Chris@16 1472 //! if(pos is near the beginning).
Chris@16 1473 iterator erase(const_iterator first, const_iterator last) BOOST_CONTAINER_NOEXCEPT
Chris@16 1474 {
Chris@16 1475 if (first == this->members_.m_start && last == this->members_.m_finish) {
Chris@16 1476 this->clear();
Chris@16 1477 return this->members_.m_finish;
Chris@16 1478 }
Chris@16 1479 else {
Chris@16 1480 const size_type n = static_cast<size_type>(last - first);
Chris@16 1481 const size_type elems_before = static_cast<size_type>(first - this->members_.m_start);
Chris@16 1482 if (elems_before < (this->size() - n) - elems_before) {
Chris@16 1483 boost::move_backward(begin(), first.unconst(), last.unconst());
Chris@16 1484 iterator new_start = this->members_.m_start + n;
Chris@16 1485 if(!Base::traits_t::trivial_dctr_after_move)
Chris@16 1486 this->priv_destroy_range(this->members_.m_start, new_start);
Chris@16 1487 this->priv_destroy_nodes(this->members_.m_start.m_node, new_start.m_node);
Chris@16 1488 this->members_.m_start = new_start;
Chris@16 1489 }
Chris@16 1490 else {
Chris@16 1491 boost::move(last.unconst(), end(), first.unconst());
Chris@16 1492 iterator new_finish = this->members_.m_finish - n;
Chris@16 1493 if(!Base::traits_t::trivial_dctr_after_move)
Chris@16 1494 this->priv_destroy_range(new_finish, this->members_.m_finish);
Chris@16 1495 this->priv_destroy_nodes(new_finish.m_node + 1, this->members_.m_finish.m_node + 1);
Chris@16 1496 this->members_.m_finish = new_finish;
Chris@16 1497 }
Chris@16 1498 return this->members_.m_start + elems_before;
Chris@16 1499 }
Chris@16 1500 }
Chris@16 1501
Chris@16 1502 //! <b>Effects</b>: Swaps the contents of *this and x.
Chris@16 1503 //!
Chris@16 1504 //! <b>Throws</b>: Nothing.
Chris@16 1505 //!
Chris@16 1506 //! <b>Complexity</b>: Constant.
Chris@16 1507 void swap(deque &x)
Chris@16 1508 {
Chris@16 1509 this->swap_members(x);
Chris@16 1510 container_detail::bool_<allocator_traits_type::propagate_on_container_swap::value> flag;
Chris@16 1511 container_detail::swap_alloc(this->alloc(), x.alloc(), flag);
Chris@16 1512 container_detail::swap_alloc(this->ptr_alloc(), x.ptr_alloc(), flag);
Chris@16 1513 }
Chris@16 1514
Chris@16 1515 //! <b>Effects</b>: Erases all the elements of the deque.
Chris@16 1516 //!
Chris@16 1517 //! <b>Throws</b>: Nothing.
Chris@16 1518 //!
Chris@16 1519 //! <b>Complexity</b>: Linear to the number of elements in the deque.
Chris@16 1520 void clear() BOOST_CONTAINER_NOEXCEPT
Chris@16 1521 {
Chris@16 1522 for (index_pointer node = this->members_.m_start.m_node + 1;
Chris@16 1523 node < this->members_.m_finish.m_node;
Chris@16 1524 ++node) {
Chris@16 1525 this->priv_destroy_range(*node, *node + this->s_buffer_size());
Chris@16 1526 this->priv_deallocate_node(*node);
Chris@16 1527 }
Chris@16 1528
Chris@16 1529 if (this->members_.m_start.m_node != this->members_.m_finish.m_node) {
Chris@16 1530 this->priv_destroy_range(this->members_.m_start.m_cur, this->members_.m_start.m_last);
Chris@16 1531 this->priv_destroy_range(this->members_.m_finish.m_first, this->members_.m_finish.m_cur);
Chris@16 1532 this->priv_deallocate_node(this->members_.m_finish.m_first);
Chris@16 1533 }
Chris@16 1534 else
Chris@16 1535 this->priv_destroy_range(this->members_.m_start.m_cur, this->members_.m_finish.m_cur);
Chris@16 1536
Chris@16 1537 this->members_.m_finish = this->members_.m_start;
Chris@16 1538 }
Chris@16 1539
Chris@16 1540 /// @cond
Chris@16 1541 private:
Chris@16 1542
Chris@16 1543 void priv_erase_last_n(size_type n)
Chris@16 1544 {
Chris@16 1545 if(n == this->size()) {
Chris@16 1546 this->clear();
Chris@16 1547 }
Chris@16 1548 else {
Chris@16 1549 iterator new_finish = this->members_.m_finish - n;
Chris@16 1550 if(!Base::traits_t::trivial_dctr_after_move)
Chris@16 1551 this->priv_destroy_range(new_finish, this->members_.m_finish);
Chris@16 1552 this->priv_destroy_nodes(new_finish.m_node + 1, this->members_.m_finish.m_node + 1);
Chris@16 1553 this->members_.m_finish = new_finish;
Chris@16 1554 }
Chris@16 1555 }
Chris@16 1556
Chris@16 1557 void priv_range_check(size_type n) const
Chris@16 1558 { if (n >= this->size()) throw_out_of_range("deque::at out of range"); }
Chris@16 1559
Chris@16 1560 template <class U>
Chris@16 1561 iterator priv_insert(const_iterator position, BOOST_FWD_REF(U) x)
Chris@16 1562 {
Chris@16 1563 if (position == cbegin()){
Chris@16 1564 this->push_front(::boost::forward<U>(x));
Chris@16 1565 return begin();
Chris@16 1566 }
Chris@16 1567 else if (position == cend()){
Chris@16 1568 this->push_back(::boost::forward<U>(x));
Chris@16 1569 return --end();
Chris@16 1570 }
Chris@16 1571 else {
Chris@16 1572 return priv_insert_aux_impl
Chris@16 1573 (position, (size_type)1, container_detail::get_insert_value_proxy<iterator>(this->alloc(), ::boost::forward<U>(x)));
Chris@16 1574 }
Chris@16 1575 }
Chris@16 1576
Chris@16 1577 template <class U>
Chris@16 1578 void priv_push_front(BOOST_FWD_REF(U) x)
Chris@16 1579 {
Chris@16 1580 if(this->priv_push_front_simple_available()){
Chris@16 1581 allocator_traits_type::construct
Chris@16 1582 ( this->alloc(), this->priv_push_front_simple_pos(), ::boost::forward<U>(x));
Chris@16 1583 this->priv_push_front_simple_commit();
Chris@16 1584 }
Chris@16 1585 else{
Chris@16 1586 priv_insert_aux_impl
Chris@16 1587 (this->cbegin(), (size_type)1, container_detail::get_insert_value_proxy<iterator>(this->alloc(), ::boost::forward<U>(x)));
Chris@16 1588 }
Chris@16 1589 }
Chris@16 1590
Chris@16 1591 template <class U>
Chris@16 1592 void priv_push_back(BOOST_FWD_REF(U) x)
Chris@16 1593 {
Chris@16 1594 if(this->priv_push_back_simple_available()){
Chris@16 1595 allocator_traits_type::construct
Chris@16 1596 ( this->alloc(), this->priv_push_back_simple_pos(), ::boost::forward<U>(x));
Chris@16 1597 this->priv_push_back_simple_commit();
Chris@16 1598 }
Chris@16 1599 else{
Chris@16 1600 priv_insert_aux_impl
Chris@16 1601 (this->cend(), (size_type)1, container_detail::get_insert_value_proxy<iterator>(this->alloc(), ::boost::forward<U>(x)));
Chris@16 1602 container_detail::insert_copy_proxy<Allocator, iterator> proxy(this->alloc(), x);
Chris@16 1603 }
Chris@16 1604 }
Chris@16 1605
Chris@16 1606 bool priv_push_back_simple_available() const
Chris@16 1607 {
Chris@16 1608 return this->members_.m_map &&
Chris@16 1609 (this->members_.m_finish.m_cur != (this->members_.m_finish.m_last - 1));
Chris@16 1610 }
Chris@16 1611
Chris@16 1612 T *priv_push_back_simple_pos() const
Chris@16 1613 {
Chris@16 1614 return container_detail::to_raw_pointer(this->members_.m_finish.m_cur);
Chris@16 1615 }
Chris@16 1616
Chris@16 1617 void priv_push_back_simple_commit()
Chris@16 1618 {
Chris@16 1619 ++this->members_.m_finish.m_cur;
Chris@16 1620 }
Chris@16 1621
Chris@16 1622 bool priv_push_front_simple_available() const
Chris@16 1623 {
Chris@16 1624 return this->members_.m_map &&
Chris@16 1625 (this->members_.m_start.m_cur != this->members_.m_start.m_first);
Chris@16 1626 }
Chris@16 1627
Chris@16 1628 T *priv_push_front_simple_pos() const
Chris@16 1629 { return container_detail::to_raw_pointer(this->members_.m_start.m_cur) - 1; }
Chris@16 1630
Chris@16 1631 void priv_push_front_simple_commit()
Chris@16 1632 { --this->members_.m_start.m_cur; }
Chris@16 1633
Chris@16 1634 void priv_destroy_range(iterator p, iterator p2)
Chris@16 1635 {
Chris@16 1636 for(;p != p2; ++p){
Chris@16 1637 allocator_traits_type::destroy
Chris@16 1638 ( this->alloc()
Chris@16 1639 , container_detail::to_raw_pointer(&*p)
Chris@16 1640 );
Chris@16 1641 }
Chris@16 1642 }
Chris@16 1643
Chris@16 1644 void priv_destroy_range(pointer p, pointer p2)
Chris@16 1645 {
Chris@16 1646 for(;p != p2; ++p){
Chris@16 1647 allocator_traits_type::destroy
Chris@16 1648 ( this->alloc()
Chris@16 1649 , container_detail::to_raw_pointer(&*p)
Chris@16 1650 );
Chris@16 1651 }
Chris@16 1652 }
Chris@16 1653
Chris@16 1654 template<class InsertProxy>
Chris@16 1655 iterator priv_insert_aux_impl(const_iterator p, size_type n, InsertProxy interf)
Chris@16 1656 {
Chris@16 1657 iterator pos(p.unconst());
Chris@16 1658 const size_type pos_n = p - this->cbegin();
Chris@16 1659 if(!this->members_.m_map){
Chris@16 1660 this->priv_initialize_map(0);
Chris@16 1661 pos = this->begin();
Chris@16 1662 }
Chris@16 1663
Chris@16 1664 const size_type elemsbefore = static_cast<size_type>(pos - this->members_.m_start);
Chris@16 1665 const size_type length = this->size();
Chris@16 1666 if (elemsbefore < length / 2) {
Chris@16 1667 const iterator new_start = this->priv_reserve_elements_at_front(n);
Chris@16 1668 const iterator old_start = this->members_.m_start;
Chris@16 1669 if(!elemsbefore){
Chris@16 1670 interf.uninitialized_copy_n_and_update(new_start, n);
Chris@16 1671 this->members_.m_start = new_start;
Chris@16 1672 }
Chris@16 1673 else{
Chris@16 1674 pos = this->members_.m_start + elemsbefore;
Chris@16 1675 if (elemsbefore >= n) {
Chris@16 1676 const iterator start_n = this->members_.m_start + n;
Chris@16 1677 ::boost::container::uninitialized_move_alloc
Chris@16 1678 (this->alloc(), this->members_.m_start, start_n, new_start);
Chris@16 1679 this->members_.m_start = new_start;
Chris@16 1680 boost::move(start_n, pos, old_start);
Chris@16 1681 interf.copy_n_and_update(pos - n, n);
Chris@16 1682 }
Chris@16 1683 else {
Chris@16 1684 const size_type mid_count = n - elemsbefore;
Chris@16 1685 const iterator mid_start = old_start - mid_count;
Chris@16 1686 interf.uninitialized_copy_n_and_update(mid_start, mid_count);
Chris@16 1687 this->members_.m_start = mid_start;
Chris@16 1688 ::boost::container::uninitialized_move_alloc
Chris@16 1689 (this->alloc(), old_start, pos, new_start);
Chris@16 1690 this->members_.m_start = new_start;
Chris@16 1691 interf.copy_n_and_update(old_start, elemsbefore);
Chris@16 1692 }
Chris@16 1693 }
Chris@16 1694 }
Chris@16 1695 else {
Chris@16 1696 const iterator new_finish = this->priv_reserve_elements_at_back(n);
Chris@16 1697 const iterator old_finish = this->members_.m_finish;
Chris@16 1698 const size_type elemsafter = length - elemsbefore;
Chris@16 1699 if(!elemsafter){
Chris@16 1700 interf.uninitialized_copy_n_and_update(old_finish, n);
Chris@16 1701 this->members_.m_finish = new_finish;
Chris@16 1702 }
Chris@16 1703 else{
Chris@16 1704 pos = old_finish - elemsafter;
Chris@16 1705 if (elemsafter >= n) {
Chris@16 1706 iterator finish_n = old_finish - difference_type(n);
Chris@16 1707 ::boost::container::uninitialized_move_alloc
Chris@16 1708 (this->alloc(), finish_n, old_finish, old_finish);
Chris@16 1709 this->members_.m_finish = new_finish;
Chris@16 1710 boost::move_backward(pos, finish_n, old_finish);
Chris@16 1711 interf.copy_n_and_update(pos, n);
Chris@16 1712 }
Chris@16 1713 else {
Chris@16 1714 const size_type raw_gap = n - elemsafter;
Chris@16 1715 ::boost::container::uninitialized_move_alloc
Chris@16 1716 (this->alloc(), pos, old_finish, old_finish + raw_gap);
Chris@16 1717 BOOST_TRY{
Chris@16 1718 interf.copy_n_and_update(pos, elemsafter);
Chris@16 1719 interf.uninitialized_copy_n_and_update(old_finish, raw_gap);
Chris@16 1720 }
Chris@16 1721 BOOST_CATCH(...){
Chris@16 1722 this->priv_destroy_range(old_finish, old_finish + elemsafter);
Chris@16 1723 BOOST_RETHROW
Chris@16 1724 }
Chris@16 1725 BOOST_CATCH_END
Chris@16 1726 this->members_.m_finish = new_finish;
Chris@16 1727 }
Chris@16 1728 }
Chris@16 1729 }
Chris@16 1730 return this->begin() + pos_n;
Chris@16 1731 }
Chris@16 1732
Chris@16 1733 template <class InsertProxy>
Chris@16 1734 iterator priv_insert_back_aux_impl(size_type n, InsertProxy interf)
Chris@16 1735 {
Chris@16 1736 if(!this->members_.m_map){
Chris@16 1737 this->priv_initialize_map(0);
Chris@16 1738 }
Chris@16 1739
Chris@16 1740 iterator new_finish = this->priv_reserve_elements_at_back(n);
Chris@16 1741 iterator old_finish = this->members_.m_finish;
Chris@16 1742 interf.uninitialized_copy_n_and_update(old_finish, n);
Chris@16 1743 this->members_.m_finish = new_finish;
Chris@16 1744 return iterator(this->members_.m_finish - n);
Chris@16 1745 }
Chris@16 1746
Chris@16 1747 template <class InsertProxy>
Chris@16 1748 iterator priv_insert_front_aux_impl(size_type n, InsertProxy interf)
Chris@16 1749 {
Chris@16 1750 if(!this->members_.m_map){
Chris@16 1751 this->priv_initialize_map(0);
Chris@16 1752 }
Chris@16 1753
Chris@16 1754 iterator new_start = this->priv_reserve_elements_at_front(n);
Chris@16 1755 interf.uninitialized_copy_n_and_update(new_start, n);
Chris@16 1756 this->members_.m_start = new_start;
Chris@16 1757 return new_start;
Chris@16 1758 }
Chris@16 1759
Chris@16 1760 iterator priv_fill_insert(const_iterator pos, size_type n, const value_type& x)
Chris@16 1761 {
Chris@16 1762 typedef constant_iterator<value_type, difference_type> c_it;
Chris@16 1763 return this->insert(pos, c_it(x, n), c_it());
Chris@16 1764 }
Chris@16 1765
Chris@16 1766 // Precondition: this->members_.m_start and this->members_.m_finish have already been initialized,
Chris@16 1767 // but none of the deque's elements have yet been constructed.
Chris@16 1768 void priv_fill_initialize(const value_type& value)
Chris@16 1769 {
Chris@16 1770 index_pointer cur;
Chris@16 1771 BOOST_TRY {
Chris@16 1772 for (cur = this->members_.m_start.m_node; cur < this->members_.m_finish.m_node; ++cur){
Chris@16 1773 boost::container::uninitialized_fill_alloc
Chris@16 1774 (this->alloc(), *cur, *cur + this->s_buffer_size(), value);
Chris@16 1775 }
Chris@16 1776 boost::container::uninitialized_fill_alloc
Chris@16 1777 (this->alloc(), this->members_.m_finish.m_first, this->members_.m_finish.m_cur, value);
Chris@16 1778 }
Chris@16 1779 BOOST_CATCH(...){
Chris@16 1780 this->priv_destroy_range(this->members_.m_start, iterator(*cur, cur));
Chris@16 1781 BOOST_RETHROW
Chris@16 1782 }
Chris@16 1783 BOOST_CATCH_END
Chris@16 1784 }
Chris@16 1785
Chris@16 1786 template <class InIt>
Chris@16 1787 void priv_range_initialize(InIt first, InIt last, std::input_iterator_tag)
Chris@16 1788 {
Chris@16 1789 this->priv_initialize_map(0);
Chris@16 1790 BOOST_TRY {
Chris@16 1791 for ( ; first != last; ++first)
Chris@16 1792 this->emplace_back(*first);
Chris@16 1793 }
Chris@16 1794 BOOST_CATCH(...){
Chris@16 1795 this->clear();
Chris@16 1796 BOOST_RETHROW
Chris@16 1797 }
Chris@16 1798 BOOST_CATCH_END
Chris@16 1799 }
Chris@16 1800
Chris@16 1801 template <class FwdIt>
Chris@16 1802 void priv_range_initialize(FwdIt first, FwdIt last, std::forward_iterator_tag)
Chris@16 1803 {
Chris@16 1804 size_type n = 0;
Chris@16 1805 n = std::distance(first, last);
Chris@16 1806 this->priv_initialize_map(n);
Chris@16 1807
Chris@16 1808 index_pointer cur_node;
Chris@16 1809 BOOST_TRY {
Chris@16 1810 for (cur_node = this->members_.m_start.m_node;
Chris@16 1811 cur_node < this->members_.m_finish.m_node;
Chris@16 1812 ++cur_node) {
Chris@16 1813 FwdIt mid = first;
Chris@16 1814 std::advance(mid, this->s_buffer_size());
Chris@16 1815 ::boost::container::uninitialized_copy_alloc(this->alloc(), first, mid, *cur_node);
Chris@16 1816 first = mid;
Chris@16 1817 }
Chris@16 1818 ::boost::container::uninitialized_copy_alloc(this->alloc(), first, last, this->members_.m_finish.m_first);
Chris@16 1819 }
Chris@16 1820 BOOST_CATCH(...){
Chris@16 1821 this->priv_destroy_range(this->members_.m_start, iterator(*cur_node, cur_node));
Chris@16 1822 BOOST_RETHROW
Chris@16 1823 }
Chris@16 1824 BOOST_CATCH_END
Chris@16 1825 }
Chris@16 1826
Chris@16 1827 // Called only if this->members_.m_finish.m_cur == this->members_.m_finish.m_first.
Chris@16 1828 void priv_pop_back_aux() BOOST_CONTAINER_NOEXCEPT
Chris@16 1829 {
Chris@16 1830 this->priv_deallocate_node(this->members_.m_finish.m_first);
Chris@16 1831 this->members_.m_finish.priv_set_node(this->members_.m_finish.m_node - 1);
Chris@16 1832 this->members_.m_finish.m_cur = this->members_.m_finish.m_last - 1;
Chris@16 1833 allocator_traits_type::destroy
Chris@16 1834 ( this->alloc()
Chris@16 1835 , container_detail::to_raw_pointer(this->members_.m_finish.m_cur)
Chris@16 1836 );
Chris@16 1837 }
Chris@16 1838
Chris@16 1839 // Called only if this->members_.m_start.m_cur == this->members_.m_start.m_last - 1. Note that
Chris@16 1840 // if the deque has at least one element (a precondition for this member
Chris@16 1841 // function), and if this->members_.m_start.m_cur == this->members_.m_start.m_last, then the deque
Chris@16 1842 // must have at least two nodes.
Chris@16 1843 void priv_pop_front_aux() BOOST_CONTAINER_NOEXCEPT
Chris@16 1844 {
Chris@16 1845 allocator_traits_type::destroy
Chris@16 1846 ( this->alloc()
Chris@16 1847 , container_detail::to_raw_pointer(this->members_.m_start.m_cur)
Chris@16 1848 );
Chris@16 1849 this->priv_deallocate_node(this->members_.m_start.m_first);
Chris@16 1850 this->members_.m_start.priv_set_node(this->members_.m_start.m_node + 1);
Chris@16 1851 this->members_.m_start.m_cur = this->members_.m_start.m_first;
Chris@16 1852 }
Chris@16 1853
Chris@16 1854 iterator priv_reserve_elements_at_front(size_type n)
Chris@16 1855 {
Chris@16 1856 size_type vacancies = this->members_.m_start.m_cur - this->members_.m_start.m_first;
Chris@16 1857 if (n > vacancies){
Chris@16 1858 size_type new_elems = n-vacancies;
Chris@16 1859 size_type new_nodes = (new_elems + this->s_buffer_size() - 1) /
Chris@16 1860 this->s_buffer_size();
Chris@16 1861 size_type s = (size_type)(this->members_.m_start.m_node - this->members_.m_map);
Chris@16 1862 if (new_nodes > s){
Chris@16 1863 this->priv_reallocate_map(new_nodes, true);
Chris@16 1864 }
Chris@16 1865 size_type i = 1;
Chris@16 1866 BOOST_TRY {
Chris@16 1867 for (; i <= new_nodes; ++i)
Chris@16 1868 *(this->members_.m_start.m_node - i) = this->priv_allocate_node();
Chris@16 1869 }
Chris@16 1870 BOOST_CATCH(...) {
Chris@16 1871 for (size_type j = 1; j < i; ++j)
Chris@16 1872 this->priv_deallocate_node(*(this->members_.m_start.m_node - j));
Chris@16 1873 BOOST_RETHROW
Chris@16 1874 }
Chris@16 1875 BOOST_CATCH_END
Chris@16 1876 }
Chris@16 1877 return this->members_.m_start - difference_type(n);
Chris@16 1878 }
Chris@16 1879
Chris@16 1880 iterator priv_reserve_elements_at_back(size_type n)
Chris@16 1881 {
Chris@16 1882 size_type vacancies = (this->members_.m_finish.m_last - this->members_.m_finish.m_cur) - 1;
Chris@16 1883 if (n > vacancies){
Chris@16 1884 size_type new_elems = n - vacancies;
Chris@16 1885 size_type new_nodes = (new_elems + this->s_buffer_size() - 1)/s_buffer_size();
Chris@16 1886 size_type s = (size_type)(this->members_.m_map_size - (this->members_.m_finish.m_node - this->members_.m_map));
Chris@16 1887 if (new_nodes + 1 > s){
Chris@16 1888 this->priv_reallocate_map(new_nodes, false);
Chris@16 1889 }
Chris@16 1890 size_type i;
Chris@16 1891 BOOST_TRY {
Chris@16 1892 for (i = 1; i <= new_nodes; ++i)
Chris@16 1893 *(this->members_.m_finish.m_node + i) = this->priv_allocate_node();
Chris@16 1894 }
Chris@16 1895 BOOST_CATCH(...) {
Chris@16 1896 for (size_type j = 1; j < i; ++j)
Chris@16 1897 this->priv_deallocate_node(*(this->members_.m_finish.m_node + j));
Chris@16 1898 BOOST_RETHROW
Chris@16 1899 }
Chris@16 1900 BOOST_CATCH_END
Chris@16 1901 }
Chris@16 1902 return this->members_.m_finish + difference_type(n);
Chris@16 1903 }
Chris@16 1904
Chris@16 1905 void priv_reallocate_map(size_type nodes_to_add, bool add_at_front)
Chris@16 1906 {
Chris@16 1907 size_type old_num_nodes = this->members_.m_finish.m_node - this->members_.m_start.m_node + 1;
Chris@16 1908 size_type new_num_nodes = old_num_nodes + nodes_to_add;
Chris@16 1909
Chris@16 1910 index_pointer new_nstart;
Chris@16 1911 if (this->members_.m_map_size > 2 * new_num_nodes) {
Chris@16 1912 new_nstart = this->members_.m_map + (this->members_.m_map_size - new_num_nodes) / 2
Chris@16 1913 + (add_at_front ? nodes_to_add : 0);
Chris@16 1914 if (new_nstart < this->members_.m_start.m_node)
Chris@16 1915 boost::move(this->members_.m_start.m_node, this->members_.m_finish.m_node + 1, new_nstart);
Chris@16 1916 else
Chris@16 1917 boost::move_backward
Chris@16 1918 (this->members_.m_start.m_node, this->members_.m_finish.m_node + 1, new_nstart + old_num_nodes);
Chris@16 1919 }
Chris@16 1920 else {
Chris@16 1921 size_type new_map_size =
Chris@16 1922 this->members_.m_map_size + container_detail::max_value(this->members_.m_map_size, nodes_to_add) + 2;
Chris@16 1923
Chris@16 1924 index_pointer new_map = this->priv_allocate_map(new_map_size);
Chris@16 1925 new_nstart = new_map + (new_map_size - new_num_nodes) / 2
Chris@16 1926 + (add_at_front ? nodes_to_add : 0);
Chris@16 1927 boost::move(this->members_.m_start.m_node, this->members_.m_finish.m_node + 1, new_nstart);
Chris@16 1928 this->priv_deallocate_map(this->members_.m_map, this->members_.m_map_size);
Chris@16 1929
Chris@16 1930 this->members_.m_map = new_map;
Chris@16 1931 this->members_.m_map_size = new_map_size;
Chris@16 1932 }
Chris@16 1933
Chris@16 1934 this->members_.m_start.priv_set_node(new_nstart);
Chris@16 1935 this->members_.m_finish.priv_set_node(new_nstart + old_num_nodes - 1);
Chris@16 1936 }
Chris@16 1937 /// @endcond
Chris@16 1938 };
Chris@16 1939
Chris@16 1940 // Nonmember functions.
Chris@16 1941 template <class T, class Allocator>
Chris@16 1942 inline bool operator==(const deque<T, Allocator>& x, const deque<T, Allocator>& y) BOOST_CONTAINER_NOEXCEPT
Chris@16 1943 {
Chris@16 1944 return x.size() == y.size() && equal(x.begin(), x.end(), y.begin());
Chris@16 1945 }
Chris@16 1946
Chris@16 1947 template <class T, class Allocator>
Chris@16 1948 inline bool operator<(const deque<T, Allocator>& x, const deque<T, Allocator>& y) BOOST_CONTAINER_NOEXCEPT
Chris@16 1949 {
Chris@16 1950 return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
Chris@16 1951 }
Chris@16 1952
Chris@16 1953 template <class T, class Allocator>
Chris@16 1954 inline bool operator!=(const deque<T, Allocator>& x, const deque<T, Allocator>& y) BOOST_CONTAINER_NOEXCEPT
Chris@16 1955 { return !(x == y); }
Chris@16 1956
Chris@16 1957 template <class T, class Allocator>
Chris@16 1958 inline bool operator>(const deque<T, Allocator>& x, const deque<T, Allocator>& y) BOOST_CONTAINER_NOEXCEPT
Chris@16 1959 { return y < x; }
Chris@16 1960
Chris@16 1961 template <class T, class Allocator>
Chris@16 1962 inline bool operator>=(const deque<T, Allocator>& x, const deque<T, Allocator>& y) BOOST_CONTAINER_NOEXCEPT
Chris@16 1963 { return !(x < y); }
Chris@16 1964
Chris@16 1965 template <class T, class Allocator>
Chris@16 1966 inline bool operator<=(const deque<T, Allocator>& x, const deque<T, Allocator>& y) BOOST_CONTAINER_NOEXCEPT
Chris@16 1967 { return !(y < x); }
Chris@16 1968
Chris@16 1969 template <class T, class Allocator>
Chris@16 1970 inline void swap(deque<T, Allocator>& x, deque<T, Allocator>& y)
Chris@16 1971 { x.swap(y); }
Chris@16 1972
Chris@16 1973 }}
Chris@16 1974
Chris@16 1975 /// @cond
Chris@16 1976
Chris@16 1977 namespace boost {
Chris@16 1978
Chris@16 1979 //!has_trivial_destructor_after_move<> == true_type
Chris@16 1980 //!specialization for optimizations
Chris@16 1981 template <class T, class Allocator>
Chris@16 1982 struct has_trivial_destructor_after_move<boost::container::deque<T, Allocator> >
Chris@16 1983 : public ::boost::has_trivial_destructor_after_move<Allocator>
Chris@16 1984 {};
Chris@16 1985
Chris@16 1986 }
Chris@16 1987
Chris@16 1988 /// @endcond
Chris@16 1989
Chris@16 1990 #include <boost/container/detail/config_end.hpp>
Chris@16 1991
Chris@16 1992 #endif // #ifndef BOOST_CONTAINER_DEQUE_HPP