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