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_ILIST_HOOK_HPP
\r
15 #define BOOST_INTRUSIVE_ILIST_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/list_node.hpp"
\r
22 #include "list_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 ilist_base_hook in order to store objects in
\r
31 //! in an ilist. ilist_base_hook holds the data necessary to maintain the
\r
32 //! list and provides an appropriate value_traits class for ilist.
\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 ilist_base_hook, then each ilist_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 ilist configured from this hook.
\r
44 template< typename Tag
\r
45 , bool SafeMode = true
\r
46 , class VoidPointer = void *
\r
48 class ilist_base_hook
\r
49 : private detail::list_node_traits<VoidPointer>::node
\r
52 typedef detail::list_node_traits<VoidPointer> node_traits;
\r
53 enum { linking_policy = SafeMode ? safe_mode_link : normal_link};
\r
56 typedef list_algorithms<node_traits> node_algorithms;
\r
59 typedef typename node_traits::node node;
\r
60 typedef typename boost::pointer_to_other
\r
61 <VoidPointer, node>::type node_ptr;
\r
62 typedef typename boost::pointer_to_other
\r
63 <VoidPointer, const node>::type const_node_ptr;
\r
64 typedef ilist_base_hook
\r
65 <Tag, SafeMode, VoidPointer> this_type;
\r
67 typedef typename boost::pointer_to_other
\r
68 <VoidPointer, this_type>::type this_type_ptr;
\r
70 typedef typename boost::pointer_to_other
\r
71 <VoidPointer, const this_type>::type const_this_type_ptr;
\r
74 node_ptr this_as_node()
\r
75 { return node_ptr(static_cast<node *const>(this)); }
\r
77 const_node_ptr this_as_node() const
\r
78 { return const_node_ptr(static_cast<const node *const>(this)); }
\r
82 //! <b>Effects</b>: If SafeMode is true initializes the node
\r
83 //! to an unlinked state.
\r
85 //! <b>Throws</b>: Nothing.
\r
90 node_algorithms::init(this_as_node());
\r
94 //! <b>Effects</b>: If SafeMode is true initializes the node
\r
95 //! to an unlinked state. The argument is ignored.
\r
97 //! <b>Throws</b>: Nothing.
\r
99 //! <b>Rationale</b>: Providing a copy-constructor
\r
100 //! makes classes using ilist_base_hook STL-compliant without forcing the
\r
101 //! user to do some additional work. "swap" can be used to emulate
\r
102 //! move-semantics.
\r
103 ilist_base_hook(const ilist_base_hook& )
\r
107 node_algorithms::init(this_as_node());
\r
111 //! <b>Effects</b>: If SafeMode is true, an assertion is raised
\r
112 //! if the node is still linked. After that, the node is initialized
\r
113 //! to an unlinked state. The argument is ignored.
\r
115 //! <b>Throws</b>: Nothing.
\r
117 //! <b>Rationale</b>: Providing an assignment operator
\r
118 //! makes classes using ilist_base_hook STL-compliant without forcing the
\r
119 //! user to do some additional work. "swap" can be used to emulate
\r
120 //! move-semantics.
\r
121 ilist_base_hook& operator=(const ilist_base_hook& )
\r
124 BOOST_ASSERT(!this->linked());
\r
129 //! <b>Effects</b>: If SafeMode is set to false, the destructor does
\r
130 //! nothing (ie. no code is generated). If SafeMode is true and the
\r
131 //! object is stored in an ilist an assertion is raised.
\r
133 //! <b>Throws</b>: Nothing.
\r
134 ~ilist_base_hook()
\r
137 BOOST_ASSERT(!this->linked());
\r
141 //! <b>Effects</b>: Swapping two nodes swaps the position of the elements
\r
142 //! related to those nodes in one or two containers. That is, if the node
\r
143 //! this is part of the element e1, the node x is part of the element e2
\r
144 //! and both elements are included in the containers s1 and s2, then after
\r
145 //! the swap-operation e1 is in s2 at the position of e2 and e2 is in s1
\r
146 //! at the position of e1. If one element is not in a container, then
\r
147 //! after the swap-operation the other element is not in a container.
\r
148 //! Iterators to e1 and e2 related to those nodes are invalidated.
\r
150 //! <b>Complexity</b>: Constant
\r
152 //! <b>Throws</b>: Nothing.
\r
153 void swap_nodes(ilist_base_hook &other)
\r
154 { node_algorithms::swap_nodes(this_as_node(), other.this_as_node()); }
\r
156 //! <b>Precondition</b>: The hook must be in safe-mode.
\r
158 //! <b>Returns</b>: true, if the node belongs to a container, false
\r
159 //! otherwise. This function can be used to test whether ilist::current
\r
160 //! will return a valid iterator.
\r
162 //! <b>Complexity</b>: Constant
\r
163 bool linked() const
\r
165 //linked() can be only used in safe-mode
\r
166 BOOST_ASSERT(SafeMode);
\r
167 return !node_algorithms::unique(this_as_node());
\r
170 //! The value_traits class is used as the first template argument for ilist.
\r
171 //! The template argument T defines the class type stored in ilist. Objects
\r
172 //! of type T and of types derived from T can be stored. T doesn't need to be
\r
173 //! copy-constructible or assignable.
\r
175 struct value_traits
\r
176 : detail::derivation_value_traits<T, this_type, Tag>
\r
179 //! <b>Effects</b>: Converts a pointer to a node into
\r
180 //! a pointer to the hook that holds that node.
\r
182 //! <b>Throws</b>: Nothing.
\r
183 static this_type_ptr to_hook_ptr(node_ptr p)
\r
185 using boost::get_pointer;
\r
186 return this_type_ptr(static_cast<ilist_base_hook*> (get_pointer(p)));
\r
189 //! <b>Effects</b>: Converts a const pointer to a node stored in a container into
\r
190 //! a const pointer to the hook that holds that node.
\r
192 //! <b>Throws</b>: Nothing.
\r
193 static const_this_type_ptr to_hook_ptr(const_node_ptr p)
\r
195 using boost::get_pointer;
\r
196 return const_this_type_ptr(static_cast<const ilist_base_hook*> (get_pointer(p)));
\r
199 //! <b>Effects</b>: Returns a pointer to the node that this hook holds.
\r
201 //! <b>Throws</b>: Nothing.
\r
202 node_ptr to_node_ptr()
\r
203 { return this_as_node(); }
\r
205 //! <b>Effects</b>: Returns a const pointer to the node that this hook holds.
\r
207 //! <b>Throws</b>: Nothing.
\r
208 const_node_ptr to_node_ptr() const
\r
209 { return this_as_node(); }
\r
213 //! Derive a class from ilist_auto_base_hook in order to store objects in
\r
214 //! in an ilist. ilist_auto_base_hook holds the data necessary to maintain the
\r
215 //! list and provides an appropriate value_traits class for ilist.
\r
217 //! The difference between ilist_auto_base_hook and ilist_base_hook is that
\r
218 //! ilist_auto_base_hook removes itself automatically from the container
\r
219 //! in the assignment operator and the destructor. It also provides a new
\r
220 //! "unlink" method so that the user can unlink its class without using
\r
223 //! ilist_auto_base_hook can only be used with non constant-time ilists.
\r
225 //! The first integer template argument defines a tag to identify the node.
\r
226 //! The same tag value can be used in different classes, but if a class is
\r
227 //! derived from more than one ilist_auto_base_hook, then each ilist_auto_base_hook needs its
\r
230 //! The second argument is the pointer type that will be used internally in the hook
\r
231 //! and the ilist configured from this hook.
\r
232 template< typename Tag
\r
233 , class VoidPointer = void *
\r
235 class ilist_auto_base_hook
\r
236 : private detail::list_node_traits<VoidPointer>::node
\r
239 typedef detail::list_node_traits<VoidPointer> node_traits;
\r
240 enum { linking_policy = auto_unlink };
\r
243 typedef list_algorithms<node_traits> node_algorithms;
\r
246 typedef typename node_traits::node node;
\r
247 typedef typename boost::pointer_to_other
\r
248 <VoidPointer, node>::type node_ptr;
\r
249 typedef typename boost::pointer_to_other
\r
250 <VoidPointer, const node>::type const_node_ptr;
\r
251 typedef ilist_auto_base_hook
\r
252 <Tag, VoidPointer> this_type;
\r
254 typedef typename boost::pointer_to_other
\r
255 <VoidPointer, this_type>::type this_type_ptr;
\r
257 typedef typename boost::pointer_to_other
\r
258 <VoidPointer, const this_type>::type const_this_type_ptr;
\r
261 node_ptr this_as_node()
\r
262 { return node_ptr(static_cast<node *const>(this)); }
\r
264 const_node_ptr this_as_node() const
\r
265 { return const_node_ptr(static_cast<const node *const>(this)); }
\r
268 //! <b>Effects</b>: Initializes the node
\r
269 //! to an unlinked state.
\r
271 //! <b>Throws</b>: Nothing.
\r
272 ilist_auto_base_hook()
\r
274 { node_algorithms::init(this_as_node()); }
\r
276 //! <b>Effects</b>: Initializes the node
\r
277 //! to an unlinked state. The argument is ignored.
\r
279 //! <b>Throws</b>: Nothing.
\r
281 //! <b>Rationale</b>: Providing a copy-constructor
\r
282 //! makes classes using ilist_auto_base_hook STL-compliant without forcing the
\r
283 //! user to do some additional work.
\r
284 ilist_auto_base_hook(const ilist_auto_base_hook& )
\r
286 { node_algorithms::init(this_as_node()); }
\r
288 //! <b>Effects</b>: Removes the node if it's inserted in a container.
\r
289 //! The argument is ignored.
\r
291 //! <b>Throws</b>: Nothing.
\r
293 //! <b>Rationale</b>: Providing an assignment operator
\r
294 //! makes classes using ilist_auto_base_hook STL-compliant without forcing the
\r
295 //! user to do some additional work.
\r
296 ilist_auto_base_hook& operator=(const ilist_auto_base_hook& )
\r
297 { this->unlink(); return *this; }
\r
299 //! <b>Effects</b>: Removes the node if it's inserted in a container.
\r
301 //! <b>Throws</b>: Nothing.
\r
302 ~ilist_auto_base_hook()
\r
303 { this->unlink(); }
\r
305 //! <b>Effects</b>: Swapping two nodes swaps the position of the elements
\r
306 //! related to those nodes in one or two containers. That is, if the node
\r
307 //! this is part of the element e1, the node x is part of the element e2
\r
308 //! and both elements are included in the containers s1 and s2, then after
\r
309 //! the swap-operation e1 is in s2 at the position of e2 and e2 is in s1
\r
310 //! at the position of e1. If one element is not in a container, then
\r
311 //! after the swap-operation the other element is not in a container.
\r
312 //! Iterators to e1 and e2 related to those nodes are invalidated.
\r
314 //! <b>Complexity</b>: Constant
\r
316 //! <b>Throws</b>: Nothing.
\r
317 void swap_nodes(ilist_auto_base_hook& other)
\r
318 { node_algorithms::swap_nodes(this_as_node(), other.this_as_node()); }
\r
320 //! <b>Returns</b>: true, if the node belongs to a container, false
\r
321 //! otherwise. This function can be used to test whether ilist::current
\r
322 //! will return a valid iterator.
\r
324 //! <b>Complexity</b>: Constant
\r
325 bool linked() const
\r
326 { return !node_algorithms::unique(this_as_node()); }
\r
328 //! <b>Effects</b>: Removes the node if it's inserted in a container.
\r
330 //! <b>Throws</b>: Nothing.
\r
333 node_algorithms::unlink(this_as_node());
\r
334 node_algorithms::init(this_as_node());
\r
337 //! The value_traits class is used as the first template argument for ilist.
\r
338 //! The template argument T defines the class type stored in ilist. Objects
\r
339 //! of type T and of types derived from T can be stored. T doesn't need to be
\r
340 //! copy-constructible or assignable.
\r
342 struct value_traits
\r
343 : detail::derivation_value_traits<T, this_type, Tag>
\r
346 //! <b>Effects</b>: Converts a pointer to a node into
\r
347 //! a pointer to the hook that holds that node.
\r
349 //! <b>Throws</b>: Nothing.
\r
350 static this_type_ptr to_hook_ptr(node_ptr p)
\r
352 using boost::get_pointer;
\r
353 return this_type_ptr(static_cast<ilist_auto_base_hook*> (get_pointer(p)));
\r
356 //! <b>Effects</b>: Converts a const pointer to a node stored in a container into
\r
357 //! a const pointer to the hook that holds that node.
\r
359 //! <b>Throws</b>: Nothing.
\r
360 static const_this_type_ptr to_hook_ptr(const_node_ptr p)
\r
362 using boost::get_pointer;
\r
363 return const_this_type_ptr(static_cast<const ilist_auto_base_hook*> (get_pointer(p)));
\r
366 //! <b>Effects</b>: Returns a pointer to the node that this hook holds.
\r
368 //! <b>Throws</b>: Nothing.
\r
369 node_ptr to_node_ptr()
\r
370 { return this_as_node(); }
\r
372 //! <b>Effects</b>: Returns a const pointer to the node that this hook holds.
\r
374 //! <b>Throws</b>: Nothing.
\r
375 const_node_ptr to_node_ptr() const
\r
376 { return this_as_node(); }
\r
379 //! Put a public data member ilist_member_hook in order to store objects of this class in
\r
380 //! an ilist. ilist_member_hook holds the data necessary for maintaining the list and
\r
381 //! provides an appropriate value_traits class for ilist.
\r
383 //! The template argument T defines the class type stored in ilist. Objects of type
\r
384 //! T and of types derived from T can be stored. T doesn't need to be
\r
385 //! copy-constructible or assignable.
\r
387 //! The second boolean template parameter will activate the safe-mode checks
\r
388 //! if it's configured as "true".
\r
390 //! The third argument is the pointer type that will be used internally in the hook
\r
391 //! and the ilist configured from this hook.
\r
392 template<class T, bool SafeMode = true, class VoidPointer = void *>
\r
393 class ilist_member_hook
\r
394 : private detail::list_node_traits<VoidPointer>::node
\r
397 typedef detail::list_node_traits<VoidPointer> node_traits;
\r
398 enum { linking_policy = SafeMode? safe_mode_link : normal_link};
\r
401 typedef list_algorithms<node_traits> node_algorithms;
\r
404 typedef typename node_traits::node node;
\r
405 typedef typename boost::pointer_to_other
\r
406 <VoidPointer, node>::type node_ptr;
\r
407 typedef typename boost::pointer_to_other
\r
408 <VoidPointer, const node>::type const_node_ptr;
\r
409 typedef ilist_member_hook
\r
410 <T, SafeMode, VoidPointer> this_type;
\r
412 typedef typename boost::pointer_to_other
\r
413 <VoidPointer, this_type >::type this_type_ptr;
\r
415 typedef typename boost::pointer_to_other
\r
416 <VoidPointer, const this_type >::type const_this_type_ptr;
\r
419 node_ptr this_as_node()
\r
420 { return node_ptr(static_cast<node *const>(this)); }
\r
422 const_node_ptr this_as_node() const
\r
423 { return const_node_ptr(static_cast<const node *const>(this)); }
\r
426 //! <b>Effects</b>: If SafeMode is true initializes the node
\r
427 //! to an unlinked state.
\r
429 //! <b>Throws</b>: Nothing.
\r
430 ilist_member_hook()
\r
434 node_algorithms::init(this_as_node());
\r
438 //! <b>Effects</b>: If SafeMode is true initializes the node
\r
439 //! to an unlinked state. The argument is ignored.
\r
441 //! <b>Throws</b>: Nothing.
\r
443 //! <b>Rationale</b>: Providing a copy-constructor
\r
444 //! makes classes using ilist_member_hook STL-compliant without forcing the
\r
445 //! user to do some additional work. "swap" can be used to emulate
\r
446 //! move-semantics.
\r
447 ilist_member_hook(const ilist_member_hook& )
\r
451 node_algorithms::init(this_as_node());
\r
455 //! <b>Effects</b>: If SafeMode is true, an assertion is raised
\r
456 //! if the node is still linked. After that, the node is initialized
\r
457 //! to an unlinked state. The argument is ignored.
\r
459 //! <b>Throws</b>: Nothing.
\r
461 //! <b>Rationale</b>: Providing an assignment operator
\r
462 //! makes classes using ilist_member_hook STL-compliant without forcing the
\r
463 //! user to do some additional work. "swap" can be used to emulate
\r
464 //! move-semantics.
\r
465 ilist_member_hook& operator=(const ilist_member_hook& )
\r
468 BOOST_ASSERT(!this->linked());
\r
473 //! <b>Effects</b>: If SafeMode is set to false, the destructor does
\r
474 //! nothing (ie. no code is generated). If SafeMode is true and the
\r
475 //! object is stored in an ilist an assertion is raised.
\r
477 //! <b>Throws</b>: Nothing.
\r
478 ~ilist_member_hook()
\r
481 BOOST_ASSERT(!this->linked());
\r
485 //! <b>Effects</b>: Swapping two nodes swaps the position of the elements
\r
486 //! related to those nodes in one or two containers. That is, if the node
\r
487 //! this is part of the element e1, the node x is part of the element e2
\r
488 //! and both elements are included in the containers s1 and s2, then after
\r
489 //! the swap-operation e1 is in s2 at the position of e2 and e2 is in s1
\r
490 //! at the position of e1. If one element is not in a container, then
\r
491 //! after the swap-operation the other element is not in a container.
\r
492 //! Iterators to e1 and e2 related to those nodes are invalidated.
\r
494 //! <b>Complexity</b>: Constant
\r
496 //! <b>Throws</b>: Nothing.
\r
497 void swap_nodes(ilist_member_hook& other)
\r
498 { node_algorithms::swap_nodes(this_as_node(), other.this_as_node()); }
\r
500 //! <b>Precondition</b>: The hook must be in safe-mode.
\r
502 //! <b>Returns</b>: true, if the node belongs to a container, false
\r
503 //! otherwise. This function can be used to test whether ilist::current
\r
504 //! will return a valid iterator.
\r
506 //! <b>Complexity</b>: Constant
\r
507 bool linked() const
\r
509 //We must be in safe-mode to know if we are really linked
\r
510 //Otherwise, this would lead to an unknown state
\r
511 BOOST_ASSERT(SafeMode);
\r
512 return !node_algorithms::unique(this_as_node());
\r
515 //! The value_traits class is used as the first template argument for ilist.
\r
516 //! The template argument is a pointer to member pointing to the node in
\r
517 //! the class. Objects of type T and of types derived from T can be stored.
\r
518 //! T doesn't need to be copy-constructible or assignable.
\r
519 template<this_type T::* M>
\r
520 struct value_traits
\r
521 : detail::member_value_traits<T, this_type, M>
\r
524 //! <b>Effects</b>: Converts a pointer to a node into
\r
525 //! a pointer to the hook that holds that node.
\r
527 //! <b>Throws</b>: Nothing.
\r
528 static this_type_ptr to_hook_ptr(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>: Converts a const pointer to a node stored in a container into
\r
535 //! a const pointer to the hook that holds that node.
\r
537 //! <b>Throws</b>: Nothing.
\r
538 static const_this_type_ptr to_hook_ptr(const_node_ptr p)
\r
540 using boost::get_pointer;
\r
541 return const_this_type_ptr(static_cast<const this_type*> (get_pointer(p)));
\r
544 //! <b>Effects</b>: Returns a pointer to the node that this hook holds.
\r
546 //! <b>Throws</b>: Nothing.
\r
547 node_ptr to_node_ptr()
\r
548 { return this_as_node(); }
\r
550 //! <b>Effects</b>: Returns a const pointer to the node that this hook holds.
\r
552 //! <b>Throws</b>: Nothing.
\r
553 const_node_ptr to_node_ptr() const
\r
554 { return this_as_node(); }
\r
557 //! Put a public data member ilist_auto_member_hook in order to store objects of this class in
\r
558 //! an ilist. ilist_auto_member_hook holds the data necessary for maintaining the list and
\r
559 //! provides an appropriate value_traits class for ilist.
\r
561 //! The difference between ilist_auto_member_hook and ilist_member_hook is that
\r
562 //! ilist_auto_member_hook removes itself automatically from the container
\r
563 //! in the assignment operator and the destructor. It also provides a new
\r
564 //! "unlink" method so that the user can unlink its class without using
\r
567 //! ilist_auto_member_hook can only be used with non constant-time ilists.
\r
569 //! The first template argument T defines the class type stored in ilist. Objects of
\r
570 //! type T and of types derived from T can be stored. T doesn't need to be
\r
571 //! copy-constructible or assignable.
\r
573 //! The second argument is the pointer type that will be used internally in the hook
\r
574 //! and the ilist configured from this hook.
\r
575 template<class T, class VoidPointer = void *>
\r
576 class ilist_auto_member_hook
\r
577 : private detail::list_node_traits<VoidPointer>::node
\r
580 typedef detail::list_node_traits<VoidPointer> node_traits;
\r
581 enum { linking_policy = auto_unlink };
\r
584 typedef list_algorithms<node_traits> node_algorithms;
\r
587 typedef typename node_traits::node node;
\r
588 typedef typename boost::pointer_to_other
\r
589 <VoidPointer, node>::type node_ptr;
\r
590 typedef typename boost::pointer_to_other
\r
591 <VoidPointer, const node>::type const_node_ptr;
\r
592 typedef ilist_auto_member_hook
\r
593 <T, VoidPointer> this_type;
\r
595 typedef typename boost::pointer_to_other
\r
596 <VoidPointer, this_type >::type this_type_ptr;
\r
598 typedef typename boost::pointer_to_other
\r
599 <VoidPointer, const this_type >::type const_this_type_ptr;
\r
602 node_ptr this_as_node()
\r
603 { return node_ptr(static_cast<node *const>(this)); }
\r
605 const_node_ptr this_as_node() const
\r
606 { return const_node_ptr(static_cast<const node *const>(this)); }
\r
609 //! <b>Effects</b>: Initializes the node
\r
610 //! to an unlinked state.
\r
612 //! <b>Throws</b>: Nothing.
\r
613 ilist_auto_member_hook()
\r
615 { node_algorithms::init(this_as_node()); }
\r
617 //! <b>Effects</b>: Initializes the node
\r
618 //! to an unlinked state. The argument is ignored.
\r
620 //! <b>Throws</b>: Nothing.
\r
622 //! <b>Rationale</b>: Providing a copy-constructor
\r
623 //! makes classes using ilist_auto_base_hook STL-compliant without forcing the
\r
624 //! user to do some additional work.
\r
625 ilist_auto_member_hook(const ilist_auto_member_hook& )
\r
627 { node_algorithms::init(this_as_node()); }
\r
629 //! <b>Effects</b>: Removes the node if it's inserted in a container.
\r
630 //! The argument is ignored.
\r
632 //! <b>Throws</b>: Nothing.
\r
634 //! <b>Rationale</b>: Providing an assignment operator
\r
635 //! makes classes using ilist_auto_base_hook STL-compliant without forcing the
\r
636 //! user to do some additional work.
\r
637 ilist_auto_member_hook& operator=(const ilist_auto_member_hook& )
\r
638 { this->unlink(); return *this; }
\r
640 //! <b>Effects</b>: Removes the node if it's inserted in a container.
\r
642 //! <b>Throws</b>: Nothing.
\r
643 ~ilist_auto_member_hook()
\r
644 { this->unlink(); }
\r
646 //! <b>Effects</b>: Swapping two nodes swaps the position of the elements
\r
647 //! related to those nodes in one or two containers. That is, if the node
\r
648 //! this is part of the element e1, the node x is part of the element e2
\r
649 //! and both elements are included in the containers s1 and s2, then after
\r
650 //! the swap-operation e1 is in s2 at the position of e2 and e2 is in s1
\r
651 //! at the position of e1. If one element is not in a container, then
\r
652 //! after the swap-operation the other element is not in a container.
\r
653 //! Iterators to e1 and e2 related to those nodes are invalidated.
\r
655 //! <b>Complexity</b>: Constant
\r
657 //! <b>Throws</b>: Nothing.
\r
658 void swap_nodes(ilist_auto_member_hook& other)
\r
659 { node_algorithms::swap_nodes(this_as_node(), other.this_as_node()); }
\r
661 //! <b>Returns</b>: true, if the node belongs to a container, false
\r
662 //! otherwise. This function can be used to test whether ilist::current
\r
663 //! will return a valid iterator.
\r
665 //! <b>Complexity</b>: Constant
\r
666 bool linked() const
\r
667 { return !node_algorithms::unique(this_as_node()); }
\r
669 //! The value_traits class is used as the first template argument for ilist.
\r
670 //! The template argument is a pointer to member pointing to the node in
\r
671 //! the class. Objects of type T and of types derived from T can be stored.
\r
672 //! T doesn't need to be copy-constructible or assignable.
\r
673 template<this_type T::* M>
\r
674 struct value_traits
\r
675 : detail::member_value_traits<T, this_type, M>
\r
678 //! <b>Effects</b>: Removes the node if it's inserted in a container.
\r
680 //! <b>Throws</b>: Nothing.
\r
683 node_algorithms::unlink(this_as_node());
\r
684 node_algorithms::init(this_as_node());
\r
687 //! <b>Effects</b>: Converts a pointer to a node into
\r
688 //! a pointer to the hook that holds that node.
\r
690 //! <b>Throws</b>: Nothing.
\r
691 static this_type_ptr to_hook_ptr(node_ptr p)
\r
693 using boost::get_pointer;
\r
694 return this_type_ptr(static_cast<this_type*> (get_pointer(p)));
\r
697 //! <b>Effects</b>: Converts a const pointer to a node stored in a container into
\r
698 //! a const pointer to the hook that holds that node.
\r
700 //! <b>Throws</b>: Nothing.
\r
701 static const_this_type_ptr to_hook_ptr(const_node_ptr p)
\r
703 using boost::get_pointer;
\r
704 return const_this_type_ptr(static_cast<const this_type*> (get_pointer(p)));
\r
707 //! <b>Effects</b>: Returns a pointer to the node that this hook holds.
\r
709 //! <b>Throws</b>: Nothing.
\r
710 node_ptr to_node_ptr()
\r
711 { return this_as_node(); }
\r
713 //! <b>Effects</b>: Returns a const pointer to the node that this hook holds.
\r
715 //! <b>Throws</b>: Nothing.
\r
716 const_node_ptr to_node_ptr() const
\r
717 { return this_as_node(); }
\r
720 } //namespace intrusive
\r
721 } //namespace boost
\r
723 #include "detail/config_end.hpp"
\r
725 #endif //BOOST_INTRUSIVE_ILIST_HOOK_HPP
\r