annotate DEPENDENCIES/generic/include/boost/intrusive/slist.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 Olaf Krzikalla 2004-2006.
Chris@16 4 // (C) Copyright Ion Gaztanaga 2006-2013
Chris@16 5 //
Chris@16 6 // Distributed under the Boost Software License, Version 1.0.
Chris@16 7 // (See accompanying file LICENSE_1_0.txt or copy at
Chris@16 8 // http://www.boost.org/LICENSE_1_0.txt)
Chris@16 9 //
Chris@16 10 // See http://www.boost.org/libs/intrusive for documentation.
Chris@16 11 //
Chris@16 12 /////////////////////////////////////////////////////////////////////////////
Chris@16 13
Chris@16 14 #ifndef BOOST_INTRUSIVE_SLIST_HPP
Chris@16 15 #define BOOST_INTRUSIVE_SLIST_HPP
Chris@16 16
Chris@16 17 #include <boost/intrusive/detail/config_begin.hpp>
Chris@16 18 #include <boost/static_assert.hpp>
Chris@16 19 #include <boost/intrusive/detail/assert.hpp>
Chris@16 20 #include <boost/intrusive/intrusive_fwd.hpp>
Chris@16 21 #include <boost/intrusive/slist_hook.hpp>
Chris@16 22 #include <boost/intrusive/circular_slist_algorithms.hpp>
Chris@16 23 #include <boost/intrusive/linear_slist_algorithms.hpp>
Chris@16 24 #include <boost/intrusive/pointer_traits.hpp>
Chris@16 25 #include <boost/intrusive/detail/clear_on_destructor_base.hpp>
Chris@16 26 #include <boost/intrusive/link_mode.hpp>
Chris@16 27 #include <boost/intrusive/options.hpp>
Chris@16 28 #include <boost/intrusive/detail/utilities.hpp>
Chris@16 29 #include <iterator>
Chris@16 30 #include <functional>
Chris@16 31 #include <algorithm>
Chris@16 32 #include <cstddef> //std::size_t
Chris@16 33 #include <utility> //std::pair
Chris@16 34 #include <boost/move/move.hpp>
Chris@16 35
Chris@16 36 namespace boost {
Chris@16 37 namespace intrusive {
Chris@16 38
Chris@16 39 /// @cond
Chris@16 40
Chris@16 41 template<class Node, class NodePtr, bool>
Chris@16 42 struct root_plus_last
Chris@16 43 {
Chris@16 44 Node root_;
Chris@16 45 NodePtr last_;
Chris@16 46 };
Chris@16 47
Chris@16 48 template<class Node, class NodePtr>
Chris@16 49 struct root_plus_last<Node, NodePtr, false>
Chris@16 50 {
Chris@16 51 Node root_;
Chris@16 52 };
Chris@16 53
Chris@16 54 struct slist_defaults
Chris@16 55 {
Chris@16 56 typedef detail::default_slist_hook proto_value_traits;
Chris@16 57 static const bool constant_time_size = true;
Chris@16 58 static const bool linear = false;
Chris@16 59 typedef std::size_t size_type;
Chris@16 60 static const bool cache_last = false;
Chris@16 61 };
Chris@16 62
Chris@16 63 struct slist_bool_flags
Chris@16 64 {
Chris@16 65 static const std::size_t linear_pos = 1u;
Chris@16 66 static const std::size_t constant_time_size_pos = 2u;
Chris@16 67 static const std::size_t cache_last_pos = 4u;
Chris@16 68 };
Chris@16 69
Chris@16 70
Chris@16 71 /// @endcond
Chris@16 72
Chris@16 73 //! The class template slist is an intrusive container, that encapsulates
Chris@16 74 //! a singly-linked list. You can use such a list to squeeze the last bit
Chris@16 75 //! of performance from your application. Unfortunately, the little gains
Chris@16 76 //! come with some huge drawbacks. A lot of member functions can't be
Chris@16 77 //! implemented as efficiently as for standard containers. To overcome
Chris@16 78 //! this limitation some other member functions with rather unusual semantics
Chris@16 79 //! have to be introduced.
Chris@16 80 //!
Chris@16 81 //! The template parameter \c T is the type to be managed by the container.
Chris@16 82 //! The user can specify additional options and if no options are provided
Chris@16 83 //! default options are used.
Chris@16 84 //!
Chris@16 85 //! The container supports the following options:
Chris@16 86 //! \c base_hook<>/member_hook<>/value_traits<>,
Chris@16 87 //! \c constant_time_size<>, \c size_type<>,
Chris@16 88 //! \c linear<> and \c cache_last<>.
Chris@16 89 //!
Chris@16 90 //! The iterators of slist are forward iterators. slist provides a static
Chris@16 91 //! function called "previous" to compute the previous iterator of a given iterator.
Chris@16 92 //! This function has linear complexity. To improve the usability esp. with
Chris@16 93 //! the '*_after' functions, ++end() == begin() and previous(begin()) == end()
Chris@16 94 //! are defined. An new special function "before_begin()" is defined, which returns
Chris@16 95 //! an iterator that points one less the beginning of the list: ++before_begin() == begin()
Chris@16 96 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
Chris@16 97 template<class T, class ...Options>
Chris@16 98 #else
Chris@16 99 template<class ValueTraits, class SizeType, std::size_t BoolFlags>
Chris@16 100 #endif
Chris@16 101 class slist_impl
Chris@16 102 : private detail::clear_on_destructor_base
Chris@16 103 < slist_impl<ValueTraits, SizeType, BoolFlags>
Chris@16 104 , is_safe_autounlink<detail::get_real_value_traits<ValueTraits>::type::link_mode>::value
Chris@16 105 >
Chris@16 106 {
Chris@16 107 template<class C, bool> friend class detail::clear_on_destructor_base;
Chris@16 108 //Public typedefs
Chris@16 109 public:
Chris@16 110 typedef ValueTraits value_traits;
Chris@16 111 /// @cond
Chris@16 112 static const bool external_value_traits =
Chris@16 113 detail::external_value_traits_bool_is_true<value_traits>::value;
Chris@16 114 typedef typename detail::get_real_value_traits<ValueTraits>::type real_value_traits;
Chris@16 115 /// @endcond
Chris@16 116 typedef typename real_value_traits::pointer pointer;
Chris@16 117 typedef typename real_value_traits::const_pointer const_pointer;
Chris@16 118 typedef typename pointer_traits<pointer>::element_type value_type;
Chris@16 119 typedef typename pointer_traits<pointer>::reference reference;
Chris@16 120 typedef typename pointer_traits<const_pointer>::reference const_reference;
Chris@16 121 typedef typename pointer_traits<pointer>::difference_type difference_type;
Chris@16 122 typedef SizeType size_type;
Chris@16 123 typedef slist_iterator<real_value_traits, false> iterator;
Chris@16 124 typedef slist_iterator<real_value_traits, true> const_iterator;
Chris@16 125 typedef typename real_value_traits::node_traits node_traits;
Chris@16 126 typedef typename node_traits::node node;
Chris@16 127 typedef typename node_traits::node_ptr node_ptr;
Chris@16 128 typedef typename node_traits::const_node_ptr const_node_ptr;
Chris@16 129
Chris@16 130 static const bool constant_time_size = 0 != (BoolFlags & slist_bool_flags::constant_time_size_pos);
Chris@16 131 static const bool stateful_value_traits = detail::is_stateful_value_traits<real_value_traits>::value;
Chris@16 132 static const bool linear = 0 != (BoolFlags & slist_bool_flags::linear_pos);
Chris@16 133 static const bool cache_last = 0 != (BoolFlags & slist_bool_flags::cache_last_pos);
Chris@16 134
Chris@16 135 typedef typename detail::if_c
Chris@16 136 < linear
Chris@16 137 , linear_slist_algorithms<node_traits>
Chris@16 138 , circular_slist_algorithms<node_traits>
Chris@16 139 >::type node_algorithms;
Chris@16 140
Chris@16 141 /// @cond
Chris@16 142 private:
Chris@16 143 typedef detail::size_holder<constant_time_size, size_type> size_traits;
Chris@16 144
Chris@16 145 //noncopyable
Chris@16 146 BOOST_MOVABLE_BUT_NOT_COPYABLE(slist_impl)
Chris@16 147
Chris@16 148 static const bool safemode_or_autounlink = is_safe_autounlink<real_value_traits::link_mode>::value;
Chris@16 149
Chris@16 150 //Constant-time size is incompatible with auto-unlink hooks!
Chris@16 151 BOOST_STATIC_ASSERT(!(constant_time_size && ((int)real_value_traits::link_mode == (int)auto_unlink)));
Chris@16 152 //Linear singly linked lists are incompatible with auto-unlink hooks!
Chris@16 153 BOOST_STATIC_ASSERT(!(linear && ((int)real_value_traits::link_mode == (int)auto_unlink)));
Chris@16 154 //A list with cached last node is incompatible with auto-unlink hooks!
Chris@16 155 BOOST_STATIC_ASSERT(!(cache_last && ((int)real_value_traits::link_mode == (int)auto_unlink)));
Chris@16 156
Chris@16 157 node_ptr get_end_node()
Chris@16 158 { return node_ptr(linear ? node_ptr() : this->get_root_node()); }
Chris@16 159
Chris@16 160 const_node_ptr get_end_node() const
Chris@16 161 {
Chris@16 162 return const_node_ptr
Chris@16 163 (linear ? const_node_ptr() : this->get_root_node()); }
Chris@16 164
Chris@16 165 node_ptr get_root_node()
Chris@16 166 { return pointer_traits<node_ptr>::pointer_to(data_.root_plus_size_.root_); }
Chris@16 167
Chris@16 168 const_node_ptr get_root_node() const
Chris@16 169 { return pointer_traits<const_node_ptr>::pointer_to(data_.root_plus_size_.root_); }
Chris@16 170
Chris@16 171 node_ptr get_last_node()
Chris@16 172 { return this->get_last_node(detail::bool_<cache_last>()); }
Chris@16 173
Chris@16 174 const_node_ptr get_last_node() const
Chris@16 175 { return this->get_last_node(detail::bool_<cache_last>()); }
Chris@16 176
Chris@16 177 void set_last_node(const node_ptr &n)
Chris@16 178 { return this->set_last_node(n, detail::bool_<cache_last>()); }
Chris@16 179
Chris@16 180 static node_ptr get_last_node(detail::bool_<false>)
Chris@16 181 {
Chris@16 182 //This function shall not be used if cache_last is not true
Chris@16 183 BOOST_INTRUSIVE_INVARIANT_ASSERT(cache_last);
Chris@16 184 return node_ptr();
Chris@16 185 }
Chris@16 186
Chris@16 187 static void set_last_node(const node_ptr &, detail::bool_<false>)
Chris@16 188 {
Chris@16 189 //This function shall not be used if cache_last is not true
Chris@16 190 BOOST_INTRUSIVE_INVARIANT_ASSERT(cache_last);
Chris@16 191 }
Chris@16 192
Chris@16 193 node_ptr get_last_node(detail::bool_<true>)
Chris@16 194 { return node_ptr(data_.root_plus_size_.last_); }
Chris@16 195
Chris@16 196 const_node_ptr get_last_node(detail::bool_<true>) const
Chris@16 197 { return const_node_ptr(data_.root_plus_size_.last_); }
Chris@16 198
Chris@16 199 void set_last_node(const node_ptr & n, detail::bool_<true>)
Chris@16 200 { data_.root_plus_size_.last_ = n; }
Chris@16 201
Chris@16 202 void set_default_constructed_state()
Chris@16 203 {
Chris@16 204 node_algorithms::init_header(this->get_root_node());
Chris@16 205 this->priv_size_traits().set_size(size_type(0));
Chris@16 206 if(cache_last){
Chris@16 207 this->set_last_node(this->get_root_node());
Chris@16 208 }
Chris@16 209 }
Chris@16 210
Chris@16 211 struct root_plus_size
Chris@16 212 : public size_traits
Chris@16 213 , public root_plus_last<node, node_ptr, cache_last>
Chris@16 214 {};
Chris@16 215
Chris@16 216 struct data_t
Chris@16 217 : public slist_impl::value_traits
Chris@16 218 {
Chris@16 219 typedef typename slist_impl::value_traits value_traits;
Chris@16 220 explicit data_t(const value_traits &val_traits)
Chris@16 221 : value_traits(val_traits)
Chris@16 222 {}
Chris@16 223
Chris@16 224 root_plus_size root_plus_size_;
Chris@16 225 } data_;
Chris@16 226
Chris@16 227 size_traits &priv_size_traits()
Chris@16 228 { return data_.root_plus_size_; }
Chris@16 229
Chris@16 230 const size_traits &priv_size_traits() const
Chris@16 231 { return data_.root_plus_size_; }
Chris@16 232
Chris@16 233 const real_value_traits &get_real_value_traits(detail::bool_<false>) const
Chris@16 234 { return data_; }
Chris@16 235
Chris@16 236 const real_value_traits &get_real_value_traits(detail::bool_<true>) const
Chris@16 237 { return data_.get_value_traits(*this); }
Chris@16 238
Chris@16 239 real_value_traits &get_real_value_traits(detail::bool_<false>)
Chris@16 240 { return data_; }
Chris@16 241
Chris@16 242 real_value_traits &get_real_value_traits(detail::bool_<true>)
Chris@16 243 { return data_.get_value_traits(*this); }
Chris@16 244
Chris@16 245 const value_traits &priv_value_traits() const
Chris@16 246 { return data_; }
Chris@16 247
Chris@16 248 value_traits &priv_value_traits()
Chris@16 249 { return data_; }
Chris@16 250
Chris@16 251 protected:
Chris@16 252 node &prot_root_node()
Chris@16 253 { return data_.root_plus_size_.root_; }
Chris@16 254
Chris@16 255 node const &prot_root_node() const
Chris@16 256 { return data_.root_plus_size_.root_; }
Chris@16 257
Chris@16 258 void prot_set_size(size_type s)
Chris@16 259 { data_.root_plus_size_.set_size(s); }
Chris@16 260
Chris@16 261 /// @endcond
Chris@16 262
Chris@16 263 public:
Chris@16 264
Chris@16 265 const real_value_traits &get_real_value_traits() const
Chris@16 266 { return this->get_real_value_traits(detail::bool_<external_value_traits>()); }
Chris@16 267
Chris@16 268 real_value_traits &get_real_value_traits()
Chris@16 269 { return this->get_real_value_traits(detail::bool_<external_value_traits>()); }
Chris@16 270
Chris@16 271 typedef typename pointer_traits<node_ptr>::template rebind_pointer<const real_value_traits>::type const_real_value_traits_ptr;
Chris@16 272
Chris@16 273 const_real_value_traits_ptr real_value_traits_ptr() const
Chris@16 274 { return pointer_traits<const_real_value_traits_ptr>::pointer_to(this->get_real_value_traits()); }
Chris@16 275
Chris@16 276 public:
Chris@16 277
Chris@16 278 ///@cond
Chris@16 279
Chris@16 280 //! <b>Requires</b>: f and before_l belong to another slist.
Chris@16 281 //!
Chris@16 282 //! <b>Effects</b>: Transfers the range [f, before_l] to this
Chris@16 283 //! list, after the element pointed by prev_pos.
Chris@16 284 //! No destructors or copy constructors are called.
Chris@16 285 //!
Chris@16 286 //! <b>Throws</b>: Nothing.
Chris@16 287 //!
Chris@16 288 //! <b>Complexity</b>: Linear to the number of elements transferred
Chris@16 289 //! if constant_time_size is true. Constant-time otherwise.
Chris@16 290 //!
Chris@16 291 //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
Chris@16 292 //! list. Iterators of this list and all the references are not invalidated.
Chris@16 293 //!
Chris@16 294 //! <b>Warning</b>: Experimental function, don't use it!
Chris@16 295 slist_impl( const node_ptr & f, const node_ptr & before_l
Chris@16 296 , size_type n, const value_traits &v_traits = value_traits())
Chris@16 297 : data_(v_traits)
Chris@16 298 {
Chris@16 299 if(n){
Chris@16 300 this->priv_size_traits().set_size(n);
Chris@16 301 if(cache_last){
Chris@16 302 this->set_last_node(before_l);
Chris@16 303 }
Chris@16 304 node_traits::set_next(this->get_root_node(), f);
Chris@16 305 node_traits::set_next(before_l, this->get_end_node());
Chris@16 306 }
Chris@16 307 else{
Chris@16 308 this->set_default_constructed_state();
Chris@16 309 }
Chris@16 310 }
Chris@16 311
Chris@16 312 ///@endcond
Chris@16 313
Chris@16 314 //! <b>Effects</b>: constructs an empty list.
Chris@16 315 //!
Chris@16 316 //! <b>Complexity</b>: Constant
Chris@16 317 //!
Chris@16 318 //! <b>Throws</b>: If value_traits::node_traits::node
Chris@16 319 //! constructor throws (this does not happen with predefined Boost.Intrusive hooks).
Chris@16 320 explicit slist_impl(const value_traits &v_traits = value_traits())
Chris@16 321 : data_(v_traits)
Chris@16 322 { this->set_default_constructed_state(); }
Chris@16 323
Chris@16 324 //! <b>Requires</b>: Dereferencing iterator must yield an lvalue of type value_type.
Chris@16 325 //!
Chris@16 326 //! <b>Effects</b>: Constructs a list equal to [b ,e).
Chris@16 327 //!
Chris@16 328 //! <b>Complexity</b>: Linear in std::distance(b, e). No copy constructors are called.
Chris@16 329 //!
Chris@16 330 //! <b>Throws</b>: If value_traits::node_traits::node
Chris@16 331 //! constructor throws (this does not happen with predefined Boost.Intrusive hooks).
Chris@16 332 template<class Iterator>
Chris@16 333 slist_impl(Iterator b, Iterator e, const value_traits &v_traits = value_traits())
Chris@16 334 : data_(v_traits)
Chris@16 335 {
Chris@16 336 this->set_default_constructed_state();
Chris@16 337 this->insert_after(this->cbefore_begin(), b, e);
Chris@16 338 }
Chris@16 339
Chris@16 340 //! <b>Effects</b>: to-do
Chris@16 341 //!
Chris@16 342 slist_impl(BOOST_RV_REF(slist_impl) x)
Chris@16 343 : data_(::boost::move(x.priv_value_traits()))
Chris@16 344 {
Chris@16 345 this->priv_size_traits().set_size(size_type(0));
Chris@16 346 node_algorithms::init_header(this->get_root_node());
Chris@16 347 this->swap(x);
Chris@16 348 }
Chris@16 349
Chris@16 350 //! <b>Effects</b>: to-do
Chris@16 351 //!
Chris@16 352 slist_impl& operator=(BOOST_RV_REF(slist_impl) x)
Chris@16 353 { this->swap(x); return *this; }
Chris@16 354
Chris@16 355 #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
Chris@16 356 //! <b>Effects</b>: If it's a safe-mode
Chris@16 357 //! or auto-unlink value, the destructor does nothing
Chris@16 358 //! (ie. no code is generated). Otherwise it detaches all elements from this.
Chris@16 359 //! In this case the objects in the list are not deleted (i.e. no destructors
Chris@16 360 //! are called), but the hooks according to the value_traits template parameter
Chris@16 361 //! are set to their default value.
Chris@16 362 //!
Chris@16 363 //! <b>Complexity</b>: Linear to the number of elements in the list, if
Chris@16 364 //! it's a safe-mode or auto-unlink value. Otherwise constant.
Chris@16 365 ~slist_impl()
Chris@16 366 {}
Chris@16 367 #endif
Chris@16 368
Chris@16 369 //! <b>Effects</b>: Erases all the elements of the container.
Chris@16 370 //!
Chris@16 371 //! <b>Throws</b>: Nothing.
Chris@16 372 //!
Chris@16 373 //! <b>Complexity</b>: Linear to the number of elements of the list.
Chris@16 374 //! if it's a safe-mode or auto-unlink value_type. Constant time otherwise.
Chris@16 375 //!
Chris@16 376 //! <b>Note</b>: Invalidates the iterators (but not the references) to the erased elements.
Chris@16 377 void clear()
Chris@16 378 {
Chris@16 379 if(safemode_or_autounlink){
Chris@16 380 this->clear_and_dispose(detail::null_disposer());
Chris@16 381 }
Chris@16 382 else{
Chris@16 383 this->set_default_constructed_state();
Chris@16 384 }
Chris@16 385 }
Chris@16 386
Chris@16 387 //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
Chris@16 388 //!
Chris@16 389 //! <b>Effects</b>: Erases all the elements of the container
Chris@16 390 //! Disposer::operator()(pointer) is called for the removed elements.
Chris@16 391 //!
Chris@16 392 //! <b>Throws</b>: Nothing.
Chris@16 393 //!
Chris@16 394 //! <b>Complexity</b>: Linear to the number of elements of the list.
Chris@16 395 //!
Chris@16 396 //! <b>Note</b>: Invalidates the iterators to the erased elements.
Chris@16 397 template <class Disposer>
Chris@16 398 void clear_and_dispose(Disposer disposer)
Chris@16 399 {
Chris@16 400 const_iterator it(this->begin()), itend(this->end());
Chris@16 401 while(it != itend){
Chris@16 402 node_ptr to_erase(it.pointed_node());
Chris@16 403 ++it;
Chris@16 404 if(safemode_or_autounlink)
Chris@16 405 node_algorithms::init(to_erase);
Chris@16 406 disposer(get_real_value_traits().to_value_ptr(to_erase));
Chris@16 407 }
Chris@16 408 this->set_default_constructed_state();
Chris@16 409 }
Chris@16 410
Chris@16 411 //! <b>Requires</b>: value must be an lvalue.
Chris@16 412 //!
Chris@16 413 //! <b>Effects</b>: Inserts the value in the front of the list.
Chris@16 414 //! No copy constructors are called.
Chris@16 415 //!
Chris@16 416 //! <b>Throws</b>: Nothing.
Chris@16 417 //!
Chris@16 418 //! <b>Complexity</b>: Constant.
Chris@16 419 //!
Chris@16 420 //! <b>Note</b>: Does not affect the validity of iterators and references.
Chris@16 421 void push_front(reference value)
Chris@16 422 {
Chris@16 423 node_ptr to_insert = get_real_value_traits().to_node_ptr(value);
Chris@16 424 if(safemode_or_autounlink)
Chris@16 425 BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::inited(to_insert));
Chris@16 426 if(cache_last){
Chris@16 427 if(this->empty()){
Chris@16 428 this->set_last_node(to_insert);
Chris@16 429 }
Chris@16 430 }
Chris@16 431 node_algorithms::link_after(this->get_root_node(), to_insert);
Chris@16 432 this->priv_size_traits().increment();
Chris@16 433 }
Chris@16 434
Chris@16 435 //! <b>Requires</b>: value must be an lvalue.
Chris@16 436 //!
Chris@16 437 //! <b>Effects</b>: Inserts the value in the back of the list.
Chris@16 438 //! No copy constructors are called.
Chris@16 439 //!
Chris@16 440 //! <b>Throws</b>: Nothing.
Chris@16 441 //!
Chris@16 442 //! <b>Complexity</b>: Constant.
Chris@16 443 //!
Chris@16 444 //! <b>Note</b>: Does not affect the validity of iterators and references.
Chris@16 445 //! This function is only available is cache_last<> is true.
Chris@16 446 void push_back(reference value)
Chris@16 447 {
Chris@16 448 BOOST_STATIC_ASSERT((cache_last));
Chris@16 449 node_ptr n = get_real_value_traits().to_node_ptr(value);
Chris@16 450 if(safemode_or_autounlink)
Chris@16 451 BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::inited(n));
Chris@16 452 node_algorithms::link_after(this->get_last_node(), n);
Chris@16 453 if(cache_last){
Chris@16 454 this->set_last_node(n);
Chris@16 455 }
Chris@16 456 this->priv_size_traits().increment();
Chris@16 457 }
Chris@16 458
Chris@16 459 //! <b>Effects</b>: Erases the first element of the list.
Chris@16 460 //! No destructors are called.
Chris@16 461 //!
Chris@16 462 //! <b>Throws</b>: Nothing.
Chris@16 463 //!
Chris@16 464 //! <b>Complexity</b>: Constant.
Chris@16 465 //!
Chris@16 466 //! <b>Note</b>: Invalidates the iterators (but not the references) to the erased element.
Chris@16 467 void pop_front()
Chris@16 468 { return this->pop_front_and_dispose(detail::null_disposer()); }
Chris@16 469
Chris@16 470 //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
Chris@16 471 //!
Chris@16 472 //! <b>Effects</b>: Erases the first element of the list.
Chris@16 473 //! Disposer::operator()(pointer) is called for the removed element.
Chris@16 474 //!
Chris@16 475 //! <b>Throws</b>: Nothing.
Chris@16 476 //!
Chris@16 477 //! <b>Complexity</b>: Constant.
Chris@16 478 //!
Chris@16 479 //! <b>Note</b>: Invalidates the iterators to the erased element.
Chris@16 480 template<class Disposer>
Chris@16 481 void pop_front_and_dispose(Disposer disposer)
Chris@16 482 {
Chris@16 483 node_ptr to_erase = node_traits::get_next(this->get_root_node());
Chris@16 484 node_algorithms::unlink_after(this->get_root_node());
Chris@16 485 this->priv_size_traits().decrement();
Chris@16 486 if(safemode_or_autounlink)
Chris@16 487 node_algorithms::init(to_erase);
Chris@16 488 disposer(get_real_value_traits().to_value_ptr(to_erase));
Chris@16 489 if(cache_last){
Chris@16 490 if(this->empty()){
Chris@16 491 this->set_last_node(this->get_root_node());
Chris@16 492 }
Chris@16 493 }
Chris@16 494 }
Chris@16 495
Chris@16 496 //! <b>Effects</b>: Returns a reference to the first element of the list.
Chris@16 497 //!
Chris@16 498 //! <b>Throws</b>: Nothing.
Chris@16 499 //!
Chris@16 500 //! <b>Complexity</b>: Constant.
Chris@16 501 reference front()
Chris@16 502 { return *this->get_real_value_traits().to_value_ptr(node_traits::get_next(this->get_root_node())); }
Chris@16 503
Chris@16 504 //! <b>Effects</b>: Returns a const_reference to the first element of the list.
Chris@16 505 //!
Chris@16 506 //! <b>Throws</b>: Nothing.
Chris@16 507 //!
Chris@16 508 //! <b>Complexity</b>: Constant.
Chris@16 509 const_reference front() const
Chris@16 510 { return *this->get_real_value_traits().to_value_ptr(detail::uncast(node_traits::get_next(this->get_root_node()))); }
Chris@16 511
Chris@16 512 //! <b>Effects</b>: Returns a reference to the last element of the list.
Chris@16 513 //!
Chris@16 514 //! <b>Throws</b>: Nothing.
Chris@16 515 //!
Chris@16 516 //! <b>Complexity</b>: Constant.
Chris@16 517 //!
Chris@16 518 //! <b>Note</b>: Does not affect the validity of iterators and references.
Chris@16 519 //! This function is only available is cache_last<> is true.
Chris@16 520 reference back()
Chris@16 521 {
Chris@16 522 BOOST_STATIC_ASSERT((cache_last));
Chris@16 523 return *this->get_real_value_traits().to_value_ptr(this->get_last_node());
Chris@16 524 }
Chris@16 525
Chris@16 526 //! <b>Effects</b>: Returns a const_reference to the last element of the list.
Chris@16 527 //!
Chris@16 528 //! <b>Throws</b>: Nothing.
Chris@16 529 //!
Chris@16 530 //! <b>Complexity</b>: Constant.
Chris@16 531 //!
Chris@16 532 //! <b>Note</b>: Does not affect the validity of iterators and references.
Chris@16 533 //! This function is only available is cache_last<> is true.
Chris@16 534 const_reference back() const
Chris@16 535 {
Chris@16 536 BOOST_STATIC_ASSERT((cache_last));
Chris@16 537 return *this->get_real_value_traits().to_value_ptr(this->get_last_node());
Chris@16 538 }
Chris@16 539
Chris@16 540 //! <b>Effects</b>: Returns an iterator to the first element contained in the list.
Chris@16 541 //!
Chris@16 542 //! <b>Throws</b>: Nothing.
Chris@16 543 //!
Chris@16 544 //! <b>Complexity</b>: Constant.
Chris@16 545 iterator begin()
Chris@16 546 { return iterator (node_traits::get_next(this->get_root_node()), this->real_value_traits_ptr()); }
Chris@16 547
Chris@16 548 //! <b>Effects</b>: Returns a const_iterator to the first element contained in the list.
Chris@16 549 //!
Chris@16 550 //! <b>Throws</b>: Nothing.
Chris@16 551 //!
Chris@16 552 //! <b>Complexity</b>: Constant.
Chris@16 553 const_iterator begin() const
Chris@16 554 { return const_iterator (node_traits::get_next(this->get_root_node()), this->real_value_traits_ptr()); }
Chris@16 555
Chris@16 556 //! <b>Effects</b>: Returns a const_iterator to the first element contained in the list.
Chris@16 557 //!
Chris@16 558 //! <b>Throws</b>: Nothing.
Chris@16 559 //!
Chris@16 560 //! <b>Complexity</b>: Constant.
Chris@16 561 const_iterator cbegin() const
Chris@16 562 { return const_iterator(node_traits::get_next(this->get_root_node()), this->real_value_traits_ptr()); }
Chris@16 563
Chris@16 564 //! <b>Effects</b>: Returns an iterator to the end of the list.
Chris@16 565 //!
Chris@16 566 //! <b>Throws</b>: Nothing.
Chris@16 567 //!
Chris@16 568 //! <b>Complexity</b>: Constant.
Chris@16 569 iterator end()
Chris@16 570 { return iterator(this->get_end_node(), this->real_value_traits_ptr()); }
Chris@16 571
Chris@16 572 //! <b>Effects</b>: Returns a const_iterator to the end of the list.
Chris@16 573 //!
Chris@16 574 //! <b>Throws</b>: Nothing.
Chris@16 575 //!
Chris@16 576 //! <b>Complexity</b>: Constant.
Chris@16 577 const_iterator end() const
Chris@16 578 { return const_iterator(detail::uncast(this->get_end_node()), this->real_value_traits_ptr()); }
Chris@16 579
Chris@16 580 //! <b>Effects</b>: Returns a const_iterator to the end of the list.
Chris@16 581 //!
Chris@16 582 //! <b>Throws</b>: Nothing.
Chris@16 583 //!
Chris@16 584 //! <b>Complexity</b>: Constant.
Chris@16 585 const_iterator cend() const
Chris@16 586 { return this->end(); }
Chris@16 587
Chris@16 588 //! <b>Effects</b>: Returns an iterator that points to a position
Chris@16 589 //! before the first element. Equivalent to "end()"
Chris@16 590 //!
Chris@16 591 //! <b>Throws</b>: Nothing.
Chris@16 592 //!
Chris@16 593 //! <b>Complexity</b>: Constant.
Chris@16 594 iterator before_begin()
Chris@16 595 { return iterator(this->get_root_node(), this->real_value_traits_ptr()); }
Chris@16 596
Chris@16 597 //! <b>Effects</b>: Returns an iterator that points to a position
Chris@16 598 //! before the first element. Equivalent to "end()"
Chris@16 599 //!
Chris@16 600 //! <b>Throws</b>: Nothing.
Chris@16 601 //!
Chris@16 602 //! <b>Complexity</b>: Constant.
Chris@16 603 const_iterator before_begin() const
Chris@16 604 { return const_iterator(detail::uncast(this->get_root_node()), this->real_value_traits_ptr()); }
Chris@16 605
Chris@16 606 //! <b>Effects</b>: Returns an iterator that points to a position
Chris@16 607 //! before the first element. Equivalent to "end()"
Chris@16 608 //!
Chris@16 609 //! <b>Throws</b>: Nothing.
Chris@16 610 //!
Chris@16 611 //! <b>Complexity</b>: Constant.
Chris@16 612 const_iterator cbefore_begin() const
Chris@16 613 { return this->before_begin(); }
Chris@16 614
Chris@16 615 //! <b>Effects</b>: Returns an iterator to the last element contained in the list.
Chris@16 616 //!
Chris@16 617 //! <b>Throws</b>: Nothing.
Chris@16 618 //!
Chris@16 619 //! <b>Complexity</b>: Constant.
Chris@16 620 //!
Chris@16 621 //! <b>Note</b>: This function is present only if cached_last<> option is true.
Chris@16 622 iterator last()
Chris@16 623 {
Chris@16 624 //This function shall not be used if cache_last is not true
Chris@16 625 BOOST_INTRUSIVE_INVARIANT_ASSERT(cache_last);
Chris@16 626 return iterator (this->get_last_node(), this->real_value_traits_ptr());
Chris@16 627 }
Chris@16 628
Chris@16 629 //! <b>Effects</b>: Returns a const_iterator to the last element contained in the list.
Chris@16 630 //!
Chris@16 631 //! <b>Throws</b>: Nothing.
Chris@16 632 //!
Chris@16 633 //! <b>Complexity</b>: Constant.
Chris@16 634 //!
Chris@16 635 //! <b>Note</b>: This function is present only if cached_last<> option is true.
Chris@16 636 const_iterator last() const
Chris@16 637 {
Chris@16 638 //This function shall not be used if cache_last is not true
Chris@16 639 BOOST_INTRUSIVE_INVARIANT_ASSERT(cache_last);
Chris@16 640 return const_iterator (this->get_last_node(), this->real_value_traits_ptr());
Chris@16 641 }
Chris@16 642
Chris@16 643 //! <b>Effects</b>: Returns a const_iterator to the last element contained in the list.
Chris@16 644 //!
Chris@16 645 //! <b>Throws</b>: Nothing.
Chris@16 646 //!
Chris@16 647 //! <b>Complexity</b>: Constant.
Chris@16 648 //!
Chris@16 649 //! <b>Note</b>: This function is present only if cached_last<> option is true.
Chris@16 650 const_iterator clast() const
Chris@16 651 { return const_iterator(this->get_last_node(), this->real_value_traits_ptr()); }
Chris@16 652
Chris@16 653 //! <b>Precondition</b>: end_iterator must be a valid end iterator
Chris@16 654 //! of slist.
Chris@16 655 //!
Chris@16 656 //! <b>Effects</b>: Returns a const reference to the slist associated to the end iterator
Chris@16 657 //!
Chris@16 658 //! <b>Throws</b>: Nothing.
Chris@16 659 //!
Chris@16 660 //! <b>Complexity</b>: Constant.
Chris@16 661 static slist_impl &container_from_end_iterator(iterator end_iterator)
Chris@16 662 { return slist_impl::priv_container_from_end_iterator(end_iterator); }
Chris@16 663
Chris@16 664 //! <b>Precondition</b>: end_iterator must be a valid end const_iterator
Chris@16 665 //! of slist.
Chris@16 666 //!
Chris@16 667 //! <b>Effects</b>: Returns a const reference to the slist associated to the end iterator
Chris@16 668 //!
Chris@16 669 //! <b>Throws</b>: Nothing.
Chris@16 670 //!
Chris@16 671 //! <b>Complexity</b>: Constant.
Chris@16 672 static const slist_impl &container_from_end_iterator(const_iterator end_iterator)
Chris@16 673 { return slist_impl::priv_container_from_end_iterator(end_iterator); }
Chris@16 674
Chris@16 675 //! <b>Effects</b>: Returns the number of the elements contained in the list.
Chris@16 676 //!
Chris@16 677 //! <b>Throws</b>: Nothing.
Chris@16 678 //!
Chris@16 679 //! <b>Complexity</b>: Linear to the number of elements contained in the list.
Chris@16 680 //! if constant_time_size is false. Constant time otherwise.
Chris@16 681 //!
Chris@16 682 //! <b>Note</b>: Does not affect the validity of iterators and references.
Chris@16 683 size_type size() const
Chris@16 684 {
Chris@16 685 if(constant_time_size)
Chris@16 686 return this->priv_size_traits().get_size();
Chris@16 687 else
Chris@16 688 return node_algorithms::count(this->get_root_node()) - 1;
Chris@16 689 }
Chris@16 690
Chris@16 691 //! <b>Effects</b>: Returns true if the list contains no elements.
Chris@16 692 //!
Chris@16 693 //! <b>Throws</b>: Nothing.
Chris@16 694 //!
Chris@16 695 //! <b>Complexity</b>: Constant.
Chris@16 696 //!
Chris@16 697 //! <b>Note</b>: Does not affect the validity of iterators and references.
Chris@16 698 bool empty() const
Chris@16 699 { return node_algorithms::unique(this->get_root_node()); }
Chris@16 700
Chris@16 701 //! <b>Effects</b>: Swaps the elements of x and *this.
Chris@16 702 //!
Chris@16 703 //! <b>Throws</b>: Nothing.
Chris@16 704 //!
Chris@16 705 //! <b>Complexity</b>: Linear to the number of elements of both lists.
Chris@16 706 //! Constant-time if linear<> and/or cache_last<> options are used.
Chris@16 707 //!
Chris@16 708 //! <b>Note</b>: Does not affect the validity of iterators and references.
Chris@16 709 void swap(slist_impl& other)
Chris@16 710 {
Chris@16 711 if(cache_last){
Chris@16 712 priv_swap_cache_last(this, &other);
Chris@16 713 }
Chris@16 714 else{
Chris@16 715 this->priv_swap_lists(this->get_root_node(), other.get_root_node(), detail::bool_<linear>());
Chris@16 716 }
Chris@16 717 if(constant_time_size){
Chris@16 718 size_type backup = this->priv_size_traits().get_size();
Chris@16 719 this->priv_size_traits().set_size(other.priv_size_traits().get_size());
Chris@16 720 other.priv_size_traits().set_size(backup);
Chris@16 721 }
Chris@16 722 }
Chris@16 723
Chris@16 724 //! <b>Effects</b>: Moves backwards all the elements, so that the first
Chris@16 725 //! element becomes the second, the second becomes the third...
Chris@16 726 //! the last element becomes the first one.
Chris@16 727 //!
Chris@16 728 //! <b>Throws</b>: Nothing.
Chris@16 729 //!
Chris@16 730 //! <b>Complexity</b>: Linear to the number of elements plus the number shifts.
Chris@16 731 //!
Chris@16 732 //! <b>Note</b>: Iterators Does not affect the validity of iterators and references.
Chris@16 733 void shift_backwards(size_type n = 1)
Chris@16 734 { this->priv_shift_backwards(n, detail::bool_<linear>()); }
Chris@16 735
Chris@16 736 //! <b>Effects</b>: Moves forward all the elements, so that the second
Chris@16 737 //! element becomes the first, the third becomes the second...
Chris@16 738 //! the first element becomes the last one.
Chris@16 739 //!
Chris@16 740 //! <b>Throws</b>: Nothing.
Chris@16 741 //!
Chris@16 742 //! <b>Complexity</b>: Linear to the number of elements plus the number shifts.
Chris@16 743 //!
Chris@16 744 //! <b>Note</b>: Does not affect the validity of iterators and references.
Chris@16 745 void shift_forward(size_type n = 1)
Chris@16 746 { this->priv_shift_forward(n, detail::bool_<linear>()); }
Chris@16 747
Chris@16 748 //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
Chris@16 749 //! Cloner should yield to nodes equivalent to the original nodes.
Chris@16 750 //!
Chris@16 751 //! <b>Effects</b>: Erases all the elements from *this
Chris@16 752 //! calling Disposer::operator()(pointer), clones all the
Chris@16 753 //! elements from src calling Cloner::operator()(const_reference )
Chris@16 754 //! and inserts them on *this.
Chris@16 755 //!
Chris@16 756 //! If cloner throws, all cloned elements are unlinked and disposed
Chris@16 757 //! calling Disposer::operator()(pointer).
Chris@16 758 //!
Chris@16 759 //! <b>Complexity</b>: Linear to erased plus inserted elements.
Chris@16 760 //!
Chris@16 761 //! <b>Throws</b>: If cloner throws.
Chris@16 762 template <class Cloner, class Disposer>
Chris@16 763 void clone_from(const slist_impl &src, Cloner cloner, Disposer disposer)
Chris@16 764 {
Chris@16 765 this->clear_and_dispose(disposer);
Chris@16 766 detail::exception_disposer<slist_impl, Disposer>
Chris@16 767 rollback(*this, disposer);
Chris@16 768 const_iterator prev(this->cbefore_begin());
Chris@16 769 const_iterator b(src.begin()), e(src.end());
Chris@16 770 for(; b != e; ++b){
Chris@16 771 prev = this->insert_after(prev, *cloner(*b));
Chris@16 772 }
Chris@16 773 rollback.release();
Chris@16 774 }
Chris@16 775
Chris@16 776 //! <b>Requires</b>: value must be an lvalue and prev_p must point to an element
Chris@16 777 //! contained by the list or to end().
Chris@16 778 //!
Chris@16 779 //! <b>Effects</b>: Inserts the value after the position pointed by prev_p.
Chris@16 780 //! No copy constructor is called.
Chris@16 781 //!
Chris@16 782 //! <b>Returns</b>: An iterator to the inserted element.
Chris@16 783 //!
Chris@16 784 //! <b>Throws</b>: Nothing.
Chris@16 785 //!
Chris@16 786 //! <b>Complexity</b>: Constant.
Chris@16 787 //!
Chris@16 788 //! <b>Note</b>: Does not affect the validity of iterators and references.
Chris@16 789 iterator insert_after(const_iterator prev_p, reference value)
Chris@16 790 {
Chris@16 791 node_ptr n = get_real_value_traits().to_node_ptr(value);
Chris@16 792 if(safemode_or_autounlink)
Chris@16 793 BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::inited(n));
Chris@16 794 node_ptr prev_n(prev_p.pointed_node());
Chris@16 795 node_algorithms::link_after(prev_n, n);
Chris@16 796 if(cache_last && (this->get_last_node() == prev_n)){
Chris@16 797 this->set_last_node(n);
Chris@16 798 }
Chris@16 799 this->priv_size_traits().increment();
Chris@16 800 return iterator (n, this->real_value_traits_ptr());
Chris@16 801 }
Chris@16 802
Chris@16 803 //! <b>Requires</b>: Dereferencing iterator must yield
Chris@16 804 //! an lvalue of type value_type and prev_p must point to an element
Chris@16 805 //! contained by the list or to the end node.
Chris@16 806 //!
Chris@16 807 //! <b>Effects</b>: Inserts the [f, l)
Chris@16 808 //! after the position prev_p.
Chris@16 809 //!
Chris@16 810 //! <b>Throws</b>: Nothing.
Chris@16 811 //!
Chris@16 812 //! <b>Complexity</b>: Linear to the number of elements inserted.
Chris@16 813 //!
Chris@16 814 //! <b>Note</b>: Does not affect the validity of iterators and references.
Chris@16 815 template<class Iterator>
Chris@16 816 void insert_after(const_iterator prev_p, Iterator f, Iterator l)
Chris@16 817 {
Chris@16 818 //Insert first nodes avoiding cache and size checks
Chris@16 819 size_type count = 0;
Chris@16 820 node_ptr prev_n(prev_p.pointed_node());
Chris@16 821 for (; f != l; ++f, ++count){
Chris@16 822 const node_ptr n = get_real_value_traits().to_node_ptr(*f);
Chris@16 823 if(safemode_or_autounlink)
Chris@16 824 BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::inited(n));
Chris@16 825 node_algorithms::link_after(prev_n, n);
Chris@16 826 prev_n = n;
Chris@16 827 }
Chris@16 828 //Now fix special cases if needed
Chris@16 829 if(cache_last && (this->get_last_node() == prev_p.pointed_node())){
Chris@16 830 this->set_last_node(prev_n);
Chris@16 831 }
Chris@16 832 if(constant_time_size){
Chris@16 833 this->priv_size_traits().increase(count);
Chris@16 834 }
Chris@16 835 }
Chris@16 836
Chris@16 837 //! <b>Requires</b>: value must be an lvalue and p must point to an element
Chris@16 838 //! contained by the list or to end().
Chris@16 839 //!
Chris@16 840 //! <b>Effects</b>: Inserts the value before the position pointed by p.
Chris@16 841 //! No copy constructor is called.
Chris@16 842 //!
Chris@16 843 //! <b>Throws</b>: Nothing.
Chris@16 844 //!
Chris@16 845 //! <b>Complexity</b>: Linear to the number of elements before p.
Chris@16 846 //! Constant-time if cache_last<> is true and p == end().
Chris@16 847 //!
Chris@16 848 //! <b>Note</b>: Does not affect the validity of iterators and references.
Chris@16 849 iterator insert(const_iterator p, reference value)
Chris@16 850 { return this->insert_after(this->previous(p), value); }
Chris@16 851
Chris@16 852 //! <b>Requires</b>: Dereferencing iterator must yield
Chris@16 853 //! an lvalue of type value_type and p must point to an element
Chris@16 854 //! contained by the list or to the end node.
Chris@16 855 //!
Chris@16 856 //! <b>Effects</b>: Inserts the pointed by b and e
Chris@16 857 //! before the position p. No copy constructors are called.
Chris@16 858 //!
Chris@16 859 //! <b>Throws</b>: Nothing.
Chris@16 860 //!
Chris@16 861 //! <b>Complexity</b>: Linear to the number of elements inserted plus linear
Chris@16 862 //! to the elements before b.
Chris@16 863 //! Linear to the number of elements to insert if cache_last<> option is true and p == end().
Chris@16 864 //!
Chris@16 865 //! <b>Note</b>: Does not affect the validity of iterators and references.
Chris@16 866 template<class Iterator>
Chris@16 867 void insert(const_iterator p, Iterator b, Iterator e)
Chris@16 868 { return this->insert_after(this->previous(p), b, e); }
Chris@16 869
Chris@16 870 //! <b>Effects</b>: Erases the element after the element pointed by prev of
Chris@16 871 //! the list. No destructors are called.
Chris@16 872 //!
Chris@16 873 //! <b>Returns</b>: the first element remaining beyond the removed elements,
Chris@16 874 //! or end() if no such element exists.
Chris@16 875 //!
Chris@16 876 //! <b>Throws</b>: Nothing.
Chris@16 877 //!
Chris@16 878 //! <b>Complexity</b>: Constant.
Chris@16 879 //!
Chris@16 880 //! <b>Note</b>: Invalidates the iterators (but not the references) to the
Chris@16 881 //! erased element.
Chris@16 882 iterator erase_after(const_iterator prev)
Chris@16 883 { return this->erase_after_and_dispose(prev, detail::null_disposer()); }
Chris@16 884
Chris@16 885 //! <b>Effects</b>: Erases the range (before_f, l) from
Chris@16 886 //! the list. No destructors are called.
Chris@16 887 //!
Chris@16 888 //! <b>Returns</b>: the first element remaining beyond the removed elements,
Chris@16 889 //! or end() if no such element exists.
Chris@16 890 //!
Chris@16 891 //! <b>Throws</b>: Nothing.
Chris@16 892 //!
Chris@16 893 //! <b>Complexity</b>: Linear to the number of erased elements if it's a safe-mode
Chris@16 894 //! , auto-unlink value or constant-time size is activated. Constant time otherwise.
Chris@16 895 //!
Chris@16 896 //! <b>Note</b>: Invalidates the iterators (but not the references) to the
Chris@16 897 //! erased element.
Chris@16 898 iterator erase_after(const_iterator before_f, const_iterator l)
Chris@16 899 {
Chris@16 900 if(safemode_or_autounlink || constant_time_size){
Chris@16 901 return this->erase_after_and_dispose(before_f, l, detail::null_disposer());
Chris@16 902 }
Chris@16 903 else{
Chris@16 904 const node_ptr bfp = before_f.pointed_node();
Chris@16 905 const node_ptr lp = l.pointed_node();
Chris@16 906 if(cache_last){
Chris@16 907 if(lp == this->get_end_node()){
Chris@16 908 this->set_last_node(bfp);
Chris@16 909 }
Chris@16 910 }
Chris@16 911 node_algorithms::unlink_after(bfp, lp);
Chris@16 912 return l.unconst();
Chris@16 913 }
Chris@16 914 }
Chris@16 915
Chris@16 916 //! <b>Effects</b>: Erases the range (before_f, l) from
Chris@16 917 //! the list. n must be std::distance(before_f, l) - 1.
Chris@16 918 //! No destructors are called.
Chris@16 919 //!
Chris@16 920 //! <b>Returns</b>: the first element remaining beyond the removed elements,
Chris@16 921 //! or end() if no such element exists.
Chris@16 922 //!
Chris@16 923 //! <b>Throws</b>: Nothing.
Chris@16 924 //!
Chris@16 925 //! <b>Complexity</b>: constant-time if link_mode is normal_link.
Chris@16 926 //! Linear to the elements (l - before_f) otherwise.
Chris@16 927 //!
Chris@16 928 //! <b>Note</b>: Invalidates the iterators (but not the references) to the
Chris@16 929 //! erased element.
Chris@16 930 iterator erase_after(const_iterator before_f, const_iterator l, size_type n)
Chris@16 931 {
Chris@16 932 BOOST_INTRUSIVE_INVARIANT_ASSERT(std::distance(++const_iterator(before_f), l) == difference_type(n));
Chris@16 933 if(safemode_or_autounlink){
Chris@16 934 return this->erase_after(before_f, l);
Chris@16 935 }
Chris@16 936 else{
Chris@16 937 const node_ptr bfp = before_f.pointed_node();
Chris@16 938 const node_ptr lp = l.pointed_node();
Chris@16 939 if(cache_last){
Chris@16 940 if((lp == this->get_end_node())){
Chris@16 941 this->set_last_node(bfp);
Chris@16 942 }
Chris@16 943 }
Chris@16 944 node_algorithms::unlink_after(bfp, lp);
Chris@16 945 if(constant_time_size){
Chris@16 946 this->priv_size_traits().decrease(n);
Chris@16 947 }
Chris@16 948 return l.unconst();
Chris@16 949 }
Chris@16 950 }
Chris@16 951
Chris@16 952 //! <b>Effects</b>: Erases the element pointed by i of the list.
Chris@16 953 //! No destructors are called.
Chris@16 954 //!
Chris@16 955 //! <b>Returns</b>: the first element remaining beyond the removed element,
Chris@16 956 //! or end() if no such element exists.
Chris@16 957 //!
Chris@16 958 //! <b>Throws</b>: Nothing.
Chris@16 959 //!
Chris@16 960 //! <b>Complexity</b>: Linear to the elements before i.
Chris@16 961 //!
Chris@16 962 //! <b>Note</b>: Invalidates the iterators (but not the references) to the
Chris@16 963 //! erased element.
Chris@16 964 iterator erase(const_iterator i)
Chris@16 965 { return this->erase_after(this->previous(i)); }
Chris@16 966
Chris@16 967 //! <b>Requires</b>: f and l must be valid iterator to elements in *this.
Chris@16 968 //!
Chris@16 969 //! <b>Effects</b>: Erases the range pointed by b and e.
Chris@16 970 //! No destructors are called.
Chris@16 971 //!
Chris@16 972 //! <b>Returns</b>: the first element remaining beyond the removed elements,
Chris@16 973 //! or end() if no such element exists.
Chris@16 974 //!
Chris@16 975 //! <b>Throws</b>: Nothing.
Chris@16 976 //!
Chris@16 977 //! <b>Complexity</b>: Linear to the elements before l.
Chris@16 978 //!
Chris@16 979 //! <b>Note</b>: Invalidates the iterators (but not the references) to the
Chris@16 980 //! erased elements.
Chris@16 981 iterator erase(const_iterator f, const_iterator l)
Chris@16 982 { return this->erase_after(this->previous(f), l); }
Chris@16 983
Chris@16 984 //! <b>Effects</b>: Erases the range [f, l) from
Chris@16 985 //! the list. n must be std::distance(f, l).
Chris@16 986 //! No destructors are called.
Chris@16 987 //!
Chris@16 988 //! <b>Returns</b>: the first element remaining beyond the removed elements,
Chris@16 989 //! or end() if no such element exists.
Chris@16 990 //!
Chris@16 991 //! <b>Throws</b>: Nothing.
Chris@16 992 //!
Chris@16 993 //! <b>Complexity</b>: linear to the elements before f if link_mode is normal_link
Chris@16 994 //! and constant_time_size is activated. Linear to the elements before l otherwise.
Chris@16 995 //!
Chris@16 996 //! <b>Note</b>: Invalidates the iterators (but not the references) to the
Chris@16 997 //! erased element.
Chris@16 998 iterator erase(const_iterator f, const_iterator l, size_type n)
Chris@16 999 { return this->erase_after(this->previous(f), l, n); }
Chris@16 1000
Chris@16 1001 //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
Chris@16 1002 //!
Chris@16 1003 //! <b>Effects</b>: Erases the element after the element pointed by prev of
Chris@16 1004 //! the list.
Chris@16 1005 //! Disposer::operator()(pointer) is called for the removed element.
Chris@16 1006 //!
Chris@16 1007 //! <b>Returns</b>: the first element remaining beyond the removed elements,
Chris@16 1008 //! or end() if no such element exists.
Chris@16 1009 //!
Chris@16 1010 //! <b>Throws</b>: Nothing.
Chris@16 1011 //!
Chris@16 1012 //! <b>Complexity</b>: Constant.
Chris@16 1013 //!
Chris@16 1014 //! <b>Note</b>: Invalidates the iterators to the erased element.
Chris@16 1015 template<class Disposer>
Chris@16 1016 iterator erase_after_and_dispose(const_iterator prev, Disposer disposer)
Chris@16 1017 {
Chris@16 1018 const_iterator it(prev);
Chris@16 1019 ++it;
Chris@16 1020 node_ptr to_erase(it.pointed_node());
Chris@16 1021 ++it;
Chris@16 1022 node_ptr prev_n(prev.pointed_node());
Chris@16 1023 node_algorithms::unlink_after(prev_n);
Chris@16 1024 if(cache_last && (to_erase == this->get_last_node())){
Chris@16 1025 this->set_last_node(prev_n);
Chris@16 1026 }
Chris@16 1027 if(safemode_or_autounlink)
Chris@16 1028 node_algorithms::init(to_erase);
Chris@16 1029 disposer(get_real_value_traits().to_value_ptr(to_erase));
Chris@16 1030 this->priv_size_traits().decrement();
Chris@16 1031 return it.unconst();
Chris@16 1032 }
Chris@16 1033
Chris@16 1034 /// @cond
Chris@16 1035
Chris@16 1036 template<class Disposer>
Chris@16 1037 static iterator s_erase_after_and_dispose(const_iterator prev, Disposer disposer)
Chris@16 1038 {
Chris@16 1039 BOOST_STATIC_ASSERT(((!cache_last)&&(!constant_time_size)&&(!stateful_value_traits)));
Chris@16 1040 const_iterator it(prev);
Chris@16 1041 ++it;
Chris@16 1042 node_ptr to_erase(it.pointed_node());
Chris@16 1043 ++it;
Chris@16 1044 node_ptr prev_n(prev.pointed_node());
Chris@16 1045 node_algorithms::unlink_after(prev_n);
Chris@16 1046 if(safemode_or_autounlink)
Chris@16 1047 node_algorithms::init(to_erase);
Chris@16 1048 disposer(real_value_traits::to_value_ptr(to_erase));
Chris@16 1049 return it.unconst();
Chris@16 1050 }
Chris@16 1051
Chris@16 1052 static iterator s_erase_after(const_iterator prev)
Chris@16 1053 { return s_erase_after_and_dispose(prev, detail::null_disposer()); }
Chris@16 1054
Chris@16 1055 /// @endcond
Chris@16 1056
Chris@16 1057 //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
Chris@16 1058 //!
Chris@16 1059 //! <b>Effects</b>: Erases the range (before_f, l) from
Chris@16 1060 //! the list.
Chris@16 1061 //! Disposer::operator()(pointer) is called for the removed elements.
Chris@16 1062 //!
Chris@16 1063 //! <b>Returns</b>: the first element remaining beyond the removed elements,
Chris@16 1064 //! or end() if no such element exists.
Chris@16 1065 //!
Chris@16 1066 //! <b>Throws</b>: Nothing.
Chris@16 1067 //!
Chris@16 1068 //! <b>Complexity</b>: Lineal to the elements (l - before_f + 1).
Chris@16 1069 //!
Chris@16 1070 //! <b>Note</b>: Invalidates the iterators to the erased element.
Chris@16 1071 template<class Disposer>
Chris@16 1072 iterator erase_after_and_dispose(const_iterator before_f, const_iterator l, Disposer disposer)
Chris@16 1073 {
Chris@16 1074 node_ptr bfp(before_f.pointed_node()), lp(l.pointed_node());
Chris@16 1075 node_ptr fp(node_traits::get_next(bfp));
Chris@16 1076 node_algorithms::unlink_after(bfp, lp);
Chris@16 1077 while(fp != lp){
Chris@16 1078 node_ptr to_erase(fp);
Chris@16 1079 fp = node_traits::get_next(fp);
Chris@16 1080 if(safemode_or_autounlink)
Chris@16 1081 node_algorithms::init(to_erase);
Chris@16 1082 disposer(get_real_value_traits().to_value_ptr(to_erase));
Chris@16 1083 this->priv_size_traits().decrement();
Chris@16 1084 }
Chris@16 1085 if(cache_last && (node_traits::get_next(bfp) == this->get_end_node())){
Chris@16 1086 this->set_last_node(bfp);
Chris@16 1087 }
Chris@16 1088 return l.unconst();
Chris@16 1089 }
Chris@16 1090
Chris@16 1091 //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
Chris@16 1092 //!
Chris@16 1093 //! <b>Effects</b>: Erases the element pointed by i of the list.
Chris@16 1094 //! No destructors are called.
Chris@16 1095 //! Disposer::operator()(pointer) is called for the removed element.
Chris@16 1096 //!
Chris@16 1097 //! <b>Returns</b>: the first element remaining beyond the removed element,
Chris@16 1098 //! or end() if no such element exists.
Chris@16 1099 //!
Chris@16 1100 //! <b>Throws</b>: Nothing.
Chris@16 1101 //!
Chris@16 1102 //! <b>Complexity</b>: Linear to the elements before i.
Chris@16 1103 //!
Chris@16 1104 //! <b>Note</b>: Invalidates the iterators (but not the references) to the
Chris@16 1105 //! erased element.
Chris@16 1106 template<class Disposer>
Chris@16 1107 iterator erase_and_dispose(const_iterator i, Disposer disposer)
Chris@16 1108 { return this->erase_after_and_dispose(this->previous(i), disposer); }
Chris@16 1109
Chris@16 1110 #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
Chris@16 1111 template<class Disposer>
Chris@16 1112 iterator erase_and_dispose(iterator i, Disposer disposer)
Chris@16 1113 { return this->erase_and_dispose(const_iterator(i), disposer); }
Chris@16 1114 #endif
Chris@16 1115
Chris@16 1116 //! <b>Requires</b>: f and l must be valid iterator to elements in *this.
Chris@16 1117 //! Disposer::operator()(pointer) shouldn't throw.
Chris@16 1118 //!
Chris@16 1119 //! <b>Effects</b>: Erases the range pointed by b and e.
Chris@16 1120 //! No destructors are called.
Chris@16 1121 //! Disposer::operator()(pointer) is called for the removed elements.
Chris@16 1122 //!
Chris@16 1123 //! <b>Returns</b>: the first element remaining beyond the removed elements,
Chris@16 1124 //! or end() if no such element exists.
Chris@16 1125 //!
Chris@16 1126 //! <b>Throws</b>: Nothing.
Chris@16 1127 //!
Chris@16 1128 //! <b>Complexity</b>: Linear to the number of erased elements plus linear
Chris@16 1129 //! to the elements before f.
Chris@16 1130 //!
Chris@16 1131 //! <b>Note</b>: Invalidates the iterators (but not the references) to the
Chris@16 1132 //! erased elements.
Chris@16 1133 template<class Disposer>
Chris@16 1134 iterator erase_and_dispose(const_iterator f, const_iterator l, Disposer disposer)
Chris@16 1135 { return this->erase_after_and_dispose(this->previous(f), l, disposer); }
Chris@16 1136
Chris@16 1137 //! <b>Requires</b>: Dereferencing iterator must yield
Chris@16 1138 //! an lvalue of type value_type.
Chris@16 1139 //!
Chris@16 1140 //! <b>Effects</b>: Clears the list and inserts the range pointed by b and e.
Chris@16 1141 //! No destructors or copy constructors are called.
Chris@16 1142 //!
Chris@16 1143 //! <b>Throws</b>: Nothing.
Chris@16 1144 //!
Chris@16 1145 //! <b>Complexity</b>: Linear to the number of elements inserted plus
Chris@16 1146 //! linear to the elements contained in the list if it's a safe-mode
Chris@16 1147 //! or auto-unlink value.
Chris@16 1148 //! Linear to the number of elements inserted in the list otherwise.
Chris@16 1149 //!
Chris@16 1150 //! <b>Note</b>: Invalidates the iterators (but not the references)
Chris@16 1151 //! to the erased elements.
Chris@16 1152 template<class Iterator>
Chris@16 1153 void assign(Iterator b, Iterator e)
Chris@16 1154 {
Chris@16 1155 this->clear();
Chris@16 1156 this->insert_after(this->cbefore_begin(), b, e);
Chris@16 1157 }
Chris@16 1158
Chris@16 1159 //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
Chris@16 1160 //!
Chris@16 1161 //! <b>Requires</b>: Dereferencing iterator must yield
Chris@16 1162 //! an lvalue of type value_type.
Chris@16 1163 //!
Chris@16 1164 //! <b>Effects</b>: Clears the list and inserts the range pointed by b and e.
Chris@16 1165 //! No destructors or copy constructors are called.
Chris@16 1166 //! Disposer::operator()(pointer) is called for the removed elements.
Chris@16 1167 //!
Chris@16 1168 //! <b>Throws</b>: Nothing.
Chris@16 1169 //!
Chris@16 1170 //! <b>Complexity</b>: Linear to the number of elements inserted plus
Chris@16 1171 //! linear to the elements contained in the list.
Chris@16 1172 //!
Chris@16 1173 //! <b>Note</b>: Invalidates the iterators (but not the references)
Chris@16 1174 //! to the erased elements.
Chris@16 1175 template<class Iterator, class Disposer>
Chris@16 1176 void dispose_and_assign(Disposer disposer, Iterator b, Iterator e)
Chris@16 1177 {
Chris@16 1178 this->clear_and_dispose(disposer);
Chris@16 1179 this->insert_after(this->cbefore_begin(), b, e, disposer);
Chris@16 1180 }
Chris@16 1181
Chris@16 1182 //! <b>Requires</b>: prev must point to an element contained by this list or
Chris@16 1183 //! to the before_begin() element
Chris@16 1184 //!
Chris@16 1185 //! <b>Effects</b>: Transfers all the elements of list x to this list, after the
Chris@16 1186 //! the element pointed by prev. No destructors or copy constructors are called.
Chris@16 1187 //!
Chris@16 1188 //! <b>Returns</b>: Nothing.
Chris@16 1189 //!
Chris@16 1190 //! <b>Throws</b>: Nothing.
Chris@16 1191 //!
Chris@16 1192 //! <b>Complexity</b>: In general, linear to the elements contained in x.
Chris@16 1193 //! Constant-time if cache_last<> option is true and also constant-time if
Chris@16 1194 //! linear<> option is true "this" is empty and "l" is not used.
Chris@16 1195 //!
Chris@16 1196 //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
Chris@16 1197 //! list. Iterators of this list and all the references are not invalidated.
Chris@16 1198 //!
Chris@16 1199 //! <b>Additional note</b>: If the optional parameter "l" is provided, it will be
Chris@16 1200 //! assigned to the last spliced element or prev if x is empty.
Chris@16 1201 //! This iterator can be used as new "prev" iterator for a new splice_after call.
Chris@16 1202 //! that will splice new values after the previously spliced values.
Chris@16 1203 void splice_after(const_iterator prev, slist_impl &x, const_iterator *l = 0)
Chris@16 1204 {
Chris@16 1205 if(x.empty()){
Chris@16 1206 if(l) *l = prev;
Chris@16 1207 }
Chris@16 1208 else if(linear && this->empty()){
Chris@16 1209 this->swap(x);
Chris@16 1210 if(l) *l = this->previous(this->cend());
Chris@16 1211 }
Chris@16 1212 else{
Chris@16 1213 const_iterator last_x(x.previous(x.end())); //<- constant time if cache_last is active
Chris@16 1214 node_ptr prev_n(prev.pointed_node());
Chris@16 1215 node_ptr last_x_n(last_x.pointed_node());
Chris@16 1216 if(cache_last){
Chris@16 1217 x.set_last_node(x.get_root_node());
Chris@16 1218 if(node_traits::get_next(prev_n) == this->get_end_node()){
Chris@16 1219 this->set_last_node(last_x_n);
Chris@16 1220 }
Chris@16 1221 }
Chris@16 1222 node_algorithms::transfer_after( prev_n, x.before_begin().pointed_node(), last_x_n);
Chris@16 1223 this->priv_size_traits().increase(x.priv_size_traits().get_size());
Chris@16 1224 x.priv_size_traits().set_size(size_type(0));
Chris@16 1225 if(l) *l = last_x;
Chris@16 1226 }
Chris@16 1227 }
Chris@16 1228
Chris@16 1229 //! <b>Requires</b>: prev must point to an element contained by this list or
Chris@16 1230 //! to the before_begin() element. prev_ele must point to an element contained in list
Chris@16 1231 //! x or must be x.before_begin().
Chris@16 1232 //!
Chris@16 1233 //! <b>Effects</b>: Transfers the element after prev_ele, from list x to this list,
Chris@16 1234 //! after the element pointed by prev. No destructors or copy constructors are called.
Chris@16 1235 //!
Chris@16 1236 //! <b>Throws</b>: Nothing.
Chris@16 1237 //!
Chris@16 1238 //! <b>Complexity</b>: Constant.
Chris@16 1239 //!
Chris@16 1240 //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
Chris@16 1241 //! list. Iterators of this list and all the references are not invalidated.
Chris@16 1242 void splice_after(const_iterator prev_pos, slist_impl &x, const_iterator prev_ele)
Chris@16 1243 {
Chris@16 1244 const_iterator elem = prev_ele;
Chris@16 1245 this->splice_after(prev_pos, x, prev_ele, ++elem, 1);
Chris@16 1246 }
Chris@16 1247
Chris@16 1248 //! <b>Requires</b>: prev_pos must be a dereferenceable iterator in *this or be
Chris@16 1249 //! before_begin(), and before_f and before_l belong to x and
Chris@16 1250 //! ++before_f != x.end() && before_l != x.end().
Chris@16 1251 //!
Chris@16 1252 //! <b>Effects</b>: Transfers the range (before_f, before_l] from list x to this
Chris@16 1253 //! list, after the element pointed by prev_pos.
Chris@16 1254 //! No destructors or copy constructors are called.
Chris@16 1255 //!
Chris@16 1256 //! <b>Throws</b>: Nothing.
Chris@16 1257 //!
Chris@16 1258 //! <b>Complexity</b>: Linear to the number of elements transferred
Chris@16 1259 //! if constant_time_size is true. Constant-time otherwise.
Chris@16 1260 //!
Chris@16 1261 //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
Chris@16 1262 //! list. Iterators of this list and all the references are not invalidated.
Chris@16 1263 void splice_after(const_iterator prev_pos, slist_impl &x, const_iterator before_f, const_iterator before_l)
Chris@16 1264 {
Chris@16 1265 if(constant_time_size)
Chris@16 1266 this->splice_after(prev_pos, x, before_f, before_l, std::distance(before_f, before_l));
Chris@16 1267 else
Chris@16 1268 this->priv_splice_after
Chris@16 1269 (prev_pos.pointed_node(), x, before_f.pointed_node(), before_l.pointed_node());
Chris@16 1270 }
Chris@16 1271
Chris@16 1272 //! <b>Requires</b>: prev_pos must be a dereferenceable iterator in *this or be
Chris@16 1273 //! before_begin(), and before_f and before_l belong to x and
Chris@16 1274 //! ++before_f != x.end() && before_l != x.end() and
Chris@16 1275 //! n == std::distance(before_f, before_l).
Chris@16 1276 //!
Chris@16 1277 //! <b>Effects</b>: Transfers the range (before_f, before_l] from list x to this
Chris@16 1278 //! list, after the element pointed by p. No destructors or copy constructors are called.
Chris@16 1279 //!
Chris@16 1280 //! <b>Throws</b>: Nothing.
Chris@16 1281 //!
Chris@16 1282 //! <b>Complexity</b>: Constant time.
Chris@16 1283 //!
Chris@16 1284 //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
Chris@16 1285 //! list. Iterators of this list and all the references are not invalidated.
Chris@16 1286 void splice_after(const_iterator prev_pos, slist_impl &x, const_iterator before_f, const_iterator before_l, size_type n)
Chris@16 1287 {
Chris@16 1288 BOOST_INTRUSIVE_INVARIANT_ASSERT(std::distance(before_f, before_l) == difference_type(n));
Chris@16 1289 this->priv_splice_after
Chris@16 1290 (prev_pos.pointed_node(), x, before_f.pointed_node(), before_l.pointed_node());
Chris@16 1291 if(constant_time_size){
Chris@16 1292 this->priv_size_traits().increase(n);
Chris@16 1293 x.priv_size_traits().decrease(n);
Chris@16 1294 }
Chris@16 1295 }
Chris@16 1296
Chris@16 1297 //! <b>Requires</b>: it is an iterator to an element in *this.
Chris@16 1298 //!
Chris@16 1299 //! <b>Effects</b>: Transfers all the elements of list x to this list, before the
Chris@16 1300 //! the element pointed by it. No destructors or copy constructors are called.
Chris@16 1301 //!
Chris@16 1302 //! <b>Returns</b>: Nothing.
Chris@16 1303 //!
Chris@16 1304 //! <b>Throws</b>: Nothing.
Chris@16 1305 //!
Chris@16 1306 //! <b>Complexity</b>: Linear to the elements contained in x plus linear to
Chris@16 1307 //! the elements before it.
Chris@16 1308 //! Linear to the elements before it if cache_last<> option is true.
Chris@16 1309 //! Constant-time if cache_last<> option is true and it == end().
Chris@16 1310 //!
Chris@16 1311 //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
Chris@16 1312 //! list. Iterators of this list and all the references are not invalidated.
Chris@16 1313 //!
Chris@16 1314 //! <b>Additional note</b>: If the optional parameter "l" is provided, it will be
Chris@16 1315 //! assigned to the last spliced element or prev if x is empty.
Chris@16 1316 //! This iterator can be used as new "prev" iterator for a new splice_after call.
Chris@16 1317 //! that will splice new values after the previously spliced values.
Chris@16 1318 void splice(const_iterator it, slist_impl &x, const_iterator *l = 0)
Chris@16 1319 { this->splice_after(this->previous(it), x, l); }
Chris@16 1320
Chris@16 1321 //! <b>Requires</b>: it p must be a valid iterator of *this.
Chris@16 1322 //! elem must point to an element contained in list
Chris@16 1323 //! x.
Chris@16 1324 //!
Chris@16 1325 //! <b>Effects</b>: Transfers the element elem, from list x to this list,
Chris@16 1326 //! before the element pointed by pos. No destructors or copy constructors are called.
Chris@16 1327 //!
Chris@16 1328 //! <b>Throws</b>: Nothing.
Chris@16 1329 //!
Chris@16 1330 //! <b>Complexity</b>: Linear to the elements before pos and before elem.
Chris@16 1331 //! Linear to the elements before elem if cache_last<> option is true and pos == end().
Chris@16 1332 //!
Chris@16 1333 //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
Chris@16 1334 //! list. Iterators of this list and all the references are not invalidated.
Chris@16 1335 void splice(const_iterator pos, slist_impl &x, const_iterator elem)
Chris@16 1336 { return this->splice_after(this->previous(pos), x, x.previous(elem)); }
Chris@16 1337
Chris@16 1338 //! <b>Requires</b>: pos must be a dereferenceable iterator in *this
Chris@16 1339 //! and f and f belong to x and f and f a valid range on x.
Chris@16 1340 //!
Chris@16 1341 //! <b>Effects</b>: Transfers the range [f, l) from list x to this
Chris@16 1342 //! list, before the element pointed by pos.
Chris@16 1343 //! No destructors or copy constructors are called.
Chris@16 1344 //!
Chris@16 1345 //! <b>Throws</b>: Nothing.
Chris@16 1346 //!
Chris@16 1347 //! <b>Complexity</b>: Linear to the sum of elements before pos, f, and l
Chris@16 1348 //! plus linear to the number of elements transferred if constant_time_size is true.
Chris@16 1349 //! Linear to the sum of elements before f, and l
Chris@16 1350 //! plus linear to the number of elements transferred if constant_time_size is true
Chris@16 1351 //! if cache_last<> is true and pos == end()
Chris@16 1352 //!
Chris@16 1353 //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
Chris@16 1354 //! list. Iterators of this list and all the references are not invalidated.
Chris@16 1355 void splice(const_iterator pos, slist_impl &x, const_iterator f, const_iterator l)
Chris@16 1356 { return this->splice_after(this->previous(pos), x, x.previous(f), x.previous(l)); }
Chris@16 1357
Chris@16 1358 //! <b>Requires</b>: pos must be a dereferenceable iterator in *this
Chris@16 1359 //! and f and l belong to x and f and l a valid range on x.
Chris@16 1360 //! n == std::distance(f, l).
Chris@16 1361 //!
Chris@16 1362 //! <b>Effects</b>: Transfers the range [f, l) from list x to this
Chris@16 1363 //! list, before the element pointed by pos.
Chris@16 1364 //! No destructors or copy constructors are called.
Chris@16 1365 //!
Chris@16 1366 //! <b>Throws</b>: Nothing.
Chris@16 1367 //!
Chris@16 1368 //! <b>Complexity</b>: Linear to the sum of elements before pos, f, and l.
Chris@16 1369 //! Linear to the sum of elements before f and l
Chris@16 1370 //! if cache_last<> is true and pos == end().
Chris@16 1371 //!
Chris@16 1372 //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
Chris@16 1373 //! list. Iterators of this list and all the references are not invalidated.
Chris@16 1374 void splice(const_iterator pos, slist_impl &x, const_iterator f, const_iterator l, size_type n)
Chris@16 1375 { return this->splice_after(this->previous(pos), x, x.previous(f), x.previous(l), n); }
Chris@16 1376
Chris@16 1377 //! <b>Effects</b>: This function sorts the list *this according to std::less<value_type>.
Chris@16 1378 //! The sort is stable, that is, the relative order of equivalent elements is preserved.
Chris@16 1379 //!
Chris@16 1380 //! <b>Throws</b>: If value_traits::node_traits::node
Chris@16 1381 //! constructor throws (this does not happen with predefined Boost.Intrusive hooks)
Chris@16 1382 //! or the predicate throws. Basic guarantee.
Chris@16 1383 //!
Chris@16 1384 //! <b>Complexity</b>: The number of comparisons is approximately N log N, where N
Chris@16 1385 //! is the list's size.
Chris@16 1386 //!
Chris@16 1387 //! <b>Note</b>: Iterators and references are not invalidated
Chris@16 1388 template<class Predicate>
Chris@16 1389 void sort(Predicate p)
Chris@16 1390 {
Chris@16 1391 if (node_traits::get_next(node_traits::get_next(this->get_root_node()))
Chris@16 1392 != this->get_root_node()) {
Chris@16 1393
Chris@16 1394 slist_impl carry(this->priv_value_traits());
Chris@16 1395 detail::array_initializer<slist_impl, 64> counter(this->priv_value_traits());
Chris@16 1396 int fill = 0;
Chris@16 1397 const_iterator last_inserted;
Chris@16 1398 while(!this->empty()){
Chris@16 1399 last_inserted = this->cbegin();
Chris@16 1400 carry.splice_after(carry.cbefore_begin(), *this, this->cbefore_begin());
Chris@16 1401 int i = 0;
Chris@16 1402 while(i < fill && !counter[i].empty()) {
Chris@16 1403 carry.swap(counter[i]);
Chris@16 1404 carry.merge(counter[i++], p, &last_inserted);
Chris@16 1405 }
Chris@16 1406 BOOST_INTRUSIVE_INVARIANT_ASSERT(counter[i].empty());
Chris@16 1407 const_iterator last_element(carry.previous(last_inserted, carry.end()));
Chris@16 1408
Chris@16 1409 if(constant_time_size){
Chris@16 1410 counter[i].splice_after( counter[i].cbefore_begin(), carry
Chris@16 1411 , carry.cbefore_begin(), last_element
Chris@16 1412 , carry.size());
Chris@16 1413 }
Chris@16 1414 else{
Chris@16 1415 counter[i].splice_after( counter[i].cbefore_begin(), carry
Chris@16 1416 , carry.cbefore_begin(), last_element);
Chris@16 1417 }
Chris@16 1418 if(i == fill)
Chris@16 1419 ++fill;
Chris@16 1420 }
Chris@16 1421
Chris@16 1422 for (int i = 1; i < fill; ++i)
Chris@16 1423 counter[i].merge(counter[i-1], p, &last_inserted);
Chris@16 1424 --fill;
Chris@16 1425 const_iterator last_element(counter[fill].previous(last_inserted, counter[fill].end()));
Chris@16 1426 if(constant_time_size){
Chris@16 1427 this->splice_after( cbefore_begin(), counter[fill], counter[fill].cbefore_begin()
Chris@16 1428 , last_element, counter[fill].size());
Chris@16 1429 }
Chris@16 1430 else{
Chris@16 1431 this->splice_after( cbefore_begin(), counter[fill], counter[fill].cbefore_begin()
Chris@16 1432 , last_element);
Chris@16 1433 }
Chris@16 1434 }
Chris@16 1435 }
Chris@16 1436
Chris@16 1437 //! <b>Requires</b>: p must be a comparison function that induces a strict weak
Chris@16 1438 //! ordering and both *this and x must be sorted according to that ordering
Chris@16 1439 //! The lists x and *this must be distinct.
Chris@16 1440 //!
Chris@16 1441 //! <b>Effects</b>: This function removes all of x's elements and inserts them
Chris@16 1442 //! in order into *this. The merge is stable; that is, if an element from *this is
Chris@16 1443 //! equivalent to one from x, then the element from *this will precede the one from x.
Chris@16 1444 //!
Chris@16 1445 //! <b>Throws</b>: If value_traits::node_traits::node
Chris@16 1446 //! constructor throws (this does not happen with predefined Boost.Intrusive hooks)
Chris@16 1447 //! or std::less<value_type> throws. Basic guarantee.
Chris@16 1448 //!
Chris@16 1449 //! <b>Complexity</b>: This function is linear time: it performs at most
Chris@16 1450 //! size() + x.size() - 1 comparisons.
Chris@16 1451 //!
Chris@16 1452 //! <b>Note</b>: Iterators and references are not invalidated.
Chris@16 1453 void sort()
Chris@16 1454 { this->sort(std::less<value_type>()); }
Chris@16 1455
Chris@16 1456 //! <b>Requires</b>: p must be a comparison function that induces a strict weak
Chris@16 1457 //! ordering and both *this and x must be sorted according to that ordering
Chris@16 1458 //! The lists x and *this must be distinct.
Chris@16 1459 //!
Chris@16 1460 //! <b>Effects</b>: This function removes all of x's elements and inserts them
Chris@16 1461 //! in order into *this. The merge is stable; that is, if an element from *this is
Chris@16 1462 //! equivalent to one from x, then the element from *this will precede the one from x.
Chris@16 1463 //!
Chris@16 1464 //! <b>Returns</b>: Nothing.
Chris@16 1465 //!
Chris@16 1466 //! <b>Throws</b>: If the predicate throws. Basic guarantee.
Chris@16 1467 //!
Chris@16 1468 //! <b>Complexity</b>: This function is linear time: it performs at most
Chris@16 1469 //! size() + x.size() - 1 comparisons.
Chris@16 1470 //!
Chris@16 1471 //! <b>Note</b>: Iterators and references are not invalidated.
Chris@16 1472 //!
Chris@16 1473 //! <b>Additional note</b>: If optional "l" argument is passed, it is assigned
Chris@16 1474 //! to an iterator to the last transferred value or end() is x is empty.
Chris@16 1475 template<class Predicate>
Chris@16 1476 void merge(slist_impl& x, Predicate p, const_iterator *l = 0)
Chris@16 1477 {
Chris@16 1478 const_iterator e(this->cend()), ex(x.cend()), bb(this->cbefore_begin()),
Chris@16 1479 bb_next;
Chris@16 1480 if(l) *l = e.unconst();
Chris@16 1481 while(!x.empty()){
Chris@16 1482 const_iterator ibx_next(x.cbefore_begin()), ibx(ibx_next++);
Chris@16 1483 while (++(bb_next = bb) != e && !p(*ibx_next, *bb_next)){
Chris@16 1484 bb = bb_next;
Chris@16 1485 }
Chris@16 1486 if(bb_next == e){
Chris@16 1487 //Now transfer the rest to the end of the container
Chris@16 1488 this->splice_after(bb, x, l);
Chris@16 1489 break;
Chris@16 1490 }
Chris@16 1491 else{
Chris@16 1492 size_type n(0);
Chris@16 1493 do{
Chris@16 1494 ibx = ibx_next; ++n;
Chris@16 1495 } while(++(ibx_next = ibx) != ex && p(*ibx_next, *bb_next));
Chris@16 1496 this->splice_after(bb, x, x.before_begin(), ibx, n);
Chris@16 1497 if(l) *l = ibx;
Chris@16 1498 }
Chris@16 1499 }
Chris@16 1500 }
Chris@16 1501
Chris@16 1502 //! <b>Effects</b>: This function removes all of x's elements and inserts them
Chris@16 1503 //! in order into *this according to std::less<value_type>. The merge is stable;
Chris@16 1504 //! that is, if an element from *this is equivalent to one from x, then the element
Chris@16 1505 //! from *this will precede the one from x.
Chris@16 1506 //!
Chris@16 1507 //! <b>Throws</b>: if std::less<value_type> throws. Basic guarantee.
Chris@16 1508 //!
Chris@16 1509 //! <b>Complexity</b>: This function is linear time: it performs at most
Chris@16 1510 //! size() + x.size() - 1 comparisons.
Chris@16 1511 //!
Chris@16 1512 //! <b>Note</b>: Iterators and references are not invalidated
Chris@16 1513 void merge(slist_impl& x)
Chris@16 1514 { this->merge(x, std::less<value_type>()); }
Chris@16 1515
Chris@16 1516 //! <b>Effects</b>: Reverses the order of elements in the list.
Chris@16 1517 //!
Chris@16 1518 //! <b>Throws</b>: Nothing.
Chris@16 1519 //!
Chris@16 1520 //! <b>Complexity</b>: This function is linear to the contained elements.
Chris@16 1521 //!
Chris@16 1522 //! <b>Note</b>: Iterators and references are not invalidated
Chris@16 1523 void reverse()
Chris@16 1524 {
Chris@16 1525 if(cache_last && !this->empty()){
Chris@16 1526 this->set_last_node(node_traits::get_next(this->get_root_node()));
Chris@16 1527 }
Chris@16 1528 this->priv_reverse(detail::bool_<linear>());
Chris@16 1529 }
Chris@16 1530
Chris@16 1531 //! <b>Effects</b>: Removes all the elements that compare equal to value.
Chris@16 1532 //! No destructors are called.
Chris@16 1533 //!
Chris@16 1534 //! <b>Throws</b>: If std::equal_to<value_type> throws. Basic guarantee.
Chris@16 1535 //!
Chris@16 1536 //! <b>Complexity</b>: Linear time. It performs exactly size() comparisons for equality.
Chris@16 1537 //!
Chris@16 1538 //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
Chris@16 1539 //! and iterators to elements that are not removed remain valid. This function is
Chris@16 1540 //! linear time: it performs exactly size() comparisons for equality.
Chris@16 1541 void remove(const_reference value)
Chris@16 1542 { this->remove_if(detail::equal_to_value<const_reference>(value)); }
Chris@16 1543
Chris@16 1544 //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
Chris@16 1545 //!
Chris@16 1546 //! <b>Effects</b>: Removes all the elements that compare equal to value.
Chris@16 1547 //! Disposer::operator()(pointer) is called for every removed element.
Chris@16 1548 //!
Chris@16 1549 //! <b>Throws</b>: If std::equal_to<value_type> throws. Basic guarantee.
Chris@16 1550 //!
Chris@16 1551 //! <b>Complexity</b>: Linear time. It performs exactly size() comparisons for equality.
Chris@16 1552 //!
Chris@16 1553 //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
Chris@16 1554 //! and iterators to elements that are not removed remain valid.
Chris@16 1555 template<class Disposer>
Chris@16 1556 void remove_and_dispose(const_reference value, Disposer disposer)
Chris@16 1557 { this->remove_and_dispose_if(detail::equal_to_value<const_reference>(value), disposer); }
Chris@16 1558
Chris@16 1559 //! <b>Effects</b>: Removes all the elements for which a specified
Chris@16 1560 //! predicate is satisfied. No destructors are called.
Chris@16 1561 //!
Chris@16 1562 //! <b>Throws</b>: If pred throws. Basic guarantee.
Chris@16 1563 //!
Chris@16 1564 //! <b>Complexity</b>: Linear time. It performs exactly size() calls to the predicate.
Chris@16 1565 //!
Chris@16 1566 //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
Chris@16 1567 //! and iterators to elements that are not removed remain valid.
Chris@16 1568 template<class Pred>
Chris@16 1569 void remove_if(Pred pred)
Chris@16 1570 { this->remove_and_dispose_if(pred, detail::null_disposer()); }
Chris@16 1571
Chris@16 1572 //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
Chris@16 1573 //!
Chris@16 1574 //! <b>Effects</b>: Removes all the elements for which a specified
Chris@16 1575 //! predicate is satisfied.
Chris@16 1576 //! Disposer::operator()(pointer) is called for every removed element.
Chris@16 1577 //!
Chris@16 1578 //! <b>Throws</b>: If pred throws. Basic guarantee.
Chris@16 1579 //!
Chris@16 1580 //! <b>Complexity</b>: Linear time. It performs exactly size() comparisons for equality.
Chris@16 1581 //!
Chris@16 1582 //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
Chris@16 1583 //! and iterators to elements that are not removed remain valid.
Chris@16 1584 template<class Pred, class Disposer>
Chris@16 1585 void remove_and_dispose_if(Pred pred, Disposer disposer)
Chris@16 1586 {
Chris@16 1587 const_iterator bcur(this->before_begin()), cur(this->begin()), e(this->end());
Chris@16 1588
Chris@16 1589 while(cur != e){
Chris@16 1590 if (pred(*cur)){
Chris@16 1591 cur = this->erase_after_and_dispose(bcur, disposer);
Chris@16 1592 }
Chris@16 1593 else{
Chris@16 1594 bcur = cur;
Chris@16 1595 ++cur;
Chris@16 1596 }
Chris@16 1597 }
Chris@16 1598 if(cache_last){
Chris@16 1599 this->set_last_node(bcur.pointed_node());
Chris@16 1600 }
Chris@16 1601 }
Chris@16 1602
Chris@16 1603 //! <b>Effects</b>: Removes adjacent duplicate elements or adjacent
Chris@16 1604 //! elements that are equal from the list. No destructors are called.
Chris@16 1605 //!
Chris@16 1606 //! <b>Throws</b>: If std::equal_to<value_type> throws. Basic guarantee.
Chris@16 1607 //!
Chris@16 1608 //! <b>Complexity</b>: Linear time (size()-1) comparisons calls to pred()).
Chris@16 1609 //!
Chris@16 1610 //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
Chris@16 1611 //! and iterators to elements that are not removed remain valid.
Chris@16 1612 void unique()
Chris@16 1613 { this->unique_and_dispose(std::equal_to<value_type>(), detail::null_disposer()); }
Chris@16 1614
Chris@16 1615 //! <b>Effects</b>: Removes adjacent duplicate elements or adjacent
Chris@16 1616 //! elements that satisfy some binary predicate from the list.
Chris@16 1617 //! No destructors are called.
Chris@16 1618 //!
Chris@16 1619 //! <b>Throws</b>: If the predicate throws. Basic guarantee.
Chris@16 1620 //!
Chris@16 1621 //! <b>Complexity</b>: Linear time (size()-1) comparisons equality comparisons.
Chris@16 1622 //!
Chris@16 1623 //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
Chris@16 1624 //! and iterators to elements that are not removed remain valid.
Chris@16 1625 template<class BinaryPredicate>
Chris@16 1626 void unique(BinaryPredicate pred)
Chris@16 1627 { this->unique_and_dispose(pred, detail::null_disposer()); }
Chris@16 1628
Chris@16 1629 //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
Chris@16 1630 //!
Chris@16 1631 //! <b>Effects</b>: Removes adjacent duplicate elements or adjacent
Chris@16 1632 //! elements that satisfy some binary predicate from the list.
Chris@16 1633 //! Disposer::operator()(pointer) is called for every removed element.
Chris@16 1634 //!
Chris@16 1635 //! <b>Throws</b>: If std::equal_to<value_type> throws. Basic guarantee.
Chris@16 1636 //!
Chris@16 1637 //! <b>Complexity</b>: Linear time (size()-1) comparisons equality comparisons.
Chris@16 1638 //!
Chris@16 1639 //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
Chris@16 1640 //! and iterators to elements that are not removed remain valid.
Chris@16 1641 template<class Disposer>
Chris@16 1642 void unique_and_dispose(Disposer disposer)
Chris@16 1643 { this->unique(std::equal_to<value_type>(), disposer); }
Chris@16 1644
Chris@16 1645 //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
Chris@16 1646 //!
Chris@16 1647 //! <b>Effects</b>: Removes adjacent duplicate elements or adjacent
Chris@16 1648 //! elements that satisfy some binary predicate from the list.
Chris@16 1649 //! Disposer::operator()(pointer) is called for every removed element.
Chris@16 1650 //!
Chris@16 1651 //! <b>Throws</b>: If the predicate throws. Basic guarantee.
Chris@16 1652 //!
Chris@16 1653 //! <b>Complexity</b>: Linear time (size()-1) comparisons equality comparisons.
Chris@16 1654 //!
Chris@16 1655 //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
Chris@16 1656 //! and iterators to elements that are not removed remain valid.
Chris@16 1657 template<class BinaryPredicate, class Disposer>
Chris@16 1658 void unique_and_dispose(BinaryPredicate pred, Disposer disposer)
Chris@16 1659 {
Chris@16 1660 const_iterator end_n(this->cend());
Chris@16 1661 const_iterator bcur(this->cbegin());
Chris@16 1662 if(bcur != end_n){
Chris@16 1663 const_iterator cur(bcur);
Chris@16 1664 ++cur;
Chris@16 1665 while(cur != end_n) {
Chris@16 1666 if (pred(*bcur, *cur)){
Chris@16 1667 cur = this->erase_after_and_dispose(bcur, disposer);
Chris@16 1668 }
Chris@16 1669 else{
Chris@16 1670 bcur = cur;
Chris@16 1671 ++cur;
Chris@16 1672 }
Chris@16 1673 }
Chris@16 1674 if(cache_last){
Chris@16 1675 this->set_last_node(bcur.pointed_node());
Chris@16 1676 }
Chris@16 1677 }
Chris@16 1678 }
Chris@16 1679
Chris@16 1680 //! <b>Requires</b>: value must be a reference to a value inserted in a list.
Chris@16 1681 //!
Chris@16 1682 //! <b>Effects</b>: This function returns a const_iterator pointing to the element
Chris@16 1683 //!
Chris@16 1684 //! <b>Throws</b>: Nothing.
Chris@16 1685 //!
Chris@16 1686 //! <b>Complexity</b>: Constant time.
Chris@16 1687 //!
Chris@16 1688 //! <b>Note</b>: Iterators and references are not invalidated.
Chris@16 1689 //! This static function is available only if the <i>value traits</i>
Chris@16 1690 //! is stateless.
Chris@16 1691 static iterator s_iterator_to(reference value)
Chris@16 1692 {
Chris@16 1693 BOOST_STATIC_ASSERT((!stateful_value_traits));
Chris@16 1694 //BOOST_INTRUSIVE_INVARIANT_ASSERT (!node_algorithms::inited(value_traits::to_node_ptr(value)));
Chris@16 1695 return iterator (value_traits::to_node_ptr(value), const_real_value_traits_ptr());
Chris@16 1696 }
Chris@16 1697
Chris@16 1698 //! <b>Requires</b>: value must be a const reference to a value inserted in a list.
Chris@16 1699 //!
Chris@16 1700 //! <b>Effects</b>: This function returns an iterator pointing to the element.
Chris@16 1701 //!
Chris@16 1702 //! <b>Throws</b>: Nothing.
Chris@16 1703 //!
Chris@16 1704 //! <b>Complexity</b>: Constant time.
Chris@16 1705 //!
Chris@16 1706 //! <b>Note</b>: Iterators and references are not invalidated.
Chris@16 1707 //! This static function is available only if the <i>value traits</i>
Chris@16 1708 //! is stateless.
Chris@16 1709 static const_iterator s_iterator_to(const_reference value)
Chris@16 1710 {
Chris@16 1711 BOOST_STATIC_ASSERT((!stateful_value_traits));
Chris@16 1712 //BOOST_INTRUSIVE_INVARIANT_ASSERT (!node_algorithms::inited(value_traits::to_node_ptr(const_cast<reference> (value))));
Chris@16 1713 return const_iterator (value_traits::to_node_ptr(const_cast<reference> (value)), const_real_value_traits_ptr());
Chris@16 1714 }
Chris@16 1715
Chris@16 1716 //! <b>Requires</b>: value must be a reference to a value inserted in a list.
Chris@16 1717 //!
Chris@16 1718 //! <b>Effects</b>: This function returns a const_iterator pointing to the element
Chris@16 1719 //!
Chris@16 1720 //! <b>Throws</b>: Nothing.
Chris@16 1721 //!
Chris@16 1722 //! <b>Complexity</b>: Constant time.
Chris@16 1723 //!
Chris@16 1724 //! <b>Note</b>: Iterators and references are not invalidated.
Chris@16 1725 iterator iterator_to(reference value)
Chris@16 1726 {
Chris@16 1727 //BOOST_INTRUSIVE_INVARIANT_ASSERT (!node_algorithms::inited(value_traits::to_node_ptr(value)));
Chris@16 1728 return iterator (value_traits::to_node_ptr(value), this->real_value_traits_ptr());
Chris@16 1729 }
Chris@16 1730
Chris@16 1731 //! <b>Requires</b>: value must be a const reference to a value inserted in a list.
Chris@16 1732 //!
Chris@16 1733 //! <b>Effects</b>: This function returns an iterator pointing to the element.
Chris@16 1734 //!
Chris@16 1735 //! <b>Throws</b>: Nothing.
Chris@16 1736 //!
Chris@16 1737 //! <b>Complexity</b>: Constant time.
Chris@16 1738 //!
Chris@16 1739 //! <b>Note</b>: Iterators and references are not invalidated.
Chris@16 1740 const_iterator iterator_to(const_reference value) const
Chris@16 1741 {
Chris@16 1742 //BOOST_INTRUSIVE_INVARIANT_ASSERT (!node_algorithms::inited(value_traits::to_node_ptr(const_cast<reference> (value))));
Chris@16 1743 return const_iterator (value_traits::to_node_ptr(const_cast<reference> (value)), this->real_value_traits_ptr());
Chris@16 1744 }
Chris@16 1745
Chris@16 1746 //! <b>Returns</b>: The iterator to the element before i in the list.
Chris@16 1747 //! Returns the end-iterator, if either i is the begin-iterator or the
Chris@16 1748 //! list is empty.
Chris@16 1749 //!
Chris@16 1750 //! <b>Throws</b>: Nothing.
Chris@16 1751 //!
Chris@16 1752 //! <b>Complexity</b>: Linear to the number of elements before i.
Chris@16 1753 //! Constant if cache_last<> is true and i == end().
Chris@16 1754 iterator previous(iterator i)
Chris@16 1755 { return this->previous(this->cbefore_begin(), i); }
Chris@16 1756
Chris@16 1757 //! <b>Returns</b>: The const_iterator to the element before i in the list.
Chris@16 1758 //! Returns the end-const_iterator, if either i is the begin-const_iterator or
Chris@16 1759 //! the list is empty.
Chris@16 1760 //!
Chris@16 1761 //! <b>Throws</b>: Nothing.
Chris@16 1762 //!
Chris@16 1763 //! <b>Complexity</b>: Linear to the number of elements before i.
Chris@16 1764 //! Constant if cache_last<> is true and i == end().
Chris@16 1765 const_iterator previous(const_iterator i) const
Chris@16 1766 { return this->previous(this->cbefore_begin(), i); }
Chris@16 1767
Chris@16 1768 //! <b>Returns</b>: The iterator to the element before i in the list,
Chris@16 1769 //! starting the search on element after prev_from.
Chris@16 1770 //! Returns the end-iterator, if either i is the begin-iterator or the
Chris@16 1771 //! list is empty.
Chris@16 1772 //!
Chris@16 1773 //! <b>Throws</b>: Nothing.
Chris@16 1774 //!
Chris@16 1775 //! <b>Complexity</b>: Linear to the number of elements before i.
Chris@16 1776 //! Constant if cache_last<> is true and i == end().
Chris@16 1777 iterator previous(const_iterator prev_from, iterator i)
Chris@16 1778 { return this->previous(prev_from, const_iterator(i)).unconst(); }
Chris@16 1779
Chris@16 1780 //! <b>Returns</b>: The const_iterator to the element before i in the list,
Chris@16 1781 //! starting the search on element after prev_from.
Chris@16 1782 //! Returns the end-const_iterator, if either i is the begin-const_iterator or
Chris@16 1783 //! the list is empty.
Chris@16 1784 //!
Chris@16 1785 //! <b>Throws</b>: Nothing.
Chris@16 1786 //!
Chris@16 1787 //! <b>Complexity</b>: Linear to the number of elements before i.
Chris@16 1788 //! Constant if cache_last<> is true and i == end().
Chris@16 1789 const_iterator previous(const_iterator prev_from, const_iterator i) const
Chris@16 1790 {
Chris@16 1791 if(cache_last && (i.pointed_node() == this->get_end_node())){
Chris@16 1792 return const_iterator(detail::uncast(this->get_last_node()), this->real_value_traits_ptr());
Chris@16 1793 }
Chris@16 1794 return const_iterator
Chris@16 1795 (node_algorithms::get_previous_node
Chris@16 1796 (prev_from.pointed_node(), i.pointed_node()), this->real_value_traits_ptr());
Chris@16 1797 }
Chris@16 1798
Chris@16 1799 ///@cond
Chris@16 1800
Chris@16 1801 //! <b>Requires</b>: prev_pos must be a dereferenceable iterator in *this or be
Chris@16 1802 //! before_begin(), and f and before_l belong to another slist.
Chris@16 1803 //!
Chris@16 1804 //! <b>Effects</b>: Transfers the range [f, before_l] to this
Chris@16 1805 //! list, after the element pointed by prev_pos.
Chris@16 1806 //! No destructors or copy constructors are called.
Chris@16 1807 //!
Chris@16 1808 //! <b>Throws</b>: Nothing.
Chris@16 1809 //!
Chris@16 1810 //! <b>Complexity</b>: Linear to the number of elements transferred
Chris@16 1811 //! if constant_time_size is true. Constant-time otherwise.
Chris@16 1812 //!
Chris@16 1813 //! <b>Note</b>: Iterators of values obtained from the list that owned f and before_l now
Chris@16 1814 //! point to elements of this list. Iterators of this list and all the references are not invalidated.
Chris@16 1815 //!
Chris@16 1816 //! <b>Warning</b>: Experimental function, don't use it!
Chris@16 1817 void incorporate_after(const_iterator prev_pos, const node_ptr & f, const node_ptr & before_l)
Chris@16 1818 {
Chris@16 1819 if(constant_time_size)
Chris@16 1820 this->incorporate_after(prev_pos, f, before_l, std::distance(f, before_l)+1);
Chris@16 1821 else
Chris@16 1822 this->priv_incorporate_after(prev_pos.pointed_node(), f, before_l);
Chris@16 1823 }
Chris@16 1824
Chris@16 1825 //! <b>Requires</b>: prev_pos must be a dereferenceable iterator in *this or be
Chris@16 1826 //! before_begin(), and f and before_l belong to another slist.
Chris@16 1827 //! n == std::distance(f, before_l) + 1.
Chris@16 1828 //!
Chris@16 1829 //! <b>Effects</b>: Transfers the range [f, before_l] to this
Chris@16 1830 //! list, after the element pointed by prev_pos.
Chris@16 1831 //! No destructors or copy constructors are called.
Chris@16 1832 //!
Chris@16 1833 //! <b>Throws</b>: Nothing.
Chris@16 1834 //!
Chris@16 1835 //! <b>Complexity</b>: Constant time.
Chris@16 1836 //!
Chris@16 1837 //! <b>Note</b>: Iterators of values obtained from the list that owned f and before_l now
Chris@16 1838 //! point to elements of this list. Iterators of this list and all the references are not invalidated.
Chris@16 1839 //!
Chris@16 1840 //! <b>Warning</b>: Experimental function, don't use it!
Chris@16 1841 void incorporate_after(const_iterator prev_pos, const node_ptr & f, const node_ptr & before_l, size_type n)
Chris@16 1842 {
Chris@16 1843 if(n){
Chris@16 1844 BOOST_INTRUSIVE_INVARIANT_ASSERT(n > 0);
Chris@16 1845 BOOST_INTRUSIVE_INVARIANT_ASSERT
Chris@16 1846 (size_type(std::distance
Chris@16 1847 ( iterator(f, this->real_value_traits_ptr())
Chris@16 1848 , iterator(before_l, this->real_value_traits_ptr())))
Chris@16 1849 +1 == n);
Chris@16 1850 this->priv_incorporate_after(prev_pos.pointed_node(), f, before_l);
Chris@16 1851 if(constant_time_size){
Chris@16 1852 this->priv_size_traits().increase(n);
Chris@16 1853 }
Chris@16 1854 }
Chris@16 1855 }
Chris@16 1856
Chris@16 1857 ///@endcond
Chris@16 1858
Chris@16 1859 private:
Chris@16 1860 void priv_splice_after(const node_ptr & prev_pos_n, slist_impl &x, const node_ptr & before_f_n, const node_ptr & before_l_n)
Chris@16 1861 {
Chris@16 1862 if (cache_last && (before_f_n != before_l_n)){
Chris@16 1863 if(prev_pos_n == this->get_last_node()){
Chris@16 1864 this->set_last_node(before_l_n);
Chris@16 1865 }
Chris@16 1866 if(&x != this && node_traits::get_next(before_l_n) == x.get_end_node()){
Chris@16 1867 x.set_last_node(before_f_n);
Chris@16 1868 }
Chris@16 1869 }
Chris@16 1870 node_algorithms::transfer_after(prev_pos_n, before_f_n, before_l_n);
Chris@16 1871 }
Chris@16 1872
Chris@16 1873 void priv_incorporate_after(const node_ptr & prev_pos_n, const node_ptr & first_n, const node_ptr & before_l_n)
Chris@16 1874 {
Chris@16 1875 if(cache_last){
Chris@16 1876 if(prev_pos_n == this->get_last_node()){
Chris@16 1877 this->set_last_node(before_l_n);
Chris@16 1878 }
Chris@16 1879 }
Chris@16 1880 node_algorithms::incorporate_after(prev_pos_n, first_n, before_l_n);
Chris@16 1881 }
Chris@16 1882
Chris@16 1883 void priv_reverse(detail::bool_<false>)
Chris@16 1884 { node_algorithms::reverse(this->get_root_node()); }
Chris@16 1885
Chris@16 1886 void priv_reverse(detail::bool_<true>)
Chris@16 1887 {
Chris@16 1888 node_ptr new_first = node_algorithms::reverse
Chris@16 1889 (node_traits::get_next(this->get_root_node()));
Chris@16 1890 node_traits::set_next(this->get_root_node(), new_first);
Chris@16 1891 }
Chris@16 1892
Chris@16 1893 void priv_shift_backwards(size_type n, detail::bool_<false>)
Chris@16 1894 {
Chris@16 1895 node_ptr l = node_algorithms::move_forward(this->get_root_node(), (std::size_t)n);
Chris@16 1896 if(cache_last && l){
Chris@16 1897 this->set_last_node(l);
Chris@16 1898 }
Chris@16 1899 }
Chris@16 1900
Chris@16 1901 void priv_shift_backwards(size_type n, detail::bool_<true>)
Chris@16 1902 {
Chris@16 1903 std::pair<node_ptr, node_ptr> ret(
Chris@16 1904 node_algorithms::move_first_n_forward
Chris@16 1905 (node_traits::get_next(this->get_root_node()), (std::size_t)n));
Chris@16 1906 if(ret.first){
Chris@16 1907 node_traits::set_next(this->get_root_node(), ret.first);
Chris@16 1908 if(cache_last){
Chris@16 1909 this->set_last_node(ret.second);
Chris@16 1910 }
Chris@16 1911 }
Chris@16 1912 }
Chris@16 1913
Chris@16 1914 void priv_shift_forward(size_type n, detail::bool_<false>)
Chris@16 1915 {
Chris@16 1916 node_ptr l = node_algorithms::move_backwards(this->get_root_node(), (std::size_t)n);
Chris@16 1917 if(cache_last && l){
Chris@16 1918 this->set_last_node(l);
Chris@16 1919 }
Chris@16 1920 }
Chris@16 1921
Chris@16 1922 void priv_shift_forward(size_type n, detail::bool_<true>)
Chris@16 1923 {
Chris@16 1924 std::pair<node_ptr, node_ptr> ret(
Chris@16 1925 node_algorithms::move_first_n_backwards
Chris@16 1926 (node_traits::get_next(this->get_root_node()), (std::size_t)n));
Chris@16 1927 if(ret.first){
Chris@16 1928 node_traits::set_next(this->get_root_node(), ret.first);
Chris@16 1929 if(cache_last){
Chris@16 1930 this->set_last_node(ret.second);
Chris@16 1931 }
Chris@16 1932 }
Chris@16 1933 }
Chris@16 1934
Chris@16 1935 static void priv_swap_cache_last(slist_impl *this_impl, slist_impl *other_impl)
Chris@16 1936 {
Chris@16 1937 bool other_was_empty = false;
Chris@16 1938 if(this_impl->empty()){
Chris@16 1939 //Check if both are empty or
Chris@16 1940 if(other_impl->empty())
Chris@16 1941 return;
Chris@16 1942 //If this is empty swap pointers
Chris@16 1943 slist_impl *tmp = this_impl;
Chris@16 1944 this_impl = other_impl;
Chris@16 1945 other_impl = tmp;
Chris@16 1946 other_was_empty = true;
Chris@16 1947 }
Chris@16 1948 else{
Chris@16 1949 other_was_empty = other_impl->empty();
Chris@16 1950 }
Chris@16 1951
Chris@16 1952 //Precondition: this is not empty
Chris@16 1953 node_ptr other_old_last(other_impl->get_last_node());
Chris@16 1954 node_ptr other_bfirst(other_impl->get_root_node());
Chris@16 1955 node_ptr this_bfirst(this_impl->get_root_node());
Chris@16 1956 node_ptr this_old_last(this_impl->get_last_node());
Chris@16 1957
Chris@16 1958 //Move all nodes from this to other's beginning
Chris@16 1959 node_algorithms::transfer_after(other_bfirst, this_bfirst, this_old_last);
Chris@16 1960 other_impl->set_last_node(this_old_last);
Chris@16 1961
Chris@16 1962 if(other_was_empty){
Chris@16 1963 this_impl->set_last_node(this_bfirst);
Chris@16 1964 }
Chris@16 1965 else{
Chris@16 1966 //Move trailing nodes from other to this
Chris@16 1967 node_algorithms::transfer_after(this_bfirst, this_old_last, other_old_last);
Chris@16 1968 this_impl->set_last_node(other_old_last);
Chris@16 1969 }
Chris@16 1970 }
Chris@16 1971
Chris@16 1972 //circular version
Chris@16 1973 static void priv_swap_lists(const node_ptr & this_node, const node_ptr & other_node, detail::bool_<false>)
Chris@16 1974 { node_algorithms::swap_nodes(this_node, other_node); }
Chris@16 1975
Chris@16 1976 //linear version
Chris@16 1977 static void priv_swap_lists(const node_ptr & this_node, const node_ptr & other_node, detail::bool_<true>)
Chris@16 1978 { node_algorithms::swap_trailing_nodes(this_node, other_node); }
Chris@16 1979
Chris@16 1980 static slist_impl &priv_container_from_end_iterator(const const_iterator &end_iterator)
Chris@16 1981 {
Chris@16 1982 //Obtaining the container from the end iterator is not possible with linear
Chris@16 1983 //singly linked lists (because "end" is represented by the null pointer)
Chris@16 1984 BOOST_STATIC_ASSERT(!linear);
Chris@16 1985 root_plus_size *r = detail::parent_from_member<root_plus_size, node>
Chris@16 1986 ( boost::intrusive::detail::to_raw_pointer(end_iterator.pointed_node()), (&root_plus_size::root_));
Chris@16 1987 data_t *d = detail::parent_from_member<data_t, root_plus_size>
Chris@16 1988 ( r, &data_t::root_plus_size_);
Chris@16 1989 slist_impl *s = detail::parent_from_member<slist_impl, data_t>(d, &slist_impl::data_);
Chris@16 1990 return *s;
Chris@16 1991 }
Chris@16 1992 };
Chris@16 1993
Chris@16 1994 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
Chris@16 1995 template<class T, class ...Options>
Chris@16 1996 #else
Chris@16 1997 template<class ValueTraits, class SizeType, std::size_t BoolFlags>
Chris@16 1998 #endif
Chris@16 1999 inline bool operator<
Chris@16 2000 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
Chris@16 2001 (const slist_impl<T, Options...> &x, const slist_impl<T, Options...> &y)
Chris@16 2002 #else
Chris@16 2003 ( const slist_impl<ValueTraits, SizeType, BoolFlags> &x
Chris@16 2004 , const slist_impl<ValueTraits, SizeType, BoolFlags> &y)
Chris@16 2005 #endif
Chris@16 2006 { return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
Chris@16 2007
Chris@16 2008 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
Chris@16 2009 template<class T, class ...Options>
Chris@16 2010 #else
Chris@16 2011 template<class ValueTraits, class SizeType, std::size_t BoolFlags>
Chris@16 2012 #endif
Chris@16 2013 bool operator==
Chris@16 2014 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
Chris@16 2015 (const slist_impl<T, Options...> &x, const slist_impl<T, Options...> &y)
Chris@16 2016 #else
Chris@16 2017 ( const slist_impl<ValueTraits, SizeType, BoolFlags> &x
Chris@16 2018 , const slist_impl<ValueTraits, SizeType, BoolFlags> &y)
Chris@16 2019 #endif
Chris@16 2020 {
Chris@16 2021 typedef slist_impl<ValueTraits, SizeType, BoolFlags> slist_type;
Chris@16 2022 typedef typename slist_type::const_iterator const_iterator;
Chris@16 2023 const bool C = slist_type::constant_time_size;
Chris@16 2024 if(C && x.size() != y.size()){
Chris@16 2025 return false;
Chris@16 2026 }
Chris@16 2027 const_iterator end1 = x.end();
Chris@16 2028
Chris@16 2029 const_iterator i1 = x.begin();
Chris@16 2030 const_iterator i2 = y.begin();
Chris@16 2031 if(C){
Chris@16 2032 while (i1 != end1 && *i1 == *i2) {
Chris@16 2033 ++i1;
Chris@16 2034 ++i2;
Chris@16 2035 }
Chris@16 2036 return i1 == end1;
Chris@16 2037 }
Chris@16 2038 else{
Chris@16 2039 const_iterator end2 = y.end();
Chris@16 2040 while (i1 != end1 && i2 != end2 && *i1 == *i2) {
Chris@16 2041 ++i1;
Chris@16 2042 ++i2;
Chris@16 2043 }
Chris@16 2044 return i1 == end1 && i2 == end2;
Chris@16 2045 }
Chris@16 2046 }
Chris@16 2047
Chris@16 2048 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
Chris@16 2049 template<class T, class ...Options>
Chris@16 2050 #else
Chris@16 2051 template<class ValueTraits, class SizeType, std::size_t BoolFlags>
Chris@16 2052 #endif
Chris@16 2053 inline bool operator!=
Chris@16 2054 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
Chris@16 2055 (const slist_impl<T, Options...> &x, const slist_impl<T, Options...> &y)
Chris@16 2056 #else
Chris@16 2057 ( const slist_impl<ValueTraits, SizeType, BoolFlags> &x
Chris@16 2058 , const slist_impl<ValueTraits, SizeType, BoolFlags> &y)
Chris@16 2059 #endif
Chris@16 2060 { return !(x == y); }
Chris@16 2061
Chris@16 2062 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
Chris@16 2063 template<class T, class ...Options>
Chris@16 2064 #else
Chris@16 2065 template<class ValueTraits, class SizeType, std::size_t BoolFlags>
Chris@16 2066 #endif
Chris@16 2067 inline bool operator>
Chris@16 2068 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
Chris@16 2069 (const slist_impl<T, Options...> &x, const slist_impl<T, Options...> &y)
Chris@16 2070 #else
Chris@16 2071 ( const slist_impl<ValueTraits, SizeType, BoolFlags> &x
Chris@16 2072 , const slist_impl<ValueTraits, SizeType, BoolFlags> &y)
Chris@16 2073 #endif
Chris@16 2074 { return y < x; }
Chris@16 2075
Chris@16 2076 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
Chris@16 2077 template<class T, class ...Options>
Chris@16 2078 #else
Chris@16 2079 template<class ValueTraits, class SizeType, std::size_t BoolFlags>
Chris@16 2080 #endif
Chris@16 2081 inline bool operator<=
Chris@16 2082 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
Chris@16 2083 (const slist_impl<T, Options...> &x, const slist_impl<T, Options...> &y)
Chris@16 2084 #else
Chris@16 2085 ( const slist_impl<ValueTraits, SizeType, BoolFlags> &x
Chris@16 2086 , const slist_impl<ValueTraits, SizeType, BoolFlags> &y)
Chris@16 2087 #endif
Chris@16 2088 { return !(y < x); }
Chris@16 2089
Chris@16 2090 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
Chris@16 2091 template<class T, class ...Options>
Chris@16 2092 #else
Chris@16 2093 template<class ValueTraits, class SizeType, std::size_t BoolFlags>
Chris@16 2094 #endif
Chris@16 2095 inline bool operator>=
Chris@16 2096 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
Chris@16 2097 (const slist_impl<T, Options...> &x, const slist_impl<T, Options...> &y)
Chris@16 2098 #else
Chris@16 2099 ( const slist_impl<ValueTraits, SizeType, BoolFlags> &x
Chris@16 2100 , const slist_impl<ValueTraits, SizeType, BoolFlags> &y)
Chris@16 2101 #endif
Chris@16 2102 { return !(x < y); }
Chris@16 2103
Chris@16 2104 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
Chris@16 2105 template<class T, class ...Options>
Chris@16 2106 #else
Chris@16 2107 template<class ValueTraits, class SizeType, std::size_t BoolFlags>
Chris@16 2108 #endif
Chris@16 2109 inline void swap
Chris@16 2110 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
Chris@16 2111 (slist_impl<T, Options...> &x, slist_impl<T, Options...> &y)
Chris@16 2112 #else
Chris@16 2113 ( slist_impl<ValueTraits, SizeType, BoolFlags> &x
Chris@16 2114 , slist_impl<ValueTraits, SizeType, BoolFlags> &y)
Chris@16 2115 #endif
Chris@16 2116 { x.swap(y); }
Chris@16 2117
Chris@16 2118 //! Helper metafunction to define a \c slist that yields to the same type when the
Chris@16 2119 //! same options (either explicitly or implicitly) are used.
Chris@16 2120 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
Chris@16 2121 template<class T, class ...Options>
Chris@16 2122 #else
Chris@16 2123 template<class T, class O1 = void, class O2 = void, class O3 = void, class O4 = void, class O5 = void>
Chris@16 2124 #endif
Chris@16 2125 struct make_slist
Chris@16 2126 {
Chris@16 2127 /// @cond
Chris@16 2128 typedef typename pack_options
Chris@16 2129 < slist_defaults,
Chris@16 2130 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
Chris@16 2131 O1, O2, O3, O4, O5
Chris@16 2132 #else
Chris@16 2133 Options...
Chris@16 2134 #endif
Chris@16 2135 >::type packed_options;
Chris@16 2136 typedef typename detail::get_value_traits
Chris@16 2137 <T, typename packed_options::proto_value_traits>::type value_traits;
Chris@16 2138 typedef slist_impl
Chris@16 2139 < value_traits
Chris@16 2140 , typename packed_options::size_type
Chris@16 2141 , (std::size_t(packed_options::linear)*slist_bool_flags::linear_pos)
Chris@16 2142 |(std::size_t(packed_options::constant_time_size)*slist_bool_flags::constant_time_size_pos)
Chris@16 2143 |(std::size_t(packed_options::cache_last)*slist_bool_flags::cache_last_pos)
Chris@16 2144 > implementation_defined;
Chris@16 2145 /// @endcond
Chris@16 2146 typedef implementation_defined type;
Chris@16 2147 };
Chris@16 2148
Chris@16 2149
Chris@16 2150 #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
Chris@16 2151
Chris@16 2152 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
Chris@16 2153 template<class T, class O1, class O2, class O3, class O4, class O5>
Chris@16 2154 #else
Chris@16 2155 template<class T, class ...Options>
Chris@16 2156 #endif
Chris@16 2157 class slist
Chris@16 2158 : public make_slist<T,
Chris@16 2159 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
Chris@16 2160 O1, O2, O3, O4, O5
Chris@16 2161 #else
Chris@16 2162 Options...
Chris@16 2163 #endif
Chris@16 2164 >::type
Chris@16 2165 {
Chris@16 2166 typedef typename make_slist
Chris@16 2167 <T,
Chris@16 2168 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
Chris@16 2169 O1, O2, O3, O4, O5
Chris@16 2170 #else
Chris@16 2171 Options...
Chris@16 2172 #endif
Chris@16 2173 >::type Base;
Chris@16 2174 typedef typename Base::real_value_traits real_value_traits;
Chris@16 2175 //Assert if passed value traits are compatible with the type
Chris@16 2176 BOOST_STATIC_ASSERT((detail::is_same<typename real_value_traits::value_type, T>::value));
Chris@16 2177 BOOST_MOVABLE_BUT_NOT_COPYABLE(slist)
Chris@16 2178
Chris@16 2179 public:
Chris@16 2180 typedef typename Base::value_traits value_traits;
Chris@16 2181 typedef typename Base::iterator iterator;
Chris@16 2182 typedef typename Base::const_iterator const_iterator;
Chris@16 2183 typedef typename Base::size_type size_type;
Chris@16 2184 typedef typename Base::node_ptr node_ptr;
Chris@16 2185
Chris@16 2186 explicit slist(const value_traits &v_traits = value_traits())
Chris@16 2187 : Base(v_traits)
Chris@16 2188 {}
Chris@16 2189
Chris@16 2190 struct incorporate_t{};
Chris@16 2191
Chris@16 2192 slist( const node_ptr & f, const node_ptr & before_l
Chris@16 2193 , size_type n, const value_traits &v_traits = value_traits())
Chris@16 2194 : Base(f, before_l, n, v_traits)
Chris@16 2195 {}
Chris@16 2196
Chris@16 2197 template<class Iterator>
Chris@16 2198 slist(Iterator b, Iterator e, const value_traits &v_traits = value_traits())
Chris@16 2199 : Base(b, e, v_traits)
Chris@16 2200 {}
Chris@16 2201
Chris@16 2202 slist(BOOST_RV_REF(slist) x)
Chris@16 2203 : Base(::boost::move(static_cast<Base&>(x)))
Chris@16 2204 {}
Chris@16 2205
Chris@16 2206 slist& operator=(BOOST_RV_REF(slist) x)
Chris@16 2207 { return static_cast<slist &>(this->Base::operator=(::boost::move(static_cast<Base&>(x)))); }
Chris@16 2208
Chris@16 2209 static slist &container_from_end_iterator(iterator end_iterator)
Chris@16 2210 { return static_cast<slist &>(Base::container_from_end_iterator(end_iterator)); }
Chris@16 2211
Chris@16 2212 static const slist &container_from_end_iterator(const_iterator end_iterator)
Chris@16 2213 { return static_cast<const slist &>(Base::container_from_end_iterator(end_iterator)); }
Chris@16 2214 };
Chris@16 2215
Chris@16 2216 #endif
Chris@16 2217
Chris@16 2218 } //namespace intrusive
Chris@16 2219 } //namespace boost
Chris@16 2220
Chris@16 2221 #include <boost/intrusive/detail/config_end.hpp>
Chris@16 2222
Chris@16 2223 #endif //BOOST_INTRUSIVE_SLIST_HPP