comparison DEPENDENCIES/generic/include/boost/intrusive/slist.hpp @ 101:c530137014c0

Update Boost headers (1.58.0)
author Chris Cannam
date Mon, 07 Sep 2015 11:12:49 +0100
parents 2665513ce2d3
children
comparison
equal deleted inserted replaced
100:793467b5e61c 101:c530137014c0
1 ///////////////////////////////////////////////////////////////////////////// 1 /////////////////////////////////////////////////////////////////////////////
2 // 2 //
3 // (C) Copyright Olaf Krzikalla 2004-2006. 3 // (C) Copyright Olaf Krzikalla 2004-2006.
4 // (C) Copyright Ion Gaztanaga 2006-2013 4 // (C) Copyright Ion Gaztanaga 2006-2014
5 // 5 //
6 // Distributed under the Boost Software License, Version 1.0. 6 // Distributed under the Boost Software License, Version 1.0.
7 // (See accompanying file LICENSE_1_0.txt or copy at 7 // (See accompanying file LICENSE_1_0.txt or copy at
8 // http://www.boost.org/LICENSE_1_0.txt) 8 // http://www.boost.org/LICENSE_1_0.txt)
9 // 9 //
13 13
14 #ifndef BOOST_INTRUSIVE_SLIST_HPP 14 #ifndef BOOST_INTRUSIVE_SLIST_HPP
15 #define BOOST_INTRUSIVE_SLIST_HPP 15 #define BOOST_INTRUSIVE_SLIST_HPP
16 16
17 #include <boost/intrusive/detail/config_begin.hpp> 17 #include <boost/intrusive/detail/config_begin.hpp>
18 #include <boost/static_assert.hpp> 18 #include <boost/intrusive/intrusive_fwd.hpp>
19
19 #include <boost/intrusive/detail/assert.hpp> 20 #include <boost/intrusive/detail/assert.hpp>
20 #include <boost/intrusive/intrusive_fwd.hpp>
21 #include <boost/intrusive/slist_hook.hpp> 21 #include <boost/intrusive/slist_hook.hpp>
22 #include <boost/intrusive/circular_slist_algorithms.hpp> 22 #include <boost/intrusive/circular_slist_algorithms.hpp>
23 #include <boost/intrusive/linear_slist_algorithms.hpp> 23 #include <boost/intrusive/linear_slist_algorithms.hpp>
24 #include <boost/intrusive/pointer_traits.hpp> 24 #include <boost/intrusive/pointer_traits.hpp>
25 #include <boost/intrusive/detail/clear_on_destructor_base.hpp>
26 #include <boost/intrusive/link_mode.hpp> 25 #include <boost/intrusive/link_mode.hpp>
27 #include <boost/intrusive/options.hpp> 26 #include <boost/intrusive/detail/get_value_traits.hpp>
28 #include <boost/intrusive/detail/utilities.hpp> 27 #include <boost/intrusive/detail/is_stateful_value_traits.hpp>
29 #include <iterator> 28 #include <boost/intrusive/detail/default_header_holder.hpp>
30 #include <functional> 29 #include <boost/intrusive/detail/uncast.hpp>
31 #include <algorithm> 30 #include <boost/intrusive/detail/mpl.hpp>
31 #include <boost/intrusive/detail/iterator.hpp>
32 #include <boost/intrusive/detail/slist_iterator.hpp>
33 #include <boost/intrusive/detail/array_initializer.hpp>
34 #include <boost/intrusive/detail/exception_disposer.hpp>
35 #include <boost/intrusive/detail/equal_to_value.hpp>
36 #include <boost/intrusive/detail/key_nodeptr_comp.hpp>
37 #include <boost/intrusive/detail/simple_disposers.hpp>
38 #include <boost/intrusive/detail/size_holder.hpp>
39 #include <boost/intrusive/detail/algorithm.hpp>
40
41 #include <boost/move/utility_core.hpp>
42 #include <boost/static_assert.hpp>
43
44 #include <boost/intrusive/detail/minimal_less_equal_header.hpp>//std::less
32 #include <cstddef> //std::size_t 45 #include <cstddef> //std::size_t
33 #include <utility> //std::pair 46 #include <boost/intrusive/detail/minimal_pair_header.hpp> //std::pair
34 #include <boost/move/move.hpp> 47
48 #if defined(BOOST_HAS_PRAGMA_ONCE)
49 # pragma once
50 #endif
35 51
36 namespace boost { 52 namespace boost {
37 namespace intrusive { 53 namespace intrusive {
38 54
39 /// @cond 55 /// @cond
40 56
41 template<class Node, class NodePtr, bool> 57 template<class HeaderHolder, class NodePtr, bool>
42 struct root_plus_last 58 struct header_holder_plus_last
43 { 59 {
44 Node root_; 60 HeaderHolder header_holder_;
45 NodePtr last_; 61 NodePtr last_;
46 }; 62 };
47 63
48 template<class Node, class NodePtr> 64 template<class HeaderHolder, class NodePtr>
49 struct root_plus_last<Node, NodePtr, false> 65 struct header_holder_plus_last<HeaderHolder, NodePtr, false>
50 { 66 {
51 Node root_; 67 HeaderHolder header_holder_;
52 }; 68 };
69
70 struct default_slist_hook_applier
71 { template <class T> struct apply{ typedef typename T::default_slist_hook type; }; };
72
73 template<>
74 struct is_default_hook_tag<default_slist_hook_applier>
75 { static const bool value = true; };
53 76
54 struct slist_defaults 77 struct slist_defaults
55 { 78 {
56 typedef detail::default_slist_hook proto_value_traits; 79 typedef default_slist_hook_applier proto_value_traits;
57 static const bool constant_time_size = true; 80 static const bool constant_time_size = true;
58 static const bool linear = false; 81 static const bool linear = false;
59 typedef std::size_t size_type; 82 typedef std::size_t size_type;
60 static const bool cache_last = false; 83 static const bool cache_last = false;
84 typedef void header_holder_type;
61 }; 85 };
62 86
63 struct slist_bool_flags 87 struct slist_bool_flags
64 { 88 {
65 static const std::size_t linear_pos = 1u; 89 static const std::size_t linear_pos = 1u;
94 //! are defined. An new special function "before_begin()" is defined, which returns 118 //! are defined. An new special function "before_begin()" is defined, which returns
95 //! an iterator that points one less the beginning of the list: ++before_begin() == begin() 119 //! an iterator that points one less the beginning of the list: ++before_begin() == begin()
96 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) 120 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
97 template<class T, class ...Options> 121 template<class T, class ...Options>
98 #else 122 #else
99 template<class ValueTraits, class SizeType, std::size_t BoolFlags> 123 template<class ValueTraits, class SizeType, std::size_t BoolFlags, typename HeaderHolder>
100 #endif 124 #endif
101 class slist_impl 125 class slist_impl
102 : private detail::clear_on_destructor_base
103 < slist_impl<ValueTraits, SizeType, BoolFlags>
104 , is_safe_autounlink<detail::get_real_value_traits<ValueTraits>::type::link_mode>::value
105 >
106 { 126 {
107 template<class C, bool> friend class detail::clear_on_destructor_base;
108 //Public typedefs 127 //Public typedefs
109 public: 128 public:
110 typedef ValueTraits value_traits; 129 typedef ValueTraits value_traits;
111 /// @cond 130 typedef typename value_traits::pointer pointer;
112 static const bool external_value_traits = 131 typedef typename value_traits::const_pointer const_pointer;
113 detail::external_value_traits_bool_is_true<value_traits>::value;
114 typedef typename detail::get_real_value_traits<ValueTraits>::type real_value_traits;
115 /// @endcond
116 typedef typename real_value_traits::pointer pointer;
117 typedef typename real_value_traits::const_pointer const_pointer;
118 typedef typename pointer_traits<pointer>::element_type value_type; 132 typedef typename pointer_traits<pointer>::element_type value_type;
119 typedef typename pointer_traits<pointer>::reference reference; 133 typedef typename pointer_traits<pointer>::reference reference;
120 typedef typename pointer_traits<const_pointer>::reference const_reference; 134 typedef typename pointer_traits<const_pointer>::reference const_reference;
121 typedef typename pointer_traits<pointer>::difference_type difference_type; 135 typedef typename pointer_traits<pointer>::difference_type difference_type;
122 typedef SizeType size_type; 136 typedef SizeType size_type;
123 typedef slist_iterator<real_value_traits, false> iterator; 137 typedef slist_iterator<value_traits, false> iterator;
124 typedef slist_iterator<real_value_traits, true> const_iterator; 138 typedef slist_iterator<value_traits, true> const_iterator;
125 typedef typename real_value_traits::node_traits node_traits; 139 typedef typename value_traits::node_traits node_traits;
126 typedef typename node_traits::node node; 140 typedef typename node_traits::node node;
127 typedef typename node_traits::node_ptr node_ptr; 141 typedef typename node_traits::node_ptr node_ptr;
128 typedef typename node_traits::const_node_ptr const_node_ptr; 142 typedef typename node_traits::const_node_ptr const_node_ptr;
143 typedef typename detail::get_header_holder_type
144 < value_traits, HeaderHolder >::type header_holder_type;
129 145
130 static const bool constant_time_size = 0 != (BoolFlags & slist_bool_flags::constant_time_size_pos); 146 static const bool constant_time_size = 0 != (BoolFlags & slist_bool_flags::constant_time_size_pos);
131 static const bool stateful_value_traits = detail::is_stateful_value_traits<real_value_traits>::value; 147 static const bool stateful_value_traits = detail::is_stateful_value_traits<value_traits>::value;
132 static const bool linear = 0 != (BoolFlags & slist_bool_flags::linear_pos); 148 static const bool linear = 0 != (BoolFlags & slist_bool_flags::linear_pos);
133 static const bool cache_last = 0 != (BoolFlags & slist_bool_flags::cache_last_pos); 149 static const bool cache_last = 0 != (BoolFlags & slist_bool_flags::cache_last_pos);
150 static const bool has_container_from_iterator =
151 detail::is_same< header_holder_type, detail::default_header_holder< node_traits > >::value;
134 152
135 typedef typename detail::if_c 153 typedef typename detail::if_c
136 < linear 154 < linear
137 , linear_slist_algorithms<node_traits> 155 , linear_slist_algorithms<node_traits>
138 , circular_slist_algorithms<node_traits> 156 , circular_slist_algorithms<node_traits>
143 typedef detail::size_holder<constant_time_size, size_type> size_traits; 161 typedef detail::size_holder<constant_time_size, size_type> size_traits;
144 162
145 //noncopyable 163 //noncopyable
146 BOOST_MOVABLE_BUT_NOT_COPYABLE(slist_impl) 164 BOOST_MOVABLE_BUT_NOT_COPYABLE(slist_impl)
147 165
148 static const bool safemode_or_autounlink = is_safe_autounlink<real_value_traits::link_mode>::value; 166 static const bool safemode_or_autounlink = is_safe_autounlink<value_traits::link_mode>::value;
149 167
150 //Constant-time size is incompatible with auto-unlink hooks! 168 //Constant-time size is incompatible with auto-unlink hooks!
151 BOOST_STATIC_ASSERT(!(constant_time_size && ((int)real_value_traits::link_mode == (int)auto_unlink))); 169 BOOST_STATIC_ASSERT(!(constant_time_size && ((int)value_traits::link_mode == (int)auto_unlink)));
152 //Linear singly linked lists are incompatible with auto-unlink hooks! 170 //Linear singly linked lists are incompatible with auto-unlink hooks!
153 BOOST_STATIC_ASSERT(!(linear && ((int)real_value_traits::link_mode == (int)auto_unlink))); 171 BOOST_STATIC_ASSERT(!(linear && ((int)value_traits::link_mode == (int)auto_unlink)));
154 //A list with cached last node is incompatible with auto-unlink hooks! 172 //A list with cached last node is incompatible with auto-unlink hooks!
155 BOOST_STATIC_ASSERT(!(cache_last && ((int)real_value_traits::link_mode == (int)auto_unlink))); 173 BOOST_STATIC_ASSERT(!(cache_last && ((int)value_traits::link_mode == (int)auto_unlink)));
156 174
157 node_ptr get_end_node() 175 node_ptr get_end_node()
158 { return node_ptr(linear ? node_ptr() : this->get_root_node()); } 176 { return node_ptr(linear ? node_ptr() : this->get_root_node()); }
159 177
160 const_node_ptr get_end_node() const 178 const_node_ptr get_end_node() const
161 { 179 {
162 return const_node_ptr 180 return const_node_ptr
163 (linear ? const_node_ptr() : this->get_root_node()); } 181 (linear ? const_node_ptr() : this->get_root_node()); }
164 182
165 node_ptr get_root_node() 183 node_ptr get_root_node()
166 { return pointer_traits<node_ptr>::pointer_to(data_.root_plus_size_.root_); } 184 { return data_.root_plus_size_.header_holder_.get_node(); }
167 185
168 const_node_ptr get_root_node() const 186 const_node_ptr get_root_node() const
169 { return pointer_traits<const_node_ptr>::pointer_to(data_.root_plus_size_.root_); } 187 { return data_.root_plus_size_.header_holder_.get_node(); }
170 188
171 node_ptr get_last_node() 189 node_ptr get_last_node()
172 { return this->get_last_node(detail::bool_<cache_last>()); } 190 { return this->get_last_node(detail::bool_<cache_last>()); }
173 191
174 const_node_ptr get_last_node() const 192 const_node_ptr get_last_node() const
206 if(cache_last){ 224 if(cache_last){
207 this->set_last_node(this->get_root_node()); 225 this->set_last_node(this->get_root_node());
208 } 226 }
209 } 227 }
210 228
229 typedef header_holder_plus_last<header_holder_type, node_ptr, cache_last> header_holder_plus_last_t;
211 struct root_plus_size 230 struct root_plus_size
212 : public size_traits 231 : public size_traits
213 , public root_plus_last<node, node_ptr, cache_last> 232 , public header_holder_plus_last_t
214 {}; 233 {};
215 234
216 struct data_t 235 struct data_t
217 : public slist_impl::value_traits 236 : public slist_impl::value_traits
218 { 237 {
228 { return data_.root_plus_size_; } 247 { return data_.root_plus_size_; }
229 248
230 const size_traits &priv_size_traits() const 249 const size_traits &priv_size_traits() const
231 { return data_.root_plus_size_; } 250 { return data_.root_plus_size_; }
232 251
233 const real_value_traits &get_real_value_traits(detail::bool_<false>) const
234 { return data_; }
235
236 const real_value_traits &get_real_value_traits(detail::bool_<true>) const
237 { return data_.get_value_traits(*this); }
238
239 real_value_traits &get_real_value_traits(detail::bool_<false>)
240 { return data_; }
241
242 real_value_traits &get_real_value_traits(detail::bool_<true>)
243 { return data_.get_value_traits(*this); }
244
245 const value_traits &priv_value_traits() const 252 const value_traits &priv_value_traits() const
246 { return data_; } 253 { return data_; }
247 254
248 value_traits &priv_value_traits() 255 value_traits &priv_value_traits()
249 { return data_; } 256 { return data_; }
250 257
251 protected: 258 typedef typename boost::intrusive::value_traits_pointers
252 node &prot_root_node() 259 <ValueTraits>::const_value_traits_ptr const_value_traits_ptr;
253 { return data_.root_plus_size_.root_; } 260
254 261 const_value_traits_ptr priv_value_traits_ptr() const
255 node const &prot_root_node() const 262 { return pointer_traits<const_value_traits_ptr>::pointer_to(this->priv_value_traits()); }
256 { return data_.root_plus_size_.root_; }
257
258 void prot_set_size(size_type s)
259 { data_.root_plus_size_.set_size(s); }
260 263
261 /// @endcond 264 /// @endcond
262
263 public:
264
265 const real_value_traits &get_real_value_traits() const
266 { return this->get_real_value_traits(detail::bool_<external_value_traits>()); }
267
268 real_value_traits &get_real_value_traits()
269 { return this->get_real_value_traits(detail::bool_<external_value_traits>()); }
270
271 typedef typename pointer_traits<node_ptr>::template rebind_pointer<const real_value_traits>::type const_real_value_traits_ptr;
272
273 const_real_value_traits_ptr real_value_traits_ptr() const
274 { return pointer_traits<const_real_value_traits_ptr>::pointer_to(this->get_real_value_traits()); }
275 265
276 public: 266 public:
277 267
278 ///@cond 268 ///@cond
279 269
323 313
324 //! <b>Requires</b>: Dereferencing iterator must yield an lvalue of type value_type. 314 //! <b>Requires</b>: Dereferencing iterator must yield an lvalue of type value_type.
325 //! 315 //!
326 //! <b>Effects</b>: Constructs a list equal to [b ,e). 316 //! <b>Effects</b>: Constructs a list equal to [b ,e).
327 //! 317 //!
328 //! <b>Complexity</b>: Linear in std::distance(b, e). No copy constructors are called. 318 //! <b>Complexity</b>: Linear in distance(b, e). No copy constructors are called.
329 //! 319 //!
330 //! <b>Throws</b>: If value_traits::node_traits::node 320 //! <b>Throws</b>: If value_traits::node_traits::node
331 //! constructor throws (this does not happen with predefined Boost.Intrusive hooks). 321 //! constructor throws (this does not happen with predefined Boost.Intrusive hooks).
332 template<class Iterator> 322 template<class Iterator>
333 slist_impl(Iterator b, Iterator e, const value_traits &v_traits = value_traits()) 323 slist_impl(Iterator b, Iterator e, const value_traits &v_traits = value_traits())
334 : data_(v_traits) 324 : data_(v_traits)
335 { 325 {
336 this->set_default_constructed_state(); 326 this->set_default_constructed_state();
327 //nothrow, no need to rollback to release elements on exception
337 this->insert_after(this->cbefore_begin(), b, e); 328 this->insert_after(this->cbefore_begin(), b, e);
338 } 329 }
339 330
340 //! <b>Effects</b>: to-do 331 //! <b>Effects</b>: to-do
341 //! 332 //!
342 slist_impl(BOOST_RV_REF(slist_impl) x) 333 slist_impl(BOOST_RV_REF(slist_impl) x)
343 : data_(::boost::move(x.priv_value_traits())) 334 : data_(::boost::move(x.priv_value_traits()))
344 { 335 {
345 this->priv_size_traits().set_size(size_type(0)); 336 this->priv_size_traits().set_size(size_type(0));
346 node_algorithms::init_header(this->get_root_node()); 337 node_algorithms::init_header(this->get_root_node());
338 //nothrow, no need to rollback to release elements on exception
347 this->swap(x); 339 this->swap(x);
348 } 340 }
349 341
350 //! <b>Effects</b>: to-do 342 //! <b>Effects</b>: to-do
351 //! 343 //!
352 slist_impl& operator=(BOOST_RV_REF(slist_impl) x) 344 slist_impl& operator=(BOOST_RV_REF(slist_impl) x)
353 { this->swap(x); return *this; } 345 { this->swap(x); return *this; }
354 346
355 #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
356 //! <b>Effects</b>: If it's a safe-mode 347 //! <b>Effects</b>: If it's a safe-mode
357 //! or auto-unlink value, the destructor does nothing 348 //! or auto-unlink value, the destructor does nothing
358 //! (ie. no code is generated). Otherwise it detaches all elements from this. 349 //! (ie. no code is generated). Otherwise it detaches all elements from this.
359 //! In this case the objects in the list are not deleted (i.e. no destructors 350 //! In this case the objects in the list are not deleted (i.e. no destructors
360 //! are called), but the hooks according to the value_traits template parameter 351 //! are called), but the hooks according to the value_traits template parameter
361 //! are set to their default value. 352 //! are set to their default value.
362 //! 353 //!
363 //! <b>Complexity</b>: Linear to the number of elements in the list, if 354 //! <b>Complexity</b>: Linear to the number of elements in the list, if
364 //! it's a safe-mode or auto-unlink value. Otherwise constant. 355 //! it's a safe-mode or auto-unlink value. Otherwise constant.
365 ~slist_impl() 356 ~slist_impl()
366 {} 357 {
367 #endif 358 if(is_safe_autounlink<ValueTraits::link_mode>::value){
359 this->clear();
360 node_algorithms::init(this->get_root_node());
361 }
362 }
368 363
369 //! <b>Effects</b>: Erases all the elements of the container. 364 //! <b>Effects</b>: Erases all the elements of the container.
370 //! 365 //!
371 //! <b>Throws</b>: Nothing. 366 //! <b>Throws</b>: Nothing.
372 //! 367 //!
401 while(it != itend){ 396 while(it != itend){
402 node_ptr to_erase(it.pointed_node()); 397 node_ptr to_erase(it.pointed_node());
403 ++it; 398 ++it;
404 if(safemode_or_autounlink) 399 if(safemode_or_autounlink)
405 node_algorithms::init(to_erase); 400 node_algorithms::init(to_erase);
406 disposer(get_real_value_traits().to_value_ptr(to_erase)); 401 disposer(priv_value_traits().to_value_ptr(to_erase));
407 } 402 }
408 this->set_default_constructed_state(); 403 this->set_default_constructed_state();
409 } 404 }
410 405
411 //! <b>Requires</b>: value must be an lvalue. 406 //! <b>Requires</b>: value must be an lvalue.
418 //! <b>Complexity</b>: Constant. 413 //! <b>Complexity</b>: Constant.
419 //! 414 //!
420 //! <b>Note</b>: Does not affect the validity of iterators and references. 415 //! <b>Note</b>: Does not affect the validity of iterators and references.
421 void push_front(reference value) 416 void push_front(reference value)
422 { 417 {
423 node_ptr to_insert = get_real_value_traits().to_node_ptr(value); 418 node_ptr to_insert = priv_value_traits().to_node_ptr(value);
424 if(safemode_or_autounlink) 419 if(safemode_or_autounlink)
425 BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::inited(to_insert)); 420 BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::inited(to_insert));
426 if(cache_last){ 421 if(cache_last){
427 if(this->empty()){ 422 if(this->empty()){
428 this->set_last_node(to_insert); 423 this->set_last_node(to_insert);
444 //! <b>Note</b>: Does not affect the validity of iterators and references. 439 //! <b>Note</b>: Does not affect the validity of iterators and references.
445 //! This function is only available is cache_last<> is true. 440 //! This function is only available is cache_last<> is true.
446 void push_back(reference value) 441 void push_back(reference value)
447 { 442 {
448 BOOST_STATIC_ASSERT((cache_last)); 443 BOOST_STATIC_ASSERT((cache_last));
449 node_ptr n = get_real_value_traits().to_node_ptr(value); 444 node_ptr n = priv_value_traits().to_node_ptr(value);
450 if(safemode_or_autounlink) 445 if(safemode_or_autounlink)
451 BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::inited(n)); 446 BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::inited(n));
452 node_algorithms::link_after(this->get_last_node(), n); 447 node_algorithms::link_after(this->get_last_node(), n);
453 if(cache_last){ 448 if(cache_last){
454 this->set_last_node(n); 449 this->set_last_node(n);
483 node_ptr to_erase = node_traits::get_next(this->get_root_node()); 478 node_ptr to_erase = node_traits::get_next(this->get_root_node());
484 node_algorithms::unlink_after(this->get_root_node()); 479 node_algorithms::unlink_after(this->get_root_node());
485 this->priv_size_traits().decrement(); 480 this->priv_size_traits().decrement();
486 if(safemode_or_autounlink) 481 if(safemode_or_autounlink)
487 node_algorithms::init(to_erase); 482 node_algorithms::init(to_erase);
488 disposer(get_real_value_traits().to_value_ptr(to_erase)); 483 disposer(priv_value_traits().to_value_ptr(to_erase));
489 if(cache_last){ 484 if(cache_last){
490 if(this->empty()){ 485 if(this->empty()){
491 this->set_last_node(this->get_root_node()); 486 this->set_last_node(this->get_root_node());
492 } 487 }
493 } 488 }
497 //! 492 //!
498 //! <b>Throws</b>: Nothing. 493 //! <b>Throws</b>: Nothing.
499 //! 494 //!
500 //! <b>Complexity</b>: Constant. 495 //! <b>Complexity</b>: Constant.
501 reference front() 496 reference front()
502 { return *this->get_real_value_traits().to_value_ptr(node_traits::get_next(this->get_root_node())); } 497 { return *this->priv_value_traits().to_value_ptr(node_traits::get_next(this->get_root_node())); }
503 498
504 //! <b>Effects</b>: Returns a const_reference to the first element of the list. 499 //! <b>Effects</b>: Returns a const_reference to the first element of the list.
505 //! 500 //!
506 //! <b>Throws</b>: Nothing. 501 //! <b>Throws</b>: Nothing.
507 //! 502 //!
508 //! <b>Complexity</b>: Constant. 503 //! <b>Complexity</b>: Constant.
509 const_reference front() const 504 const_reference front() const
510 { return *this->get_real_value_traits().to_value_ptr(detail::uncast(node_traits::get_next(this->get_root_node()))); } 505 { return *this->priv_value_traits().to_value_ptr(detail::uncast(node_traits::get_next(this->get_root_node()))); }
511 506
512 //! <b>Effects</b>: Returns a reference to the last element of the list. 507 //! <b>Effects</b>: Returns a reference to the last element of the list.
513 //! 508 //!
514 //! <b>Throws</b>: Nothing. 509 //! <b>Throws</b>: Nothing.
515 //! 510 //!
518 //! <b>Note</b>: Does not affect the validity of iterators and references. 513 //! <b>Note</b>: Does not affect the validity of iterators and references.
519 //! This function is only available is cache_last<> is true. 514 //! This function is only available is cache_last<> is true.
520 reference back() 515 reference back()
521 { 516 {
522 BOOST_STATIC_ASSERT((cache_last)); 517 BOOST_STATIC_ASSERT((cache_last));
523 return *this->get_real_value_traits().to_value_ptr(this->get_last_node()); 518 return *this->priv_value_traits().to_value_ptr(this->get_last_node());
524 } 519 }
525 520
526 //! <b>Effects</b>: Returns a const_reference to the last element of the list. 521 //! <b>Effects</b>: Returns a const_reference to the last element of the list.
527 //! 522 //!
528 //! <b>Throws</b>: Nothing. 523 //! <b>Throws</b>: Nothing.
532 //! <b>Note</b>: Does not affect the validity of iterators and references. 527 //! <b>Note</b>: Does not affect the validity of iterators and references.
533 //! This function is only available is cache_last<> is true. 528 //! This function is only available is cache_last<> is true.
534 const_reference back() const 529 const_reference back() const
535 { 530 {
536 BOOST_STATIC_ASSERT((cache_last)); 531 BOOST_STATIC_ASSERT((cache_last));
537 return *this->get_real_value_traits().to_value_ptr(this->get_last_node()); 532 return *this->priv_value_traits().to_value_ptr(this->get_last_node());
538 } 533 }
539 534
540 //! <b>Effects</b>: Returns an iterator to the first element contained in the list. 535 //! <b>Effects</b>: Returns an iterator to the first element contained in the list.
541 //! 536 //!
542 //! <b>Throws</b>: Nothing. 537 //! <b>Throws</b>: Nothing.
543 //! 538 //!
544 //! <b>Complexity</b>: Constant. 539 //! <b>Complexity</b>: Constant.
545 iterator begin() 540 iterator begin()
546 { return iterator (node_traits::get_next(this->get_root_node()), this->real_value_traits_ptr()); } 541 { return iterator (node_traits::get_next(this->get_root_node()), this->priv_value_traits_ptr()); }
547 542
548 //! <b>Effects</b>: Returns a const_iterator to the first element contained in the list. 543 //! <b>Effects</b>: Returns a const_iterator to the first element contained in the list.
549 //! 544 //!
550 //! <b>Throws</b>: Nothing. 545 //! <b>Throws</b>: Nothing.
551 //! 546 //!
552 //! <b>Complexity</b>: Constant. 547 //! <b>Complexity</b>: Constant.
553 const_iterator begin() const 548 const_iterator begin() const
554 { return const_iterator (node_traits::get_next(this->get_root_node()), this->real_value_traits_ptr()); } 549 { return const_iterator (node_traits::get_next(this->get_root_node()), this->priv_value_traits_ptr()); }
555 550
556 //! <b>Effects</b>: Returns a const_iterator to the first element contained in the list. 551 //! <b>Effects</b>: Returns a const_iterator to the first element contained in the list.
557 //! 552 //!
558 //! <b>Throws</b>: Nothing. 553 //! <b>Throws</b>: Nothing.
559 //! 554 //!
560 //! <b>Complexity</b>: Constant. 555 //! <b>Complexity</b>: Constant.
561 const_iterator cbegin() const 556 const_iterator cbegin() const
562 { return const_iterator(node_traits::get_next(this->get_root_node()), this->real_value_traits_ptr()); } 557 { return const_iterator(node_traits::get_next(this->get_root_node()), this->priv_value_traits_ptr()); }
563 558
564 //! <b>Effects</b>: Returns an iterator to the end of the list. 559 //! <b>Effects</b>: Returns an iterator to the end of the list.
565 //! 560 //!
566 //! <b>Throws</b>: Nothing. 561 //! <b>Throws</b>: Nothing.
567 //! 562 //!
568 //! <b>Complexity</b>: Constant. 563 //! <b>Complexity</b>: Constant.
569 iterator end() 564 iterator end()
570 { return iterator(this->get_end_node(), this->real_value_traits_ptr()); } 565 { return iterator(this->get_end_node(), this->priv_value_traits_ptr()); }
571 566
572 //! <b>Effects</b>: Returns a const_iterator to the end of the list. 567 //! <b>Effects</b>: Returns a const_iterator to the end of the list.
573 //! 568 //!
574 //! <b>Throws</b>: Nothing. 569 //! <b>Throws</b>: Nothing.
575 //! 570 //!
576 //! <b>Complexity</b>: Constant. 571 //! <b>Complexity</b>: Constant.
577 const_iterator end() const 572 const_iterator end() const
578 { return const_iterator(detail::uncast(this->get_end_node()), this->real_value_traits_ptr()); } 573 { return const_iterator(detail::uncast(this->get_end_node()), this->priv_value_traits_ptr()); }
579 574
580 //! <b>Effects</b>: Returns a const_iterator to the end of the list. 575 //! <b>Effects</b>: Returns a const_iterator to the end of the list.
581 //! 576 //!
582 //! <b>Throws</b>: Nothing. 577 //! <b>Throws</b>: Nothing.
583 //! 578 //!
590 //! 585 //!
591 //! <b>Throws</b>: Nothing. 586 //! <b>Throws</b>: Nothing.
592 //! 587 //!
593 //! <b>Complexity</b>: Constant. 588 //! <b>Complexity</b>: Constant.
594 iterator before_begin() 589 iterator before_begin()
595 { return iterator(this->get_root_node(), this->real_value_traits_ptr()); } 590 { return iterator(this->get_root_node(), this->priv_value_traits_ptr()); }
596 591
597 //! <b>Effects</b>: Returns an iterator that points to a position 592 //! <b>Effects</b>: Returns an iterator that points to a position
598 //! before the first element. Equivalent to "end()" 593 //! before the first element. Equivalent to "end()"
599 //! 594 //!
600 //! <b>Throws</b>: Nothing. 595 //! <b>Throws</b>: Nothing.
601 //! 596 //!
602 //! <b>Complexity</b>: Constant. 597 //! <b>Complexity</b>: Constant.
603 const_iterator before_begin() const 598 const_iterator before_begin() const
604 { return const_iterator(detail::uncast(this->get_root_node()), this->real_value_traits_ptr()); } 599 { return const_iterator(detail::uncast(this->get_root_node()), this->priv_value_traits_ptr()); }
605 600
606 //! <b>Effects</b>: Returns an iterator that points to a position 601 //! <b>Effects</b>: Returns an iterator that points to a position
607 //! before the first element. Equivalent to "end()" 602 //! before the first element. Equivalent to "end()"
608 //! 603 //!
609 //! <b>Throws</b>: Nothing. 604 //! <b>Throws</b>: Nothing.
621 //! <b>Note</b>: This function is present only if cached_last<> option is true. 616 //! <b>Note</b>: This function is present only if cached_last<> option is true.
622 iterator last() 617 iterator last()
623 { 618 {
624 //This function shall not be used if cache_last is not true 619 //This function shall not be used if cache_last is not true
625 BOOST_INTRUSIVE_INVARIANT_ASSERT(cache_last); 620 BOOST_INTRUSIVE_INVARIANT_ASSERT(cache_last);
626 return iterator (this->get_last_node(), this->real_value_traits_ptr()); 621 return iterator (this->get_last_node(), this->priv_value_traits_ptr());
627 } 622 }
628 623
629 //! <b>Effects</b>: Returns a const_iterator to the last element contained in the list. 624 //! <b>Effects</b>: Returns a const_iterator to the last element contained in the list.
630 //! 625 //!
631 //! <b>Throws</b>: Nothing. 626 //! <b>Throws</b>: Nothing.
635 //! <b>Note</b>: This function is present only if cached_last<> option is true. 630 //! <b>Note</b>: This function is present only if cached_last<> option is true.
636 const_iterator last() const 631 const_iterator last() const
637 { 632 {
638 //This function shall not be used if cache_last is not true 633 //This function shall not be used if cache_last is not true
639 BOOST_INTRUSIVE_INVARIANT_ASSERT(cache_last); 634 BOOST_INTRUSIVE_INVARIANT_ASSERT(cache_last);
640 return const_iterator (this->get_last_node(), this->real_value_traits_ptr()); 635 return const_iterator (this->get_last_node(), this->priv_value_traits_ptr());
641 } 636 }
642 637
643 //! <b>Effects</b>: Returns a const_iterator to the last element contained in the list. 638 //! <b>Effects</b>: Returns a const_iterator to the last element contained in the list.
644 //! 639 //!
645 //! <b>Throws</b>: Nothing. 640 //! <b>Throws</b>: Nothing.
646 //! 641 //!
647 //! <b>Complexity</b>: Constant. 642 //! <b>Complexity</b>: Constant.
648 //! 643 //!
649 //! <b>Note</b>: This function is present only if cached_last<> option is true. 644 //! <b>Note</b>: This function is present only if cached_last<> option is true.
650 const_iterator clast() const 645 const_iterator clast() const
651 { return const_iterator(this->get_last_node(), this->real_value_traits_ptr()); } 646 { return const_iterator(this->get_last_node(), this->priv_value_traits_ptr()); }
652 647
653 //! <b>Precondition</b>: end_iterator must be a valid end iterator 648 //! <b>Precondition</b>: end_iterator must be a valid end iterator
654 //! of slist. 649 //! of slist.
655 //! 650 //!
656 //! <b>Effects</b>: Returns a const reference to the slist associated to the end iterator 651 //! <b>Effects</b>: Returns a const reference to the slist associated to the end iterator
786 //! <b>Complexity</b>: Constant. 781 //! <b>Complexity</b>: Constant.
787 //! 782 //!
788 //! <b>Note</b>: Does not affect the validity of iterators and references. 783 //! <b>Note</b>: Does not affect the validity of iterators and references.
789 iterator insert_after(const_iterator prev_p, reference value) 784 iterator insert_after(const_iterator prev_p, reference value)
790 { 785 {
791 node_ptr n = get_real_value_traits().to_node_ptr(value); 786 node_ptr n = priv_value_traits().to_node_ptr(value);
792 if(safemode_or_autounlink) 787 if(safemode_or_autounlink)
793 BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::inited(n)); 788 BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::inited(n));
794 node_ptr prev_n(prev_p.pointed_node()); 789 node_ptr prev_n(prev_p.pointed_node());
795 node_algorithms::link_after(prev_n, n); 790 node_algorithms::link_after(prev_n, n);
796 if(cache_last && (this->get_last_node() == prev_n)){ 791 if(cache_last && (this->get_last_node() == prev_n)){
797 this->set_last_node(n); 792 this->set_last_node(n);
798 } 793 }
799 this->priv_size_traits().increment(); 794 this->priv_size_traits().increment();
800 return iterator (n, this->real_value_traits_ptr()); 795 return iterator (n, this->priv_value_traits_ptr());
801 } 796 }
802 797
803 //! <b>Requires</b>: Dereferencing iterator must yield 798 //! <b>Requires</b>: Dereferencing iterator must yield
804 //! an lvalue of type value_type and prev_p must point to an element 799 //! an lvalue of type value_type and prev_p must point to an element
805 //! contained by the list or to the end node. 800 //! contained by the list or to the end node.
817 { 812 {
818 //Insert first nodes avoiding cache and size checks 813 //Insert first nodes avoiding cache and size checks
819 size_type count = 0; 814 size_type count = 0;
820 node_ptr prev_n(prev_p.pointed_node()); 815 node_ptr prev_n(prev_p.pointed_node());
821 for (; f != l; ++f, ++count){ 816 for (; f != l; ++f, ++count){
822 const node_ptr n = get_real_value_traits().to_node_ptr(*f); 817 const node_ptr n = priv_value_traits().to_node_ptr(*f);
823 if(safemode_or_autounlink) 818 if(safemode_or_autounlink)
824 BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::inited(n)); 819 BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::inited(n));
825 node_algorithms::link_after(prev_n, n); 820 node_algorithms::link_after(prev_n, n);
826 prev_n = n; 821 prev_n = n;
827 } 822 }
912 return l.unconst(); 907 return l.unconst();
913 } 908 }
914 } 909 }
915 910
916 //! <b>Effects</b>: Erases the range (before_f, l) from 911 //! <b>Effects</b>: Erases the range (before_f, l) from
917 //! the list. n must be std::distance(before_f, l) - 1. 912 //! the list. n must be distance(before_f, l) - 1.
918 //! No destructors are called. 913 //! No destructors are called.
919 //! 914 //!
920 //! <b>Returns</b>: the first element remaining beyond the removed elements, 915 //! <b>Returns</b>: the first element remaining beyond the removed elements,
921 //! or end() if no such element exists. 916 //! or end() if no such element exists.
922 //! 917 //!
927 //! 922 //!
928 //! <b>Note</b>: Invalidates the iterators (but not the references) to the 923 //! <b>Note</b>: Invalidates the iterators (but not the references) to the
929 //! erased element. 924 //! erased element.
930 iterator erase_after(const_iterator before_f, const_iterator l, size_type n) 925 iterator erase_after(const_iterator before_f, const_iterator l, size_type n)
931 { 926 {
932 BOOST_INTRUSIVE_INVARIANT_ASSERT(std::distance(++const_iterator(before_f), l) == difference_type(n)); 927 BOOST_INTRUSIVE_INVARIANT_ASSERT(node_algorithms::distance((++const_iterator(before_f)).pointed_node(), l.pointed_node()) == n);
933 if(safemode_or_autounlink){ 928 if(safemode_or_autounlink){
934 return this->erase_after(before_f, l); 929 return this->erase_after(before_f, l);
935 } 930 }
936 else{ 931 else{
937 const node_ptr bfp = before_f.pointed_node(); 932 const node_ptr bfp = before_f.pointed_node();
980 //! erased elements. 975 //! erased elements.
981 iterator erase(const_iterator f, const_iterator l) 976 iterator erase(const_iterator f, const_iterator l)
982 { return this->erase_after(this->previous(f), l); } 977 { return this->erase_after(this->previous(f), l); }
983 978
984 //! <b>Effects</b>: Erases the range [f, l) from 979 //! <b>Effects</b>: Erases the range [f, l) from
985 //! the list. n must be std::distance(f, l). 980 //! the list. n must be distance(f, l).
986 //! No destructors are called. 981 //! No destructors are called.
987 //! 982 //!
988 //! <b>Returns</b>: the first element remaining beyond the removed elements, 983 //! <b>Returns</b>: the first element remaining beyond the removed elements,
989 //! or end() if no such element exists. 984 //! or end() if no such element exists.
990 //! 985 //!
1024 if(cache_last && (to_erase == this->get_last_node())){ 1019 if(cache_last && (to_erase == this->get_last_node())){
1025 this->set_last_node(prev_n); 1020 this->set_last_node(prev_n);
1026 } 1021 }
1027 if(safemode_or_autounlink) 1022 if(safemode_or_autounlink)
1028 node_algorithms::init(to_erase); 1023 node_algorithms::init(to_erase);
1029 disposer(get_real_value_traits().to_value_ptr(to_erase)); 1024 disposer(priv_value_traits().to_value_ptr(to_erase));
1030 this->priv_size_traits().decrement(); 1025 this->priv_size_traits().decrement();
1031 return it.unconst(); 1026 return it.unconst();
1032 } 1027 }
1033 1028
1034 /// @cond 1029 /// @cond
1043 ++it; 1038 ++it;
1044 node_ptr prev_n(prev.pointed_node()); 1039 node_ptr prev_n(prev.pointed_node());
1045 node_algorithms::unlink_after(prev_n); 1040 node_algorithms::unlink_after(prev_n);
1046 if(safemode_or_autounlink) 1041 if(safemode_or_autounlink)
1047 node_algorithms::init(to_erase); 1042 node_algorithms::init(to_erase);
1048 disposer(real_value_traits::to_value_ptr(to_erase)); 1043 disposer(value_traits::to_value_ptr(to_erase));
1049 return it.unconst(); 1044 return it.unconst();
1050 } 1045 }
1051 1046
1052 static iterator s_erase_after(const_iterator prev) 1047 static iterator s_erase_after(const_iterator prev)
1053 { return s_erase_after_and_dispose(prev, detail::null_disposer()); } 1048 { return s_erase_after_and_dispose(prev, detail::null_disposer()); }
1077 while(fp != lp){ 1072 while(fp != lp){
1078 node_ptr to_erase(fp); 1073 node_ptr to_erase(fp);
1079 fp = node_traits::get_next(fp); 1074 fp = node_traits::get_next(fp);
1080 if(safemode_or_autounlink) 1075 if(safemode_or_autounlink)
1081 node_algorithms::init(to_erase); 1076 node_algorithms::init(to_erase);
1082 disposer(get_real_value_traits().to_value_ptr(to_erase)); 1077 disposer(priv_value_traits().to_value_ptr(to_erase));
1083 this->priv_size_traits().decrement(); 1078 this->priv_size_traits().decrement();
1084 } 1079 }
1085 if(cache_last && (node_traits::get_next(bfp) == this->get_end_node())){ 1080 if(cache_last && (node_traits::get_next(bfp) == this->get_end_node())){
1086 this->set_last_node(bfp); 1081 this->set_last_node(bfp);
1087 } 1082 }
1261 //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this 1256 //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
1262 //! list. Iterators of this list and all the references are not invalidated. 1257 //! list. Iterators of this list and all the references are not invalidated.
1263 void splice_after(const_iterator prev_pos, slist_impl &x, const_iterator before_f, const_iterator before_l) 1258 void splice_after(const_iterator prev_pos, slist_impl &x, const_iterator before_f, const_iterator before_l)
1264 { 1259 {
1265 if(constant_time_size) 1260 if(constant_time_size)
1266 this->splice_after(prev_pos, x, before_f, before_l, std::distance(before_f, before_l)); 1261 this->splice_after(prev_pos, x, before_f, before_l, node_algorithms::distance(before_f.pointed_node(), before_l.pointed_node()));
1267 else 1262 else
1268 this->priv_splice_after 1263 this->priv_splice_after
1269 (prev_pos.pointed_node(), x, before_f.pointed_node(), before_l.pointed_node()); 1264 (prev_pos.pointed_node(), x, before_f.pointed_node(), before_l.pointed_node());
1270 } 1265 }
1271 1266
1272 //! <b>Requires</b>: prev_pos must be a dereferenceable iterator in *this or be 1267 //! <b>Requires</b>: prev_pos must be a dereferenceable iterator in *this or be
1273 //! before_begin(), and before_f and before_l belong to x and 1268 //! before_begin(), and before_f and before_l belong to x and
1274 //! ++before_f != x.end() && before_l != x.end() and 1269 //! ++before_f != x.end() && before_l != x.end() and
1275 //! n == std::distance(before_f, before_l). 1270 //! n == distance(before_f, before_l).
1276 //! 1271 //!
1277 //! <b>Effects</b>: Transfers the range (before_f, before_l] from list x to this 1272 //! <b>Effects</b>: Transfers the range (before_f, before_l] from list x to this
1278 //! list, after the element pointed by p. No destructors or copy constructors are called. 1273 //! list, after the element pointed by p. No destructors or copy constructors are called.
1279 //! 1274 //!
1280 //! <b>Throws</b>: Nothing. 1275 //! <b>Throws</b>: Nothing.
1283 //! 1278 //!
1284 //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this 1279 //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
1285 //! list. Iterators of this list and all the references are not invalidated. 1280 //! list. Iterators of this list and all the references are not invalidated.
1286 void splice_after(const_iterator prev_pos, slist_impl &x, const_iterator before_f, const_iterator before_l, size_type n) 1281 void splice_after(const_iterator prev_pos, slist_impl &x, const_iterator before_f, const_iterator before_l, size_type n)
1287 { 1282 {
1288 BOOST_INTRUSIVE_INVARIANT_ASSERT(std::distance(before_f, before_l) == difference_type(n)); 1283 BOOST_INTRUSIVE_INVARIANT_ASSERT(node_algorithms::distance(before_f.pointed_node(), before_l.pointed_node()) == n);
1289 this->priv_splice_after 1284 this->priv_splice_after
1290 (prev_pos.pointed_node(), x, before_f.pointed_node(), before_l.pointed_node()); 1285 (prev_pos.pointed_node(), x, before_f.pointed_node(), before_l.pointed_node());
1291 if(constant_time_size){ 1286 if(constant_time_size){
1292 this->priv_size_traits().increase(n); 1287 this->priv_size_traits().increase(n);
1293 x.priv_size_traits().decrease(n); 1288 x.priv_size_traits().decrease(n);
1355 void splice(const_iterator pos, slist_impl &x, const_iterator f, const_iterator l) 1350 void splice(const_iterator pos, slist_impl &x, const_iterator f, const_iterator l)
1356 { return this->splice_after(this->previous(pos), x, x.previous(f), x.previous(l)); } 1351 { return this->splice_after(this->previous(pos), x, x.previous(f), x.previous(l)); }
1357 1352
1358 //! <b>Requires</b>: pos must be a dereferenceable iterator in *this 1353 //! <b>Requires</b>: pos must be a dereferenceable iterator in *this
1359 //! and f and l belong to x and f and l a valid range on x. 1354 //! and f and l belong to x and f and l a valid range on x.
1360 //! n == std::distance(f, l). 1355 //! n == distance(f, l).
1361 //! 1356 //!
1362 //! <b>Effects</b>: Transfers the range [f, l) from list x to this 1357 //! <b>Effects</b>: Transfers the range [f, l) from list x to this
1363 //! list, before the element pointed by pos. 1358 //! list, before the element pointed by pos.
1364 //! No destructors or copy constructors are called. 1359 //! No destructors or copy constructors are called.
1365 //! 1360 //!
1565 //! 1560 //!
1566 //! <b>Note</b>: The relative order of elements that are not removed is unchanged, 1561 //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
1567 //! and iterators to elements that are not removed remain valid. 1562 //! and iterators to elements that are not removed remain valid.
1568 template<class Pred> 1563 template<class Pred>
1569 void remove_if(Pred pred) 1564 void remove_if(Pred pred)
1570 { this->remove_and_dispose_if(pred, detail::null_disposer()); } 1565 {
1566 const node_ptr bbeg = this->get_root_node();
1567 typename node_algorithms::stable_partition_info info;
1568 node_algorithms::stable_partition
1569 (bbeg, this->get_end_node(), detail::key_nodeptr_comp<Pred, value_traits>(pred, &this->priv_value_traits()), info);
1570 //After cache last is set, slist invariants are preserved...
1571 if(cache_last){
1572 this->set_last_node(info.new_last_node);
1573 }
1574 //...so erase can be safely called
1575 this->erase_after( const_iterator(bbeg, this->priv_value_traits_ptr())
1576 , const_iterator(info.beg_2st_partition, this->priv_value_traits_ptr())
1577 , info.num_1st_partition);
1578 }
1571 1579
1572 //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw. 1580 //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
1573 //! 1581 //!
1574 //! <b>Effects</b>: Removes all the elements for which a specified 1582 //! <b>Effects</b>: Removes all the elements for which a specified
1575 //! predicate is satisfied. 1583 //! predicate is satisfied.
1582 //! <b>Note</b>: The relative order of elements that are not removed is unchanged, 1590 //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
1583 //! and iterators to elements that are not removed remain valid. 1591 //! and iterators to elements that are not removed remain valid.
1584 template<class Pred, class Disposer> 1592 template<class Pred, class Disposer>
1585 void remove_and_dispose_if(Pred pred, Disposer disposer) 1593 void remove_and_dispose_if(Pred pred, Disposer disposer)
1586 { 1594 {
1587 const_iterator bcur(this->before_begin()), cur(this->begin()), e(this->end()); 1595 const node_ptr bbeg = this->get_root_node();
1588 1596 typename node_algorithms::stable_partition_info info;
1589 while(cur != e){ 1597 node_algorithms::stable_partition
1590 if (pred(*cur)){ 1598 (bbeg, this->get_end_node(), detail::key_nodeptr_comp<Pred, value_traits>(pred, &this->priv_value_traits()), info);
1591 cur = this->erase_after_and_dispose(bcur, disposer); 1599 //After cache last is set, slist invariants are preserved...
1592 }
1593 else{
1594 bcur = cur;
1595 ++cur;
1596 }
1597 }
1598 if(cache_last){ 1600 if(cache_last){
1599 this->set_last_node(bcur.pointed_node()); 1601 this->set_last_node(info.new_last_node);
1600 } 1602 }
1603 //...so erase can be safely called
1604 this->erase_after_and_dispose( const_iterator(bbeg, this->priv_value_traits_ptr())
1605 , const_iterator(info.beg_2st_partition, this->priv_value_traits_ptr())
1606 , disposer);
1601 } 1607 }
1602 1608
1603 //! <b>Effects</b>: Removes adjacent duplicate elements or adjacent 1609 //! <b>Effects</b>: Removes adjacent duplicate elements or adjacent
1604 //! elements that are equal from the list. No destructors are called. 1610 //! elements that are equal from the list. No destructors are called.
1605 //! 1611 //!
1689 //! This static function is available only if the <i>value traits</i> 1695 //! This static function is available only if the <i>value traits</i>
1690 //! is stateless. 1696 //! is stateless.
1691 static iterator s_iterator_to(reference value) 1697 static iterator s_iterator_to(reference value)
1692 { 1698 {
1693 BOOST_STATIC_ASSERT((!stateful_value_traits)); 1699 BOOST_STATIC_ASSERT((!stateful_value_traits));
1694 //BOOST_INTRUSIVE_INVARIANT_ASSERT (!node_algorithms::inited(value_traits::to_node_ptr(value))); 1700 return iterator (value_traits::to_node_ptr(value), const_value_traits_ptr());
1695 return iterator (value_traits::to_node_ptr(value), const_real_value_traits_ptr());
1696 } 1701 }
1697 1702
1698 //! <b>Requires</b>: value must be a const reference to a value inserted in a list. 1703 //! <b>Requires</b>: value must be a const reference to a value inserted in a list.
1699 //! 1704 //!
1700 //! <b>Effects</b>: This function returns an iterator pointing to the element. 1705 //! <b>Effects</b>: This function returns an iterator pointing to the element.
1707 //! This static function is available only if the <i>value traits</i> 1712 //! This static function is available only if the <i>value traits</i>
1708 //! is stateless. 1713 //! is stateless.
1709 static const_iterator s_iterator_to(const_reference value) 1714 static const_iterator s_iterator_to(const_reference value)
1710 { 1715 {
1711 BOOST_STATIC_ASSERT((!stateful_value_traits)); 1716 BOOST_STATIC_ASSERT((!stateful_value_traits));
1712 //BOOST_INTRUSIVE_INVARIANT_ASSERT (!node_algorithms::inited(value_traits::to_node_ptr(const_cast<reference> (value)))); 1717 reference r =*detail::uncast(pointer_traits<const_pointer>::pointer_to(value));
1713 return const_iterator (value_traits::to_node_ptr(const_cast<reference> (value)), const_real_value_traits_ptr()); 1718 return const_iterator(value_traits::to_node_ptr(r), const_value_traits_ptr());
1714 } 1719 }
1715 1720
1716 //! <b>Requires</b>: value must be a reference to a value inserted in a list. 1721 //! <b>Requires</b>: value must be a reference to a value inserted in a list.
1717 //! 1722 //!
1718 //! <b>Effects</b>: This function returns a const_iterator pointing to the element 1723 //! <b>Effects</b>: This function returns a const_iterator pointing to the element
1722 //! <b>Complexity</b>: Constant time. 1727 //! <b>Complexity</b>: Constant time.
1723 //! 1728 //!
1724 //! <b>Note</b>: Iterators and references are not invalidated. 1729 //! <b>Note</b>: Iterators and references are not invalidated.
1725 iterator iterator_to(reference value) 1730 iterator iterator_to(reference value)
1726 { 1731 {
1727 //BOOST_INTRUSIVE_INVARIANT_ASSERT (!node_algorithms::inited(value_traits::to_node_ptr(value))); 1732 BOOST_INTRUSIVE_INVARIANT_ASSERT(linear || !node_algorithms::inited(this->priv_value_traits().to_node_ptr(value)));
1728 return iterator (value_traits::to_node_ptr(value), this->real_value_traits_ptr()); 1733 return iterator (this->priv_value_traits().to_node_ptr(value), this->priv_value_traits_ptr());
1729 } 1734 }
1730 1735
1731 //! <b>Requires</b>: value must be a const reference to a value inserted in a list. 1736 //! <b>Requires</b>: value must be a const reference to a value inserted in a list.
1732 //! 1737 //!
1733 //! <b>Effects</b>: This function returns an iterator pointing to the element. 1738 //! <b>Effects</b>: This function returns an iterator pointing to the element.
1737 //! <b>Complexity</b>: Constant time. 1742 //! <b>Complexity</b>: Constant time.
1738 //! 1743 //!
1739 //! <b>Note</b>: Iterators and references are not invalidated. 1744 //! <b>Note</b>: Iterators and references are not invalidated.
1740 const_iterator iterator_to(const_reference value) const 1745 const_iterator iterator_to(const_reference value) const
1741 { 1746 {
1742 //BOOST_INTRUSIVE_INVARIANT_ASSERT (!node_algorithms::inited(value_traits::to_node_ptr(const_cast<reference> (value)))); 1747 reference r =*detail::uncast(pointer_traits<const_pointer>::pointer_to(value));
1743 return const_iterator (value_traits::to_node_ptr(const_cast<reference> (value)), this->real_value_traits_ptr()); 1748 BOOST_INTRUSIVE_INVARIANT_ASSERT (linear || !node_algorithms::inited(this->priv_value_traits().to_node_ptr(r)));
1749 return const_iterator(this->priv_value_traits().to_node_ptr(r), this->priv_value_traits_ptr());
1744 } 1750 }
1745 1751
1746 //! <b>Returns</b>: The iterator to the element before i in the list. 1752 //! <b>Returns</b>: The iterator to the element before i in the list.
1747 //! Returns the end-iterator, if either i is the begin-iterator or the 1753 //! Returns the end-iterator, if either i is the begin-iterator or the
1748 //! list is empty. 1754 //! list is empty.
1787 //! <b>Complexity</b>: Linear to the number of elements before i. 1793 //! <b>Complexity</b>: Linear to the number of elements before i.
1788 //! Constant if cache_last<> is true and i == end(). 1794 //! Constant if cache_last<> is true and i == end().
1789 const_iterator previous(const_iterator prev_from, const_iterator i) const 1795 const_iterator previous(const_iterator prev_from, const_iterator i) const
1790 { 1796 {
1791 if(cache_last && (i.pointed_node() == this->get_end_node())){ 1797 if(cache_last && (i.pointed_node() == this->get_end_node())){
1792 return const_iterator(detail::uncast(this->get_last_node()), this->real_value_traits_ptr()); 1798 return const_iterator(detail::uncast(this->get_last_node()), this->priv_value_traits_ptr());
1793 } 1799 }
1794 return const_iterator 1800 return const_iterator
1795 (node_algorithms::get_previous_node 1801 (node_algorithms::get_previous_node
1796 (prev_from.pointed_node(), i.pointed_node()), this->real_value_traits_ptr()); 1802 (prev_from.pointed_node(), i.pointed_node()), this->priv_value_traits_ptr());
1797 } 1803 }
1798 1804
1799 ///@cond 1805 ///@cond
1800 1806
1801 //! <b>Requires</b>: prev_pos must be a dereferenceable iterator in *this or be 1807 //! <b>Requires</b>: prev_pos must be a dereferenceable iterator in *this or be
1815 //! 1821 //!
1816 //! <b>Warning</b>: Experimental function, don't use it! 1822 //! <b>Warning</b>: Experimental function, don't use it!
1817 void incorporate_after(const_iterator prev_pos, const node_ptr & f, const node_ptr & before_l) 1823 void incorporate_after(const_iterator prev_pos, const node_ptr & f, const node_ptr & before_l)
1818 { 1824 {
1819 if(constant_time_size) 1825 if(constant_time_size)
1820 this->incorporate_after(prev_pos, f, before_l, std::distance(f, before_l)+1); 1826 this->incorporate_after(prev_pos, f, before_l, node_algorithms::distance(f.pointed_node(), before_l.pointed_node())+1);
1821 else 1827 else
1822 this->priv_incorporate_after(prev_pos.pointed_node(), f, before_l); 1828 this->priv_incorporate_after(prev_pos.pointed_node(), f, before_l);
1823 } 1829 }
1824 1830
1825 //! <b>Requires</b>: prev_pos must be a dereferenceable iterator in *this or be 1831 //! <b>Requires</b>: prev_pos must be a dereferenceable iterator in *this or be
1826 //! before_begin(), and f and before_l belong to another slist. 1832 //! before_begin(), and f and before_l belong to another slist.
1827 //! n == std::distance(f, before_l) + 1. 1833 //! n == distance(f, before_l) + 1.
1828 //! 1834 //!
1829 //! <b>Effects</b>: Transfers the range [f, before_l] to this 1835 //! <b>Effects</b>: Transfers the range [f, before_l] to this
1830 //! list, after the element pointed by prev_pos. 1836 //! list, after the element pointed by prev_pos.
1831 //! No destructors or copy constructors are called. 1837 //! No destructors or copy constructors are called.
1832 //! 1838 //!
1841 void incorporate_after(const_iterator prev_pos, const node_ptr & f, const node_ptr & before_l, size_type n) 1847 void incorporate_after(const_iterator prev_pos, const node_ptr & f, const node_ptr & before_l, size_type n)
1842 { 1848 {
1843 if(n){ 1849 if(n){
1844 BOOST_INTRUSIVE_INVARIANT_ASSERT(n > 0); 1850 BOOST_INTRUSIVE_INVARIANT_ASSERT(n > 0);
1845 BOOST_INTRUSIVE_INVARIANT_ASSERT 1851 BOOST_INTRUSIVE_INVARIANT_ASSERT
1846 (size_type(std::distance 1852 (size_type(boost::intrusive::iterator_distance
1847 ( iterator(f, this->real_value_traits_ptr()) 1853 ( iterator(f, this->priv_value_traits_ptr())
1848 , iterator(before_l, this->real_value_traits_ptr()))) 1854 , iterator(before_l, this->priv_value_traits_ptr())))
1849 +1 == n); 1855 +1 == n);
1850 this->priv_incorporate_after(prev_pos.pointed_node(), f, before_l); 1856 this->priv_incorporate_after(prev_pos.pointed_node(), f, before_l);
1851 if(constant_time_size){ 1857 if(constant_time_size){
1852 this->priv_size_traits().increase(n); 1858 this->priv_size_traits().increase(n);
1853 } 1859 }
1854 } 1860 }
1855 } 1861 }
1856 1862
1857 ///@endcond 1863 ///@endcond
1864
1865 //! <b>Effects</b>: Asserts the integrity of the container.
1866 //!
1867 //! <b>Complexity</b>: Linear time.
1868 //!
1869 //! <b>Note</b>: The method has no effect when asserts are turned off (e.g., with NDEBUG).
1870 //! Experimental function, interface might change in future versions.
1871 void check() const
1872 {
1873 const_node_ptr header_ptr = get_root_node();
1874 // header's next is never null
1875 BOOST_INTRUSIVE_INVARIANT_ASSERT(node_traits::get_next(header_ptr));
1876 if (node_traits::get_next(header_ptr) == header_ptr)
1877 {
1878 if (constant_time_size)
1879 BOOST_INTRUSIVE_INVARIANT_ASSERT(this->priv_size_traits().get_size() == 0);
1880 return;
1881 }
1882 size_t node_count = 0;
1883 const_node_ptr p = header_ptr;
1884 while (true)
1885 {
1886 const_node_ptr next_p = node_traits::get_next(p);
1887 if (!linear)
1888 {
1889 BOOST_INTRUSIVE_INVARIANT_ASSERT(next_p);
1890 }
1891 else
1892 {
1893 BOOST_INTRUSIVE_INVARIANT_ASSERT(next_p != header_ptr);
1894 }
1895 if ((!linear && next_p == header_ptr) || (linear && !next_p))
1896 {
1897 if (cache_last)
1898 BOOST_INTRUSIVE_INVARIANT_ASSERT(get_last_node() == p);
1899 break;
1900 }
1901 p = next_p;
1902 ++node_count;
1903 }
1904 if (constant_time_size)
1905 BOOST_INTRUSIVE_INVARIANT_ASSERT(this->priv_size_traits().get_size() == node_count);
1906 }
1858 1907
1859 private: 1908 private:
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) 1909 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)
1861 { 1910 {
1862 if (cache_last && (before_f_n != before_l_n)){ 1911 if (cache_last && (before_f_n != before_l_n)){
1980 static slist_impl &priv_container_from_end_iterator(const const_iterator &end_iterator) 2029 static slist_impl &priv_container_from_end_iterator(const const_iterator &end_iterator)
1981 { 2030 {
1982 //Obtaining the container from the end iterator is not possible with linear 2031 //Obtaining the container from the end iterator is not possible with linear
1983 //singly linked lists (because "end" is represented by the null pointer) 2032 //singly linked lists (because "end" is represented by the null pointer)
1984 BOOST_STATIC_ASSERT(!linear); 2033 BOOST_STATIC_ASSERT(!linear);
1985 root_plus_size *r = detail::parent_from_member<root_plus_size, node> 2034 BOOST_STATIC_ASSERT((has_container_from_iterator));
1986 ( boost::intrusive::detail::to_raw_pointer(end_iterator.pointed_node()), (&root_plus_size::root_)); 2035 node_ptr p = end_iterator.pointed_node();
2036 header_holder_type* h = header_holder_type::get_holder(p);
2037 header_holder_plus_last_t* hpl = detail::parent_from_member< header_holder_plus_last_t, header_holder_type>
2038 (h, &header_holder_plus_last_t::header_holder_);
2039 root_plus_size* r = static_cast< root_plus_size* >(hpl);
1987 data_t *d = detail::parent_from_member<data_t, root_plus_size> 2040 data_t *d = detail::parent_from_member<data_t, root_plus_size>
1988 ( r, &data_t::root_plus_size_); 2041 ( r, &data_t::root_plus_size_);
1989 slist_impl *s = detail::parent_from_member<slist_impl, data_t>(d, &slist_impl::data_); 2042 slist_impl *s = detail::parent_from_member<slist_impl, data_t>(d, &slist_impl::data_);
1990 return *s; 2043 return *s;
1991 } 2044 }
1992 }; 2045 };
1993 2046
1994 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) 2047 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
1995 template<class T, class ...Options> 2048 template<class T, class ...Options>
1996 #else 2049 #else
1997 template<class ValueTraits, class SizeType, std::size_t BoolFlags> 2050 template<class ValueTraits, class SizeType, std::size_t BoolFlags, typename HeaderHolder>
1998 #endif 2051 #endif
1999 inline bool operator< 2052 inline bool operator<
2000 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) 2053 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
2001 (const slist_impl<T, Options...> &x, const slist_impl<T, Options...> &y) 2054 (const slist_impl<T, Options...> &x, const slist_impl<T, Options...> &y)
2002 #else 2055 #else
2003 ( const slist_impl<ValueTraits, SizeType, BoolFlags> &x 2056 ( const slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> &x
2004 , const slist_impl<ValueTraits, SizeType, BoolFlags> &y) 2057 , const slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> &y)
2005 #endif 2058 #endif
2006 { return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); } 2059 { return ::boost::intrusive::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
2007 2060
2008 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) 2061 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
2009 template<class T, class ...Options> 2062 template<class T, class ...Options>
2010 #else 2063 #else
2011 template<class ValueTraits, class SizeType, std::size_t BoolFlags> 2064 template<class ValueTraits, class SizeType, std::size_t BoolFlags, typename HeaderHolder>
2012 #endif 2065 #endif
2013 bool operator== 2066 bool operator==
2014 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) 2067 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
2015 (const slist_impl<T, Options...> &x, const slist_impl<T, Options...> &y) 2068 (const slist_impl<T, Options...> &x, const slist_impl<T, Options...> &y)
2016 #else 2069 #else
2017 ( const slist_impl<ValueTraits, SizeType, BoolFlags> &x 2070 ( const slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> &x
2018 , const slist_impl<ValueTraits, SizeType, BoolFlags> &y) 2071 , const slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> &y)
2019 #endif 2072 #endif
2020 { 2073 {
2021 typedef slist_impl<ValueTraits, SizeType, BoolFlags> slist_type; 2074 typedef slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> slist_type;
2022 typedef typename slist_type::const_iterator const_iterator;
2023 const bool C = slist_type::constant_time_size; 2075 const bool C = slist_type::constant_time_size;
2024 if(C && x.size() != y.size()){ 2076 if(C && x.size() != y.size()){
2025 return false; 2077 return false;
2026 } 2078 }
2027 const_iterator end1 = x.end(); 2079 return ::boost::intrusive::algo_equal(x.cbegin(), x.cend(), y.cbegin(), y.cend());
2028
2029 const_iterator i1 = x.begin();
2030 const_iterator i2 = y.begin();
2031 if(C){
2032 while (i1 != end1 && *i1 == *i2) {
2033 ++i1;
2034 ++i2;
2035 }
2036 return i1 == end1;
2037 }
2038 else{
2039 const_iterator end2 = y.end();
2040 while (i1 != end1 && i2 != end2 && *i1 == *i2) {
2041 ++i1;
2042 ++i2;
2043 }
2044 return i1 == end1 && i2 == end2;
2045 }
2046 } 2080 }
2047 2081
2048 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) 2082 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
2049 template<class T, class ...Options> 2083 template<class T, class ...Options>
2050 #else 2084 #else
2051 template<class ValueTraits, class SizeType, std::size_t BoolFlags> 2085 template<class ValueTraits, class SizeType, std::size_t BoolFlags, typename HeaderHolder>
2052 #endif 2086 #endif
2053 inline bool operator!= 2087 inline bool operator!=
2054 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) 2088 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
2055 (const slist_impl<T, Options...> &x, const slist_impl<T, Options...> &y) 2089 (const slist_impl<T, Options...> &x, const slist_impl<T, Options...> &y)
2056 #else 2090 #else
2057 ( const slist_impl<ValueTraits, SizeType, BoolFlags> &x 2091 ( const slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> &x
2058 , const slist_impl<ValueTraits, SizeType, BoolFlags> &y) 2092 , const slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> &y)
2059 #endif 2093 #endif
2060 { return !(x == y); } 2094 { return !(x == y); }
2061 2095
2062 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) 2096 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
2063 template<class T, class ...Options> 2097 template<class T, class ...Options>
2064 #else 2098 #else
2065 template<class ValueTraits, class SizeType, std::size_t BoolFlags> 2099 template<class ValueTraits, class SizeType, std::size_t BoolFlags, typename HeaderHolder>
2066 #endif 2100 #endif
2067 inline bool operator> 2101 inline bool operator>
2068 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) 2102 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
2069 (const slist_impl<T, Options...> &x, const slist_impl<T, Options...> &y) 2103 (const slist_impl<T, Options...> &x, const slist_impl<T, Options...> &y)
2070 #else 2104 #else
2071 ( const slist_impl<ValueTraits, SizeType, BoolFlags> &x 2105 ( const slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> &x
2072 , const slist_impl<ValueTraits, SizeType, BoolFlags> &y) 2106 , const slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> &y)
2073 #endif 2107 #endif
2074 { return y < x; } 2108 { return y < x; }
2075 2109
2076 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) 2110 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
2077 template<class T, class ...Options> 2111 template<class T, class ...Options>
2078 #else 2112 #else
2079 template<class ValueTraits, class SizeType, std::size_t BoolFlags> 2113 template<class ValueTraits, class SizeType, std::size_t BoolFlags, typename HeaderHolder>
2080 #endif 2114 #endif
2081 inline bool operator<= 2115 inline bool operator<=
2082 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) 2116 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
2083 (const slist_impl<T, Options...> &x, const slist_impl<T, Options...> &y) 2117 (const slist_impl<T, Options...> &x, const slist_impl<T, Options...> &y)
2084 #else 2118 #else
2085 ( const slist_impl<ValueTraits, SizeType, BoolFlags> &x 2119 ( const slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> &x
2086 , const slist_impl<ValueTraits, SizeType, BoolFlags> &y) 2120 , const slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> &y)
2087 #endif 2121 #endif
2088 { return !(y < x); } 2122 { return !(y < x); }
2089 2123
2090 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) 2124 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
2091 template<class T, class ...Options> 2125 template<class T, class ...Options>
2092 #else 2126 #else
2093 template<class ValueTraits, class SizeType, std::size_t BoolFlags> 2127 template<class ValueTraits, class SizeType, std::size_t BoolFlags, typename HeaderHolder>
2094 #endif 2128 #endif
2095 inline bool operator>= 2129 inline bool operator>=
2096 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) 2130 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
2097 (const slist_impl<T, Options...> &x, const slist_impl<T, Options...> &y) 2131 (const slist_impl<T, Options...> &x, const slist_impl<T, Options...> &y)
2098 #else 2132 #else
2099 ( const slist_impl<ValueTraits, SizeType, BoolFlags> &x 2133 ( const slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> &x
2100 , const slist_impl<ValueTraits, SizeType, BoolFlags> &y) 2134 , const slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> &y)
2101 #endif 2135 #endif
2102 { return !(x < y); } 2136 { return !(x < y); }
2103 2137
2104 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) 2138 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
2105 template<class T, class ...Options> 2139 template<class T, class ...Options>
2106 #else 2140 #else
2107 template<class ValueTraits, class SizeType, std::size_t BoolFlags> 2141 template<class ValueTraits, class SizeType, std::size_t BoolFlags, typename HeaderHolder>
2108 #endif 2142 #endif
2109 inline void swap 2143 inline void swap
2110 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) 2144 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
2111 (slist_impl<T, Options...> &x, slist_impl<T, Options...> &y) 2145 (slist_impl<T, Options...> &x, slist_impl<T, Options...> &y)
2112 #else 2146 #else
2113 ( slist_impl<ValueTraits, SizeType, BoolFlags> &x 2147 ( slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> &x
2114 , slist_impl<ValueTraits, SizeType, BoolFlags> &y) 2148 , slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> &y)
2115 #endif 2149 #endif
2116 { x.swap(y); } 2150 { x.swap(y); }
2117 2151
2118 //! Helper metafunction to define a \c slist that yields to the same type when the 2152 //! Helper metafunction to define a \c slist that yields to the same type when the
2119 //! same options (either explicitly or implicitly) are used. 2153 //! same options (either explicitly or implicitly) are used.
2120 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) 2154 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
2121 template<class T, class ...Options> 2155 template<class T, class ...Options>
2122 #else 2156 #else
2123 template<class T, class O1 = void, class O2 = void, class O3 = void, class O4 = void, class O5 = void> 2157 template<class T, class O1 = void, class O2 = void, class O3 = void, class O4 = void, class O5 = void, class O6 = void>
2124 #endif 2158 #endif
2125 struct make_slist 2159 struct make_slist
2126 { 2160 {
2127 /// @cond 2161 /// @cond
2128 typedef typename pack_options 2162 typedef typename pack_options
2129 < slist_defaults, 2163 < slist_defaults,
2130 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) 2164 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
2131 O1, O2, O3, O4, O5 2165 O1, O2, O3, O4, O5, O6
2132 #else 2166 #else
2133 Options... 2167 Options...
2134 #endif 2168 #endif
2135 >::type packed_options; 2169 >::type packed_options;
2170
2136 typedef typename detail::get_value_traits 2171 typedef typename detail::get_value_traits
2137 <T, typename packed_options::proto_value_traits>::type value_traits; 2172 <T, typename packed_options::proto_value_traits>::type value_traits;
2138 typedef slist_impl 2173 typedef slist_impl
2139 < value_traits 2174 < value_traits
2140 , typename packed_options::size_type 2175 , typename packed_options::size_type
2141 , (std::size_t(packed_options::linear)*slist_bool_flags::linear_pos) 2176 , (std::size_t(packed_options::linear)*slist_bool_flags::linear_pos)
2142 |(std::size_t(packed_options::constant_time_size)*slist_bool_flags::constant_time_size_pos) 2177 |(std::size_t(packed_options::constant_time_size)*slist_bool_flags::constant_time_size_pos)
2143 |(std::size_t(packed_options::cache_last)*slist_bool_flags::cache_last_pos) 2178 |(std::size_t(packed_options::cache_last)*slist_bool_flags::cache_last_pos)
2179 , typename packed_options::header_holder_type
2144 > implementation_defined; 2180 > implementation_defined;
2145 /// @endcond 2181 /// @endcond
2146 typedef implementation_defined type; 2182 typedef implementation_defined type;
2147 }; 2183 };
2148 2184
2149 2185
2150 #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED 2186 #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
2151 2187
2152 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) 2188 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
2153 template<class T, class O1, class O2, class O3, class O4, class O5> 2189 template<class T, class O1, class O2, class O3, class O4, class O5, class O6>
2154 #else 2190 #else
2155 template<class T, class ...Options> 2191 template<class T, class ...Options>
2156 #endif 2192 #endif
2157 class slist 2193 class slist
2158 : public make_slist<T, 2194 : public make_slist<T,
2159 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) 2195 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
2160 O1, O2, O3, O4, O5 2196 O1, O2, O3, O4, O5, O6
2161 #else 2197 #else
2162 Options... 2198 Options...
2163 #endif 2199 #endif
2164 >::type 2200 >::type
2165 { 2201 {
2166 typedef typename make_slist 2202 typedef typename make_slist
2167 <T, 2203 <T,
2168 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) 2204 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
2169 O1, O2, O3, O4, O5 2205 O1, O2, O3, O4, O5, O6
2170 #else 2206 #else
2171 Options... 2207 Options...
2172 #endif 2208 #endif
2173 >::type Base; 2209 >::type Base;
2174 typedef typename Base::real_value_traits real_value_traits;
2175 //Assert if passed value traits are compatible with the type 2210 //Assert if passed value traits are compatible with the type
2176 BOOST_STATIC_ASSERT((detail::is_same<typename real_value_traits::value_type, T>::value)); 2211 BOOST_STATIC_ASSERT((detail::is_same<typename Base::value_traits::value_type, T>::value));
2177 BOOST_MOVABLE_BUT_NOT_COPYABLE(slist) 2212 BOOST_MOVABLE_BUT_NOT_COPYABLE(slist)
2178 2213
2179 public: 2214 public:
2180 typedef typename Base::value_traits value_traits; 2215 typedef typename Base::value_traits value_traits;
2181 typedef typename Base::iterator iterator; 2216 typedef typename Base::iterator iterator;
2198 slist(Iterator b, Iterator e, const value_traits &v_traits = value_traits()) 2233 slist(Iterator b, Iterator e, const value_traits &v_traits = value_traits())
2199 : Base(b, e, v_traits) 2234 : Base(b, e, v_traits)
2200 {} 2235 {}
2201 2236
2202 slist(BOOST_RV_REF(slist) x) 2237 slist(BOOST_RV_REF(slist) x)
2203 : Base(::boost::move(static_cast<Base&>(x))) 2238 : Base(BOOST_MOVE_BASE(Base, x))
2204 {} 2239 {}
2205 2240
2206 slist& operator=(BOOST_RV_REF(slist) x) 2241 slist& operator=(BOOST_RV_REF(slist) x)
2207 { return static_cast<slist &>(this->Base::operator=(::boost::move(static_cast<Base&>(x)))); } 2242 { return static_cast<slist &>(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); }
2208 2243
2209 static slist &container_from_end_iterator(iterator end_iterator) 2244 static slist &container_from_end_iterator(iterator end_iterator)
2210 { return static_cast<slist &>(Base::container_from_end_iterator(end_iterator)); } 2245 { return static_cast<slist &>(Base::container_from_end_iterator(end_iterator)); }
2211 2246
2212 static const slist &container_from_end_iterator(const_iterator end_iterator) 2247 static const slist &container_from_end_iterator(const_iterator end_iterator)