annotate DEPENDENCIES/generic/include/boost/intrusive/list.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_LIST_HPP
Chris@16 15 #define BOOST_INTRUSIVE_LIST_HPP
Chris@16 16
Chris@16 17 #include <boost/intrusive/detail/config_begin.hpp>
Chris@16 18 #include <boost/intrusive/detail/assert.hpp>
Chris@16 19 #include <boost/intrusive/intrusive_fwd.hpp>
Chris@16 20 #include <boost/intrusive/list_hook.hpp>
Chris@16 21 #include <boost/intrusive/circular_list_algorithms.hpp>
Chris@16 22 #include <boost/intrusive/pointer_traits.hpp>
Chris@16 23 #include <boost/intrusive/detail/clear_on_destructor_base.hpp>
Chris@16 24 #include <boost/intrusive/detail/mpl.hpp>
Chris@16 25 #include <boost/intrusive/link_mode.hpp>
Chris@16 26 #include <boost/static_assert.hpp>
Chris@16 27 #include <boost/intrusive/options.hpp>
Chris@16 28 #include <boost/intrusive/pointer_traits.hpp>
Chris@16 29 #include <boost/intrusive/detail/utilities.hpp>
Chris@16 30 #include <iterator>
Chris@16 31 #include <algorithm>
Chris@16 32 #include <functional>
Chris@16 33 #include <cstddef>
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 struct list_defaults
Chris@16 42 {
Chris@16 43 typedef detail::default_list_hook proto_value_traits;
Chris@16 44 static const bool constant_time_size = true;
Chris@16 45 typedef std::size_t size_type;
Chris@16 46 };
Chris@16 47
Chris@16 48 /// @endcond
Chris@16 49
Chris@16 50 //! The class template list is an intrusive container that mimics most of the
Chris@16 51 //! interface of std::list as described in the C++ standard.
Chris@16 52 //!
Chris@16 53 //! The template parameter \c T is the type to be managed by the container.
Chris@16 54 //! The user can specify additional options and if no options are provided
Chris@16 55 //! default options are used.
Chris@16 56 //!
Chris@16 57 //! The container supports the following options:
Chris@16 58 //! \c base_hook<>/member_hook<>/value_traits<>,
Chris@16 59 //! \c constant_time_size<> and \c size_type<>.
Chris@16 60 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
Chris@16 61 template<class T, class ...Options>
Chris@16 62 #else
Chris@16 63 template <class ValueTraits, class SizeType, bool ConstantTimeSize>
Chris@16 64 #endif
Chris@16 65 class list_impl
Chris@16 66 : private detail::clear_on_destructor_base
Chris@16 67 < list_impl<ValueTraits, SizeType, ConstantTimeSize>
Chris@16 68 , is_safe_autounlink<detail::get_real_value_traits<ValueTraits>::type::link_mode>::value
Chris@16 69 >
Chris@16 70 {
Chris@16 71 template<class C, bool> friend class detail::clear_on_destructor_base;
Chris@16 72 //Public typedefs
Chris@16 73 public:
Chris@16 74 typedef ValueTraits value_traits;
Chris@16 75 /// @cond
Chris@16 76 static const bool external_value_traits =
Chris@16 77 detail::external_value_traits_bool_is_true<value_traits>::value;
Chris@16 78 typedef typename detail::get_real_value_traits<ValueTraits>::type real_value_traits;
Chris@16 79 /// @endcond
Chris@16 80 typedef typename real_value_traits::pointer pointer;
Chris@16 81 typedef typename real_value_traits::const_pointer const_pointer;
Chris@16 82 typedef typename pointer_traits<pointer>::element_type value_type;
Chris@16 83 typedef typename pointer_traits<pointer>::reference reference;
Chris@16 84 typedef typename pointer_traits<const_pointer>::reference const_reference;
Chris@16 85 typedef typename pointer_traits<pointer>::difference_type difference_type;
Chris@16 86 typedef SizeType size_type;
Chris@16 87 typedef list_iterator<real_value_traits, false> iterator;
Chris@16 88 typedef list_iterator<real_value_traits, true> const_iterator;
Chris@16 89 typedef boost::intrusive::detail::reverse_iterator<iterator> reverse_iterator;
Chris@16 90 typedef boost::intrusive::detail::reverse_iterator<const_iterator>const_reverse_iterator;
Chris@16 91 typedef typename real_value_traits::node_traits node_traits;
Chris@16 92 typedef typename node_traits::node node;
Chris@16 93 typedef typename node_traits::node_ptr node_ptr;
Chris@16 94 typedef typename node_traits::const_node_ptr const_node_ptr;
Chris@16 95 typedef circular_list_algorithms<node_traits> node_algorithms;
Chris@16 96
Chris@16 97 static const bool constant_time_size = ConstantTimeSize;
Chris@16 98 static const bool stateful_value_traits = detail::is_stateful_value_traits<real_value_traits>::value;
Chris@16 99
Chris@16 100 /// @cond
Chris@16 101
Chris@16 102 private:
Chris@16 103 typedef detail::size_holder<constant_time_size, size_type> size_traits;
Chris@16 104
Chris@16 105 //noncopyable
Chris@16 106 BOOST_MOVABLE_BUT_NOT_COPYABLE(list_impl)
Chris@16 107
Chris@16 108 static const bool safemode_or_autounlink = is_safe_autounlink<real_value_traits::link_mode>::value;
Chris@16 109
Chris@16 110 //Constant-time size is incompatible with auto-unlink hooks!
Chris@16 111 BOOST_STATIC_ASSERT(!(constant_time_size &&
Chris@16 112 ((int)real_value_traits::link_mode == (int)auto_unlink)
Chris@16 113 ));
Chris@16 114
Chris@16 115 node_ptr get_root_node()
Chris@16 116 { return pointer_traits<node_ptr>::pointer_to(data_.root_plus_size_.root_); }
Chris@16 117
Chris@16 118 const_node_ptr get_root_node() const
Chris@16 119 { return pointer_traits<const_node_ptr>::pointer_to(data_.root_plus_size_.root_); }
Chris@16 120
Chris@16 121 struct root_plus_size : public size_traits
Chris@16 122 {
Chris@16 123 node root_;
Chris@16 124 };
Chris@16 125
Chris@16 126 struct data_t : public value_traits
Chris@16 127 {
Chris@16 128 typedef typename list_impl::value_traits value_traits;
Chris@16 129 explicit data_t(const value_traits &val_traits)
Chris@16 130 : value_traits(val_traits)
Chris@16 131 {}
Chris@16 132
Chris@16 133 root_plus_size root_plus_size_;
Chris@16 134 } data_;
Chris@16 135
Chris@16 136 size_traits &priv_size_traits()
Chris@16 137 { return data_.root_plus_size_; }
Chris@16 138
Chris@16 139 const size_traits &priv_size_traits() const
Chris@16 140 { return data_.root_plus_size_; }
Chris@16 141
Chris@16 142 const real_value_traits &get_real_value_traits(detail::bool_<false>) const
Chris@16 143 { return data_; }
Chris@16 144
Chris@16 145 const real_value_traits &get_real_value_traits(detail::bool_<true>) const
Chris@16 146 { return data_.get_value_traits(*this); }
Chris@16 147
Chris@16 148 real_value_traits &get_real_value_traits(detail::bool_<false>)
Chris@16 149 { return data_; }
Chris@16 150
Chris@16 151 real_value_traits &get_real_value_traits(detail::bool_<true>)
Chris@16 152 { return data_.get_value_traits(*this); }
Chris@16 153
Chris@16 154 const value_traits &priv_value_traits() const
Chris@16 155 { return data_; }
Chris@16 156
Chris@16 157 value_traits &priv_value_traits()
Chris@16 158 { return data_; }
Chris@16 159
Chris@16 160 protected:
Chris@16 161 node &prot_root_node()
Chris@16 162 { return data_.root_plus_size_.root_; }
Chris@16 163
Chris@16 164 node const &prot_root_node() const
Chris@16 165 { return data_.root_plus_size_.root_; }
Chris@16 166
Chris@16 167 void prot_set_size(size_type s)
Chris@16 168 { data_.root_plus_size_.set_size(s); }
Chris@16 169
Chris@16 170 /// @endcond
Chris@16 171
Chris@16 172 public:
Chris@16 173
Chris@16 174 const real_value_traits &get_real_value_traits() const
Chris@16 175 { return this->get_real_value_traits(detail::bool_<external_value_traits>()); }
Chris@16 176
Chris@16 177 real_value_traits &get_real_value_traits()
Chris@16 178 { return this->get_real_value_traits(detail::bool_<external_value_traits>()); }
Chris@16 179
Chris@16 180 typedef typename pointer_traits<node_ptr>::template rebind_pointer<real_value_traits const>::type const_real_value_traits_ptr;
Chris@16 181
Chris@16 182 const_real_value_traits_ptr real_value_traits_ptr() const
Chris@16 183 { return pointer_traits<const_real_value_traits_ptr>::pointer_to(this->get_real_value_traits()); }
Chris@16 184
Chris@16 185 //! <b>Effects</b>: constructs an empty list.
Chris@16 186 //!
Chris@16 187 //! <b>Complexity</b>: Constant
Chris@16 188 //!
Chris@16 189 //! <b>Throws</b>: If real_value_traits::node_traits::node
Chris@16 190 //! constructor throws (this does not happen with predefined Boost.Intrusive hooks).
Chris@16 191 explicit list_impl(const value_traits &v_traits = value_traits())
Chris@16 192 : data_(v_traits)
Chris@16 193 {
Chris@16 194 this->priv_size_traits().set_size(size_type(0));
Chris@16 195 node_algorithms::init_header(this->get_root_node());
Chris@16 196 }
Chris@16 197
Chris@16 198 //! <b>Requires</b>: Dereferencing iterator must yield an lvalue of type value_type.
Chris@16 199 //!
Chris@16 200 //! <b>Effects</b>: Constructs a list equal to the range [first,last).
Chris@16 201 //!
Chris@16 202 //! <b>Complexity</b>: Linear in std::distance(b, e). No copy constructors are called.
Chris@16 203 //!
Chris@16 204 //! <b>Throws</b>: If real_value_traits::node_traits::node
Chris@16 205 //! constructor throws (this does not happen with predefined Boost.Intrusive hooks).
Chris@16 206 template<class Iterator>
Chris@16 207 list_impl(Iterator b, Iterator e, const value_traits &v_traits = value_traits())
Chris@16 208 : data_(v_traits)
Chris@16 209 {
Chris@16 210 this->priv_size_traits().set_size(size_type(0));
Chris@16 211 node_algorithms::init_header(this->get_root_node());
Chris@16 212 this->insert(this->cend(), b, e);
Chris@16 213 }
Chris@16 214
Chris@16 215 //! <b>Effects</b>: to-do
Chris@16 216 //!
Chris@16 217 list_impl(BOOST_RV_REF(list_impl) x)
Chris@16 218 : data_(::boost::move(x.priv_value_traits()))
Chris@16 219 {
Chris@16 220 this->priv_size_traits().set_size(size_type(0));
Chris@16 221 node_algorithms::init_header(this->get_root_node());
Chris@16 222 this->swap(x);
Chris@16 223 }
Chris@16 224
Chris@16 225 //! <b>Effects</b>: to-do
Chris@16 226 //!
Chris@16 227 list_impl& operator=(BOOST_RV_REF(list_impl) x)
Chris@16 228 { this->swap(x); return *this; }
Chris@16 229
Chris@16 230 #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
Chris@16 231 //! <b>Effects</b>: If it's not a safe-mode or an auto-unlink value_type
Chris@16 232 //! the destructor does nothing
Chris@16 233 //! (ie. no code is generated). Otherwise it detaches all elements from this.
Chris@16 234 //! In this case the objects in the list are not deleted (i.e. no destructors
Chris@16 235 //! are called), but the hooks according to the ValueTraits template parameter
Chris@16 236 //! are set to their default value.
Chris@16 237 //!
Chris@16 238 //! <b>Complexity</b>: Linear to the number of elements in the list, if
Chris@16 239 //! it's a safe-mode or auto-unlink value . Otherwise constant.
Chris@16 240 ~list_impl()
Chris@16 241 {}
Chris@16 242 #endif
Chris@16 243
Chris@16 244 //! <b>Requires</b>: value must be an lvalue.
Chris@16 245 //!
Chris@16 246 //! <b>Effects</b>: Inserts the value in the back of the list.
Chris@16 247 //! No copy constructors are called.
Chris@16 248 //!
Chris@16 249 //! <b>Throws</b>: Nothing.
Chris@16 250 //!
Chris@16 251 //! <b>Complexity</b>: Constant.
Chris@16 252 //!
Chris@16 253 //! <b>Note</b>: Does not affect the validity of iterators and references.
Chris@16 254 void push_back(reference value)
Chris@16 255 {
Chris@16 256 node_ptr to_insert = get_real_value_traits().to_node_ptr(value);
Chris@16 257 if(safemode_or_autounlink)
Chris@16 258 BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::inited(to_insert));
Chris@16 259 node_algorithms::link_before(this->get_root_node(), to_insert);
Chris@16 260 this->priv_size_traits().increment();
Chris@16 261 }
Chris@16 262
Chris@16 263 //! <b>Requires</b>: value must be an lvalue.
Chris@16 264 //!
Chris@16 265 //! <b>Effects</b>: Inserts the value in the front of the list.
Chris@16 266 //! No copy constructors are called.
Chris@16 267 //!
Chris@16 268 //! <b>Throws</b>: Nothing.
Chris@16 269 //!
Chris@16 270 //! <b>Complexity</b>: Constant.
Chris@16 271 //!
Chris@16 272 //! <b>Note</b>: Does not affect the validity of iterators and references.
Chris@16 273 void push_front(reference value)
Chris@16 274 {
Chris@16 275 node_ptr to_insert = get_real_value_traits().to_node_ptr(value);
Chris@16 276 if(safemode_or_autounlink)
Chris@16 277 BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::inited(to_insert));
Chris@16 278 node_algorithms::link_before(node_traits::get_next(this->get_root_node()), to_insert);
Chris@16 279 this->priv_size_traits().increment();
Chris@16 280 }
Chris@16 281
Chris@16 282 //! <b>Effects</b>: Erases the last element of the list.
Chris@16 283 //! No destructors are called.
Chris@16 284 //!
Chris@16 285 //! <b>Throws</b>: Nothing.
Chris@16 286 //!
Chris@16 287 //! <b>Complexity</b>: Constant.
Chris@16 288 //!
Chris@16 289 //! <b>Note</b>: Invalidates the iterators (but not the references) to the erased element.
Chris@16 290 void pop_back()
Chris@16 291 { return this->pop_back_and_dispose(detail::null_disposer()); }
Chris@16 292
Chris@16 293 //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
Chris@16 294 //!
Chris@16 295 //! <b>Effects</b>: Erases the last element of the list.
Chris@16 296 //! No destructors are called.
Chris@16 297 //! Disposer::operator()(pointer) is called for the removed element.
Chris@16 298 //!
Chris@16 299 //! <b>Throws</b>: Nothing.
Chris@16 300 //!
Chris@16 301 //! <b>Complexity</b>: Constant.
Chris@16 302 //!
Chris@16 303 //! <b>Note</b>: Invalidates the iterators to the erased element.
Chris@16 304 template<class Disposer>
Chris@16 305 void pop_back_and_dispose(Disposer disposer)
Chris@16 306 {
Chris@16 307 node_ptr to_erase = node_traits::get_previous(this->get_root_node());
Chris@16 308 node_algorithms::unlink(to_erase);
Chris@16 309 this->priv_size_traits().decrement();
Chris@16 310 if(safemode_or_autounlink)
Chris@16 311 node_algorithms::init(to_erase);
Chris@16 312 disposer(get_real_value_traits().to_value_ptr(to_erase));
Chris@16 313 }
Chris@16 314
Chris@16 315 //! <b>Effects</b>: Erases the first element of the list.
Chris@16 316 //! No destructors are called.
Chris@16 317 //!
Chris@16 318 //! <b>Throws</b>: Nothing.
Chris@16 319 //!
Chris@16 320 //! <b>Complexity</b>: Constant.
Chris@16 321 //!
Chris@16 322 //! <b>Note</b>: Invalidates the iterators (but not the references) to the erased element.
Chris@16 323 void pop_front()
Chris@16 324 { return this->pop_front_and_dispose(detail::null_disposer()); }
Chris@16 325
Chris@16 326 //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
Chris@16 327 //!
Chris@16 328 //! <b>Effects</b>: Erases the first element of the list.
Chris@16 329 //! No destructors are called.
Chris@16 330 //! Disposer::operator()(pointer) is called for the removed element.
Chris@16 331 //!
Chris@16 332 //! <b>Throws</b>: Nothing.
Chris@16 333 //!
Chris@16 334 //! <b>Complexity</b>: Constant.
Chris@16 335 //!
Chris@16 336 //! <b>Note</b>: Invalidates the iterators to the erased element.
Chris@16 337 template<class Disposer>
Chris@16 338 void pop_front_and_dispose(Disposer disposer)
Chris@16 339 {
Chris@16 340 node_ptr to_erase = node_traits::get_next(this->get_root_node());
Chris@16 341 node_algorithms::unlink(to_erase);
Chris@16 342 this->priv_size_traits().decrement();
Chris@16 343 if(safemode_or_autounlink)
Chris@16 344 node_algorithms::init(to_erase);
Chris@16 345 disposer(get_real_value_traits().to_value_ptr(to_erase));
Chris@16 346 }
Chris@16 347
Chris@16 348 //! <b>Effects</b>: Returns a reference to the first element of the list.
Chris@16 349 //!
Chris@16 350 //! <b>Throws</b>: Nothing.
Chris@16 351 //!
Chris@16 352 //! <b>Complexity</b>: Constant.
Chris@16 353 reference front()
Chris@16 354 { return *get_real_value_traits().to_value_ptr(node_traits::get_next(this->get_root_node())); }
Chris@16 355
Chris@16 356 //! <b>Effects</b>: Returns a const_reference to the first element of the list.
Chris@16 357 //!
Chris@16 358 //! <b>Throws</b>: Nothing.
Chris@16 359 //!
Chris@16 360 //! <b>Complexity</b>: Constant.
Chris@16 361 const_reference front() const
Chris@16 362 { return *get_real_value_traits().to_value_ptr(detail::uncast(node_traits::get_next(this->get_root_node()))); }
Chris@16 363
Chris@16 364 //! <b>Effects</b>: Returns a reference to the last element of the list.
Chris@16 365 //!
Chris@16 366 //! <b>Throws</b>: Nothing.
Chris@16 367 //!
Chris@16 368 //! <b>Complexity</b>: Constant.
Chris@16 369 reference back()
Chris@16 370 { return *get_real_value_traits().to_value_ptr(node_traits::get_previous(this->get_root_node())); }
Chris@16 371
Chris@16 372 //! <b>Effects</b>: Returns a const_reference to the last element of the list.
Chris@16 373 //!
Chris@16 374 //! <b>Throws</b>: Nothing.
Chris@16 375 //!
Chris@16 376 //! <b>Complexity</b>: Constant.
Chris@16 377 const_reference back() const
Chris@16 378 { return *get_real_value_traits().to_value_ptr(detail::uncast(node_traits::get_previous(this->get_root_node()))); }
Chris@16 379
Chris@16 380 //! <b>Effects</b>: Returns an iterator to the first element contained in the list.
Chris@16 381 //!
Chris@16 382 //! <b>Throws</b>: Nothing.
Chris@16 383 //!
Chris@16 384 //! <b>Complexity</b>: Constant.
Chris@16 385 iterator begin()
Chris@16 386 { return iterator(node_traits::get_next(this->get_root_node()), real_value_traits_ptr()); }
Chris@16 387
Chris@16 388 //! <b>Effects</b>: Returns a const_iterator to the first element contained in the list.
Chris@16 389 //!
Chris@16 390 //! <b>Throws</b>: Nothing.
Chris@16 391 //!
Chris@16 392 //! <b>Complexity</b>: Constant.
Chris@16 393 const_iterator begin() const
Chris@16 394 { return this->cbegin(); }
Chris@16 395
Chris@16 396 //! <b>Effects</b>: Returns a const_iterator to the first element contained in the list.
Chris@16 397 //!
Chris@16 398 //! <b>Throws</b>: Nothing.
Chris@16 399 //!
Chris@16 400 //! <b>Complexity</b>: Constant.
Chris@16 401 const_iterator cbegin() const
Chris@16 402 { return const_iterator(node_traits::get_next(this->get_root_node()), real_value_traits_ptr()); }
Chris@16 403
Chris@16 404 //! <b>Effects</b>: Returns an iterator to the end of the list.
Chris@16 405 //!
Chris@16 406 //! <b>Throws</b>: Nothing.
Chris@16 407 //!
Chris@16 408 //! <b>Complexity</b>: Constant.
Chris@16 409 iterator end()
Chris@16 410 { return iterator(this->get_root_node(), real_value_traits_ptr()); }
Chris@16 411
Chris@16 412 //! <b>Effects</b>: Returns a const_iterator to the end of the list.
Chris@16 413 //!
Chris@16 414 //! <b>Throws</b>: Nothing.
Chris@16 415 //!
Chris@16 416 //! <b>Complexity</b>: Constant.
Chris@16 417 const_iterator end() const
Chris@16 418 { return this->cend(); }
Chris@16 419
Chris@16 420 //! <b>Effects</b>: Returns a constant iterator to the end of the list.
Chris@16 421 //!
Chris@16 422 //! <b>Throws</b>: Nothing.
Chris@16 423 //!
Chris@16 424 //! <b>Complexity</b>: Constant.
Chris@16 425 const_iterator cend() const
Chris@16 426 { return const_iterator(detail::uncast(this->get_root_node()), real_value_traits_ptr()); }
Chris@16 427
Chris@16 428 //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
Chris@16 429 //! of the reversed list.
Chris@16 430 //!
Chris@16 431 //! <b>Throws</b>: Nothing.
Chris@16 432 //!
Chris@16 433 //! <b>Complexity</b>: Constant.
Chris@16 434 reverse_iterator rbegin()
Chris@16 435 { return reverse_iterator(this->end()); }
Chris@16 436
Chris@16 437 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
Chris@16 438 //! of the reversed list.
Chris@16 439 //!
Chris@16 440 //! <b>Throws</b>: Nothing.
Chris@16 441 //!
Chris@16 442 //! <b>Complexity</b>: Constant.
Chris@16 443 const_reverse_iterator rbegin() const
Chris@16 444 { return this->crbegin(); }
Chris@16 445
Chris@16 446 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
Chris@16 447 //! of the reversed list.
Chris@16 448 //!
Chris@16 449 //! <b>Throws</b>: Nothing.
Chris@16 450 //!
Chris@16 451 //! <b>Complexity</b>: Constant.
Chris@16 452 const_reverse_iterator crbegin() const
Chris@16 453 { return const_reverse_iterator(end()); }
Chris@16 454
Chris@16 455 //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
Chris@16 456 //! of the reversed list.
Chris@16 457 //!
Chris@16 458 //! <b>Throws</b>: Nothing.
Chris@16 459 //!
Chris@16 460 //! <b>Complexity</b>: Constant.
Chris@16 461 reverse_iterator rend()
Chris@16 462 { return reverse_iterator(begin()); }
Chris@16 463
Chris@16 464 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
Chris@16 465 //! of the reversed list.
Chris@16 466 //!
Chris@16 467 //! <b>Throws</b>: Nothing.
Chris@16 468 //!
Chris@16 469 //! <b>Complexity</b>: Constant.
Chris@16 470 const_reverse_iterator rend() const
Chris@16 471 { return this->crend(); }
Chris@16 472
Chris@16 473 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
Chris@16 474 //! of the reversed list.
Chris@16 475 //!
Chris@16 476 //! <b>Throws</b>: Nothing.
Chris@16 477 //!
Chris@16 478 //! <b>Complexity</b>: Constant.
Chris@16 479 const_reverse_iterator crend() const
Chris@16 480 { return const_reverse_iterator(this->begin()); }
Chris@16 481
Chris@16 482 //! <b>Precondition</b>: end_iterator must be a valid end iterator
Chris@16 483 //! of list.
Chris@16 484 //!
Chris@16 485 //! <b>Effects</b>: Returns a const reference to the list associated to the end iterator
Chris@16 486 //!
Chris@16 487 //! <b>Throws</b>: Nothing.
Chris@16 488 //!
Chris@16 489 //! <b>Complexity</b>: Constant.
Chris@16 490 static list_impl &container_from_end_iterator(iterator end_iterator)
Chris@16 491 { return list_impl::priv_container_from_end_iterator(end_iterator); }
Chris@16 492
Chris@16 493 //! <b>Precondition</b>: end_iterator must be a valid end const_iterator
Chris@16 494 //! of list.
Chris@16 495 //!
Chris@16 496 //! <b>Effects</b>: Returns a const reference to the list associated to the end iterator
Chris@16 497 //!
Chris@16 498 //! <b>Throws</b>: Nothing.
Chris@16 499 //!
Chris@16 500 //! <b>Complexity</b>: Constant.
Chris@16 501 static const list_impl &container_from_end_iterator(const_iterator end_iterator)
Chris@16 502 { return list_impl::priv_container_from_end_iterator(end_iterator); }
Chris@16 503
Chris@16 504 //! <b>Effects</b>: Returns the number of the elements contained in the list.
Chris@16 505 //!
Chris@16 506 //! <b>Throws</b>: Nothing.
Chris@16 507 //!
Chris@16 508 //! <b>Complexity</b>: Linear to the number of elements contained in the list.
Chris@16 509 //! if constant-time size option is disabled. Constant time otherwise.
Chris@16 510 //!
Chris@16 511 //! <b>Note</b>: Does not affect the validity of iterators and references.
Chris@16 512 size_type size() const
Chris@16 513 {
Chris@16 514 if(constant_time_size)
Chris@16 515 return this->priv_size_traits().get_size();
Chris@16 516 else
Chris@16 517 return node_algorithms::count(this->get_root_node()) - 1;
Chris@16 518 }
Chris@16 519
Chris@16 520 //! <b>Effects</b>: Returns true if the list contains no elements.
Chris@16 521 //!
Chris@16 522 //! <b>Throws</b>: Nothing.
Chris@16 523 //!
Chris@16 524 //! <b>Complexity</b>: Constant.
Chris@16 525 //!
Chris@16 526 //! <b>Note</b>: Does not affect the validity of iterators and references.
Chris@16 527 bool empty() const
Chris@16 528 { return node_algorithms::unique(this->get_root_node()); }
Chris@16 529
Chris@16 530 //! <b>Effects</b>: Swaps the elements of x and *this.
Chris@16 531 //!
Chris@16 532 //! <b>Throws</b>: Nothing.
Chris@16 533 //!
Chris@16 534 //! <b>Complexity</b>: Constant.
Chris@16 535 //!
Chris@16 536 //! <b>Note</b>: Does not affect the validity of iterators and references.
Chris@16 537 void swap(list_impl& other)
Chris@16 538 {
Chris@16 539 node_algorithms::swap_nodes(this->get_root_node(), other.get_root_node());
Chris@16 540 if(constant_time_size){
Chris@16 541 size_type backup = this->priv_size_traits().get_size();
Chris@16 542 this->priv_size_traits().set_size(other.priv_size_traits().get_size());
Chris@16 543 other.priv_size_traits().set_size(backup);
Chris@16 544 }
Chris@16 545 }
Chris@16 546
Chris@16 547 //! <b>Effects</b>: Moves backwards all the elements, so that the first
Chris@16 548 //! element becomes the second, the second becomes the third...
Chris@16 549 //! the last element becomes the first one.
Chris@16 550 //!
Chris@16 551 //! <b>Throws</b>: Nothing.
Chris@16 552 //!
Chris@16 553 //! <b>Complexity</b>: Linear to the number of shifts.
Chris@16 554 //!
Chris@16 555 //! <b>Note</b>: Does not affect the validity of iterators and references.
Chris@16 556 void shift_backwards(size_type n = 1)
Chris@16 557 { node_algorithms::move_forward(this->get_root_node(), n); }
Chris@16 558
Chris@16 559 //! <b>Effects</b>: Moves forward all the elements, so that the second
Chris@16 560 //! element becomes the first, the third becomes the second...
Chris@16 561 //! the first element becomes the last one.
Chris@16 562 //!
Chris@16 563 //! <b>Throws</b>: Nothing.
Chris@16 564 //!
Chris@16 565 //! <b>Complexity</b>: Linear to the number of shifts.
Chris@16 566 //!
Chris@16 567 //! <b>Note</b>: Does not affect the validity of iterators and references.
Chris@16 568 void shift_forward(size_type n = 1)
Chris@16 569 { node_algorithms::move_backwards(this->get_root_node(), n); }
Chris@16 570
Chris@16 571 //! <b>Effects</b>: Erases the element pointed by i of the list.
Chris@16 572 //! No destructors are called.
Chris@16 573 //!
Chris@16 574 //! <b>Returns</b>: the first element remaining beyond the removed element,
Chris@16 575 //! or end() if no such element exists.
Chris@16 576 //!
Chris@16 577 //! <b>Throws</b>: Nothing.
Chris@16 578 //!
Chris@16 579 //! <b>Complexity</b>: Constant.
Chris@16 580 //!
Chris@16 581 //! <b>Note</b>: Invalidates the iterators (but not the references) to the
Chris@16 582 //! erased element.
Chris@16 583 iterator erase(const_iterator i)
Chris@16 584 { return this->erase_and_dispose(i, detail::null_disposer()); }
Chris@16 585
Chris@16 586 //! <b>Requires</b>: b and e must be valid iterators to elements in *this.
Chris@16 587 //!
Chris@16 588 //! <b>Effects</b>: Erases the element range pointed by b and e
Chris@16 589 //! No destructors are called.
Chris@16 590 //!
Chris@16 591 //! <b>Returns</b>: the first element remaining beyond the removed elements,
Chris@16 592 //! or end() if no such element exists.
Chris@16 593 //!
Chris@16 594 //! <b>Throws</b>: Nothing.
Chris@16 595 //!
Chris@16 596 //! <b>Complexity</b>: Linear to the number of erased elements if it's a safe-mode
Chris@16 597 //! or auto-unlink value, or constant-time size is enabled. Constant-time otherwise.
Chris@16 598 //!
Chris@16 599 //! <b>Note</b>: Invalidates the iterators (but not the references) to the
Chris@16 600 //! erased elements.
Chris@16 601 iterator erase(const_iterator b, const_iterator e)
Chris@16 602 {
Chris@16 603 if(safemode_or_autounlink || constant_time_size){
Chris@16 604 return this->erase_and_dispose(b, e, detail::null_disposer());
Chris@16 605 }
Chris@16 606 else{
Chris@16 607 node_algorithms::unlink(b.pointed_node(), e.pointed_node());
Chris@16 608 return e.unconst();
Chris@16 609 }
Chris@16 610 }
Chris@16 611
Chris@16 612 //! <b>Requires</b>: b and e must be valid iterators to elements in *this.
Chris@16 613 //! n must be std::distance(b, e).
Chris@16 614 //!
Chris@16 615 //! <b>Effects</b>: Erases the element range pointed by b and e
Chris@16 616 //! No destructors are called.
Chris@16 617 //!
Chris@16 618 //! <b>Returns</b>: the first element remaining beyond the removed elements,
Chris@16 619 //! or end() if no such element exists.
Chris@16 620 //!
Chris@16 621 //! <b>Throws</b>: Nothing.
Chris@16 622 //!
Chris@16 623 //! <b>Complexity</b>: Linear to the number of erased elements if it's a safe-mode
Chris@16 624 //! or auto-unlink value is enabled. Constant-time otherwise.
Chris@16 625 //!
Chris@16 626 //! <b>Note</b>: Invalidates the iterators (but not the references) to the
Chris@16 627 //! erased elements.
Chris@16 628 iterator erase(const_iterator b, const_iterator e, difference_type n)
Chris@16 629 {
Chris@16 630 BOOST_INTRUSIVE_INVARIANT_ASSERT(std::distance(b, e) == difference_type(n));
Chris@16 631 if(safemode_or_autounlink || constant_time_size){
Chris@16 632 return this->erase_and_dispose(b, e, detail::null_disposer());
Chris@16 633 }
Chris@16 634 else{
Chris@16 635 if(constant_time_size){
Chris@16 636 this->priv_size_traits().decrease(n);
Chris@16 637 }
Chris@16 638 node_algorithms::unlink(b.pointed_node(), e.pointed_node());
Chris@16 639 return e.unconst();
Chris@16 640 }
Chris@16 641 }
Chris@16 642
Chris@16 643 //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
Chris@16 644 //!
Chris@16 645 //! <b>Effects</b>: Erases the element pointed by i of the list.
Chris@16 646 //! No destructors are called.
Chris@16 647 //! Disposer::operator()(pointer) is called for the removed element.
Chris@16 648 //!
Chris@16 649 //! <b>Returns</b>: the first element remaining beyond the removed element,
Chris@16 650 //! or end() if no such element exists.
Chris@16 651 //!
Chris@16 652 //! <b>Throws</b>: Nothing.
Chris@16 653 //!
Chris@16 654 //! <b>Complexity</b>: Constant.
Chris@16 655 //!
Chris@16 656 //! <b>Note</b>: Invalidates the iterators to the erased element.
Chris@16 657 template <class Disposer>
Chris@16 658 iterator erase_and_dispose(const_iterator i, Disposer disposer)
Chris@16 659 {
Chris@16 660 node_ptr to_erase(i.pointed_node());
Chris@16 661 ++i;
Chris@16 662 node_algorithms::unlink(to_erase);
Chris@16 663 this->priv_size_traits().decrement();
Chris@16 664 if(safemode_or_autounlink)
Chris@16 665 node_algorithms::init(to_erase);
Chris@16 666 disposer(this->get_real_value_traits().to_value_ptr(to_erase));
Chris@16 667 return i.unconst();
Chris@16 668 }
Chris@16 669
Chris@16 670 #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
Chris@16 671 template<class Disposer>
Chris@16 672 iterator erase_and_dispose(iterator i, Disposer disposer)
Chris@16 673 { return this->erase_and_dispose(const_iterator(i), disposer); }
Chris@16 674 #endif
Chris@16 675
Chris@16 676 //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
Chris@16 677 //!
Chris@16 678 //! <b>Effects</b>: Erases the element range pointed by b and e
Chris@16 679 //! No destructors are called.
Chris@16 680 //! Disposer::operator()(pointer) is called for the removed elements.
Chris@16 681 //!
Chris@16 682 //! <b>Returns</b>: the first element remaining beyond the removed elements,
Chris@16 683 //! or end() if no such element exists.
Chris@16 684 //!
Chris@16 685 //! <b>Throws</b>: Nothing.
Chris@16 686 //!
Chris@16 687 //! <b>Complexity</b>: Linear to the number of elements erased.
Chris@16 688 //!
Chris@16 689 //! <b>Note</b>: Invalidates the iterators to the erased elements.
Chris@16 690 template <class Disposer>
Chris@16 691 iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer)
Chris@16 692 {
Chris@16 693 node_ptr bp(b.pointed_node()), ep(e.pointed_node());
Chris@16 694 node_algorithms::unlink(bp, ep);
Chris@16 695 while(bp != ep){
Chris@16 696 node_ptr to_erase(bp);
Chris@16 697 bp = node_traits::get_next(bp);
Chris@16 698 if(safemode_or_autounlink)
Chris@16 699 node_algorithms::init(to_erase);
Chris@16 700 disposer(get_real_value_traits().to_value_ptr(to_erase));
Chris@16 701 this->priv_size_traits().decrement();
Chris@16 702 }
Chris@16 703 return e.unconst();
Chris@16 704 }
Chris@16 705
Chris@16 706 //! <b>Effects</b>: Erases all the elements of the container.
Chris@16 707 //! No destructors are called.
Chris@16 708 //!
Chris@16 709 //! <b>Throws</b>: Nothing.
Chris@16 710 //!
Chris@16 711 //! <b>Complexity</b>: Linear to the number of elements of the list.
Chris@16 712 //! if it's a safe-mode or auto-unlink value_type. Constant time otherwise.
Chris@16 713 //!
Chris@16 714 //! <b>Note</b>: Invalidates the iterators (but not the references) to the erased elements.
Chris@16 715 void clear()
Chris@16 716 {
Chris@16 717 if(safemode_or_autounlink){
Chris@16 718 this->clear_and_dispose(detail::null_disposer());
Chris@16 719 }
Chris@16 720 else{
Chris@16 721 node_algorithms::init_header(this->get_root_node());
Chris@16 722 this->priv_size_traits().set_size(size_type(0));
Chris@16 723 }
Chris@16 724 }
Chris@16 725
Chris@16 726 //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
Chris@16 727 //!
Chris@16 728 //! <b>Effects</b>: Erases all the elements of the container.
Chris@16 729 //! No destructors are called.
Chris@16 730 //! Disposer::operator()(pointer) is called for the removed elements.
Chris@16 731 //!
Chris@16 732 //! <b>Throws</b>: Nothing.
Chris@16 733 //!
Chris@16 734 //! <b>Complexity</b>: Linear to the number of elements of the list.
Chris@16 735 //!
Chris@16 736 //! <b>Note</b>: Invalidates the iterators to the erased elements.
Chris@16 737 template <class Disposer>
Chris@16 738 void clear_and_dispose(Disposer disposer)
Chris@16 739 {
Chris@16 740 const_iterator it(this->begin()), itend(this->end());
Chris@16 741 while(it != itend){
Chris@16 742 node_ptr to_erase(it.pointed_node());
Chris@16 743 ++it;
Chris@16 744 if(safemode_or_autounlink)
Chris@16 745 node_algorithms::init(to_erase);
Chris@16 746 disposer(get_real_value_traits().to_value_ptr(to_erase));
Chris@16 747 }
Chris@16 748 node_algorithms::init_header(this->get_root_node());
Chris@16 749 this->priv_size_traits().set_size(0);
Chris@16 750 }
Chris@16 751
Chris@16 752 //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
Chris@16 753 //! Cloner should yield to nodes equivalent to the original nodes.
Chris@16 754 //!
Chris@16 755 //! <b>Effects</b>: Erases all the elements from *this
Chris@16 756 //! calling Disposer::operator()(pointer), clones all the
Chris@16 757 //! elements from src calling Cloner::operator()(const_reference )
Chris@16 758 //! and inserts them on *this.
Chris@16 759 //!
Chris@16 760 //! If cloner throws, all cloned elements are unlinked and disposed
Chris@16 761 //! calling Disposer::operator()(pointer).
Chris@16 762 //!
Chris@16 763 //! <b>Complexity</b>: Linear to erased plus inserted elements.
Chris@16 764 //!
Chris@16 765 //! <b>Throws</b>: If cloner throws. Basic guarantee.
Chris@16 766 template <class Cloner, class Disposer>
Chris@16 767 void clone_from(const list_impl &src, Cloner cloner, Disposer disposer)
Chris@16 768 {
Chris@16 769 this->clear_and_dispose(disposer);
Chris@16 770 detail::exception_disposer<list_impl, Disposer>
Chris@16 771 rollback(*this, disposer);
Chris@16 772 const_iterator b(src.begin()), e(src.end());
Chris@16 773 for(; b != e; ++b){
Chris@16 774 this->push_back(*cloner(*b));
Chris@16 775 }
Chris@16 776 rollback.release();
Chris@16 777 }
Chris@16 778
Chris@16 779 //! <b>Requires</b>: value must be an lvalue and p must be a valid iterator of *this.
Chris@16 780 //!
Chris@16 781 //! <b>Effects</b>: Inserts the value before the position pointed by p.
Chris@16 782 //!
Chris@16 783 //! <b>Returns</b>: An iterator to the inserted element.
Chris@16 784 //!
Chris@16 785 //! <b>Throws</b>: Nothing.
Chris@16 786 //!
Chris@16 787 //! <b>Complexity</b>: Constant time. No copy constructors are called.
Chris@16 788 //!
Chris@16 789 //! <b>Note</b>: Does not affect the validity of iterators and references.
Chris@16 790 iterator insert(const_iterator p, reference value)
Chris@16 791 {
Chris@16 792 node_ptr to_insert = this->get_real_value_traits().to_node_ptr(value);
Chris@16 793 if(safemode_or_autounlink)
Chris@16 794 BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::inited(to_insert));
Chris@16 795 node_algorithms::link_before(p.pointed_node(), to_insert);
Chris@16 796 this->priv_size_traits().increment();
Chris@16 797 return iterator(to_insert, real_value_traits_ptr());
Chris@16 798 }
Chris@16 799
Chris@16 800 //! <b>Requires</b>: Dereferencing iterator must yield
Chris@16 801 //! an lvalue of type value_type and p must be a valid iterator of *this.
Chris@16 802 //!
Chris@16 803 //! <b>Effects</b>: Inserts the range pointed by b and e before the position p.
Chris@16 804 //! No copy constructors are called.
Chris@16 805 //!
Chris@16 806 //! <b>Throws</b>: Nothing.
Chris@16 807 //!
Chris@16 808 //! <b>Complexity</b>: Linear to the number of elements inserted.
Chris@16 809 //!
Chris@16 810 //! <b>Note</b>: Does not affect the validity of iterators and references.
Chris@16 811 template<class Iterator>
Chris@16 812 void insert(const_iterator p, Iterator b, Iterator e)
Chris@16 813 {
Chris@16 814 for (; b != e; ++b)
Chris@16 815 this->insert(p, *b);
Chris@16 816 }
Chris@16 817
Chris@16 818 //! <b>Requires</b>: Dereferencing iterator must yield
Chris@16 819 //! an lvalue of type value_type.
Chris@16 820 //!
Chris@16 821 //! <b>Effects</b>: Clears the list and inserts the range pointed by b and e.
Chris@16 822 //! No destructors or copy constructors are called.
Chris@16 823 //!
Chris@16 824 //! <b>Throws</b>: Nothing.
Chris@16 825 //!
Chris@16 826 //! <b>Complexity</b>: Linear to the number of elements inserted plus
Chris@16 827 //! linear to the elements contained in the list if it's a safe-mode
Chris@16 828 //! or auto-unlink value.
Chris@16 829 //! Linear to the number of elements inserted in the list otherwise.
Chris@16 830 //!
Chris@16 831 //! <b>Note</b>: Invalidates the iterators (but not the references)
Chris@16 832 //! to the erased elements.
Chris@16 833 template<class Iterator>
Chris@16 834 void assign(Iterator b, Iterator e)
Chris@16 835 {
Chris@16 836 this->clear();
Chris@16 837 this->insert(this->cend(), b, e);
Chris@16 838 }
Chris@16 839
Chris@16 840 //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
Chris@16 841 //!
Chris@16 842 //! <b>Requires</b>: Dereferencing iterator must yield
Chris@16 843 //! an lvalue of type value_type.
Chris@16 844 //!
Chris@16 845 //! <b>Effects</b>: Clears the list and inserts the range pointed by b and e.
Chris@16 846 //! No destructors or copy constructors are called.
Chris@16 847 //! Disposer::operator()(pointer) is called for the removed elements.
Chris@16 848 //!
Chris@16 849 //! <b>Throws</b>: Nothing.
Chris@16 850 //!
Chris@16 851 //! <b>Complexity</b>: Linear to the number of elements inserted plus
Chris@16 852 //! linear to the elements contained in the list.
Chris@16 853 //!
Chris@16 854 //! <b>Note</b>: Invalidates the iterators (but not the references)
Chris@16 855 //! to the erased elements.
Chris@16 856 template<class Iterator, class Disposer>
Chris@16 857 void dispose_and_assign(Disposer disposer, Iterator b, Iterator e)
Chris@16 858 {
Chris@16 859 this->clear_and_dispose(disposer);
Chris@16 860 this->insert(this->cend(), b, e);
Chris@16 861 }
Chris@16 862
Chris@16 863 //! <b>Requires</b>: p must be a valid iterator of *this.
Chris@16 864 //!
Chris@16 865 //! <b>Effects</b>: Transfers all the elements of list x to this list, before the
Chris@16 866 //! the element pointed by p. No destructors or copy constructors are called.
Chris@16 867 //!
Chris@16 868 //! <b>Throws</b>: Nothing.
Chris@16 869 //!
Chris@16 870 //! <b>Complexity</b>: Constant.
Chris@16 871 //!
Chris@16 872 //! <b>Note</b>: Iterators of values obtained from list x now point to elements of
Chris@16 873 //! this list. Iterators of this list and all the references are not invalidated.
Chris@16 874 void splice(const_iterator p, list_impl& x)
Chris@16 875 {
Chris@16 876 if(!x.empty()){
Chris@16 877 node_algorithms::transfer
Chris@16 878 (p.pointed_node(), x.begin().pointed_node(), x.end().pointed_node());
Chris@16 879 size_traits &thist = this->priv_size_traits();
Chris@16 880 size_traits &xt = x.priv_size_traits();
Chris@16 881 thist.increase(xt.get_size());
Chris@16 882 xt.set_size(size_type(0));
Chris@16 883 }
Chris@16 884 }
Chris@16 885
Chris@16 886 //! <b>Requires</b>: p must be a valid iterator of *this.
Chris@16 887 //! new_ele must point to an element contained in list x.
Chris@16 888 //!
Chris@16 889 //! <b>Effects</b>: Transfers the value pointed by new_ele, from list x to this list,
Chris@16 890 //! before the the element pointed by p. No destructors or copy constructors are called.
Chris@16 891 //! If p == new_ele or p == ++new_ele, this function is a null operation.
Chris@16 892 //!
Chris@16 893 //! <b>Throws</b>: Nothing.
Chris@16 894 //!
Chris@16 895 //! <b>Complexity</b>: Constant.
Chris@16 896 //!
Chris@16 897 //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
Chris@16 898 //! list. Iterators of this list and all the references are not invalidated.
Chris@16 899 void splice(const_iterator p, list_impl&x, const_iterator new_ele)
Chris@16 900 {
Chris@16 901 node_algorithms::transfer(p.pointed_node(), new_ele.pointed_node());
Chris@16 902 x.priv_size_traits().decrement();
Chris@16 903 this->priv_size_traits().increment();
Chris@16 904 }
Chris@16 905
Chris@16 906 //! <b>Requires</b>: p must be a valid iterator of *this.
Chris@16 907 //! f and e must point to elements contained in list x.
Chris@16 908 //!
Chris@16 909 //! <b>Effects</b>: Transfers the range pointed by f and e from list x to this list,
Chris@16 910 //! before the the element pointed by p. No destructors or copy constructors are called.
Chris@16 911 //!
Chris@16 912 //! <b>Throws</b>: Nothing.
Chris@16 913 //!
Chris@16 914 //! <b>Complexity</b>: Linear to the number of elements transferred
Chris@16 915 //! if constant-time size option is enabled. Constant-time otherwise.
Chris@16 916 //!
Chris@16 917 //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
Chris@16 918 //! list. Iterators of this list and all the references are not invalidated.
Chris@16 919 void splice(const_iterator p, list_impl&x, const_iterator f, const_iterator e)
Chris@16 920 {
Chris@16 921 if(constant_time_size)
Chris@16 922 this->splice(p, x, f, e, std::distance(f, e));
Chris@16 923 else
Chris@16 924 this->splice(p, x, f, e, 1);//distance is a dummy value
Chris@16 925 }
Chris@16 926
Chris@16 927 //! <b>Requires</b>: p must be a valid iterator of *this.
Chris@16 928 //! f and e must point to elements contained in list x.
Chris@16 929 //! n == std::distance(f, e)
Chris@16 930 //!
Chris@16 931 //! <b>Effects</b>: Transfers the range pointed by f and e from list x to this list,
Chris@16 932 //! before the the element pointed by p. No destructors or copy constructors are called.
Chris@16 933 //!
Chris@16 934 //! <b>Throws</b>: Nothing.
Chris@16 935 //!
Chris@16 936 //! <b>Complexity</b>: Constant.
Chris@16 937 //!
Chris@16 938 //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
Chris@16 939 //! list. Iterators of this list and all the references are not invalidated.
Chris@16 940 void splice(const_iterator p, list_impl&x, const_iterator f, const_iterator e, difference_type n)
Chris@16 941 {
Chris@16 942 if(n){
Chris@16 943 if(constant_time_size){
Chris@16 944 BOOST_INTRUSIVE_INVARIANT_ASSERT(n == std::distance(f, e));
Chris@16 945 node_algorithms::transfer(p.pointed_node(), f.pointed_node(), e.pointed_node());
Chris@16 946 size_traits &thist = this->priv_size_traits();
Chris@16 947 size_traits &xt = x.priv_size_traits();
Chris@16 948 thist.increase(n);
Chris@16 949 xt.decrease(n);
Chris@16 950 }
Chris@16 951 else{
Chris@16 952 node_algorithms::transfer(p.pointed_node(), f.pointed_node(), e.pointed_node());
Chris@16 953 }
Chris@16 954 }
Chris@16 955 }
Chris@16 956
Chris@16 957 //! <b>Effects</b>: This function sorts the list *this according to std::less<value_type>.
Chris@16 958 //! The sort is stable, that is, the relative order of equivalent elements is preserved.
Chris@16 959 //!
Chris@16 960 //! <b>Throws</b>: If real_value_traits::node_traits::node
Chris@16 961 //! constructor throws (this does not happen with predefined Boost.Intrusive hooks)
Chris@16 962 //! or std::less<value_type> throws. Basic guarantee.
Chris@16 963 //!
Chris@16 964 //! <b>Notes</b>: Iterators and references are not invalidated.
Chris@16 965 //!
Chris@16 966 //! <b>Complexity</b>: The number of comparisons is approximately N log N, where N
Chris@16 967 //! is the list's size.
Chris@16 968 void sort()
Chris@16 969 { this->sort(std::less<value_type>()); }
Chris@16 970
Chris@16 971 //! <b>Requires</b>: p must be a comparison function that induces a strict weak ordering
Chris@16 972 //!
Chris@16 973 //! <b>Effects</b>: This function sorts the list *this according to p. The sort is
Chris@16 974 //! stable, that is, the relative order of equivalent elements is preserved.
Chris@16 975 //!
Chris@16 976 //! <b>Throws</b>: If real_value_traits::node_traits::node
Chris@16 977 //! constructor throws (this does not happen with predefined Boost.Intrusive hooks)
Chris@16 978 //! or the predicate throws. Basic guarantee.
Chris@16 979 //!
Chris@16 980 //! <b>Notes</b>: This won't throw if list_base_hook<> or
Chris@16 981 //! list_member_hook are used.
Chris@16 982 //! Iterators and references are not invalidated.
Chris@16 983 //!
Chris@16 984 //! <b>Complexity</b>: The number of comparisons is approximately N log N, where N
Chris@16 985 //! is the list's size.
Chris@16 986 template<class Predicate>
Chris@16 987 void sort(Predicate p)
Chris@16 988 {
Chris@16 989 if(node_traits::get_next(this->get_root_node())
Chris@16 990 != node_traits::get_previous(this->get_root_node())){
Chris@16 991 list_impl carry(this->priv_value_traits());
Chris@16 992 detail::array_initializer<list_impl, 64> counter(this->priv_value_traits());
Chris@16 993 int fill = 0;
Chris@16 994 while(!this->empty()){
Chris@16 995 carry.splice(carry.cbegin(), *this, this->cbegin());
Chris@16 996 int i = 0;
Chris@16 997 while(i < fill && !counter[i].empty()) {
Chris@16 998 counter[i].merge(carry, p);
Chris@16 999 carry.swap(counter[i++]);
Chris@16 1000 }
Chris@16 1001 carry.swap(counter[i]);
Chris@16 1002 if(i == fill)
Chris@16 1003 ++fill;
Chris@16 1004 }
Chris@16 1005 for (int i = 1; i < fill; ++i)
Chris@16 1006 counter[i].merge(counter[i-1], p);
Chris@16 1007 this->swap(counter[fill-1]);
Chris@16 1008 }
Chris@16 1009 }
Chris@16 1010
Chris@16 1011 //! <b>Effects</b>: This function removes all of x's elements and inserts them
Chris@16 1012 //! in order into *this according to std::less<value_type>. The merge is stable;
Chris@16 1013 //! that is, if an element from *this is equivalent to one from x, then the element
Chris@16 1014 //! from *this will precede the one from x.
Chris@16 1015 //!
Chris@16 1016 //! <b>Throws</b>: If std::less<value_type> throws. Basic guarantee.
Chris@16 1017 //!
Chris@16 1018 //! <b>Complexity</b>: This function is linear time: it performs at most
Chris@16 1019 //! size() + x.size() - 1 comparisons.
Chris@16 1020 //!
Chris@16 1021 //! <b>Note</b>: Iterators and references are not invalidated
Chris@16 1022 void merge(list_impl& x)
Chris@16 1023 { this->merge(x, std::less<value_type>()); }
Chris@16 1024
Chris@16 1025 //! <b>Requires</b>: p must be a comparison function that induces a strict weak
Chris@16 1026 //! ordering and both *this and x must be sorted according to that ordering
Chris@16 1027 //! The lists x and *this must be distinct.
Chris@16 1028 //!
Chris@16 1029 //! <b>Effects</b>: This function removes all of x's elements and inserts them
Chris@16 1030 //! in order into *this. The merge is stable; that is, if an element from *this is
Chris@16 1031 //! equivalent to one from x, then the element from *this will precede the one from x.
Chris@16 1032 //!
Chris@16 1033 //! <b>Throws</b>: If the predicate throws. Basic guarantee.
Chris@16 1034 //!
Chris@16 1035 //! <b>Complexity</b>: This function is linear time: it performs at most
Chris@16 1036 //! size() + x.size() - 1 comparisons.
Chris@16 1037 //!
Chris@16 1038 //! <b>Note</b>: Iterators and references are not invalidated.
Chris@16 1039 template<class Predicate>
Chris@16 1040 void merge(list_impl& x, Predicate p)
Chris@16 1041 {
Chris@16 1042 const_iterator e(this->cend()), ex(x.cend());
Chris@16 1043 const_iterator b(this->cbegin());
Chris@16 1044 while(!x.empty()){
Chris@16 1045 const_iterator ix(x.cbegin());
Chris@16 1046 while (b != e && !p(*ix, *b)){
Chris@16 1047 ++b;
Chris@16 1048 }
Chris@16 1049 if(b == e){
Chris@16 1050 //Now transfer the rest to the end of the container
Chris@16 1051 this->splice(e, x);
Chris@16 1052 break;
Chris@16 1053 }
Chris@16 1054 else{
Chris@16 1055 size_type n(0);
Chris@16 1056 do{
Chris@16 1057 ++ix; ++n;
Chris@16 1058 } while(ix != ex && p(*ix, *b));
Chris@16 1059 this->splice(b, x, x.begin(), ix, n);
Chris@16 1060 }
Chris@16 1061 }
Chris@16 1062 }
Chris@16 1063
Chris@16 1064 //! <b>Effects</b>: Reverses the order of elements in the list.
Chris@16 1065 //!
Chris@16 1066 //! <b>Throws</b>: Nothing.
Chris@16 1067 //!
Chris@16 1068 //! <b>Complexity</b>: This function is linear time.
Chris@16 1069 //!
Chris@16 1070 //! <b>Note</b>: Iterators and references are not invalidated
Chris@16 1071 void reverse()
Chris@16 1072 { node_algorithms::reverse(this->get_root_node()); }
Chris@16 1073
Chris@16 1074 //! <b>Effects</b>: Removes all the elements that compare equal to value.
Chris@16 1075 //! No destructors are called.
Chris@16 1076 //!
Chris@16 1077 //! <b>Throws</b>: If std::equal_to<value_type> throws. Basic guarantee.
Chris@16 1078 //!
Chris@16 1079 //! <b>Complexity</b>: Linear time. It performs exactly size() comparisons for equality.
Chris@16 1080 //!
Chris@16 1081 //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
Chris@16 1082 //! and iterators to elements that are not removed remain valid.
Chris@16 1083 void remove(const_reference value)
Chris@16 1084 { this->remove_if(detail::equal_to_value<const_reference>(value)); }
Chris@16 1085
Chris@16 1086 //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
Chris@16 1087 //!
Chris@16 1088 //! <b>Effects</b>: Removes all the elements that compare equal to value.
Chris@16 1089 //! Disposer::operator()(pointer) is called for every removed element.
Chris@16 1090 //!
Chris@16 1091 //! <b>Throws</b>: If std::equal_to<value_type> throws. Basic guarantee.
Chris@16 1092 //!
Chris@16 1093 //! <b>Complexity</b>: Linear time. It performs exactly size() comparisons for equality.
Chris@16 1094 //!
Chris@16 1095 //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
Chris@16 1096 //! and iterators to elements that are not removed remain valid.
Chris@16 1097 template<class Disposer>
Chris@16 1098 void remove_and_dispose(const_reference value, Disposer disposer)
Chris@16 1099 { this->remove_and_dispose_if(detail::equal_to_value<const_reference>(value), disposer); }
Chris@16 1100
Chris@16 1101 //! <b>Effects</b>: Removes all the elements for which a specified
Chris@16 1102 //! predicate is satisfied. No destructors are called.
Chris@16 1103 //!
Chris@16 1104 //! <b>Throws</b>: If pred throws. Basic guarantee.
Chris@16 1105 //!
Chris@16 1106 //! <b>Complexity</b>: Linear time. It performs exactly size() calls to the predicate.
Chris@16 1107 //!
Chris@16 1108 //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
Chris@16 1109 //! and iterators to elements that are not removed remain valid.
Chris@16 1110 template<class Pred>
Chris@16 1111 void remove_if(Pred pred)
Chris@16 1112 { this->remove_and_dispose_if(pred, detail::null_disposer()); }
Chris@16 1113
Chris@16 1114 //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
Chris@16 1115 //!
Chris@16 1116 //! <b>Effects</b>: Removes all the elements for which a specified
Chris@16 1117 //! predicate is satisfied.
Chris@16 1118 //! Disposer::operator()(pointer) is called for every removed element.
Chris@16 1119 //!
Chris@16 1120 //! <b>Throws</b>: If pred throws. Basic guarantee.
Chris@16 1121 //!
Chris@16 1122 //! <b>Complexity</b>: Linear time. It performs exactly size() comparisons for equality.
Chris@16 1123 //!
Chris@16 1124 //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
Chris@16 1125 //! and iterators to elements that are not removed remain valid.
Chris@16 1126 template<class Pred, class Disposer>
Chris@16 1127 void remove_and_dispose_if(Pred pred, Disposer disposer)
Chris@16 1128 {
Chris@16 1129 const_iterator cur(this->cbegin());
Chris@16 1130 const_iterator last(this->cend());
Chris@16 1131 while(cur != last) {
Chris@16 1132 if(pred(*cur)){
Chris@16 1133 cur = this->erase_and_dispose(cur, disposer);
Chris@16 1134 }
Chris@16 1135 else{
Chris@16 1136 ++cur;
Chris@16 1137 }
Chris@16 1138 }
Chris@16 1139 }
Chris@16 1140
Chris@16 1141 //! <b>Effects</b>: Removes adjacent duplicate elements or adjacent
Chris@16 1142 //! elements that are equal from the list. No destructors are called.
Chris@16 1143 //!
Chris@16 1144 //! <b>Throws</b>: If std::equal_to<value_type throws. Basic guarantee.
Chris@16 1145 //!
Chris@16 1146 //! <b>Complexity</b>: Linear time (size()-1 comparisons calls to pred()).
Chris@16 1147 //!
Chris@16 1148 //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
Chris@16 1149 //! and iterators to elements that are not removed remain valid.
Chris@16 1150 void unique()
Chris@16 1151 { this->unique_and_dispose(std::equal_to<value_type>(), detail::null_disposer()); }
Chris@16 1152
Chris@16 1153 //! <b>Effects</b>: Removes adjacent duplicate elements or adjacent
Chris@16 1154 //! elements that satisfy some binary predicate from the list.
Chris@16 1155 //! No destructors are called.
Chris@16 1156 //!
Chris@16 1157 //! <b>Throws</b>: If pred throws. Basic guarantee.
Chris@16 1158 //!
Chris@16 1159 //! <b>Complexity</b>: Linear time (size()-1 comparisons equality comparisons).
Chris@16 1160 //!
Chris@16 1161 //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
Chris@16 1162 //! and iterators to elements that are not removed remain valid.
Chris@16 1163 template<class BinaryPredicate>
Chris@16 1164 void unique(BinaryPredicate pred)
Chris@16 1165 { this->unique_and_dispose(pred, detail::null_disposer()); }
Chris@16 1166
Chris@16 1167 //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
Chris@16 1168 //!
Chris@16 1169 //! <b>Effects</b>: Removes adjacent duplicate elements or adjacent
Chris@16 1170 //! elements that are equal from the list.
Chris@16 1171 //! Disposer::operator()(pointer) is called for every removed element.
Chris@16 1172 //!
Chris@16 1173 //! <b>Throws</b>: If std::equal_to<value_type throws. Basic guarantee.
Chris@16 1174 //!
Chris@16 1175 //! <b>Complexity</b>: Linear time (size()-1) comparisons equality comparisons.
Chris@16 1176 //!
Chris@16 1177 //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
Chris@16 1178 //! and iterators to elements that are not removed remain valid.
Chris@16 1179 template<class Disposer>
Chris@16 1180 void unique_and_dispose(Disposer disposer)
Chris@16 1181 { this->unique_and_dispose(std::equal_to<value_type>(), disposer); }
Chris@16 1182
Chris@16 1183 //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
Chris@16 1184 //!
Chris@16 1185 //! <b>Effects</b>: Removes adjacent duplicate elements or adjacent
Chris@16 1186 //! elements that satisfy some binary predicate from the list.
Chris@16 1187 //! Disposer::operator()(pointer) is called for every removed element.
Chris@16 1188 //!
Chris@16 1189 //! <b>Throws</b>: If pred throws. Basic guarantee.
Chris@16 1190 //!
Chris@16 1191 //! <b>Complexity</b>: Linear time (size()-1) comparisons equality comparisons.
Chris@16 1192 //!
Chris@16 1193 //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
Chris@16 1194 //! and iterators to elements that are not removed remain valid.
Chris@16 1195 template<class BinaryPredicate, class Disposer>
Chris@16 1196 void unique_and_dispose(BinaryPredicate pred, Disposer disposer)
Chris@16 1197 {
Chris@16 1198 const_iterator itend(this->cend());
Chris@16 1199 const_iterator cur(this->cbegin());
Chris@16 1200
Chris@16 1201 if(cur != itend){
Chris@16 1202 const_iterator after(cur);
Chris@16 1203 ++after;
Chris@16 1204 while(after != itend){
Chris@16 1205 if(pred(*cur, *after)){
Chris@16 1206 after = this->erase_and_dispose(after, disposer);
Chris@16 1207 }
Chris@16 1208 else{
Chris@16 1209 cur = after;
Chris@16 1210 ++after;
Chris@16 1211 }
Chris@16 1212 }
Chris@16 1213 }
Chris@16 1214 }
Chris@16 1215
Chris@16 1216 //! <b>Requires</b>: value must be a reference to a value inserted in a list.
Chris@16 1217 //!
Chris@16 1218 //! <b>Effects</b>: This function returns a const_iterator pointing to the element
Chris@16 1219 //!
Chris@16 1220 //! <b>Throws</b>: Nothing.
Chris@16 1221 //!
Chris@16 1222 //! <b>Complexity</b>: Constant time.
Chris@16 1223 //!
Chris@16 1224 //! <b>Note</b>: Iterators and references are not invalidated.
Chris@16 1225 //! This static function is available only if the <i>value traits</i>
Chris@16 1226 //! is stateless.
Chris@16 1227 static iterator s_iterator_to(reference value)
Chris@16 1228 {
Chris@16 1229 BOOST_STATIC_ASSERT((!stateful_value_traits));
Chris@16 1230 BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::inited(real_value_traits::to_node_ptr(value)));
Chris@16 1231 return iterator(real_value_traits::to_node_ptr(value), const_real_value_traits_ptr());
Chris@16 1232 }
Chris@16 1233
Chris@16 1234 //! <b>Requires</b>: value must be a const reference to a value inserted in a list.
Chris@16 1235 //!
Chris@16 1236 //! <b>Effects</b>: This function returns an iterator pointing to the element.
Chris@16 1237 //!
Chris@16 1238 //! <b>Throws</b>: Nothing.
Chris@16 1239 //!
Chris@16 1240 //! <b>Complexity</b>: Constant time.
Chris@16 1241 //!
Chris@16 1242 //! <b>Note</b>: Iterators and references are not invalidated.
Chris@16 1243 //! This static function is available only if the <i>value traits</i>
Chris@16 1244 //! is stateless.
Chris@16 1245 static const_iterator s_iterator_to(const_reference value)
Chris@16 1246 {
Chris@16 1247 BOOST_STATIC_ASSERT((!stateful_value_traits));
Chris@16 1248 BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::inited(real_value_traits::to_node_ptr(const_cast<reference> (value))));
Chris@16 1249 return const_iterator(real_value_traits::to_node_ptr(const_cast<reference> (value)), const_real_value_traits_ptr());
Chris@16 1250 }
Chris@16 1251
Chris@16 1252 //! <b>Requires</b>: value must be a reference to a value inserted in a list.
Chris@16 1253 //!
Chris@16 1254 //! <b>Effects</b>: This function returns a const_iterator pointing to the element
Chris@16 1255 //!
Chris@16 1256 //! <b>Throws</b>: Nothing.
Chris@16 1257 //!
Chris@16 1258 //! <b>Complexity</b>: Constant time.
Chris@16 1259 //!
Chris@16 1260 //! <b>Note</b>: Iterators and references are not invalidated.
Chris@16 1261 iterator iterator_to(reference value)
Chris@16 1262 {
Chris@16 1263 BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::inited(real_value_traits::to_node_ptr(value)));
Chris@16 1264 return iterator(real_value_traits::to_node_ptr(value), real_value_traits_ptr());
Chris@16 1265 }
Chris@16 1266
Chris@16 1267 //! <b>Requires</b>: value must be a const reference to a value inserted in a list.
Chris@16 1268 //!
Chris@16 1269 //! <b>Effects</b>: This function returns an iterator pointing to the element.
Chris@16 1270 //!
Chris@16 1271 //! <b>Throws</b>: Nothing.
Chris@16 1272 //!
Chris@16 1273 //! <b>Complexity</b>: Constant time.
Chris@16 1274 //!
Chris@16 1275 //! <b>Note</b>: Iterators and references are not invalidated.
Chris@16 1276 const_iterator iterator_to(const_reference value) const
Chris@16 1277 {
Chris@16 1278 BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::inited(real_value_traits::to_node_ptr(const_cast<reference> (value))));
Chris@16 1279 return const_iterator(real_value_traits::to_node_ptr(const_cast<reference> (value)), real_value_traits_ptr());
Chris@16 1280 }
Chris@16 1281
Chris@16 1282 /// @cond
Chris@16 1283
Chris@16 1284 private:
Chris@16 1285 static list_impl &priv_container_from_end_iterator(const const_iterator &end_iterator)
Chris@16 1286 {
Chris@16 1287 root_plus_size *r = detail::parent_from_member<root_plus_size, node>
Chris@16 1288 ( boost::intrusive::detail::to_raw_pointer(end_iterator.pointed_node()), &root_plus_size::root_);
Chris@16 1289 data_t *d = detail::parent_from_member<data_t, root_plus_size>
Chris@16 1290 ( r, &data_t::root_plus_size_);
Chris@16 1291 list_impl *s = detail::parent_from_member<list_impl, data_t>(d, &list_impl::data_);
Chris@16 1292 return *s;
Chris@16 1293 }
Chris@16 1294 /// @endcond
Chris@16 1295 };
Chris@16 1296
Chris@16 1297 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
Chris@16 1298 template<class T, class ...Options>
Chris@16 1299 #else
Chris@16 1300 template <class ValueTraits, class SizeType, bool ConstantTimeSize>
Chris@16 1301 #endif
Chris@16 1302 inline bool operator<
Chris@16 1303 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
Chris@16 1304 (const list_impl<T, Options...> &x, const list_impl<T, Options...> &y)
Chris@16 1305 #else
Chris@16 1306 (const list_impl<ValueTraits, SizeType, ConstantTimeSize> &x, const list_impl<ValueTraits, SizeType, ConstantTimeSize> &y)
Chris@16 1307 #endif
Chris@16 1308 { return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
Chris@16 1309
Chris@16 1310 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
Chris@16 1311 template<class T, class ...Options>
Chris@16 1312 #else
Chris@16 1313 template <class ValueTraits, class SizeType, bool ConstantTimeSize>
Chris@16 1314 #endif
Chris@16 1315 bool operator==
Chris@16 1316 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
Chris@16 1317 (const list_impl<T, Options...> &x, const list_impl<T, Options...> &y)
Chris@16 1318 #else
Chris@16 1319 (const list_impl<ValueTraits, SizeType, ConstantTimeSize> &x, const list_impl<ValueTraits, SizeType, ConstantTimeSize> &y)
Chris@16 1320 #endif
Chris@16 1321 {
Chris@16 1322 typedef list_impl<ValueTraits, SizeType, ConstantTimeSize> list_type;
Chris@16 1323 typedef typename list_type::const_iterator const_iterator;
Chris@16 1324 const bool C = list_type::constant_time_size;
Chris@16 1325 if(C && x.size() != y.size()){
Chris@16 1326 return false;
Chris@16 1327 }
Chris@16 1328 const_iterator end1 = x.end();
Chris@16 1329
Chris@16 1330 const_iterator i1 = x.begin();
Chris@16 1331 const_iterator i2 = y.begin();
Chris@16 1332 if(C){
Chris@16 1333 while (i1 != end1 && *i1 == *i2) {
Chris@16 1334 ++i1;
Chris@16 1335 ++i2;
Chris@16 1336 }
Chris@16 1337 return i1 == end1;
Chris@16 1338 }
Chris@16 1339 else{
Chris@16 1340 const_iterator end2 = y.end();
Chris@16 1341 while (i1 != end1 && i2 != end2 && *i1 == *i2) {
Chris@16 1342 ++i1;
Chris@16 1343 ++i2;
Chris@16 1344 }
Chris@16 1345 return i1 == end1 && i2 == end2;
Chris@16 1346 }
Chris@16 1347 }
Chris@16 1348
Chris@16 1349 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
Chris@16 1350 template<class T, class ...Options>
Chris@16 1351 #else
Chris@16 1352 template <class ValueTraits, class SizeType, bool ConstantTimeSize>
Chris@16 1353 #endif
Chris@16 1354 inline bool operator!=
Chris@16 1355 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
Chris@16 1356 (const list_impl<T, Options...> &x, const list_impl<T, Options...> &y)
Chris@16 1357 #else
Chris@16 1358 (const list_impl<ValueTraits, SizeType, ConstantTimeSize> &x, const list_impl<ValueTraits, SizeType, ConstantTimeSize> &y)
Chris@16 1359 #endif
Chris@16 1360 { return !(x == y); }
Chris@16 1361
Chris@16 1362 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
Chris@16 1363 template<class T, class ...Options>
Chris@16 1364 #else
Chris@16 1365 template <class ValueTraits, class SizeType, bool ConstantTimeSize>
Chris@16 1366 #endif
Chris@16 1367 inline bool operator>
Chris@16 1368 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
Chris@16 1369 (const list_impl<T, Options...> &x, const list_impl<T, Options...> &y)
Chris@16 1370 #else
Chris@16 1371 (const list_impl<ValueTraits, SizeType, ConstantTimeSize> &x, const list_impl<ValueTraits, SizeType, ConstantTimeSize> &y)
Chris@16 1372 #endif
Chris@16 1373 { return y < x; }
Chris@16 1374
Chris@16 1375 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
Chris@16 1376 template<class T, class ...Options>
Chris@16 1377 #else
Chris@16 1378 template <class ValueTraits, class SizeType, bool ConstantTimeSize>
Chris@16 1379 #endif
Chris@16 1380 inline bool operator<=
Chris@16 1381 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
Chris@16 1382 (const list_impl<T, Options...> &x, const list_impl<T, Options...> &y)
Chris@16 1383 #else
Chris@16 1384 (const list_impl<ValueTraits, SizeType, ConstantTimeSize> &x, const list_impl<ValueTraits, SizeType, ConstantTimeSize> &y)
Chris@16 1385 #endif
Chris@16 1386 { return !(y < x); }
Chris@16 1387
Chris@16 1388 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
Chris@16 1389 template<class T, class ...Options>
Chris@16 1390 #else
Chris@16 1391 template <class ValueTraits, class SizeType, bool ConstantTimeSize>
Chris@16 1392 #endif
Chris@16 1393 inline bool operator>=
Chris@16 1394 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
Chris@16 1395 (const list_impl<T, Options...> &x, const list_impl<T, Options...> &y)
Chris@16 1396 #else
Chris@16 1397 (const list_impl<ValueTraits, SizeType, ConstantTimeSize> &x, const list_impl<ValueTraits, SizeType, ConstantTimeSize> &y)
Chris@16 1398 #endif
Chris@16 1399 { return !(x < y); }
Chris@16 1400
Chris@16 1401 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
Chris@16 1402 template<class T, class ...Options>
Chris@16 1403 #else
Chris@16 1404 template <class ValueTraits, class SizeType, bool ConstantTimeSize>
Chris@16 1405 #endif
Chris@16 1406 inline void swap
Chris@16 1407 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
Chris@16 1408 (list_impl<T, Options...> &x, list_impl<T, Options...> &y)
Chris@16 1409 #else
Chris@16 1410 (list_impl<ValueTraits, SizeType, ConstantTimeSize> &x, list_impl<ValueTraits, SizeType, ConstantTimeSize> &y)
Chris@16 1411 #endif
Chris@16 1412 { x.swap(y); }
Chris@16 1413
Chris@16 1414 //! Helper metafunction to define a \c list that yields to the same type when the
Chris@16 1415 //! same options (either explicitly or implicitly) are used.
Chris@16 1416 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
Chris@16 1417 template<class T, class ...Options>
Chris@16 1418 #else
Chris@16 1419 template<class T, class O1 = void, class O2 = void, class O3 = void>
Chris@16 1420 #endif
Chris@16 1421 struct make_list
Chris@16 1422 {
Chris@16 1423 /// @cond
Chris@16 1424 typedef typename pack_options
Chris@16 1425 < list_defaults,
Chris@16 1426 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
Chris@16 1427 O1, O2, O3
Chris@16 1428 #else
Chris@16 1429 Options...
Chris@16 1430 #endif
Chris@16 1431 >::type packed_options;
Chris@16 1432
Chris@16 1433 typedef typename detail::get_value_traits
Chris@16 1434 <T, typename packed_options::proto_value_traits>::type value_traits;
Chris@16 1435
Chris@16 1436 typedef list_impl
Chris@16 1437 <
Chris@16 1438 value_traits,
Chris@16 1439 typename packed_options::size_type,
Chris@16 1440 packed_options::constant_time_size
Chris@16 1441 > implementation_defined;
Chris@16 1442 /// @endcond
Chris@16 1443 typedef implementation_defined type;
Chris@16 1444 };
Chris@16 1445
Chris@16 1446
Chris@16 1447 #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
Chris@16 1448
Chris@16 1449 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
Chris@16 1450 template<class T, class O1, class O2, class O3>
Chris@16 1451 #else
Chris@16 1452 template<class T, class ...Options>
Chris@16 1453 #endif
Chris@16 1454 class list
Chris@16 1455 : public make_list<T,
Chris@16 1456 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
Chris@16 1457 O1, O2, O3
Chris@16 1458 #else
Chris@16 1459 Options...
Chris@16 1460 #endif
Chris@16 1461 >::type
Chris@16 1462 {
Chris@16 1463 typedef typename make_list
Chris@16 1464 <T,
Chris@16 1465 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
Chris@16 1466 O1, O2, O3
Chris@16 1467 #else
Chris@16 1468 Options...
Chris@16 1469 #endif
Chris@16 1470 >::type Base;
Chris@16 1471 typedef typename Base::real_value_traits real_value_traits;
Chris@16 1472 //Assert if passed value traits are compatible with the type
Chris@16 1473 BOOST_STATIC_ASSERT((detail::is_same<typename real_value_traits::value_type, T>::value));
Chris@16 1474 BOOST_MOVABLE_BUT_NOT_COPYABLE(list)
Chris@16 1475
Chris@16 1476 public:
Chris@16 1477 typedef typename Base::value_traits value_traits;
Chris@16 1478 typedef typename Base::iterator iterator;
Chris@16 1479 typedef typename Base::const_iterator const_iterator;
Chris@16 1480
Chris@16 1481 explicit list(const value_traits &v_traits = value_traits())
Chris@16 1482 : Base(v_traits)
Chris@16 1483 {}
Chris@16 1484
Chris@16 1485 template<class Iterator>
Chris@16 1486 list(Iterator b, Iterator e, const value_traits &v_traits = value_traits())
Chris@16 1487 : Base(b, e, v_traits)
Chris@16 1488 {}
Chris@16 1489
Chris@16 1490 list(BOOST_RV_REF(list) x)
Chris@16 1491 : Base(::boost::move(static_cast<Base&>(x)))
Chris@16 1492 {}
Chris@16 1493
Chris@16 1494 list& operator=(BOOST_RV_REF(list) x)
Chris@16 1495 { return static_cast<list &>(this->Base::operator=(::boost::move(static_cast<Base&>(x)))); }
Chris@16 1496
Chris@16 1497 static list &container_from_end_iterator(iterator end_iterator)
Chris@16 1498 { return static_cast<list &>(Base::container_from_end_iterator(end_iterator)); }
Chris@16 1499
Chris@16 1500 static const list &container_from_end_iterator(const_iterator end_iterator)
Chris@16 1501 { return static_cast<const list &>(Base::container_from_end_iterator(end_iterator)); }
Chris@16 1502 };
Chris@16 1503
Chris@16 1504 #endif
Chris@16 1505
Chris@16 1506 } //namespace intrusive
Chris@16 1507 } //namespace boost
Chris@16 1508
Chris@16 1509 #include <boost/intrusive/detail/config_end.hpp>
Chris@16 1510
Chris@16 1511 #endif //BOOST_INTRUSIVE_LIST_HPP