annotate DEPENDENCIES/generic/include/boost/container/stable_vector.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 2008-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 // Stable vector.
Chris@16 11 //
Chris@16 12 // Copyright 2008 Joaquin M Lopez Munoz.
Chris@16 13 // Distributed under the Boost Software License, Version 1.0.
Chris@16 14 // (See accompanying file LICENSE_1_0.txt or copy at
Chris@16 15 // http://www.boost.org/LICENSE_1_0.txt)
Chris@16 16 //
Chris@16 17 //////////////////////////////////////////////////////////////////////////////
Chris@16 18
Chris@16 19 #ifndef BOOST_CONTAINER_STABLE_VECTOR_HPP
Chris@16 20 #define BOOST_CONTAINER_STABLE_VECTOR_HPP
Chris@16 21
Chris@16 22 #if defined(_MSC_VER)
Chris@16 23 # pragma once
Chris@16 24 #endif
Chris@16 25
Chris@16 26 #include <boost/container/detail/config_begin.hpp>
Chris@16 27 #include <boost/container/detail/workaround.hpp>
Chris@16 28 #include <boost/container/container_fwd.hpp>
Chris@16 29 #include <boost/mpl/bool.hpp>
Chris@16 30 #include <boost/mpl/not.hpp>
Chris@16 31 #include <boost/assert.hpp>
Chris@16 32 #include <boost/container/throw_exception.hpp>
Chris@16 33 #include <boost/container/detail/allocator_version_traits.hpp>
Chris@16 34 #include <boost/container/detail/utilities.hpp>
Chris@16 35 #include <boost/container/detail/iterators.hpp>
Chris@16 36 #include <boost/container/detail/algorithms.hpp>
Chris@16 37 #include <boost/container/allocator_traits.hpp>
Chris@16 38 #include <boost/container/throw_exception.hpp>
Chris@16 39 #include <boost/intrusive/pointer_traits.hpp>
Chris@16 40 #include <boost/detail/no_exceptions_support.hpp>
Chris@16 41 #include <boost/aligned_storage.hpp>
Chris@16 42 #include <boost/move/utility.hpp>
Chris@16 43 #include <boost/move/iterator.hpp>
Chris@16 44 #include <boost/move/detail/move_helpers.hpp>
Chris@16 45 #include <algorithm> //max
Chris@16 46
Chris@16 47 #include <memory>
Chris@16 48 #include <new> //placement new
Chris@16 49
Chris@16 50 ///@cond
Chris@16 51
Chris@16 52 #include <boost/container/vector.hpp>
Chris@16 53
Chris@16 54 //#define STABLE_VECTOR_ENABLE_INVARIANT_CHECKING
Chris@16 55
Chris@16 56 ///@endcond
Chris@16 57
Chris@16 58 namespace boost {
Chris@16 59 namespace container {
Chris@16 60
Chris@16 61 ///@cond
Chris@16 62
Chris@16 63 namespace stable_vector_detail{
Chris@16 64
Chris@16 65 template <class C>
Chris@16 66 class clear_on_destroy
Chris@16 67 {
Chris@16 68 public:
Chris@16 69 clear_on_destroy(C &c)
Chris@16 70 : c_(c), do_clear_(true)
Chris@16 71 {}
Chris@16 72
Chris@16 73 void release()
Chris@16 74 { do_clear_ = false; }
Chris@16 75
Chris@16 76 ~clear_on_destroy()
Chris@16 77 {
Chris@16 78 if(do_clear_){
Chris@16 79 c_.clear();
Chris@16 80 c_.priv_clear_pool();
Chris@16 81 }
Chris@16 82 }
Chris@16 83
Chris@16 84 private:
Chris@16 85 clear_on_destroy(const clear_on_destroy &);
Chris@16 86 clear_on_destroy &operator=(const clear_on_destroy &);
Chris@16 87 C &c_;
Chris@16 88 bool do_clear_;
Chris@16 89 };
Chris@16 90
Chris@16 91 template<typename Pointer>
Chris@16 92 struct node;
Chris@16 93
Chris@16 94 template<class VoidPtr>
Chris@16 95 struct node_base
Chris@16 96 {
Chris@16 97 private:
Chris@16 98 typedef typename boost::intrusive::
Chris@16 99 pointer_traits<VoidPtr> void_ptr_traits;
Chris@16 100 typedef typename void_ptr_traits::
Chris@16 101 template rebind_pointer
Chris@16 102 <node_base>::type node_base_ptr;
Chris@16 103 typedef typename void_ptr_traits::
Chris@16 104 template rebind_pointer
Chris@16 105 <node_base_ptr>::type node_base_ptr_ptr;
Chris@16 106
Chris@16 107 public:
Chris@16 108 node_base(const node_base_ptr_ptr &n)
Chris@16 109 : up(n)
Chris@16 110 {}
Chris@16 111
Chris@16 112 node_base()
Chris@16 113 : up()
Chris@16 114 {}
Chris@16 115
Chris@16 116 node_base_ptr_ptr up;
Chris@16 117 };
Chris@16 118
Chris@16 119 template<typename Pointer>
Chris@16 120 struct node
Chris@16 121 : public node_base
Chris@16 122 <typename ::boost::intrusive::pointer_traits<Pointer>::template
Chris@16 123 rebind_pointer<void>::type
Chris@16 124 >
Chris@16 125 {
Chris@16 126 // private:
Chris@16 127 // node();
Chris@16 128
Chris@16 129 public:
Chris@16 130 typename ::boost::intrusive::pointer_traits<Pointer>::element_type value;
Chris@16 131 };
Chris@16 132
Chris@16 133 template<typename Pointer, bool IsConst>
Chris@16 134 class iterator
Chris@16 135 {
Chris@16 136 typedef boost::intrusive::pointer_traits<Pointer> non_const_ptr_traits;
Chris@16 137 public:
Chris@16 138 typedef std::random_access_iterator_tag iterator_category;
Chris@16 139 typedef typename non_const_ptr_traits::element_type value_type;
Chris@16 140 typedef typename non_const_ptr_traits::difference_type difference_type;
Chris@16 141 typedef typename ::boost::container::container_detail::if_c
Chris@16 142 < IsConst
Chris@16 143 , typename non_const_ptr_traits::template
Chris@16 144 rebind_pointer<const value_type>::type
Chris@16 145 , Pointer
Chris@16 146 >::type pointer;
Chris@16 147 typedef typename ::boost::container::container_detail::if_c
Chris@16 148 < IsConst
Chris@16 149 , const value_type&
Chris@16 150 , value_type&
Chris@16 151 >::type reference;
Chris@16 152
Chris@16 153 private:
Chris@16 154 typedef typename non_const_ptr_traits::template
Chris@16 155 rebind_pointer<void>::type void_ptr;
Chris@16 156 typedef node<Pointer> node_type;
Chris@16 157 typedef node_base<void_ptr> node_base_type;
Chris@16 158 typedef typename non_const_ptr_traits::template
Chris@16 159 rebind_pointer<node_type>::type node_ptr;
Chris@16 160 typedef boost::intrusive::
Chris@16 161 pointer_traits<node_ptr> node_ptr_traits;
Chris@16 162 typedef typename non_const_ptr_traits::template
Chris@16 163 rebind_pointer<node_base_type>::type node_base_ptr;
Chris@16 164 typedef typename non_const_ptr_traits::template
Chris@16 165 rebind_pointer<node_base_ptr>::type node_base_ptr_ptr;
Chris@16 166
Chris@16 167 node_ptr m_pn;
Chris@16 168
Chris@16 169 public:
Chris@16 170
Chris@16 171 explicit iterator(node_ptr p) BOOST_CONTAINER_NOEXCEPT
Chris@16 172 : m_pn(p)
Chris@16 173 {}
Chris@16 174
Chris@16 175 iterator() BOOST_CONTAINER_NOEXCEPT
Chris@16 176 {}
Chris@16 177
Chris@16 178 iterator(iterator<Pointer, false> const& other) BOOST_CONTAINER_NOEXCEPT
Chris@16 179 : m_pn(other.node_pointer())
Chris@16 180 {}
Chris@16 181
Chris@16 182 node_ptr &node_pointer() BOOST_CONTAINER_NOEXCEPT
Chris@16 183 { return m_pn; }
Chris@16 184
Chris@16 185 const node_ptr &node_pointer() const BOOST_CONTAINER_NOEXCEPT
Chris@16 186 { return m_pn; }
Chris@16 187
Chris@16 188 public:
Chris@16 189 //Pointer like operators
Chris@16 190 reference operator*() const BOOST_CONTAINER_NOEXCEPT
Chris@16 191 { return m_pn->value; }
Chris@16 192
Chris@16 193 pointer operator->() const BOOST_CONTAINER_NOEXCEPT
Chris@16 194 {
Chris@16 195 typedef boost::intrusive::pointer_traits<pointer> ptr_traits;
Chris@16 196 return ptr_traits::pointer_to(this->operator*());
Chris@16 197 }
Chris@16 198
Chris@16 199 //Increment / Decrement
Chris@16 200 iterator& operator++() BOOST_CONTAINER_NOEXCEPT
Chris@16 201 {
Chris@16 202 if(node_base_ptr_ptr p = this->m_pn->up){
Chris@16 203 ++p;
Chris@16 204 this->m_pn = node_ptr_traits::static_cast_from(*p);
Chris@16 205 }
Chris@16 206 return *this;
Chris@16 207 }
Chris@16 208
Chris@16 209 iterator operator++(int) BOOST_CONTAINER_NOEXCEPT
Chris@16 210 { iterator tmp(*this); ++*this; return iterator(tmp); }
Chris@16 211
Chris@16 212 iterator& operator--() BOOST_CONTAINER_NOEXCEPT
Chris@16 213 {
Chris@16 214 if(node_base_ptr_ptr p = this->m_pn->up){
Chris@16 215 --p;
Chris@16 216 this->m_pn = node_ptr_traits::static_cast_from(*p);
Chris@16 217 }
Chris@16 218 return *this;
Chris@16 219 }
Chris@16 220
Chris@16 221 iterator operator--(int) BOOST_CONTAINER_NOEXCEPT
Chris@16 222 { iterator tmp(*this); --*this; return iterator(tmp); }
Chris@16 223
Chris@16 224 reference operator[](difference_type off) const BOOST_CONTAINER_NOEXCEPT
Chris@16 225 {
Chris@16 226 iterator tmp(*this);
Chris@16 227 tmp += off;
Chris@16 228 return *tmp;
Chris@16 229 }
Chris@16 230
Chris@16 231 iterator& operator+=(difference_type off) BOOST_CONTAINER_NOEXCEPT
Chris@16 232 {
Chris@16 233 if(node_base_ptr_ptr p = this->m_pn->up){
Chris@16 234 p += off;
Chris@16 235 this->m_pn = node_ptr_traits::static_cast_from(*p);
Chris@16 236 }
Chris@16 237 return *this;
Chris@16 238 }
Chris@16 239
Chris@16 240 friend iterator operator+(const iterator &left, difference_type off) BOOST_CONTAINER_NOEXCEPT
Chris@16 241 {
Chris@16 242 iterator tmp(left);
Chris@16 243 tmp += off;
Chris@16 244 return tmp;
Chris@16 245 }
Chris@16 246
Chris@16 247 friend iterator operator+(difference_type off, const iterator& right) BOOST_CONTAINER_NOEXCEPT
Chris@16 248 {
Chris@16 249 iterator tmp(right);
Chris@16 250 tmp += off;
Chris@16 251 return tmp;
Chris@16 252 }
Chris@16 253
Chris@16 254 iterator& operator-=(difference_type off) BOOST_CONTAINER_NOEXCEPT
Chris@16 255 { *this += -off; return *this; }
Chris@16 256
Chris@16 257 friend iterator operator-(const iterator &left, difference_type off) BOOST_CONTAINER_NOEXCEPT
Chris@16 258 {
Chris@16 259 iterator tmp(left);
Chris@16 260 tmp -= off;
Chris@16 261 return tmp;
Chris@16 262 }
Chris@16 263
Chris@16 264 friend difference_type operator-(const iterator& left, const iterator& right) BOOST_CONTAINER_NOEXCEPT
Chris@16 265 { return left.m_pn->up - right.m_pn->up; }
Chris@16 266
Chris@16 267 //Comparison operators
Chris@16 268 friend bool operator== (const iterator& l, const iterator& r) BOOST_CONTAINER_NOEXCEPT
Chris@16 269 { return l.m_pn == r.m_pn; }
Chris@16 270
Chris@16 271 friend bool operator!= (const iterator& l, const iterator& r) BOOST_CONTAINER_NOEXCEPT
Chris@16 272 { return l.m_pn != r.m_pn; }
Chris@16 273
Chris@16 274 friend bool operator< (const iterator& l, const iterator& r) BOOST_CONTAINER_NOEXCEPT
Chris@16 275 { return l.m_pn->up < r.m_pn->up; }
Chris@16 276
Chris@16 277 friend bool operator<= (const iterator& l, const iterator& r) BOOST_CONTAINER_NOEXCEPT
Chris@16 278 { return l.m_pn->up <= r.m_pn->up; }
Chris@16 279
Chris@16 280 friend bool operator> (const iterator& l, const iterator& r) BOOST_CONTAINER_NOEXCEPT
Chris@16 281 { return l.m_pn->up > r.m_pn->up; }
Chris@16 282
Chris@16 283 friend bool operator>= (const iterator& l, const iterator& r) BOOST_CONTAINER_NOEXCEPT
Chris@16 284 { return l.m_pn->up >= r.m_pn->up; }
Chris@16 285 };
Chris@16 286
Chris@16 287 template<class VoidPtr, class VoidAllocator>
Chris@16 288 struct index_traits
Chris@16 289 {
Chris@16 290 typedef boost::intrusive::
Chris@16 291 pointer_traits
Chris@16 292 <VoidPtr> void_ptr_traits;
Chris@16 293 typedef stable_vector_detail::
Chris@16 294 node_base<VoidPtr> node_base_type;
Chris@16 295 typedef typename void_ptr_traits::template
Chris@16 296 rebind_pointer<node_base_type>::type node_base_ptr;
Chris@16 297 typedef typename void_ptr_traits::template
Chris@16 298 rebind_pointer<node_base_ptr>::type node_base_ptr_ptr;
Chris@16 299 typedef boost::intrusive::
Chris@16 300 pointer_traits<node_base_ptr> node_base_ptr_traits;
Chris@16 301 typedef boost::intrusive::
Chris@16 302 pointer_traits<node_base_ptr_ptr> node_base_ptr_ptr_traits;
Chris@16 303 typedef typename allocator_traits<VoidAllocator>::
Chris@16 304 template portable_rebind_alloc
Chris@16 305 <node_base_ptr>::type node_base_ptr_allocator;
Chris@16 306 typedef ::boost::container::vector
Chris@16 307 <node_base_ptr, node_base_ptr_allocator> index_type;
Chris@16 308 typedef typename index_type::iterator index_iterator;
Chris@16 309 typedef typename index_type::const_iterator const_index_iterator;
Chris@16 310 typedef typename index_type::size_type size_type;
Chris@16 311
Chris@16 312 static const size_type ExtraPointers = 3;
Chris@16 313 //Stable vector stores metadata at the end of the index (node_base_ptr vector) with additional 3 pointers:
Chris@16 314 // back() is this->index.back() - ExtraPointers;
Chris@16 315 // end node index is *(this->index.end() - 3)
Chris@16 316 // Node cache first is *(this->index.end() - 2);
Chris@16 317 // Node cache last is this->index.back();
Chris@16 318
Chris@16 319 static node_base_ptr_ptr ptr_to_node_base_ptr(node_base_ptr &n)
Chris@16 320 { return node_base_ptr_ptr_traits::pointer_to(n); }
Chris@16 321
Chris@16 322 static void fix_up_pointers(index_iterator first, index_iterator last)
Chris@16 323 {
Chris@16 324 while(first != last){
Chris@16 325 typedef typename index_type::reference node_base_ptr_ref;
Chris@16 326 node_base_ptr_ref nbp = *first;
Chris@16 327 nbp->up = index_traits::ptr_to_node_base_ptr(nbp);
Chris@16 328 ++first;
Chris@16 329 }
Chris@16 330 }
Chris@16 331
Chris@16 332 static index_iterator get_fix_up_end(index_type &index)
Chris@16 333 { return index.end() - (ExtraPointers - 1); }
Chris@16 334
Chris@16 335 static void fix_up_pointers_from(index_type & index, index_iterator first)
Chris@16 336 { index_traits::fix_up_pointers(first, index_traits::get_fix_up_end(index)); }
Chris@16 337
Chris@16 338 static void readjust_end_node(index_type &index, node_base_type &end_node)
Chris@16 339 {
Chris@16 340 if(!index.empty()){
Chris@16 341 index_iterator end_node_it(index_traits::get_fix_up_end(index));
Chris@16 342 node_base_ptr &end_node_idx_ref = *(--end_node_it);
Chris@16 343 end_node_idx_ref = node_base_ptr_traits::pointer_to(end_node);
Chris@16 344 end_node.up = node_base_ptr_ptr_traits::pointer_to(end_node_idx_ref);
Chris@16 345 }
Chris@16 346 else{
Chris@16 347 end_node.up = node_base_ptr_ptr();
Chris@16 348 }
Chris@16 349 }
Chris@16 350
Chris@16 351 static void initialize_end_node(index_type &index, node_base_type &end_node, const size_type index_capacity_if_empty)
Chris@16 352 {
Chris@16 353 if(index.empty()){
Chris@16 354 index.reserve(index_capacity_if_empty + ExtraPointers);
Chris@16 355 index.resize(ExtraPointers);
Chris@16 356 node_base_ptr &end_node_ref = *index.data();
Chris@16 357 end_node_ref = node_base_ptr_traits::pointer_to(end_node);
Chris@16 358 end_node.up = index_traits::ptr_to_node_base_ptr(end_node_ref);
Chris@16 359 }
Chris@16 360 }
Chris@16 361
Chris@16 362 #ifdef STABLE_VECTOR_ENABLE_INVARIANT_CHECKING
Chris@16 363 static bool invariants(index_type &index)
Chris@16 364 {
Chris@16 365 for( index_iterator it = index.begin()
Chris@16 366 , it_end = index_traits::get_fix_up_end(index)
Chris@16 367 ; it != it_end
Chris@16 368 ; ++it){
Chris@16 369 if((*it)->up != index_traits::ptr_to_node_base_ptr(*it)){
Chris@16 370 return false;
Chris@16 371 }
Chris@16 372 }
Chris@16 373 return true;
Chris@16 374 }
Chris@16 375 #endif //STABLE_VECTOR_ENABLE_INVARIANT_CHECKING
Chris@16 376 };
Chris@16 377
Chris@16 378 } //namespace stable_vector_detail
Chris@16 379
Chris@16 380 #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
Chris@16 381
Chris@16 382 #if defined(STABLE_VECTOR_ENABLE_INVARIANT_CHECKING)
Chris@16 383
Chris@16 384 #define STABLE_VECTOR_CHECK_INVARIANT \
Chris@16 385 invariant_checker BOOST_JOIN(check_invariant_,__LINE__)(*this); \
Chris@16 386 BOOST_JOIN(check_invariant_,__LINE__).touch();
Chris@16 387
Chris@16 388 #else //STABLE_VECTOR_ENABLE_INVARIANT_CHECKING
Chris@16 389
Chris@16 390 #define STABLE_VECTOR_CHECK_INVARIANT
Chris@16 391
Chris@16 392 #endif //#if defined(STABLE_VECTOR_ENABLE_INVARIANT_CHECKING)
Chris@16 393
Chris@16 394 #endif //#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
Chris@16 395
Chris@16 396 /// @endcond
Chris@16 397
Chris@16 398 //! Originally developed by Joaquin M. Lopez Munoz, stable_vector is a std::vector
Chris@16 399 //! drop-in replacement implemented as a node container, offering iterator and reference
Chris@16 400 //! stability.
Chris@16 401 //!
Chris@16 402 //! Here are the details taken from the author's blog
Chris@16 403 //! (<a href="http://bannalia.blogspot.com/2008/09/introducing-stablevector.html" >
Chris@16 404 //! Introducing stable_vector</a>):
Chris@16 405 //!
Chris@16 406 //! We present stable_vector, a fully STL-compliant stable container that provides
Chris@16 407 //! most of the features of std::vector except element contiguity.
Chris@16 408 //!
Chris@16 409 //! General properties: stable_vector satisfies all the requirements of a container,
Chris@16 410 //! a reversible container and a sequence and provides all the optional operations
Chris@16 411 //! present in std::vector. Like std::vector, iterators are random access.
Chris@16 412 //! stable_vector does not provide element contiguity; in exchange for this absence,
Chris@16 413 //! the container is stable, i.e. references and iterators to an element of a stable_vector
Chris@16 414 //! remain valid as long as the element is not erased, and an iterator that has been
Chris@16 415 //! assigned the return value of end() always remain valid until the destruction of
Chris@16 416 //! the associated stable_vector.
Chris@16 417 //!
Chris@16 418 //! Operation complexity: The big-O complexities of stable_vector operations match
Chris@16 419 //! exactly those of std::vector. In general, insertion/deletion is constant time at
Chris@16 420 //! the end of the sequence and linear elsewhere. Unlike std::vector, stable_vector
Chris@16 421 //! does not internally perform any value_type destruction, copy or assignment
Chris@16 422 //! operations other than those exactly corresponding to the insertion of new
Chris@16 423 //! elements or deletion of stored elements, which can sometimes compensate in terms
Chris@16 424 //! of performance for the extra burden of doing more pointer manipulation and an
Chris@16 425 //! additional allocation per element.
Chris@16 426 //!
Chris@16 427 //! Exception safety: As stable_vector does not internally copy elements around, some
Chris@16 428 //! operations provide stronger exception safety guarantees than in std::vector.
Chris@16 429 #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
Chris@16 430 template <class T, class Allocator = std::allocator<T> >
Chris@16 431 #else
Chris@16 432 template <class T, class Allocator>
Chris@16 433 #endif
Chris@16 434 class stable_vector
Chris@16 435 {
Chris@16 436 ///@cond
Chris@16 437 typedef allocator_traits<Allocator> allocator_traits_type;
Chris@16 438 typedef boost::intrusive::
Chris@16 439 pointer_traits
Chris@16 440 <typename allocator_traits_type::pointer> ptr_traits;
Chris@16 441 typedef typename ptr_traits::
Chris@16 442 template rebind_pointer<void>::type void_ptr;
Chris@16 443 typedef typename allocator_traits_type::
Chris@16 444 template portable_rebind_alloc
Chris@16 445 <void>::type void_allocator_type;
Chris@16 446 typedef stable_vector_detail::index_traits
Chris@16 447 <void_ptr, void_allocator_type> index_traits_type;
Chris@16 448 typedef typename index_traits_type::node_base_type node_base_type;
Chris@16 449 typedef typename index_traits_type::node_base_ptr node_base_ptr;
Chris@16 450 typedef typename index_traits_type::
Chris@16 451 node_base_ptr_ptr node_base_ptr_ptr;
Chris@16 452 typedef typename index_traits_type::
Chris@16 453 node_base_ptr_traits node_base_ptr_traits;
Chris@16 454 typedef typename index_traits_type::
Chris@16 455 node_base_ptr_ptr_traits node_base_ptr_ptr_traits;
Chris@16 456 typedef typename index_traits_type::index_type index_type;
Chris@16 457 typedef typename index_traits_type::index_iterator index_iterator;
Chris@16 458 typedef typename index_traits_type::
Chris@16 459 const_index_iterator const_index_iterator;
Chris@16 460 typedef stable_vector_detail::node
Chris@16 461 <typename ptr_traits::pointer> node_type;
Chris@16 462 typedef typename ptr_traits::template
Chris@16 463 rebind_pointer<node_type>::type node_ptr;
Chris@16 464 typedef boost::intrusive::
Chris@16 465 pointer_traits<node_ptr> node_ptr_traits;
Chris@16 466 typedef typename ptr_traits::template
Chris@16 467 rebind_pointer<const node_type>::type const_node_ptr;
Chris@16 468 typedef boost::intrusive::
Chris@16 469 pointer_traits<const_node_ptr> const_node_ptr_traits;
Chris@16 470 typedef typename node_ptr_traits::reference node_reference;
Chris@16 471 typedef typename const_node_ptr_traits::reference const_node_reference;
Chris@16 472
Chris@16 473 typedef ::boost::container::container_detail::
Chris@16 474 integral_constant<unsigned, 1> allocator_v1;
Chris@16 475 typedef ::boost::container::container_detail::
Chris@16 476 integral_constant<unsigned, 2> allocator_v2;
Chris@16 477 typedef ::boost::container::container_detail::integral_constant
Chris@16 478 <unsigned, boost::container::container_detail::
Chris@16 479 version<Allocator>::value> alloc_version;
Chris@16 480 typedef typename allocator_traits_type::
Chris@16 481 template portable_rebind_alloc
Chris@16 482 <node_type>::type node_allocator_type;
Chris@16 483
Chris@16 484 typedef ::boost::container::container_detail::
Chris@16 485 allocator_version_traits<node_allocator_type> allocator_version_traits_t;
Chris@16 486 typedef typename allocator_version_traits_t::multiallocation_chain multiallocation_chain;
Chris@16 487
Chris@16 488 node_ptr allocate_one()
Chris@16 489 { return allocator_version_traits_t::allocate_one(this->priv_node_alloc()); }
Chris@16 490
Chris@16 491 void deallocate_one(const node_ptr &p)
Chris@16 492 { allocator_version_traits_t::deallocate_one(this->priv_node_alloc(), p); }
Chris@16 493
Chris@16 494 void allocate_individual(typename allocator_traits_type::size_type n, multiallocation_chain &m)
Chris@16 495 { allocator_version_traits_t::allocate_individual(this->priv_node_alloc(), n, m); }
Chris@16 496
Chris@16 497 void deallocate_individual(multiallocation_chain &holder)
Chris@16 498 { allocator_version_traits_t::deallocate_individual(this->priv_node_alloc(), holder); }
Chris@16 499
Chris@16 500 friend class stable_vector_detail::clear_on_destroy<stable_vector>;
Chris@16 501 typedef stable_vector_detail::iterator
Chris@16 502 < typename allocator_traits<Allocator>::pointer
Chris@16 503 , false> iterator_impl;
Chris@16 504 typedef stable_vector_detail::iterator
Chris@16 505 < typename allocator_traits<Allocator>::pointer
Chris@16 506 , false> const_iterator_impl;
Chris@16 507 ///@endcond
Chris@16 508 public:
Chris@16 509
Chris@16 510 //////////////////////////////////////////////
Chris@16 511 //
Chris@16 512 // types
Chris@16 513 //
Chris@16 514 //////////////////////////////////////////////
Chris@16 515 typedef T value_type;
Chris@16 516 typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
Chris@16 517 typedef typename ::boost::container::allocator_traits<Allocator>::const_pointer const_pointer;
Chris@16 518 typedef typename ::boost::container::allocator_traits<Allocator>::reference reference;
Chris@16 519 typedef typename ::boost::container::allocator_traits<Allocator>::const_reference const_reference;
Chris@16 520 typedef typename ::boost::container::allocator_traits<Allocator>::size_type size_type;
Chris@16 521 typedef typename ::boost::container::allocator_traits<Allocator>::difference_type difference_type;
Chris@16 522 typedef Allocator allocator_type;
Chris@16 523 typedef node_allocator_type stored_allocator_type;
Chris@16 524 typedef BOOST_CONTAINER_IMPDEF(iterator_impl) iterator;
Chris@16 525 typedef BOOST_CONTAINER_IMPDEF(const_iterator_impl) const_iterator;
Chris@16 526 typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator<iterator>) reverse_iterator;
Chris@16 527 typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator<const_iterator>) const_reverse_iterator;
Chris@16 528
Chris@16 529 ///@cond
Chris@16 530 private:
Chris@16 531 BOOST_COPYABLE_AND_MOVABLE(stable_vector)
Chris@16 532 static const size_type ExtraPointers = index_traits_type::ExtraPointers;
Chris@16 533
Chris@16 534 class insert_rollback;
Chris@16 535 friend class insert_rollback;
Chris@16 536
Chris@16 537 class push_back_rollback;
Chris@16 538 friend class push_back_rollback;
Chris@16 539 ///@endcond
Chris@16 540
Chris@16 541 public:
Chris@16 542 //////////////////////////////////////////////
Chris@16 543 //
Chris@16 544 // construct/copy/destroy
Chris@16 545 //
Chris@16 546 //////////////////////////////////////////////
Chris@16 547
Chris@16 548 //! <b>Effects</b>: Default constructs a stable_vector.
Chris@16 549 //!
Chris@16 550 //! <b>Throws</b>: If allocator_type's default constructor throws.
Chris@16 551 //!
Chris@16 552 //! <b>Complexity</b>: Constant.
Chris@16 553 stable_vector()
Chris@16 554 : internal_data(), index()
Chris@16 555 {
Chris@16 556 STABLE_VECTOR_CHECK_INVARIANT;
Chris@16 557 }
Chris@16 558
Chris@16 559 //! <b>Effects</b>: Constructs a stable_vector taking the allocator as parameter.
Chris@16 560 //!
Chris@16 561 //! <b>Throws</b>: Nothing
Chris@16 562 //!
Chris@16 563 //! <b>Complexity</b>: Constant.
Chris@16 564 explicit stable_vector(const allocator_type& al) BOOST_CONTAINER_NOEXCEPT
Chris@16 565 : internal_data(al), index(al)
Chris@16 566 {
Chris@16 567 STABLE_VECTOR_CHECK_INVARIANT;
Chris@16 568 }
Chris@16 569
Chris@16 570 //! <b>Effects</b>: Constructs a stable_vector that will use a copy of allocator a
Chris@16 571 //! and inserts n value initialized values.
Chris@16 572 //!
Chris@16 573 //! <b>Throws</b>: If allocator_type's default constructor or copy constructor
Chris@16 574 //! throws or T's default or copy constructor throws.
Chris@16 575 //!
Chris@16 576 //! <b>Complexity</b>: Linear to n.
Chris@16 577 explicit stable_vector(size_type n)
Chris@16 578 : internal_data(), index()
Chris@16 579 {
Chris@16 580 stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
Chris@16 581 this->resize(n);
Chris@16 582 STABLE_VECTOR_CHECK_INVARIANT;
Chris@16 583 cod.release();
Chris@16 584 }
Chris@16 585
Chris@16 586 //! <b>Effects</b>: Constructs a stable_vector that will use a copy of allocator a
Chris@16 587 //! and inserts n default initialized values.
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 default or copy constructor throws.
Chris@16 591 //!
Chris@16 592 //! <b>Complexity</b>: Linear to n.
Chris@16 593 //!
Chris@16 594 //! <b>Note</b>: Non-standard extension
Chris@16 595 stable_vector(size_type n, default_init_t)
Chris@16 596 : internal_data(), index()
Chris@16 597 {
Chris@16 598 stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
Chris@16 599 this->resize(n, default_init);
Chris@16 600 STABLE_VECTOR_CHECK_INVARIANT;
Chris@16 601 cod.release();
Chris@16 602 }
Chris@16 603
Chris@16 604 //! <b>Effects</b>: Constructs a stable_vector that will use a copy of allocator a
Chris@16 605 //! and inserts n copies of value.
Chris@16 606 //!
Chris@16 607 //! <b>Throws</b>: If allocator_type's default constructor or copy constructor
Chris@16 608 //! throws or T's default or copy constructor throws.
Chris@16 609 //!
Chris@16 610 //! <b>Complexity</b>: Linear to n.
Chris@16 611 stable_vector(size_type n, const T& t, const allocator_type& al = allocator_type())
Chris@16 612 : internal_data(al), index(al)
Chris@16 613 {
Chris@16 614 stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
Chris@16 615 this->insert(this->cend(), n, t);
Chris@16 616 STABLE_VECTOR_CHECK_INVARIANT;
Chris@16 617 cod.release();
Chris@16 618 }
Chris@16 619
Chris@16 620 //! <b>Effects</b>: Constructs a stable_vector that will use a copy of allocator a
Chris@16 621 //! and inserts a copy of the range [first, last) in the stable_vector.
Chris@16 622 //!
Chris@16 623 //! <b>Throws</b>: If allocator_type's default constructor or copy constructor
Chris@16 624 //! throws or T's constructor taking an dereferenced InIt throws.
Chris@16 625 //!
Chris@16 626 //! <b>Complexity</b>: Linear to the range [first, last).
Chris@16 627 template <class InputIterator>
Chris@16 628 stable_vector(InputIterator first,InputIterator last, const allocator_type& al = allocator_type())
Chris@16 629 : internal_data(al), index(al)
Chris@16 630 {
Chris@16 631 stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
Chris@16 632 this->insert(this->cend(), first, last);
Chris@16 633 STABLE_VECTOR_CHECK_INVARIANT;
Chris@16 634 cod.release();
Chris@16 635 }
Chris@16 636
Chris@16 637 //! <b>Effects</b>: Copy constructs a stable_vector.
Chris@16 638 //!
Chris@16 639 //! <b>Postcondition</b>: x == *this.
Chris@16 640 //!
Chris@16 641 //! <b>Complexity</b>: Linear to the elements x contains.
Chris@16 642 stable_vector(const stable_vector& x)
Chris@16 643 : internal_data(allocator_traits<node_allocator_type>::
Chris@16 644 select_on_container_copy_construction(x.priv_node_alloc()))
Chris@16 645 , index(allocator_traits<allocator_type>::
Chris@16 646 select_on_container_copy_construction(x.index.get_stored_allocator()))
Chris@16 647 {
Chris@16 648 stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
Chris@16 649 this->insert(this->cend(), x.begin(), x.end());
Chris@16 650 STABLE_VECTOR_CHECK_INVARIANT;
Chris@16 651 cod.release();
Chris@16 652 }
Chris@16 653
Chris@16 654 //! <b>Effects</b>: Move constructor. Moves mx's resources to *this.
Chris@16 655 //!
Chris@16 656 //! <b>Throws</b>: If allocator_type's copy constructor throws.
Chris@16 657 //!
Chris@16 658 //! <b>Complexity</b>: Constant.
Chris@16 659 stable_vector(BOOST_RV_REF(stable_vector) x)
Chris@16 660 : internal_data(boost::move(x.priv_node_alloc())), index(boost::move(x.index))
Chris@16 661 {
Chris@16 662 this->priv_swap_members(x);
Chris@16 663 }
Chris@16 664
Chris@16 665 //! <b>Effects</b>: Copy constructs a stable_vector using the specified allocator.
Chris@16 666 //!
Chris@16 667 //! <b>Postcondition</b>: x == *this.
Chris@16 668 //!
Chris@16 669 //! <b>Complexity</b>: Linear to the elements x contains.
Chris@16 670 stable_vector(const stable_vector& x, const allocator_type &a)
Chris@16 671 : internal_data(a), index(a)
Chris@16 672 {
Chris@16 673 stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
Chris@16 674 this->insert(this->cend(), x.begin(), x.end());
Chris@16 675 STABLE_VECTOR_CHECK_INVARIANT;
Chris@16 676 cod.release();
Chris@16 677 }
Chris@16 678
Chris@16 679 //! <b>Effects</b>: Move constructor using the specified allocator.
Chris@16 680 //! Moves mx's resources to *this.
Chris@16 681 //!
Chris@16 682 //! <b>Throws</b>: If allocator_type's copy constructor throws.
Chris@16 683 //!
Chris@16 684 //! <b>Complexity</b>: Constant if a == x.get_allocator(), linear otherwise
Chris@16 685 stable_vector(BOOST_RV_REF(stable_vector) x, const allocator_type &a)
Chris@16 686 : internal_data(a), index(a)
Chris@16 687 {
Chris@16 688 if(this->priv_node_alloc() == x.priv_node_alloc()){
Chris@16 689 this->priv_swap_members(x);
Chris@16 690 }
Chris@16 691 else{
Chris@16 692 stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
Chris@16 693 this->insert(this->cend(), x.begin(), x.end());
Chris@16 694 STABLE_VECTOR_CHECK_INVARIANT;
Chris@16 695 cod.release();
Chris@16 696 }
Chris@16 697 }
Chris@16 698
Chris@16 699 //! <b>Effects</b>: Destroys the stable_vector. All stored values are destroyed
Chris@16 700 //! and used memory is deallocated.
Chris@16 701 //!
Chris@16 702 //! <b>Throws</b>: Nothing.
Chris@16 703 //!
Chris@16 704 //! <b>Complexity</b>: Linear to the number of elements.
Chris@16 705 ~stable_vector()
Chris@16 706 {
Chris@16 707 this->clear();
Chris@16 708 this->priv_clear_pool();
Chris@16 709 }
Chris@16 710
Chris@16 711 //! <b>Effects</b>: Makes *this contain the same elements as x.
Chris@16 712 //!
Chris@16 713 //! <b>Postcondition</b>: this->size() == x.size(). *this contains a copy
Chris@16 714 //! of each of x's elements.
Chris@16 715 //!
Chris@16 716 //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
Chris@16 717 //!
Chris@16 718 //! <b>Complexity</b>: Linear to the number of elements in x.
Chris@16 719 stable_vector& operator=(BOOST_COPY_ASSIGN_REF(stable_vector) x)
Chris@16 720 {
Chris@16 721 STABLE_VECTOR_CHECK_INVARIANT;
Chris@16 722 if (&x != this){
Chris@16 723 node_allocator_type &this_alloc = this->priv_node_alloc();
Chris@16 724 const node_allocator_type &x_alloc = x.priv_node_alloc();
Chris@16 725 container_detail::bool_<allocator_traits_type::
Chris@16 726 propagate_on_container_copy_assignment::value> flag;
Chris@16 727 if(flag && this_alloc != x_alloc){
Chris@16 728 this->clear();
Chris@16 729 this->shrink_to_fit();
Chris@16 730 }
Chris@16 731 container_detail::assign_alloc(this->priv_node_alloc(), x.priv_node_alloc(), flag);
Chris@16 732 container_detail::assign_alloc(this->index.get_stored_allocator(), x.index.get_stored_allocator(), flag);
Chris@16 733 this->assign(x.begin(), x.end());
Chris@16 734 }
Chris@16 735 return *this;
Chris@16 736 }
Chris@16 737
Chris@16 738 //! <b>Effects</b>: Move assignment. All mx's values are transferred to *this.
Chris@16 739 //!
Chris@16 740 //! <b>Postcondition</b>: x.empty(). *this contains a the elements x had
Chris@16 741 //! before the function.
Chris@16 742 //!
Chris@16 743 //! <b>Throws</b>: If allocator_type's copy constructor throws.
Chris@16 744 //!
Chris@16 745 //! <b>Complexity</b>: Linear.
Chris@16 746 stable_vector& operator=(BOOST_RV_REF(stable_vector) x)
Chris@16 747 {
Chris@16 748 if (&x != this){
Chris@16 749 node_allocator_type &this_alloc = this->priv_node_alloc();
Chris@16 750 node_allocator_type &x_alloc = x.priv_node_alloc();
Chris@16 751 //If allocators are equal we can just swap pointers
Chris@16 752 if(this_alloc == x_alloc){
Chris@16 753 //Destroy objects but retain memory
Chris@16 754 this->clear();
Chris@16 755 this->index = boost::move(x.index);
Chris@16 756 this->priv_swap_members(x);
Chris@16 757 //Move allocator if needed
Chris@16 758 container_detail::bool_<allocator_traits_type::
Chris@16 759 propagate_on_container_move_assignment::value> flag;
Chris@16 760 container_detail::move_alloc(this->priv_node_alloc(), x.priv_node_alloc(), flag);
Chris@16 761 }
Chris@16 762 //If unequal allocators, then do a one by one move
Chris@16 763 else{
Chris@16 764 this->assign( boost::make_move_iterator(x.begin())
Chris@16 765 , boost::make_move_iterator(x.end()));
Chris@16 766 }
Chris@16 767 }
Chris@16 768 return *this;
Chris@16 769 }
Chris@16 770
Chris@16 771
Chris@16 772 //! <b>Effects</b>: Assigns the n copies of val to *this.
Chris@16 773 //!
Chris@16 774 //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
Chris@16 775 //!
Chris@16 776 //! <b>Complexity</b>: Linear to n.
Chris@16 777 void assign(size_type n, const T& t)
Chris@16 778 {
Chris@16 779 typedef constant_iterator<value_type, difference_type> cvalue_iterator;
Chris@16 780 this->assign(cvalue_iterator(t, n), cvalue_iterator());
Chris@16 781 }
Chris@16 782
Chris@16 783 //! <b>Effects</b>: Assigns the the range [first, last) to *this.
Chris@16 784 //!
Chris@16 785 //! <b>Throws</b>: If memory allocation throws or
Chris@16 786 //! T's constructor from dereferencing InpIt throws.
Chris@16 787 //!
Chris@16 788 //! <b>Complexity</b>: Linear to n.
Chris@16 789 template<typename InputIterator>
Chris@16 790 void assign(InputIterator first,InputIterator last
Chris@16 791 #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
Chris@16 792 , typename container_detail::enable_if_c
Chris@16 793 < !container_detail::is_convertible<InputIterator, size_type>::value
Chris@16 794 >::type * = 0
Chris@16 795 #endif
Chris@16 796 )
Chris@16 797 {
Chris@16 798 STABLE_VECTOR_CHECK_INVARIANT;
Chris@16 799 iterator first1 = this->begin();
Chris@16 800 iterator last1 = this->end();
Chris@16 801 for ( ; first1 != last1 && first != last; ++first1, ++first)
Chris@16 802 *first1 = *first;
Chris@16 803 if (first == last){
Chris@16 804 this->erase(first1, last1);
Chris@16 805 }
Chris@16 806 else{
Chris@16 807 this->insert(last1, first, last);
Chris@16 808 }
Chris@16 809 }
Chris@16 810
Chris@16 811 //! <b>Effects</b>: Returns a copy of the internal allocator.
Chris@16 812 //!
Chris@16 813 //! <b>Throws</b>: If allocator's copy constructor throws.
Chris@16 814 //!
Chris@16 815 //! <b>Complexity</b>: Constant.
Chris@16 816 allocator_type get_allocator() const
Chris@16 817 { return this->priv_node_alloc(); }
Chris@16 818
Chris@16 819 //! <b>Effects</b>: Returns a reference to the internal allocator.
Chris@16 820 //!
Chris@16 821 //! <b>Throws</b>: Nothing
Chris@16 822 //!
Chris@16 823 //! <b>Complexity</b>: Constant.
Chris@16 824 //!
Chris@16 825 //! <b>Note</b>: Non-standard extension.
Chris@16 826 const stored_allocator_type &get_stored_allocator() const BOOST_CONTAINER_NOEXCEPT
Chris@16 827 { return this->priv_node_alloc(); }
Chris@16 828
Chris@16 829 //! <b>Effects</b>: Returns a reference to the internal allocator.
Chris@16 830 //!
Chris@16 831 //! <b>Throws</b>: Nothing
Chris@16 832 //!
Chris@16 833 //! <b>Complexity</b>: Constant.
Chris@16 834 //!
Chris@16 835 //! <b>Note</b>: Non-standard extension.
Chris@16 836 stored_allocator_type &get_stored_allocator() BOOST_CONTAINER_NOEXCEPT
Chris@16 837 { return this->priv_node_alloc(); }
Chris@16 838
Chris@16 839 //////////////////////////////////////////////
Chris@16 840 //
Chris@16 841 // iterators
Chris@16 842 //
Chris@16 843 //////////////////////////////////////////////
Chris@16 844
Chris@16 845 //! <b>Effects</b>: Returns an iterator to the first element contained in the stable_vector.
Chris@16 846 //!
Chris@16 847 //! <b>Throws</b>: Nothing.
Chris@16 848 //!
Chris@16 849 //! <b>Complexity</b>: Constant.
Chris@16 850 iterator begin() BOOST_CONTAINER_NOEXCEPT
Chris@16 851 { return (this->index.empty()) ? this->end(): iterator(node_ptr_traits::static_cast_from(this->index.front())); }
Chris@16 852
Chris@16 853 //! <b>Effects</b>: Returns a const_iterator to the first element contained in the stable_vector.
Chris@16 854 //!
Chris@16 855 //! <b>Throws</b>: Nothing.
Chris@16 856 //!
Chris@16 857 //! <b>Complexity</b>: Constant.
Chris@16 858 const_iterator begin() const BOOST_CONTAINER_NOEXCEPT
Chris@16 859 { return (this->index.empty()) ? this->cend() : const_iterator(node_ptr_traits::static_cast_from(this->index.front())) ; }
Chris@16 860
Chris@16 861 //! <b>Effects</b>: Returns an iterator to the end of the stable_vector.
Chris@16 862 //!
Chris@16 863 //! <b>Throws</b>: Nothing.
Chris@16 864 //!
Chris@16 865 //! <b>Complexity</b>: Constant.
Chris@16 866 iterator end() BOOST_CONTAINER_NOEXCEPT
Chris@16 867 { return iterator(this->priv_get_end_node()); }
Chris@16 868
Chris@16 869 //! <b>Effects</b>: Returns a const_iterator to the end of the stable_vector.
Chris@16 870 //!
Chris@16 871 //! <b>Throws</b>: Nothing.
Chris@16 872 //!
Chris@16 873 //! <b>Complexity</b>: Constant.
Chris@16 874 const_iterator end() const BOOST_CONTAINER_NOEXCEPT
Chris@16 875 { return const_iterator(this->priv_get_end_node()); }
Chris@16 876
Chris@16 877 //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
Chris@16 878 //! of the reversed stable_vector.
Chris@16 879 //!
Chris@16 880 //! <b>Throws</b>: Nothing.
Chris@16 881 //!
Chris@16 882 //! <b>Complexity</b>: Constant.
Chris@16 883 reverse_iterator rbegin() BOOST_CONTAINER_NOEXCEPT
Chris@16 884 { return reverse_iterator(this->end()); }
Chris@16 885
Chris@16 886 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
Chris@16 887 //! of the reversed stable_vector.
Chris@16 888 //!
Chris@16 889 //! <b>Throws</b>: Nothing.
Chris@16 890 //!
Chris@16 891 //! <b>Complexity</b>: Constant.
Chris@16 892 const_reverse_iterator rbegin() const BOOST_CONTAINER_NOEXCEPT
Chris@16 893 { return const_reverse_iterator(this->end()); }
Chris@16 894
Chris@16 895 //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
Chris@16 896 //! of the reversed stable_vector.
Chris@16 897 //!
Chris@16 898 //! <b>Throws</b>: Nothing.
Chris@16 899 //!
Chris@16 900 //! <b>Complexity</b>: Constant.
Chris@16 901 reverse_iterator rend() BOOST_CONTAINER_NOEXCEPT
Chris@16 902 { return reverse_iterator(this->begin()); }
Chris@16 903
Chris@16 904 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
Chris@16 905 //! of the reversed stable_vector.
Chris@16 906 //!
Chris@16 907 //! <b>Throws</b>: Nothing.
Chris@16 908 //!
Chris@16 909 //! <b>Complexity</b>: Constant.
Chris@16 910 const_reverse_iterator rend() const BOOST_CONTAINER_NOEXCEPT
Chris@16 911 { return const_reverse_iterator(this->begin()); }
Chris@16 912
Chris@16 913 //! <b>Effects</b>: Returns a const_iterator to the first element contained in the stable_vector.
Chris@16 914 //!
Chris@16 915 //! <b>Throws</b>: Nothing.
Chris@16 916 //!
Chris@16 917 //! <b>Complexity</b>: Constant.
Chris@16 918 const_iterator cbegin() const BOOST_CONTAINER_NOEXCEPT
Chris@16 919 { return this->begin(); }
Chris@16 920
Chris@16 921 //! <b>Effects</b>: Returns a const_iterator to the end of the stable_vector.
Chris@16 922 //!
Chris@16 923 //! <b>Throws</b>: Nothing.
Chris@16 924 //!
Chris@16 925 //! <b>Complexity</b>: Constant.
Chris@16 926 const_iterator cend() const BOOST_CONTAINER_NOEXCEPT
Chris@16 927 { return this->end(); }
Chris@16 928
Chris@16 929 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
Chris@16 930 //! of the reversed stable_vector.
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 crbegin() const BOOST_CONTAINER_NOEXCEPT
Chris@16 936 { return this->rbegin(); }
Chris@16 937
Chris@16 938 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
Chris@16 939 //! of the reversed stable_vector.
Chris@16 940 //!
Chris@16 941 //! <b>Throws</b>: Nothing.
Chris@16 942 //!
Chris@16 943 //! <b>Complexity</b>: Constant.
Chris@16 944 const_reverse_iterator crend()const BOOST_CONTAINER_NOEXCEPT
Chris@16 945 { return this->rend(); }
Chris@16 946
Chris@16 947 //////////////////////////////////////////////
Chris@16 948 //
Chris@16 949 // capacity
Chris@16 950 //
Chris@16 951 //////////////////////////////////////////////
Chris@16 952
Chris@16 953 //! <b>Effects</b>: Returns true if the stable_vector contains no elements.
Chris@16 954 //!
Chris@16 955 //! <b>Throws</b>: Nothing.
Chris@16 956 //!
Chris@16 957 //! <b>Complexity</b>: Constant.
Chris@16 958 bool empty() const BOOST_CONTAINER_NOEXCEPT
Chris@16 959 { return this->index.size() <= ExtraPointers; }
Chris@16 960
Chris@16 961 //! <b>Effects</b>: Returns the number of the elements contained in the stable_vector.
Chris@16 962 //!
Chris@16 963 //! <b>Throws</b>: Nothing.
Chris@16 964 //!
Chris@16 965 //! <b>Complexity</b>: Constant.
Chris@16 966 size_type size() const BOOST_CONTAINER_NOEXCEPT
Chris@16 967 {
Chris@16 968 const size_type index_size = this->index.size();
Chris@16 969 return (index_size - ExtraPointers) & (std::size_t(0u) -std::size_t(index_size != 0));
Chris@16 970 }
Chris@16 971
Chris@16 972 //! <b>Effects</b>: Returns the largest possible size of the stable_vector.
Chris@16 973 //!
Chris@16 974 //! <b>Throws</b>: Nothing.
Chris@16 975 //!
Chris@16 976 //! <b>Complexity</b>: Constant.
Chris@16 977 size_type max_size() const BOOST_CONTAINER_NOEXCEPT
Chris@16 978 { return this->index.max_size() - ExtraPointers; }
Chris@16 979
Chris@16 980 //! <b>Effects</b>: Inserts or erases elements at the end such that
Chris@16 981 //! the size becomes n. New elements are value initialized.
Chris@16 982 //!
Chris@16 983 //! <b>Throws</b>: If memory allocation throws, or T's default constructor throws.
Chris@16 984 //!
Chris@16 985 //! <b>Complexity</b>: Linear to the difference between size() and new_size.
Chris@16 986 void resize(size_type n)
Chris@16 987 {
Chris@16 988 typedef value_init_construct_iterator<value_type, difference_type> value_init_iterator;
Chris@16 989 STABLE_VECTOR_CHECK_INVARIANT;
Chris@16 990 if(n > this->size())
Chris@16 991 this->insert(this->cend(), value_init_iterator(n - this->size()), value_init_iterator());
Chris@16 992 else if(n < this->size())
Chris@16 993 this->erase(this->cbegin() + n, this->cend());
Chris@16 994 }
Chris@16 995
Chris@16 996 //! <b>Effects</b>: Inserts or erases elements at the end such that
Chris@16 997 //! the size becomes n. New elements are default initialized.
Chris@16 998 //!
Chris@16 999 //! <b>Throws</b>: If memory allocation throws, or T's default constructor throws.
Chris@16 1000 //!
Chris@16 1001 //! <b>Complexity</b>: Linear to the difference between size() and new_size.
Chris@16 1002 //!
Chris@16 1003 //! <b>Note</b>: Non-standard extension
Chris@16 1004 void resize(size_type n, default_init_t)
Chris@16 1005 {
Chris@16 1006 typedef default_init_construct_iterator<value_type, difference_type> default_init_iterator;
Chris@16 1007 STABLE_VECTOR_CHECK_INVARIANT;
Chris@16 1008 if(n > this->size())
Chris@16 1009 this->insert(this->cend(), default_init_iterator(n - this->size()), default_init_iterator());
Chris@16 1010 else if(n < this->size())
Chris@16 1011 this->erase(this->cbegin() + n, this->cend());
Chris@16 1012 }
Chris@16 1013
Chris@16 1014 //! <b>Effects</b>: Inserts or erases elements at the end such that
Chris@16 1015 //! the size becomes n. New elements are copy constructed from x.
Chris@16 1016 //!
Chris@16 1017 //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
Chris@16 1018 //!
Chris@16 1019 //! <b>Complexity</b>: Linear to the difference between size() and new_size.
Chris@16 1020 void resize(size_type n, const T& t)
Chris@16 1021 {
Chris@16 1022 STABLE_VECTOR_CHECK_INVARIANT;
Chris@16 1023 if(n > this->size())
Chris@16 1024 this->insert(this->cend(), n - this->size(), t);
Chris@16 1025 else if(n < this->size())
Chris@16 1026 this->erase(this->cbegin() + n, this->cend());
Chris@16 1027 }
Chris@16 1028
Chris@16 1029 //! <b>Effects</b>: Number of elements for which memory has been allocated.
Chris@16 1030 //! capacity() is always greater than or equal to size().
Chris@16 1031 //!
Chris@16 1032 //! <b>Throws</b>: Nothing.
Chris@16 1033 //!
Chris@16 1034 //! <b>Complexity</b>: Constant.
Chris@16 1035 size_type capacity() const BOOST_CONTAINER_NOEXCEPT
Chris@16 1036 {
Chris@16 1037 const size_type index_size = this->index.size();
Chris@16 1038 BOOST_ASSERT(!index_size || index_size >= ExtraPointers);
Chris@16 1039 const size_type bucket_extra_capacity = this->index.capacity()- index_size;
Chris@16 1040 const size_type node_extra_capacity = this->internal_data.pool_size;
Chris@16 1041 const size_type extra_capacity = (bucket_extra_capacity < node_extra_capacity)
Chris@16 1042 ? bucket_extra_capacity : node_extra_capacity;
Chris@16 1043 const size_type index_offset =
Chris@16 1044 (ExtraPointers + extra_capacity) & (size_type(0u) - size_type(index_size != 0));
Chris@16 1045 return index_size - index_offset;
Chris@16 1046 }
Chris@16 1047
Chris@16 1048 //! <b>Effects</b>: If n is less than or equal to capacity(), this call has no
Chris@16 1049 //! effect. Otherwise, it is a request for allocation of additional memory.
Chris@16 1050 //! If the request is successful, then capacity() is greater than or equal to
Chris@16 1051 //! n; otherwise, capacity() is unchanged. In either case, size() is unchanged.
Chris@16 1052 //!
Chris@16 1053 //! <b>Throws</b>: If memory allocation allocation throws.
Chris@16 1054 void reserve(size_type n)
Chris@16 1055 {
Chris@16 1056 STABLE_VECTOR_CHECK_INVARIANT;
Chris@16 1057 if(n > this->max_size()){
Chris@16 1058 throw_length_error("stable_vector::reserve max_size() exceeded");
Chris@16 1059 }
Chris@16 1060
Chris@16 1061 size_type sz = this->size();
Chris@16 1062 size_type old_capacity = this->capacity();
Chris@16 1063 if(n > old_capacity){
Chris@16 1064 index_traits_type::initialize_end_node(this->index, this->internal_data.end_node, n);
Chris@16 1065 const void * old_ptr = &index[0];
Chris@16 1066 this->index.reserve(n + ExtraPointers);
Chris@16 1067 bool realloced = &index[0] != old_ptr;
Chris@16 1068 //Fix the pointers for the newly allocated buffer
Chris@16 1069 if(realloced){
Chris@16 1070 index_traits_type::fix_up_pointers_from(this->index, this->index.begin());
Chris@16 1071 }
Chris@16 1072 //Now fill pool if data is not enough
Chris@16 1073 if((n - sz) > this->internal_data.pool_size){
Chris@16 1074 this->priv_increase_pool((n - sz) - this->internal_data.pool_size);
Chris@16 1075 }
Chris@16 1076 }
Chris@16 1077 }
Chris@16 1078
Chris@16 1079 //! <b>Effects</b>: Tries to deallocate the excess of memory created
Chris@16 1080 //! with previous allocations. The size of the stable_vector is unchanged
Chris@16 1081 //!
Chris@16 1082 //! <b>Throws</b>: If memory allocation throws.
Chris@16 1083 //!
Chris@16 1084 //! <b>Complexity</b>: Linear to size().
Chris@16 1085 void shrink_to_fit()
Chris@16 1086 {
Chris@16 1087 if(this->capacity()){
Chris@16 1088 //First empty allocated node pool
Chris@16 1089 this->priv_clear_pool();
Chris@16 1090 //If empty completely destroy the index, let's recover default-constructed state
Chris@16 1091 if(this->empty()){
Chris@16 1092 this->index.clear();
Chris@16 1093 this->index.shrink_to_fit();
Chris@16 1094 this->internal_data.end_node.up = node_base_ptr_ptr();
Chris@16 1095 }
Chris@16 1096 //Otherwise, try to shrink-to-fit the index and readjust pointers if necessary
Chris@16 1097 else{
Chris@16 1098 const void* old_ptr = &index[0];
Chris@16 1099 this->index.shrink_to_fit();
Chris@16 1100 bool realloced = &index[0] != old_ptr;
Chris@16 1101 //Fix the pointers for the newly allocated buffer
Chris@16 1102 if(realloced){
Chris@16 1103 index_traits_type::fix_up_pointers_from(this->index, this->index.begin());
Chris@16 1104 }
Chris@16 1105 }
Chris@16 1106 }
Chris@16 1107 }
Chris@16 1108
Chris@16 1109 //////////////////////////////////////////////
Chris@16 1110 //
Chris@16 1111 // element access
Chris@16 1112 //
Chris@16 1113 //////////////////////////////////////////////
Chris@16 1114
Chris@16 1115 //! <b>Requires</b>: !empty()
Chris@16 1116 //!
Chris@16 1117 //! <b>Effects</b>: Returns a reference to the first
Chris@16 1118 //! element of the container.
Chris@16 1119 //!
Chris@16 1120 //! <b>Throws</b>: Nothing.
Chris@16 1121 //!
Chris@16 1122 //! <b>Complexity</b>: Constant.
Chris@16 1123 reference front() BOOST_CONTAINER_NOEXCEPT
Chris@16 1124 { return static_cast<node_reference>(*this->index.front()).value; }
Chris@16 1125
Chris@16 1126 //! <b>Requires</b>: !empty()
Chris@16 1127 //!
Chris@16 1128 //! <b>Effects</b>: Returns a const reference to the first
Chris@16 1129 //! element of the container.
Chris@16 1130 //!
Chris@16 1131 //! <b>Throws</b>: Nothing.
Chris@16 1132 //!
Chris@16 1133 //! <b>Complexity</b>: Constant.
Chris@16 1134 const_reference front() const BOOST_CONTAINER_NOEXCEPT
Chris@16 1135 { return static_cast<const_node_reference>(*this->index.front()).value; }
Chris@16 1136
Chris@16 1137 //! <b>Requires</b>: !empty()
Chris@16 1138 //!
Chris@16 1139 //! <b>Effects</b>: Returns a reference to the last
Chris@16 1140 //! element of the container.
Chris@16 1141 //!
Chris@16 1142 //! <b>Throws</b>: Nothing.
Chris@16 1143 //!
Chris@16 1144 //! <b>Complexity</b>: Constant.
Chris@16 1145 reference back() BOOST_CONTAINER_NOEXCEPT
Chris@16 1146 { return static_cast<node_reference>(*this->index[this->size()-1u]).value; }
Chris@16 1147
Chris@16 1148 //! <b>Requires</b>: !empty()
Chris@16 1149 //!
Chris@16 1150 //! <b>Effects</b>: Returns a const reference to the last
Chris@16 1151 //! element of the container.
Chris@16 1152 //!
Chris@16 1153 //! <b>Throws</b>: Nothing.
Chris@16 1154 //!
Chris@16 1155 //! <b>Complexity</b>: Constant.
Chris@16 1156 const_reference back() const BOOST_CONTAINER_NOEXCEPT
Chris@16 1157 { return static_cast<const_node_reference>(*this->index[this->size()-1u]).value; }
Chris@16 1158
Chris@16 1159 //! <b>Requires</b>: size() > n.
Chris@16 1160 //!
Chris@16 1161 //! <b>Effects</b>: Returns a reference to the nth element
Chris@16 1162 //! from the beginning of the container.
Chris@16 1163 //!
Chris@16 1164 //! <b>Throws</b>: Nothing.
Chris@16 1165 //!
Chris@16 1166 //! <b>Complexity</b>: Constant.
Chris@16 1167 reference operator[](size_type n) BOOST_CONTAINER_NOEXCEPT
Chris@16 1168 {
Chris@16 1169 BOOST_ASSERT(n < this->size());
Chris@16 1170 return static_cast<node_reference>(*this->index[n]).value;
Chris@16 1171 }
Chris@16 1172
Chris@16 1173 //! <b>Requires</b>: size() > n.
Chris@16 1174 //!
Chris@16 1175 //! <b>Effects</b>: Returns a const reference to the nth element
Chris@16 1176 //! from the beginning of the container.
Chris@16 1177 //!
Chris@16 1178 //! <b>Throws</b>: Nothing.
Chris@16 1179 //!
Chris@16 1180 //! <b>Complexity</b>: Constant.
Chris@16 1181 const_reference operator[](size_type n) const BOOST_CONTAINER_NOEXCEPT
Chris@16 1182 {
Chris@16 1183 BOOST_ASSERT(n < this->size());
Chris@16 1184 return static_cast<const_node_reference>(*this->index[n]).value;
Chris@16 1185 }
Chris@16 1186
Chris@16 1187 //! <b>Requires</b>: size() > n.
Chris@16 1188 //!
Chris@16 1189 //! <b>Effects</b>: Returns a reference to the nth element
Chris@16 1190 //! from the beginning of the container.
Chris@16 1191 //!
Chris@16 1192 //! <b>Throws</b>: std::range_error if n >= size()
Chris@16 1193 //!
Chris@16 1194 //! <b>Complexity</b>: Constant.
Chris@16 1195 reference at(size_type n)
Chris@16 1196 {
Chris@16 1197 if(n >= this->size()){
Chris@16 1198 throw_out_of_range("vector::at invalid subscript");
Chris@16 1199 }
Chris@16 1200 return operator[](n);
Chris@16 1201 }
Chris@16 1202
Chris@16 1203 //! <b>Requires</b>: size() > n.
Chris@16 1204 //!
Chris@16 1205 //! <b>Effects</b>: Returns a const reference to the nth element
Chris@16 1206 //! from the beginning of the container.
Chris@16 1207 //!
Chris@16 1208 //! <b>Throws</b>: std::range_error if n >= size()
Chris@16 1209 //!
Chris@16 1210 //! <b>Complexity</b>: Constant.
Chris@16 1211 const_reference at(size_type n)const
Chris@16 1212 {
Chris@16 1213 if(n >= this->size()){
Chris@16 1214 throw_out_of_range("vector::at invalid subscript");
Chris@16 1215 }
Chris@16 1216 return operator[](n);
Chris@16 1217 }
Chris@16 1218
Chris@16 1219 //////////////////////////////////////////////
Chris@16 1220 //
Chris@16 1221 // modifiers
Chris@16 1222 //
Chris@16 1223 //////////////////////////////////////////////
Chris@16 1224
Chris@16 1225 #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
Chris@16 1226
Chris@16 1227 //! <b>Effects</b>: Inserts an object of type T constructed with
Chris@16 1228 //! std::forward<Args>(args)... in the end of the stable_vector.
Chris@16 1229 //!
Chris@16 1230 //! <b>Throws</b>: If memory allocation throws or the in-place constructor throws.
Chris@16 1231 //!
Chris@16 1232 //! <b>Complexity</b>: Amortized constant time.
Chris@16 1233 template<class ...Args>
Chris@16 1234 void emplace_back(Args &&...args)
Chris@16 1235 {
Chris@16 1236 typedef emplace_functor<Args...> EmplaceFunctor;
Chris@16 1237 typedef emplace_iterator<value_type, EmplaceFunctor, difference_type> EmplaceIterator;
Chris@16 1238 EmplaceFunctor &&ef = EmplaceFunctor(boost::forward<Args>(args)...);
Chris@16 1239 this->insert(this->cend(), EmplaceIterator(ef), EmplaceIterator());
Chris@16 1240 }
Chris@16 1241
Chris@16 1242 //! <b>Requires</b>: position must be a valid iterator of *this.
Chris@16 1243 //!
Chris@16 1244 //! <b>Effects</b>: Inserts an object of type T constructed with
Chris@16 1245 //! std::forward<Args>(args)... before position
Chris@16 1246 //!
Chris@16 1247 //! <b>Throws</b>: If memory allocation throws or the in-place constructor throws.
Chris@16 1248 //!
Chris@16 1249 //! <b>Complexity</b>: If position is end(), amortized constant time
Chris@16 1250 //! Linear time otherwise.
Chris@16 1251 template<class ...Args>
Chris@16 1252 iterator emplace(const_iterator position, Args && ...args)
Chris@16 1253 {
Chris@16 1254 //Just call more general insert(pos, size, value) and return iterator
Chris@16 1255 size_type pos_n = position - cbegin();
Chris@16 1256 typedef emplace_functor<Args...> EmplaceFunctor;
Chris@16 1257 typedef emplace_iterator<value_type, EmplaceFunctor, difference_type> EmplaceIterator;
Chris@16 1258 EmplaceFunctor &&ef = EmplaceFunctor(boost::forward<Args>(args)...);
Chris@16 1259 this->insert(position, EmplaceIterator(ef), EmplaceIterator());
Chris@16 1260 return iterator(this->begin() + pos_n);
Chris@16 1261 }
Chris@16 1262
Chris@16 1263 #else
Chris@16 1264
Chris@16 1265 #define BOOST_PP_LOCAL_MACRO(n) \
Chris@16 1266 BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
Chris@16 1267 void emplace_back(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
Chris@16 1268 { \
Chris@16 1269 typedef BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg) \
Chris@16 1270 BOOST_PP_EXPR_IF(n, <) BOOST_PP_ENUM_PARAMS(n, P) BOOST_PP_EXPR_IF(n, >) \
Chris@16 1271 EmplaceFunctor; \
Chris@16 1272 typedef emplace_iterator<value_type, EmplaceFunctor, difference_type> EmplaceIterator; \
Chris@16 1273 EmplaceFunctor ef BOOST_PP_LPAREN_IF(n) \
Chris@16 1274 BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) \
Chris@16 1275 BOOST_PP_RPAREN_IF(n); \
Chris@16 1276 this->insert(this->cend() , EmplaceIterator(ef), EmplaceIterator()); \
Chris@16 1277 } \
Chris@16 1278 \
Chris@16 1279 BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
Chris@16 1280 iterator emplace(const_iterator pos \
Chris@16 1281 BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
Chris@16 1282 { \
Chris@16 1283 typedef BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg) \
Chris@16 1284 BOOST_PP_EXPR_IF(n, <) BOOST_PP_ENUM_PARAMS(n, P) BOOST_PP_EXPR_IF(n, >) \
Chris@16 1285 EmplaceFunctor; \
Chris@16 1286 typedef emplace_iterator<value_type, EmplaceFunctor, difference_type> EmplaceIterator; \
Chris@16 1287 EmplaceFunctor ef BOOST_PP_LPAREN_IF(n) \
Chris@16 1288 BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) \
Chris@16 1289 BOOST_PP_RPAREN_IF(n); \
Chris@16 1290 size_type pos_n = pos - this->cbegin(); \
Chris@16 1291 this->insert(pos, EmplaceIterator(ef), EmplaceIterator()); \
Chris@16 1292 return iterator(this->begin() + pos_n); \
Chris@16 1293 } \
Chris@16 1294 //!
Chris@16 1295 #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
Chris@16 1296 #include BOOST_PP_LOCAL_ITERATE()
Chris@16 1297
Chris@16 1298 #endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
Chris@16 1299
Chris@16 1300 #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
Chris@16 1301 //! <b>Effects</b>: Inserts a copy of x at the end of the stable_vector.
Chris@16 1302 //!
Chris@16 1303 //! <b>Throws</b>: If memory allocation throws or
Chris@16 1304 //! T's copy constructor throws.
Chris@16 1305 //!
Chris@16 1306 //! <b>Complexity</b>: Amortized constant time.
Chris@16 1307 void push_back(const T &x);
Chris@16 1308
Chris@16 1309 //! <b>Effects</b>: Constructs a new element in the end of the stable_vector
Chris@16 1310 //! and moves the resources of mx to this new element.
Chris@16 1311 //!
Chris@16 1312 //! <b>Throws</b>: If memory allocation throws.
Chris@16 1313 //!
Chris@16 1314 //! <b>Complexity</b>: Amortized constant time.
Chris@16 1315 void push_back(T &&x);
Chris@16 1316 #else
Chris@16 1317 BOOST_MOVE_CONVERSION_AWARE_CATCH(push_back, T, void, priv_push_back)
Chris@16 1318 #endif
Chris@16 1319
Chris@16 1320 #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
Chris@16 1321 //! <b>Requires</b>: position must be a valid iterator of *this.
Chris@16 1322 //!
Chris@16 1323 //! <b>Effects</b>: Insert a copy of x before position.
Chris@16 1324 //!
Chris@16 1325 //! <b>Returns</b>: An iterator to the inserted element.
Chris@16 1326 //!
Chris@16 1327 //! <b>Throws</b>: If memory allocation throws or x's copy constructor throws.
Chris@16 1328 //!
Chris@16 1329 //! <b>Complexity</b>: If position is end(), amortized constant time
Chris@16 1330 //! Linear time otherwise.
Chris@16 1331 iterator insert(const_iterator position, const T &x);
Chris@16 1332
Chris@16 1333 //! <b>Requires</b>: position must be a valid iterator of *this.
Chris@16 1334 //!
Chris@16 1335 //! <b>Effects</b>: Insert a new element before position with mx's resources.
Chris@16 1336 //!
Chris@16 1337 //! <b>Returns</b>: an iterator to the inserted element.
Chris@16 1338 //!
Chris@16 1339 //! <b>Throws</b>: If memory allocation throws.
Chris@16 1340 //!
Chris@16 1341 //! <b>Complexity</b>: If position is end(), amortized constant time
Chris@16 1342 //! Linear time otherwise.
Chris@16 1343 iterator insert(const_iterator position, T &&x);
Chris@16 1344 #else
Chris@16 1345 BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert, T, iterator, priv_insert, const_iterator, const_iterator)
Chris@16 1346 #endif
Chris@16 1347
Chris@16 1348 //! <b>Requires</b>: pos must be a valid iterator of *this.
Chris@16 1349 //!
Chris@16 1350 //! <b>Effects</b>: Insert n copies of x before position.
Chris@16 1351 //!
Chris@16 1352 //! <b>Returns</b>: an iterator to the first inserted element or position if n is 0.
Chris@16 1353 //!
Chris@16 1354 //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
Chris@16 1355 //!
Chris@16 1356 //! <b>Complexity</b>: Linear to n.
Chris@16 1357 iterator insert(const_iterator position, size_type n, const T& t)
Chris@16 1358 {
Chris@16 1359 STABLE_VECTOR_CHECK_INVARIANT;
Chris@16 1360 typedef constant_iterator<value_type, difference_type> cvalue_iterator;
Chris@16 1361 return this->insert(position, cvalue_iterator(t, n), cvalue_iterator());
Chris@16 1362 }
Chris@16 1363
Chris@16 1364 //! <b>Requires</b>: pos must be a valid iterator of *this.
Chris@16 1365 //!
Chris@16 1366 //! <b>Effects</b>: Insert a copy of the [first, last) range before pos.
Chris@16 1367 //!
Chris@16 1368 //! <b>Returns</b>: an iterator to the first inserted element or position if first == last.
Chris@16 1369 //!
Chris@16 1370 //! <b>Throws</b>: If memory allocation throws, T's constructor from a
Chris@16 1371 //! dereferenced InpIt throws or T's copy constructor throws.
Chris@16 1372 //!
Chris@16 1373 //! <b>Complexity</b>: Linear to std::distance [first, last).
Chris@16 1374 template <class InputIterator>
Chris@16 1375 iterator insert(const_iterator position, InputIterator first, InputIterator last
Chris@16 1376 #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
Chris@16 1377 , typename container_detail::enable_if_c
Chris@16 1378 < !container_detail::is_convertible<InputIterator, size_type>::value
Chris@16 1379 && container_detail::is_input_iterator<InputIterator>::value
Chris@16 1380 >::type * = 0
Chris@16 1381 #endif
Chris@16 1382 )
Chris@16 1383 {
Chris@16 1384 STABLE_VECTOR_CHECK_INVARIANT;
Chris@16 1385 const size_type pos_n = position - this->cbegin();
Chris@16 1386 for(; first != last; ++first){
Chris@16 1387 this->emplace(position, *first);
Chris@16 1388 }
Chris@16 1389 return this->begin() + pos_n;
Chris@16 1390 }
Chris@16 1391
Chris@16 1392 #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
Chris@16 1393 template <class FwdIt>
Chris@16 1394 iterator insert(const_iterator position, FwdIt first, FwdIt last
Chris@16 1395 , typename container_detail::enable_if_c
Chris@16 1396 < !container_detail::is_convertible<FwdIt, size_type>::value
Chris@16 1397 && !container_detail::is_input_iterator<FwdIt>::value
Chris@16 1398 >::type * = 0
Chris@16 1399 )
Chris@16 1400 {
Chris@16 1401 const size_type num_new = static_cast<size_type>(std::distance(first, last));
Chris@16 1402 const size_type pos = static_cast<size_type>(position - this->cbegin());
Chris@16 1403 if(num_new){
Chris@16 1404 //Fills the node pool and inserts num_new null pointers in pos.
Chris@16 1405 //If a new buffer was needed fixes up pointers up to pos so
Chris@16 1406 //past-new nodes are not aligned until the end of this function
Chris@16 1407 //or in a rollback in case of exception
Chris@16 1408 index_iterator it_past_newly_constructed(this->priv_insert_forward_non_templated(pos, num_new));
Chris@16 1409 const index_iterator it_past_new(it_past_newly_constructed + num_new);
Chris@16 1410 {
Chris@16 1411 //Prepare rollback
Chris@16 1412 insert_rollback rollback(*this, it_past_newly_constructed, it_past_new);
Chris@16 1413 while(first != last){
Chris@16 1414 const node_ptr p = this->priv_get_from_pool();
Chris@16 1415 BOOST_ASSERT(!!p);
Chris@16 1416 //Put it in the index so rollback can return it in pool if construct_in_place throws
Chris@16 1417 *it_past_newly_constructed = p;
Chris@16 1418 //Constructs and fixes up pointers This can throw
Chris@16 1419 this->priv_build_node_from_it(p, it_past_newly_constructed, first);
Chris@16 1420 ++first;
Chris@16 1421 ++it_past_newly_constructed;
Chris@16 1422 }
Chris@16 1423 //rollback.~insert_rollback() called in case of exception
Chris@16 1424 }
Chris@16 1425 //Fix up pointers for past-new nodes (new nodes were fixed during construction) and
Chris@16 1426 //nodes before insertion position in priv_insert_forward_non_templated(...)
Chris@16 1427 index_traits_type::fix_up_pointers_from(this->index, it_past_newly_constructed);
Chris@16 1428 }
Chris@16 1429 return this->begin() + pos;
Chris@16 1430 }
Chris@16 1431 #endif
Chris@16 1432
Chris@16 1433 //! <b>Effects</b>: Removes the last element from the stable_vector.
Chris@16 1434 //!
Chris@16 1435 //! <b>Throws</b>: Nothing.
Chris@16 1436 //!
Chris@16 1437 //! <b>Complexity</b>: Constant time.
Chris@16 1438 void pop_back() BOOST_CONTAINER_NOEXCEPT
Chris@16 1439 { this->erase(--this->cend()); }
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. Constant if pos is the last element.
Chris@16 1447 iterator erase(const_iterator position) BOOST_CONTAINER_NOEXCEPT
Chris@16 1448 {
Chris@16 1449 STABLE_VECTOR_CHECK_INVARIANT;
Chris@16 1450 const size_type d = position - this->cbegin();
Chris@16 1451 index_iterator it = this->index.begin() + d;
Chris@16 1452 this->priv_delete_node(position.node_pointer());
Chris@16 1453 it = this->index.erase(it);
Chris@16 1454 index_traits_type::fix_up_pointers_from(this->index, it);
Chris@16 1455 return iterator(node_ptr_traits::static_cast_from(*it));
Chris@16 1456 }
Chris@16 1457
Chris@16 1458 //! <b>Effects</b>: Erases the elements pointed by [first, last).
Chris@16 1459 //!
Chris@16 1460 //! <b>Throws</b>: Nothing.
Chris@16 1461 //!
Chris@16 1462 //! <b>Complexity</b>: Linear to the distance between first and last
Chris@16 1463 //! plus linear to the elements between pos and the last element.
Chris@16 1464 iterator erase(const_iterator first, const_iterator last) BOOST_CONTAINER_NOEXCEPT
Chris@16 1465 {
Chris@16 1466 STABLE_VECTOR_CHECK_INVARIANT;
Chris@16 1467 const const_iterator cbeg(this->cbegin());
Chris@16 1468 const size_type d1 = static_cast<size_type>(first - cbeg),
Chris@16 1469 d2 = static_cast<size_type>(last - cbeg);
Chris@16 1470 size_type d_dif = d2 - d1;
Chris@16 1471 if(d_dif){
Chris@16 1472 multiallocation_chain holder;
Chris@16 1473 const index_iterator it1(this->index.begin() + d1);
Chris@16 1474 const index_iterator it2(it1 + d_dif);
Chris@16 1475 index_iterator it(it1);
Chris@16 1476 while(d_dif--){
Chris@16 1477 node_base_ptr &nb = *it;
Chris@16 1478 ++it;
Chris@16 1479 node_type &n = *node_ptr_traits::static_cast_from(nb);
Chris@16 1480 this->priv_destroy_node(n);
Chris@16 1481 holder.push_back(node_ptr_traits::pointer_to(n));
Chris@16 1482 }
Chris@16 1483 this->priv_put_in_pool(holder);
Chris@16 1484 const index_iterator e = this->index.erase(it1, it2);
Chris@16 1485 index_traits_type::fix_up_pointers_from(this->index, e);
Chris@16 1486 }
Chris@16 1487 return iterator(last.node_pointer());
Chris@16 1488 }
Chris@16 1489
Chris@16 1490 //! <b>Effects</b>: Swaps the contents of *this and x.
Chris@16 1491 //!
Chris@16 1492 //! <b>Throws</b>: Nothing.
Chris@16 1493 //!
Chris@16 1494 //! <b>Complexity</b>: Constant.
Chris@16 1495 void swap(stable_vector & x)
Chris@16 1496 {
Chris@16 1497 STABLE_VECTOR_CHECK_INVARIANT;
Chris@16 1498 container_detail::bool_<allocator_traits_type::propagate_on_container_swap::value> flag;
Chris@16 1499 container_detail::swap_alloc(this->priv_node_alloc(), x.priv_node_alloc(), flag);
Chris@16 1500 //vector's allocator is swapped here
Chris@16 1501 this->index.swap(x.index);
Chris@16 1502 this->priv_swap_members(x);
Chris@16 1503 }
Chris@16 1504
Chris@16 1505 //! <b>Effects</b>: Erases all the elements of the stable_vector.
Chris@16 1506 //!
Chris@16 1507 //! <b>Throws</b>: Nothing.
Chris@16 1508 //!
Chris@16 1509 //! <b>Complexity</b>: Linear to the number of elements in the stable_vector.
Chris@16 1510 void clear() BOOST_CONTAINER_NOEXCEPT
Chris@16 1511 { this->erase(this->cbegin(),this->cend()); }
Chris@16 1512
Chris@16 1513 /// @cond
Chris@16 1514
Chris@16 1515 private:
Chris@16 1516
Chris@16 1517 class insert_rollback
Chris@16 1518 {
Chris@16 1519 public:
Chris@16 1520
Chris@16 1521 insert_rollback(stable_vector &sv, index_iterator &it_past_constructed, const index_iterator &it_past_new)
Chris@16 1522 : m_sv(sv), m_it_past_constructed(it_past_constructed), m_it_past_new(it_past_new)
Chris@16 1523 {}
Chris@16 1524
Chris@16 1525 ~insert_rollback()
Chris@16 1526 {
Chris@16 1527 if(m_it_past_constructed != m_it_past_new){
Chris@16 1528 m_sv.priv_put_in_pool(node_ptr_traits::static_cast_from(*m_it_past_constructed));
Chris@16 1529 index_iterator e = m_sv.index.erase(m_it_past_constructed, m_it_past_new);
Chris@16 1530 index_traits_type::fix_up_pointers_from(m_sv.index, e);
Chris@16 1531 }
Chris@16 1532 }
Chris@16 1533
Chris@16 1534 private:
Chris@16 1535 stable_vector &m_sv;
Chris@16 1536 index_iterator &m_it_past_constructed;
Chris@16 1537 const index_iterator &m_it_past_new;
Chris@16 1538 };
Chris@16 1539
Chris@16 1540 class push_back_rollback
Chris@16 1541 {
Chris@16 1542 public:
Chris@16 1543 push_back_rollback(stable_vector &sv, const node_ptr &p)
Chris@16 1544 : m_sv(sv), m_p(p)
Chris@16 1545 {}
Chris@16 1546
Chris@16 1547 ~push_back_rollback()
Chris@16 1548 {
Chris@16 1549 if(m_p){
Chris@16 1550 m_sv.priv_put_in_pool(m_p);
Chris@16 1551 }
Chris@16 1552 }
Chris@16 1553
Chris@16 1554 void release()
Chris@16 1555 { m_p = node_ptr(); }
Chris@16 1556
Chris@16 1557 private:
Chris@16 1558 stable_vector &m_sv;
Chris@16 1559 node_ptr m_p;
Chris@16 1560 };
Chris@16 1561
Chris@16 1562 index_iterator priv_insert_forward_non_templated(size_type pos, size_type num_new)
Chris@16 1563 {
Chris@16 1564 index_traits_type::initialize_end_node(this->index, this->internal_data.end_node, num_new);
Chris@16 1565
Chris@16 1566 //Now try to fill the pool with new data
Chris@16 1567 if(this->internal_data.pool_size < num_new){
Chris@16 1568 this->priv_increase_pool(num_new - this->internal_data.pool_size);
Chris@16 1569 }
Chris@16 1570
Chris@16 1571 //Now try to make room in the vector
Chris@16 1572 const node_base_ptr_ptr old_buffer = this->index.data();
Chris@16 1573 this->index.insert(this->index.begin() + pos, num_new, node_ptr());
Chris@16 1574 bool new_buffer = this->index.data() != old_buffer;
Chris@16 1575
Chris@16 1576 //Fix the pointers for the newly allocated buffer
Chris@16 1577 const index_iterator index_beg = this->index.begin();
Chris@16 1578 if(new_buffer){
Chris@16 1579 index_traits_type::fix_up_pointers(index_beg, index_beg + pos);
Chris@16 1580 }
Chris@16 1581 return index_beg + pos;
Chris@16 1582 }
Chris@16 1583
Chris@16 1584 bool priv_capacity_bigger_than_size() const
Chris@16 1585 {
Chris@16 1586 return this->index.capacity() > this->index.size() &&
Chris@16 1587 this->internal_data.pool_size > 0;
Chris@16 1588 }
Chris@16 1589
Chris@16 1590 template <class U>
Chris@16 1591 void priv_push_back(BOOST_MOVE_CATCH_FWD(U) x)
Chris@16 1592 {
Chris@16 1593 if(this->priv_capacity_bigger_than_size()){
Chris@16 1594 //Enough memory in the pool and in the index
Chris@16 1595 const node_ptr p = this->priv_get_from_pool();
Chris@16 1596 BOOST_ASSERT(!!p);
Chris@16 1597 {
Chris@16 1598 push_back_rollback rollback(*this, p);
Chris@16 1599 //This might throw
Chris@16 1600 this->priv_build_node_from_convertible(p, ::boost::forward<U>(x));
Chris@16 1601 rollback.release();
Chris@16 1602 }
Chris@16 1603 //This can't throw as there is room for a new elements in the index
Chris@16 1604 index_iterator new_index = this->index.insert(this->index.end() - ExtraPointers, p);
Chris@16 1605 index_traits_type::fix_up_pointers_from(this->index, new_index);
Chris@16 1606 }
Chris@16 1607 else{
Chris@16 1608 this->insert(this->cend(), ::boost::forward<U>(x));
Chris@16 1609 }
Chris@16 1610 }
Chris@16 1611
Chris@16 1612 iterator priv_insert(const_iterator position, const value_type &t)
Chris@16 1613 {
Chris@16 1614 typedef constant_iterator<value_type, difference_type> cvalue_iterator;
Chris@16 1615 return this->insert(position, cvalue_iterator(t, 1), cvalue_iterator());
Chris@16 1616 }
Chris@16 1617
Chris@16 1618 iterator priv_insert(const_iterator position, BOOST_RV_REF(T) x)
Chris@16 1619 {
Chris@16 1620 typedef repeat_iterator<T, difference_type> repeat_it;
Chris@16 1621 typedef boost::move_iterator<repeat_it> repeat_move_it;
Chris@16 1622 //Just call more general insert(pos, size, value) and return iterator
Chris@16 1623 return this->insert(position, repeat_move_it(repeat_it(x, 1)), repeat_move_it(repeat_it()));
Chris@16 1624 }
Chris@16 1625
Chris@16 1626 void priv_clear_pool()
Chris@16 1627 {
Chris@16 1628 if(!this->index.empty() && this->index.back()){
Chris@16 1629 node_base_ptr &pool_first_ref = *(this->index.end() - 2);
Chris@16 1630 node_base_ptr &pool_last_ref = this->index.back();
Chris@16 1631
Chris@16 1632 multiallocation_chain holder;
Chris@16 1633 holder.incorporate_after( holder.before_begin()
Chris@16 1634 , node_ptr_traits::static_cast_from(pool_first_ref)
Chris@16 1635 , node_ptr_traits::static_cast_from(pool_last_ref)
Chris@16 1636 , internal_data.pool_size);
Chris@16 1637 this->deallocate_individual(holder);
Chris@16 1638 pool_first_ref = pool_last_ref = 0;
Chris@16 1639 this->internal_data.pool_size = 0;
Chris@16 1640 }
Chris@16 1641 }
Chris@16 1642
Chris@16 1643 void priv_increase_pool(size_type n)
Chris@16 1644 {
Chris@16 1645 node_base_ptr &pool_first_ref = *(this->index.end() - 2);
Chris@16 1646 node_base_ptr &pool_last_ref = this->index.back();
Chris@16 1647 multiallocation_chain holder;
Chris@16 1648 holder.incorporate_after( holder.before_begin()
Chris@16 1649 , node_ptr_traits::static_cast_from(pool_first_ref)
Chris@16 1650 , node_ptr_traits::static_cast_from(pool_last_ref)
Chris@16 1651 , internal_data.pool_size);
Chris@16 1652 multiallocation_chain m;
Chris@16 1653 this->allocate_individual(n, m);
Chris@16 1654 holder.splice_after(holder.before_begin(), m, m.before_begin(), m.last(), n);
Chris@16 1655 this->internal_data.pool_size += n;
Chris@16 1656 std::pair<node_ptr, node_ptr> data(holder.extract_data());
Chris@16 1657 pool_first_ref = data.first;
Chris@16 1658 pool_last_ref = data.second;
Chris@16 1659 }
Chris@16 1660
Chris@16 1661 void priv_put_in_pool(const node_ptr &p)
Chris@16 1662 {
Chris@16 1663 node_base_ptr &pool_first_ref = *(this->index.end()-2);
Chris@16 1664 node_base_ptr &pool_last_ref = this->index.back();
Chris@16 1665 multiallocation_chain holder;
Chris@16 1666 holder.incorporate_after( holder.before_begin()
Chris@16 1667 , node_ptr_traits::static_cast_from(pool_first_ref)
Chris@16 1668 , node_ptr_traits::static_cast_from(pool_last_ref)
Chris@16 1669 , internal_data.pool_size);
Chris@16 1670 holder.push_front(p);
Chris@16 1671 ++this->internal_data.pool_size;
Chris@16 1672 std::pair<node_ptr, node_ptr> ret(holder.extract_data());
Chris@16 1673 pool_first_ref = ret.first;
Chris@16 1674 pool_last_ref = ret.second;
Chris@16 1675 }
Chris@16 1676
Chris@16 1677 void priv_put_in_pool(multiallocation_chain &ch)
Chris@16 1678 {
Chris@16 1679 node_base_ptr &pool_first_ref = *(this->index.end()-(ExtraPointers-1));
Chris@16 1680 node_base_ptr &pool_last_ref = this->index.back();
Chris@16 1681 ch.incorporate_after( ch.before_begin()
Chris@16 1682 , node_ptr_traits::static_cast_from(pool_first_ref)
Chris@16 1683 , node_ptr_traits::static_cast_from(pool_last_ref)
Chris@16 1684 , internal_data.pool_size);
Chris@16 1685 this->internal_data.pool_size = ch.size();
Chris@16 1686 const std::pair<node_ptr, node_ptr> ret(ch.extract_data());
Chris@16 1687 pool_first_ref = ret.first;
Chris@16 1688 pool_last_ref = ret.second;
Chris@16 1689 }
Chris@16 1690
Chris@16 1691 node_ptr priv_get_from_pool()
Chris@16 1692 {
Chris@16 1693 //Precondition: index is not empty
Chris@16 1694 BOOST_ASSERT(!this->index.empty());
Chris@16 1695 node_base_ptr &pool_first_ref = *(this->index.end() - (ExtraPointers-1));
Chris@16 1696 node_base_ptr &pool_last_ref = this->index.back();
Chris@16 1697 multiallocation_chain holder;
Chris@16 1698 holder.incorporate_after( holder.before_begin()
Chris@16 1699 , node_ptr_traits::static_cast_from(pool_first_ref)
Chris@16 1700 , node_ptr_traits::static_cast_from(pool_last_ref)
Chris@16 1701 , internal_data.pool_size);
Chris@16 1702 node_ptr ret = holder.pop_front();
Chris@16 1703 --this->internal_data.pool_size;
Chris@16 1704 if(!internal_data.pool_size){
Chris@16 1705 pool_first_ref = pool_last_ref = node_ptr();
Chris@16 1706 }
Chris@16 1707 else{
Chris@16 1708 const std::pair<node_ptr, node_ptr> data(holder.extract_data());
Chris@16 1709 pool_first_ref = data.first;
Chris@16 1710 pool_last_ref = data.second;
Chris@16 1711 }
Chris@16 1712 return ret;
Chris@16 1713 }
Chris@16 1714
Chris@16 1715 node_ptr priv_get_end_node() const
Chris@16 1716 {
Chris@16 1717 return node_ptr_traits::pointer_to
Chris@16 1718 (static_cast<node_type&>(const_cast<node_base_type&>(this->internal_data.end_node)));
Chris@16 1719 }
Chris@16 1720
Chris@16 1721 void priv_destroy_node(const node_type &n)
Chris@16 1722 {
Chris@16 1723 allocator_traits<node_allocator_type>::
Chris@16 1724 destroy(this->priv_node_alloc(), container_detail::addressof(n.value));
Chris@16 1725 static_cast<const node_base_type*>(&n)->~node_base_type();
Chris@16 1726 }
Chris@16 1727
Chris@16 1728 void priv_delete_node(const node_ptr &n)
Chris@16 1729 {
Chris@16 1730 this->priv_destroy_node(*n);
Chris@16 1731 this->priv_put_in_pool(n);
Chris@16 1732 }
Chris@16 1733
Chris@16 1734 template<class Iterator>
Chris@16 1735 void priv_build_node_from_it(const node_ptr &p, const index_iterator &up_index, const Iterator &it)
Chris@16 1736 {
Chris@16 1737 //This can throw
Chris@16 1738 boost::container::construct_in_place
Chris@16 1739 ( this->priv_node_alloc()
Chris@16 1740 , container_detail::addressof(p->value)
Chris@16 1741 , it);
Chris@16 1742 //This does not throw
Chris@16 1743 ::new(static_cast<node_base_type*>(container_detail::to_raw_pointer(p)))
Chris@16 1744 node_base_type(index_traits_type::ptr_to_node_base_ptr(*up_index));
Chris@16 1745 }
Chris@16 1746
Chris@16 1747 template<class ValueConvertible>
Chris@16 1748 void priv_build_node_from_convertible(const node_ptr &p, BOOST_FWD_REF(ValueConvertible) value_convertible)
Chris@16 1749 {
Chris@16 1750 //This can throw
Chris@16 1751 boost::container::allocator_traits<node_allocator_type>::construct
Chris@16 1752 ( this->priv_node_alloc()
Chris@16 1753 , container_detail::addressof(p->value)
Chris@16 1754 , ::boost::forward<ValueConvertible>(value_convertible));
Chris@16 1755 //This does not throw
Chris@16 1756 ::new(static_cast<node_base_type*>(container_detail::to_raw_pointer(p))) node_base_type;
Chris@16 1757 }
Chris@16 1758
Chris@16 1759 void priv_swap_members(stable_vector &x)
Chris@16 1760 {
Chris@16 1761 boost::container::swap_dispatch(this->internal_data.pool_size, x.internal_data.pool_size);
Chris@16 1762 index_traits_type::readjust_end_node(this->index, this->internal_data.end_node);
Chris@16 1763 index_traits_type::readjust_end_node(x.index, x.internal_data.end_node);
Chris@16 1764 }
Chris@16 1765
Chris@16 1766 #if defined(STABLE_VECTOR_ENABLE_INVARIANT_CHECKING)
Chris@16 1767 bool priv_invariant()const
Chris@16 1768 {
Chris@16 1769 index_type & index_ref = const_cast<index_type&>(this->index);
Chris@16 1770
Chris@16 1771 if(index.empty())
Chris@16 1772 return !this->capacity() && !this->size();
Chris@16 1773 if(this->priv_get_end_node() != *(index.end() - ExtraPointers)){
Chris@16 1774 return false;
Chris@16 1775 }
Chris@16 1776
Chris@16 1777 if(!index_traits_type::invariants(index_ref)){
Chris@16 1778 return false;
Chris@16 1779 }
Chris@16 1780
Chris@16 1781 size_type n = this->capacity() - this->size();
Chris@16 1782 node_base_ptr &pool_first_ref = *(index_ref.end() - (ExtraPointers-1));
Chris@16 1783 node_base_ptr &pool_last_ref = index_ref.back();
Chris@16 1784 multiallocation_chain holder;
Chris@16 1785 holder.incorporate_after( holder.before_begin()
Chris@16 1786 , node_ptr_traits::static_cast_from(pool_first_ref)
Chris@16 1787 , node_ptr_traits::static_cast_from(pool_last_ref)
Chris@16 1788 , internal_data.pool_size);
Chris@16 1789 typename multiallocation_chain::iterator beg(holder.begin()), end(holder.end());
Chris@16 1790 size_type num_pool = 0;
Chris@16 1791 while(beg != end){
Chris@16 1792 ++num_pool;
Chris@16 1793 ++beg;
Chris@16 1794 }
Chris@16 1795 return n >= num_pool && num_pool == internal_data.pool_size;
Chris@16 1796 }
Chris@16 1797
Chris@16 1798 class invariant_checker
Chris@16 1799 {
Chris@16 1800 invariant_checker(const invariant_checker &);
Chris@16 1801 invariant_checker & operator=(const invariant_checker &);
Chris@16 1802 const stable_vector* p;
Chris@16 1803
Chris@16 1804 public:
Chris@16 1805 invariant_checker(const stable_vector& v):p(&v){}
Chris@16 1806 ~invariant_checker(){BOOST_ASSERT(p->priv_invariant());}
Chris@16 1807 void touch(){}
Chris@16 1808 };
Chris@16 1809 #endif
Chris@16 1810
Chris@16 1811 class ebo_holder
Chris@16 1812 : public node_allocator_type
Chris@16 1813 {
Chris@16 1814 private:
Chris@16 1815 BOOST_MOVABLE_BUT_NOT_COPYABLE(ebo_holder)
Chris@16 1816
Chris@16 1817 public:
Chris@16 1818 template<class AllocatorRLValue>
Chris@16 1819 explicit ebo_holder(BOOST_FWD_REF(AllocatorRLValue) a)
Chris@16 1820 : node_allocator_type(boost::forward<AllocatorRLValue>(a))
Chris@16 1821 , pool_size(0)
Chris@16 1822 , end_node()
Chris@16 1823 {}
Chris@16 1824
Chris@16 1825 ebo_holder()
Chris@16 1826 : node_allocator_type()
Chris@16 1827 , pool_size(0)
Chris@16 1828 , end_node()
Chris@16 1829 {}
Chris@16 1830
Chris@16 1831 size_type pool_size;
Chris@16 1832 node_base_type end_node;
Chris@16 1833 } internal_data;
Chris@16 1834
Chris@16 1835 node_allocator_type &priv_node_alloc() { return internal_data; }
Chris@16 1836 const node_allocator_type &priv_node_alloc() const { return internal_data; }
Chris@16 1837
Chris@16 1838 index_type index;
Chris@16 1839 /// @endcond
Chris@16 1840 };
Chris@16 1841
Chris@16 1842 template <typename T,typename Allocator>
Chris@16 1843 bool operator==(const stable_vector<T,Allocator>& x,const stable_vector<T,Allocator>& y)
Chris@16 1844 {
Chris@16 1845 return x.size()==y.size()&&std::equal(x.begin(),x.end(),y.begin());
Chris@16 1846 }
Chris@16 1847
Chris@16 1848 template <typename T,typename Allocator>
Chris@16 1849 bool operator< (const stable_vector<T,Allocator>& x,const stable_vector<T,Allocator>& y)
Chris@16 1850 {
Chris@16 1851 return std::lexicographical_compare(x.begin(),x.end(),y.begin(),y.end());
Chris@16 1852 }
Chris@16 1853
Chris@16 1854 template <typename T,typename Allocator>
Chris@16 1855 bool operator!=(const stable_vector<T,Allocator>& x,const stable_vector<T,Allocator>& y)
Chris@16 1856 {
Chris@16 1857 return !(x==y);
Chris@16 1858 }
Chris@16 1859
Chris@16 1860 template <typename T,typename Allocator>
Chris@16 1861 bool operator> (const stable_vector<T,Allocator>& x,const stable_vector<T,Allocator>& y)
Chris@16 1862 {
Chris@16 1863 return y<x;
Chris@16 1864 }
Chris@16 1865
Chris@16 1866 template <typename T,typename Allocator>
Chris@16 1867 bool operator>=(const stable_vector<T,Allocator>& x,const stable_vector<T,Allocator>& y)
Chris@16 1868 {
Chris@16 1869 return !(x<y);
Chris@16 1870 }
Chris@16 1871
Chris@16 1872 template <typename T,typename Allocator>
Chris@16 1873 bool operator<=(const stable_vector<T,Allocator>& x,const stable_vector<T,Allocator>& y)
Chris@16 1874 {
Chris@16 1875 return !(x>y);
Chris@16 1876 }
Chris@16 1877
Chris@16 1878 // specialized algorithms:
Chris@16 1879
Chris@16 1880 template <typename T, typename Allocator>
Chris@16 1881 void swap(stable_vector<T,Allocator>& x,stable_vector<T,Allocator>& y)
Chris@16 1882 {
Chris@16 1883 x.swap(y);
Chris@16 1884 }
Chris@16 1885
Chris@16 1886 /// @cond
Chris@16 1887
Chris@16 1888 #undef STABLE_VECTOR_CHECK_INVARIANT
Chris@16 1889
Chris@16 1890 /// @endcond
Chris@16 1891
Chris@16 1892 /*
Chris@16 1893
Chris@16 1894 //!has_trivial_destructor_after_move<> == true_type
Chris@16 1895 //!specialization for optimizations
Chris@16 1896 template <class T, class Allocator>
Chris@16 1897 struct has_trivial_destructor_after_move<boost::container::stable_vector<T, Allocator> >
Chris@16 1898 : public has_trivial_destructor_after_move<Allocator>::value
Chris@16 1899 {};
Chris@16 1900
Chris@16 1901 */
Chris@16 1902
Chris@16 1903 }}
Chris@16 1904
Chris@16 1905 #include <boost/container/detail/config_end.hpp>
Chris@16 1906
Chris@16 1907 #endif //BOOST_CONTAINER_STABLE_VECTOR_HPP