1 /////////////////////////////////////////////////////////////////////////////
\r
3 // (C) Copyright Olaf Krzikalla 2004-2006.
\r
4 // (C) Copyright Ion GaztaƱaga 2006-2007
\r
6 // Distributed under the Boost Software License, Version 1.0.
\r
7 // (See accompanying file LICENSE_1_0.txt or copy at
\r
8 // http://www.boost.org/LICENSE_1_0.txt)
\r
10 // See http://www.boost.org/libs/intrusive for documentation.
\r
12 /////////////////////////////////////////////////////////////////////////////
\r
14 #ifndef BOOST_INTRUSIVE_ISLIST_HOOK_HPP
\r
15 #define BOOST_INTRUSIVE_ISLIST_HOOK_HPP
\r
17 #include "detail/config_begin.hpp"
\r
18 #include "detail/utilities.hpp"
\r
19 #include "detail/pointer_type.hpp"
\r
20 #include "detail/pointer_to_other.hpp"
\r
21 #include "detail/slist_node.hpp"
\r
22 #include "slist_algorithms.hpp"
\r
23 #include "linking_policy.hpp"
\r
24 #include <boost/get_pointer.hpp>
\r
25 #include <stdexcept>
\r
28 namespace intrusive {
\r
30 //! Derive a class from islist_base_hook in order to store objects in
\r
31 //! in an islist. islist_base_hook holds the data necessary to maintain the
\r
32 //! list and provides an appropriate value_traits class for islist.
\r
34 //! The first integer template argument defines a tag to identify the node.
\r
35 //! The same tag value can be used in different classes, but if a class is
\r
36 //! derived from more than one islist_base_hook, then each islist_base_hook needs its
\r
39 //! The second boolean template parameter will activate the safe-mode checks
\r
40 //! if it's configured as "true".
\r
42 //! The third argument is the pointer type that will be used internally in the hook
\r
43 //! and the islist configured from this hook.
\r
44 template<typename Tag, bool SafeMode = true, class VoidPointer = void*>
\r
45 class islist_base_hook
\r
46 : private detail::slist_node_traits<VoidPointer>::node
\r
49 typedef detail::slist_node_traits<VoidPointer> node_traits;
\r
50 enum { linking_policy = SafeMode? safe_mode_link : normal_link};
\r
53 typedef slist_algorithms<node_traits> node_algorithms;
\r
56 typedef typename node_traits::node node;
\r
57 typedef islist_base_hook
\r
58 <Tag, SafeMode, VoidPointer> this_type;
\r
59 typedef typename boost::pointer_to_other
\r
60 <VoidPointer, node>::type node_ptr;
\r
61 typedef typename boost::pointer_to_other
\r
62 <VoidPointer, const node>::type const_node_ptr;
\r
63 typedef typename boost::pointer_to_other
\r
64 <VoidPointer, this_type>::type this_type_ptr;
\r
65 typedef typename boost::pointer_to_other
\r
66 <VoidPointer, const this_type>::type const_this_type_ptr;
\r
69 node_ptr this_as_node()
\r
70 { return node_ptr(static_cast<node *const>(this)); }
\r
72 const_node_ptr this_as_node() const
\r
73 { return const_node_ptr(static_cast<const node *const>(this)); }
\r
77 //! <b>Effects</b>: If SafeMode is true initializes the node
\r
78 //! to an unlinked state.
\r
80 //! <b>Throws</b>: Nothing.
\r
82 : node_traits::node()
\r
85 node_algorithms::init(this_as_node());
\r
89 //! <b>Effects</b>: If SafeMode is true initializes the node
\r
90 //! to an unlinked state. The argument is ignored.
\r
92 //! <b>Throws</b>: Nothing.
\r
94 //! <b>Rationale</b>: Providing a copy-constructor
\r
95 //! makes classes using islist_base_hook STL-compliant without forcing the
\r
96 //! user to do some additional work. "swap" can be used to emulate
\r
98 islist_base_hook(const islist_base_hook& )
\r
99 : node_traits::node()
\r
102 node_algorithms::init(this_as_node());
\r
106 //! <b>Effects</b>: If SafeMode is true, an assertion is raised
\r
107 //! if the node is still linked. After that, the node is initialized
\r
108 //! to an unlinked state. The argument is ignored.
\r
110 //! <b>Throws</b>: Nothing.
\r
112 //! <b>Rationale</b>: Providing an assignment operator
\r
113 //! makes classes using islist_base_hook STL-compliant without forcing the
\r
114 //! user to do some additional work. "swap" can be used to emulate
\r
115 //! move-semantics.
\r
116 islist_base_hook& operator=(const islist_base_hook& )
\r
119 BOOST_ASSERT(!this->linked());
\r
124 //! <b>Effects</b>: If SafeMode is set to false, the destructor does
\r
125 //! nothing (ie. no code is generated). If SafeMode is true and the
\r
126 //! object is stored in an islist an assertion is raised.
\r
128 //! <b>Throws</b>: Nothing.
\r
129 ~islist_base_hook()
\r
132 BOOST_ASSERT(!this->linked());
\r
136 //! <b>Effects</b>: Swapping two nodes swaps the position of the elements
\r
137 //! related to those nodes in one or two containers. That is, if the node
\r
138 //! this is part of the element e1, the node x is part of the element e2
\r
139 //! and both elements are included in the containers s1 and s2, then after
\r
140 //! the swap-operation e1 is in s2 at the position of e2 and e2 is in s1
\r
141 //! at the position of e1. If one element is not in a container, then
\r
142 //! after the swap-operation the other element is not in a container.
\r
143 //! Iterators to e1 and e2 related to those nodes are invalidated.
\r
145 //! <b>Complexity</b>: Linear
\r
147 //! <b>Throws</b>: Nothing.
\r
148 void swap_nodes(islist_base_hook& other)
\r
149 { node_algorithms::swap_nodes(this_as_node(), other.this_as_node()); }
\r
151 //! <b>Precondition</b>: The hook must be in safe-mode.
\r
153 //! <b>Returns</b>: true, if the node belongs to a container, false
\r
154 //! otherwise. This function can be used to test whether islist::current
\r
155 //! will return a valid iterator.
\r
157 //! <b>Complexity</b>: Constant
\r
158 bool linked() const
\r
160 //linked() can be only used in safe-mode
\r
161 BOOST_ASSERT(SafeMode);
\r
162 return !node_algorithms::unique(this_as_node());
\r
165 //! The value_traits class is used as the first template argument for islist.
\r
166 //! The template argument T defines the class type stored in islist. Objects
\r
167 //! of type T and of types derived from T can be stored. T doesn't need to be
\r
168 //! copy-constructible or assignable.
\r
170 struct value_traits
\r
171 : detail::derivation_value_traits<T, this_type, Tag>
\r
174 //! <b>Effects</b>: Converts a pointer to a node into
\r
175 //! a pointer to the hook that holds that node.
\r
177 //! <b>Throws</b>: Nothing.
\r
178 static this_type_ptr to_hook_ptr(node_ptr p)
\r
180 using boost::get_pointer;
\r
181 return this_type_ptr(static_cast<islist_base_hook*> (get_pointer(p)));
\r
184 //! <b>Effects</b>: Converts a const pointer to a node stored in a container into
\r
185 //! a const pointer to the hook that holds that node.
\r
187 //! <b>Throws</b>: Nothing.
\r
188 static const_this_type_ptr to_hook_ptr(const_node_ptr p)
\r
190 using boost::get_pointer;
\r
191 return this_type_ptr(static_cast<const islist_base_hook*> (get_pointer(p)));
\r
194 //! <b>Effects</b>: Returns a pointer to the node that this hook holds.
\r
196 //! <b>Throws</b>: Nothing.
\r
197 node_ptr to_node_ptr()
\r
198 { return this_as_node(); }
\r
200 //! <b>Effects</b>: Returns a const pointer to the node that this hook holds.
\r
202 //! <b>Throws</b>: Nothing.
\r
203 const_node_ptr to_node_ptr() const
\r
204 { return this_as_node(); }
\r
208 //! Derive a class from islist_auto_base_hook in order to store objects in
\r
209 //! in an islist. islist_auto_base_hook holds the data necessary to maintain the
\r
210 //! list and provides an appropriate value_traits class for islist.
\r
212 //! The difference between islist_auto_base_hook and islist_base_hook is that
\r
213 //! islist_auto_base_hook removes itself automatically from the container
\r
214 //! in the assignment operator and the destructor. It also provides a new
\r
215 //! "unlink" method so that the user can unlink its class without using
\r
218 //! islist_auto_base_hook can only be used with non constant-time islists.
\r
220 //! The first integer template argument defines a tag to identify the node.
\r
221 //! The same tag value can be used in different classes, but if a class is
\r
222 //! derived from more than one islist_auto_base_hook, then each islist_auto_base_hook needs its
\r
225 //! The second argument is the pointer type that will be used internally in the hook
\r
226 //! and the islist configured from this hook.
\r
227 template<typename Tag, class VoidPointer = void*>
\r
228 class islist_auto_base_hook
\r
229 : private detail::slist_node_traits<VoidPointer>::node
\r
232 typedef detail::slist_node_traits<VoidPointer> node_traits;
\r
233 enum { linking_policy = auto_unlink };
\r
236 typedef slist_algorithms<node_traits> node_algorithms;
\r
239 typedef islist_auto_base_hook
\r
240 <Tag, VoidPointer> this_type;
\r
241 typedef typename node_traits::node node;
\r
242 typedef typename boost::pointer_to_other
\r
243 <VoidPointer, node>::type node_ptr;
\r
244 typedef typename boost::pointer_to_other
\r
245 <VoidPointer, const node>::type const_node_ptr;
\r
246 typedef typename boost::pointer_to_other
\r
247 <VoidPointer, this_type>::type this_type_ptr;
\r
248 typedef typename boost::pointer_to_other
\r
249 <VoidPointer, const this_type>::type const_this_type_ptr;
\r
252 node_ptr this_as_node()
\r
253 { return node_ptr(static_cast<node *const>(this)); }
\r
255 const_node_ptr this_as_node() const
\r
256 { return const_node_ptr(static_cast<const node *const>(this)); }
\r
260 //! <b>Effects</b>: Initializes the node
\r
261 //! to an unlinked state.
\r
263 //! <b>Throws</b>: Nothing.
\r
264 islist_auto_base_hook()
\r
265 : node_traits::node()
\r
266 { node_algorithms::init(this_as_node()); }
\r
268 //! <b>Effects</b>: Initializes the node
\r
269 //! to an unlinked state. The argument is ignored.
\r
271 //! <b>Throws</b>: Nothing.
\r
273 //! <b>Rationale</b>: Providing a copy-constructor
\r
274 //! makes classes using islist_auto_base_hook STL-compliant without forcing the
\r
275 //! user to do some additional work.
\r
276 islist_auto_base_hook(const islist_auto_base_hook& )
\r
277 : node_traits::node()
\r
278 { node_algorithms::init(this_as_node()); }
\r
280 //! <b>Effects</b>: Removes the node if it's inserted in a container.
\r
281 //! The argument is ignored.
\r
283 //! <b>Throws</b>: Nothing.
\r
285 //! <b>Rationale</b>: Providing an assignment operator
\r
286 //! makes classes using islist_auto_base_hook STL-compliant without forcing the
\r
287 //! user to do some additional work.
\r
288 islist_auto_base_hook& operator=(const islist_auto_base_hook& )
\r
289 { this->unlink(); return *this; }
\r
291 //! <b>Effects</b>: Removes the node if it's inserted in a container.
\r
293 //! <b>Throws</b>: Nothing.
\r
294 ~islist_auto_base_hook()
\r
295 { this->unlink(); }
\r
297 //! <b>Effects</b>: Swapping two nodes swaps the position of the elements
\r
298 //! related to those nodes in one or two containers. That is, if the node
\r
299 //! this is part of the element e1, the node x is part of the element e2
\r
300 //! and both elements are included in the containers s1 and s2, then after
\r
301 //! the swap-operation e1 is in s2 at the position of e2 and e2 is in s1
\r
302 //! at the position of e1. If one element is not in a container, then
\r
303 //! after the swap-operation the other element is not in a container.
\r
304 //! Iterators to e1 and e2 related to those nodes are invalidated.
\r
306 //! <b>Complexity</b>: Linear
\r
308 //! <b>Throws</b>: Nothing.
\r
309 void swap_nodes(islist_auto_base_hook& other)
\r
310 { node_algorithms::swap_nodes(this_as_node(), other.this_as_node()); }
\r
312 //! <b>Returns</b>: true, if the node belongs to a container, false
\r
313 //! otherwise. This function can be used to test whether islist::current
\r
314 //! will return a valid iterator.
\r
316 //! <b>Complexity</b>: Constant
\r
317 bool linked() const
\r
318 { return !node_algorithms::unique(this_as_node()); }
\r
320 //! <b>Effects</b>: Removes the node if it's inserted in a container.
\r
322 //! <b>Throws</b>: Nothing.
\r
325 node_algorithms::unlink(this_as_node());
\r
326 node_algorithms::init(this_as_node());
\r
329 //! The value_traits class is used as the first template argument for islist.
\r
330 //! The template argument T defines the class type stored in islist. Objects
\r
331 //! of type T and of types derived from T can be stored. T doesn't need to be
\r
332 //! copy-constructible or assignable.
\r
334 struct value_traits
\r
335 : detail::derivation_value_traits<T, this_type, Tag>
\r
338 //! <b>Effects</b>: Converts a pointer to a node into
\r
339 //! a pointer to the hook that holds that node.
\r
341 //! <b>Throws</b>: Nothing.
\r
342 static this_type_ptr to_hook_ptr(node_ptr p)
\r
344 using boost::get_pointer;
\r
345 return this_type_ptr(static_cast<islist_auto_base_hook*> (get_pointer(p)));
\r
348 //! <b>Effects</b>: Converts a const pointer to a node stored in a container into
\r
349 //! a const pointer to the hook that holds that node.
\r
351 //! <b>Throws</b>: Nothing.
\r
352 static const_this_type_ptr to_hook_ptr(const_node_ptr p)
\r
354 using boost::get_pointer;
\r
355 return this_type_ptr(static_cast<const islist_auto_base_hook*> (get_pointer(p)));
\r
358 //! <b>Effects</b>: Returns a pointer to the node that this hook holds.
\r
360 //! <b>Throws</b>: Nothing.
\r
361 node_ptr to_node_ptr()
\r
362 { return this_as_node(); }
\r
364 //! <b>Effects</b>: Returns a const pointer to the node that this hook holds.
\r
366 //! <b>Throws</b>: Nothing.
\r
367 const_node_ptr to_node_ptr() const
\r
368 { return this_as_node(); }
\r
372 //! Put a public data member islist_member_hook in order to store objects of this class in
\r
373 //! an islist. islist_member_hook holds the data necessary for maintaining the list and
\r
374 //! provides an appropriate value_traits class for islist.
\r
376 //! The template argument T defines the class type stored in islist. Objects of type
\r
377 //! T and of types derived from T can be stored. T doesn't need to be
\r
378 //! copy-constructible or assignable.
\r
380 //! The second boolean template parameter will activate the safe-mode checks
\r
381 //! if it's configured as "true".
\r
383 //! The third argument is the pointer type that will be used internally in the hook
\r
384 //! and the islist configured from this hook.
\r
385 template<class T, bool SafeMode = true, class VoidPointer = void*>
\r
386 class islist_member_hook
\r
387 : private detail::slist_node_traits<VoidPointer>::node
\r
390 typedef detail::slist_node_traits<VoidPointer> node_traits;
\r
391 enum { linking_policy = SafeMode? safe_mode_link : normal_link};
\r
394 typedef slist_algorithms<node_traits> node_algorithms;
\r
397 typedef typename node_traits::node node;
\r
398 typedef islist_member_hook<T, SafeMode, VoidPointer> this_type;
\r
399 typedef typename boost::pointer_to_other
\r
400 <VoidPointer, node>::type node_ptr;
\r
401 typedef typename boost::pointer_to_other
\r
402 <VoidPointer, const node>::type const_node_ptr;
\r
403 typedef typename boost::pointer_to_other
\r
404 <VoidPointer, this_type >::type this_type_ptr;
\r
405 typedef typename boost::pointer_to_other
\r
406 <VoidPointer, const this_type >::type const_this_type_ptr;
\r
409 node_ptr this_as_node()
\r
410 { return node_ptr(static_cast<node *const>(this)); }
\r
412 const_node_ptr this_as_node() const
\r
413 { return const_node_ptr(static_cast<const node *const>(this)); }
\r
416 //! <b>Effects</b>: If SafeMode is true initializes the node
\r
417 //! to an unlinked state.
\r
419 //! <b>Throws</b>: Nothing.
\r
420 islist_member_hook()
\r
421 : node_traits::node()
\r
424 node_algorithms::init(this_as_node());
\r
428 //! <b>Effects</b>: If SafeMode is true initializes the node
\r
429 //! to an unlinked state. The argument is ignored.
\r
431 //! <b>Throws</b>: Nothing.
\r
433 //! <b>Rationale</b>: Providing a copy-constructor
\r
434 //! makes classes using islist_member_hook STL-compliant without forcing the
\r
435 //! user to do some additional work. "swap" can be used to emulate
\r
436 //! move-semantics.
\r
437 islist_member_hook(const islist_member_hook& )
\r
438 : node_traits::node()
\r
441 node_algorithms::init(this_as_node());
\r
445 //! <b>Effects</b>: If SafeMode is true, an assertion is raised
\r
446 //! if the node is still linked. After that, the node is initialized
\r
447 //! to an unlinked state. The argument is ignored.
\r
449 //! <b>Throws</b>: Nothing.
\r
451 //! <b>Rationale</b>: Providing an assignment operator
\r
452 //! makes classes using islist_member_hook STL-compliant without forcing the
\r
453 //! user to do some additional work. "swap" can be used to emulate
\r
454 //! move-semantics.
\r
455 islist_member_hook& operator=(const islist_member_hook& )
\r
458 BOOST_ASSERT(!this->linked());
\r
463 //! <b>Effects</b>: If SafeMode is set to false, the destructor does
\r
464 //! nothing (ie. no code is generated). If SafeMode is true and the
\r
465 //! object is stored in an islist an assertion is raised.
\r
467 //! <b>Throws</b>: Nothing.
\r
468 ~islist_member_hook()
\r
471 BOOST_ASSERT(!this->linked());
\r
475 //! <b>Effects</b>: Swapping two nodes swaps the position of the elements
\r
476 //! related to those nodes in one or two containers. That is, if the node
\r
477 //! this is part of the element e1, the node x is part of the element e2
\r
478 //! and both elements are included in the containers s1 and s2, then after
\r
479 //! the swap-operation e1 is in s2 at the position of e2 and e2 is in s1
\r
480 //! at the position of e1. If one element is not in a container, then
\r
481 //! after the swap-operation the other element is not in a container.
\r
482 //! Iterators to e1 and e2 related to those nodes are invalidated.
\r
484 //! <b>Complexity</b>: Linear
\r
486 //! <b>Throws</b>: Nothing.
\r
487 void swap_nodes(islist_member_hook& other)
\r
488 { node_algorithms::swap_nodes(this_as_node(), other.this_as_node()); }
\r
490 //! <b>Precondition</b>: The hook must be in safe-mode.
\r
492 //! <b>Returns</b>: true, if the node belongs to a container, false
\r
493 //! otherwise. This function can be used to test whether islist::current
\r
494 //! will return a valid iterator.
\r
496 //! <b>Complexity</b>: Constant
\r
497 bool linked() const
\r
499 //We must be in safe-mode to know if we are really linked
\r
500 //Otherwise, this would lead to an unknown state
\r
501 BOOST_ASSERT(SafeMode);
\r
502 return !node_algorithms::unique(this_as_node());
\r
505 //! The value_traits class is used as the first template argument for islist.
\r
506 //! The template argument is a pointer to member pointing to the node in
\r
507 //! the class. Objects of type T and of types derived from T can be stored.
\r
508 //! T doesn't need to be copy-constructible or assignable.
\r
509 template<this_type T::* M>
\r
510 struct value_traits
\r
511 : detail::member_value_traits<T, this_type, M>
\r
514 //! <b>Effects</b>: Converts a pointer to a node into
\r
515 //! a pointer to the hook that holds that node.
\r
517 //! <b>Throws</b>: Nothing.
\r
518 static this_type_ptr to_hook_ptr(node_ptr p)
\r
520 using boost::get_pointer;
\r
521 return this_type_ptr(static_cast<this_type*> (get_pointer(p)));
\r
524 //! <b>Effects</b>: Converts a const pointer to a node stored in a container into
\r
525 //! a const pointer to the hook that holds that node.
\r
527 //! <b>Throws</b>: Nothing.
\r
528 static const_this_type_ptr to_hook_ptr(const_node_ptr p)
\r
530 using boost::get_pointer;
\r
531 return this_type_ptr(static_cast<this_type*> (get_pointer(p)));
\r
534 //! <b>Effects</b>: Returns a pointer to the node that this hook holds.
\r
536 //! <b>Throws</b>: Nothing.
\r
537 node_ptr to_node_ptr()
\r
538 { return this_as_node(); }
\r
540 //! <b>Effects</b>: Returns a const pointer to the node that this hook holds.
\r
542 //! <b>Throws</b>: Nothing.
\r
543 const_node_ptr to_node_ptr() const
\r
544 { return this_as_node(); }
\r
548 //! Put a public data member islist_auto_member_hook in order to store objects of this class in
\r
549 //! an islist. islist_auto_member_hook holds the data necessary for maintaining the list and
\r
550 //! provides an appropriate value_traits class for islist.
\r
552 //! The difference between islist_auto_member_hook and islist_member_hook is that
\r
553 //! islist_auto_member_hook removes itself automatically from the container
\r
554 //! in the assignment operator and the destructor. It also provides a new
\r
555 //! "unlink" method so that the user can unlink its class without using
\r
558 //! islist_auto_member_hook can only be used with non constant-time islists.
\r
560 //! The first template argument T defines the class type stored in islist. Objects of
\r
561 //! type T and of types derived from T can be stored. T doesn't need to be
\r
562 //! copy-constructible or assignable.
\r
564 //! The second argument is the pointer type that will be used internally in the hook
\r
565 //! and the islist configured from this hook.
\r
566 template<class T, class VoidPointer = void*>
\r
567 class islist_auto_member_hook
\r
568 : private detail::slist_node_traits<VoidPointer>::node
\r
571 typedef detail::slist_node_traits<VoidPointer> node_traits;
\r
572 enum { linking_policy = auto_unlink };
\r
575 typedef slist_algorithms<node_traits> node_algorithms;
\r
578 typedef typename node_traits::node node;
\r
579 typedef islist_auto_member_hook<T, VoidPointer> this_type;
\r
580 typedef typename boost::pointer_to_other
\r
581 <VoidPointer, node>::type node_ptr;
\r
582 typedef typename boost::pointer_to_other
\r
583 <VoidPointer, const node>::type const_node_ptr;
\r
584 typedef typename boost::pointer_to_other
\r
585 <VoidPointer, this_type >::type this_type_ptr;
\r
586 typedef typename boost::pointer_to_other
\r
587 <VoidPointer, const this_type >::type const_this_type_ptr;
\r
590 node_ptr this_as_node()
\r
591 { return node_ptr(static_cast<node *const>(this)); }
\r
593 const_node_ptr this_as_node() const
\r
594 { return const_node_ptr(static_cast<const node *const>(this)); }
\r
597 //! <b>Effects</b>: Initializes the node
\r
598 //! to an unlinked state.
\r
600 //! <b>Throws</b>: Nothing.
\r
601 islist_auto_member_hook()
\r
602 : node_traits::node()
\r
603 { node_algorithms::init(this_as_node()); }
\r
605 //! <b>Effects</b>: Initializes the node
\r
606 //! to an unlinked state. The argument is ignored.
\r
608 //! <b>Throws</b>: Nothing.
\r
610 //! <b>Rationale</b>: Providing a copy-constructor
\r
611 //! makes classes using islist_auto_base_hook STL-compliant without forcing the
\r
612 //! user to do some additional work.
\r
613 islist_auto_member_hook(const islist_auto_member_hook& )
\r
614 : node_traits::node()
\r
615 { node_algorithms::init(this_as_node()); }
\r
617 //! <b>Effects</b>: Removes the node if it's inserted in a container.
\r
618 //! The argument is ignored.
\r
620 //! <b>Throws</b>: Nothing.
\r
622 //! <b>Rationale</b>: Providing an assignment operator
\r
623 //! makes classes using islist_auto_base_hook STL-compliant without forcing the
\r
624 //! user to do some additional work.
\r
625 islist_auto_member_hook& operator=(const islist_auto_member_hook& )
\r
626 { this->unlink(); return *this; }
\r
628 //! <b>Effects</b>: If SafeMode is set to false, the destructor does
\r
629 //! nothing (ie. no code is generated). If SafeMode is true and the
\r
630 //! object is stored in an islist an assertion is raised.
\r
632 //! <b>Throws</b>: Nothing.
\r
633 ~islist_auto_member_hook()
\r
634 { this->unlink(); }
\r
636 //! <b>Effects</b>: Swapping two nodes swaps the position of the elements
\r
637 //! related to those nodes in one or two containers. That is, if the node
\r
638 //! this is part of the element e1, the node x is part of the element e2
\r
639 //! and both elements are included in the containers s1 and s2, then after
\r
640 //! the swap-operation e1 is in s2 at the position of e2 and e2 is in s1
\r
641 //! at the position of e1. If one element is not in a container, then
\r
642 //! after the swap-operation the other element is not in a container.
\r
643 //! Iterators to e1 and e2 related to those nodes are invalidated.
\r
645 //! <b>Complexity</b>: Constant
\r
647 //! <b>Throws</b>: Nothing.
\r
648 void swap_nodes(islist_auto_member_hook& other)
\r
649 { node_algorithms::swap_nodes(this_as_node(), other.this_as_node()); }
\r
651 //! <b>Returns</b>: true, if the node belongs to a container, false
\r
652 //! otherwise. This function can be used to test whether islist::current
\r
653 //! will return a valid iterator.
\r
655 //! <b>Complexity</b>: Constant
\r
656 bool linked() const
\r
657 { return !node_algorithms::unique(this_as_node()); }
\r
659 //! The value_traits class is used as the first template argument for islist.
\r
660 //! The template argument is a pointer to member pointing to the node in
\r
661 //! the class. Objects of type T and of types derived from T can be stored.
\r
662 //! T doesn't need to be copy-constructible or assignable.
\r
663 template<this_type T::* M>
\r
664 struct value_traits
\r
665 : detail::member_value_traits<T, this_type, M>
\r
668 //! <b>Effects</b>: Removes the node if it's inserted in a container.
\r
670 //! <b>Throws</b>: Nothing.
\r
673 node_algorithms::unlink(this_as_node());
\r
674 node_algorithms::init(this_as_node());
\r
677 //! <b>Effects</b>: Converts a pointer to a node into
\r
678 //! a pointer to the hook that holds that node.
\r
680 //! <b>Throws</b>: Nothing.
\r
681 static this_type_ptr to_hook_ptr(node_ptr p)
\r
683 using boost::get_pointer;
\r
684 return this_type_ptr(static_cast<this_type*> (get_pointer(p)));
\r
687 //! <b>Effects</b>: Converts a const pointer to a node stored in a container into
\r
688 //! a const pointer to the hook that holds that node.
\r
690 //! <b>Throws</b>: Nothing.
\r
691 static const_this_type_ptr to_hook_ptr(const_node_ptr p)
\r
693 using boost::get_pointer;
\r
694 return const_this_type_ptr(static_cast<const this_type*> (get_pointer(p)));
\r
697 //! <b>Effects</b>: Returns a pointer to the node that this hook holds.
\r
699 //! <b>Throws</b>: Nothing.
\r
700 node_ptr to_node_ptr()
\r
701 { return this_as_node(); }
\r
703 //! <b>Effects</b>: Returns a const pointer to the node that this hook holds.
\r
705 //! <b>Throws</b>: Nothing.
\r
706 const_node_ptr to_node_ptr() const
\r
707 { return this_as_node(); }
\r
710 } //namespace intrusive
\r
711 } //namespace boost
\r
713 #include<boost/intrusive/detail/config_end.hpp>
\r
715 #endif //BOOST_INTRUSIVE_ISLIST_HOOK_HPP
\r