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_ISET_HOOK_HPP
\r
15 #define BOOST_INTRUSIVE_ISET_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/rbtree_node.hpp"
\r
22 #include "rbtree_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 iset_base_hook in order to store objects in
\r
31 //! in an iset/imultiset. iset_base_hook holds the data necessary to maintain
\r
32 //! the set/multiset and provides an appropriate value_traits class for iset/imultiset.
\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 iset_base_hook, then each iset_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 iset/imultiset configured from this hook.
\r
44 template<typename Tag, bool SafeMode = true, class VoidPointer = void*>
\r
45 class iset_base_hook
\r
46 : private detail::rbtree_node_traits<VoidPointer>::node
\r
49 typedef detail::rbtree_node_traits<VoidPointer> node_traits;
\r
50 enum { linking_policy = SafeMode? safe_mode_link : normal_link};
\r
53 typedef rbtree_algorithms<node_traits> node_algorithms;
\r
56 typedef typename node_traits::node node;
\r
57 typedef typename boost::pointer_to_other
\r
58 <VoidPointer, node>::type node_ptr;
\r
59 typedef typename boost::pointer_to_other
\r
60 <VoidPointer, const node>::type const_node_ptr;
\r
61 typedef iset_base_hook
\r
62 <Tag, SafeMode, VoidPointer> this_type;
\r
64 typedef typename boost::pointer_to_other
\r
65 <VoidPointer, this_type>::type this_type_ptr;
\r
67 typedef typename boost::pointer_to_other
\r
68 <VoidPointer, const this_type>::type const_this_type_ptr;
\r
72 node_ptr this_as_node()
\r
73 { return node_ptr(static_cast<node *const>(this)); }
\r
75 const_node_ptr this_as_node() const
\r
76 { return const_node_ptr(static_cast<const node *const>(this)); }
\r
80 //! <b>Effects</b>: If SafeMode is true initializes the node
\r
81 //! to an unlinked state.
\r
83 //! <b>Throws</b>: Nothing.
\r
88 node_algorithms::init(this_as_node());
\r
92 //! <b>Effects</b>: If SafeMode is true initializes the node
\r
93 //! to an unlinked state. The argument is ignored.
\r
95 //! <b>Throws</b>: Nothing.
\r
97 //! <b>Rationale</b>: Providing a copy-constructor
\r
98 //! makes classes using iset_base_hook STL-compliant without forcing the
\r
99 //! user to do some additional work. "swap" can be used to emulate
\r
100 //! move-semantics.
\r
101 iset_base_hook(const iset_base_hook& )
\r
105 node_algorithms::init(this_as_node());
\r
109 //! <b>Effects</b>: If SafeMode is true, an assertion is raised
\r
110 //! if the node is still linked. After that, the node is initialized
\r
111 //! to an unlinked state. The argument is ignored.
\r
113 //! <b>Throws</b>: Nothing.
\r
115 //! <b>Rationale</b>: Providing an assignment operator
\r
116 //! makes classes using iset_base_hook STL-compliant without forcing the
\r
117 //! user to do some additional work. "swap" can be used to emulate
\r
118 //! move-semantics.
\r
119 iset_base_hook& operator=(const iset_base_hook& )
\r
122 BOOST_ASSERT(!this->linked());
\r
127 //! <b>Effects</b>: If SafeMode is set to false, the destructor does
\r
128 //! nothing (ie. no code is generated). If SafeMode is true and the
\r
129 //! object is stored in an iset an assertion is raised.
\r
131 //! <b>Throws</b>: Nothing.
\r
135 BOOST_ASSERT(!this->linked());
\r
139 //! <b>Precondition</b>: The hook must be in safe-mode.
\r
141 //! <b>Returns</b>: true, if the node belongs to a container, false
\r
142 //! otherwise. This function can be used to test whether iset::current
\r
143 //! will return a valid iterator.
\r
145 //! <b>Complexity</b>: Constant
\r
146 bool linked() const
\r
148 //linked() can be only used in safe-mode
\r
149 BOOST_ASSERT(SafeMode);
\r
150 return !node_algorithms::unique(this_as_node());
\r
153 //! The value_traits class is used as the first template argument for imultiset.
\r
154 //! The template argument T defines the class type stored in imultiset. Objects
\r
155 //! of type T and of types derived from T can be stored. T don't need to be
\r
156 //! copy-constructible or assignable.
\r
158 struct value_traits
\r
159 : detail::derivation_value_traits<T, this_type, Tag>
\r
162 //! <b>Effects</b>: Converts a pointer to a node into
\r
163 //! a pointer to the hook that holds that node.
\r
165 //! <b>Throws</b>: Nothing.
\r
166 static this_type_ptr to_hook_ptr(node_ptr p)
\r
168 using boost::get_pointer;
\r
169 return this_type_ptr(static_cast<iset_base_hook*> (get_pointer(p)));
\r
172 //! <b>Effects</b>: Converts a const pointer to a node stored in a container into
\r
173 //! a const pointer to the hook that holds that node.
\r
175 //! <b>Throws</b>: Nothing.
\r
176 static const_this_type_ptr to_hook_ptr(const_node_ptr p)
\r
178 using boost::get_pointer;
\r
179 return const_this_type_ptr(static_cast<const iset_base_hook*> (get_pointer(p)));
\r
182 //! <b>Effects</b>: Returns a pointer to the node that this hook holds.
\r
184 //! <b>Throws</b>: Nothing.
\r
185 node_ptr to_node_ptr()
\r
186 { return this_as_node(); }
\r
188 //! <b>Effects</b>: Returns a const pointer to the node that this hook holds.
\r
190 //! <b>Throws</b>: Nothing.
\r
191 const_node_ptr to_node_ptr() const
\r
192 { return this_as_node(); }
\r
195 //! Derive a class from iset_auto_base_hook in order to store objects in an
\r
196 //! iset/imultiset. iset_auto_base_hook holds the data necessary to maintain the
\r
197 //! set and provides an appropriate value_traits class for iset/imultiset.
\r
199 //! The difference between iset_auto_base_hook and iset_base_hook is that
\r
200 //! iset_auto_base_hook removes itself automatically from the container
\r
201 //! in the assignment operator and the destructor. It also provides a new
\r
202 //! "unlink" method so that the user can unlink its class without using
\r
205 //! iset_auto_base_hook can only be used with non constant-time iset/imultisets.
\r
207 //! The first integer template argument defines a tag to identify the node.
\r
208 //! The same tag value can be used in different classes, but if a class is
\r
209 //! derived from more than one iset_auto_base_hook, then each iset_auto_base_hook needs its
\r
212 //! The second argument is the pointer type that will be used internally in the hook
\r
213 //! and the iset/multiset configured from this hook.
\r
214 template<typename Tag, class VoidPointer = void*>
\r
215 class iset_auto_base_hook
\r
216 : private detail::rbtree_node_traits<VoidPointer>::node
\r
219 typedef detail::rbtree_node_traits<VoidPointer> node_traits;
\r
220 enum { linking_policy = auto_unlink };
\r
223 typedef rbtree_algorithms<node_traits> node_algorithms;
\r
226 typedef typename node_traits::node node;
\r
227 typedef typename boost::pointer_to_other
\r
228 <VoidPointer, node>::type node_ptr;
\r
229 typedef typename boost::pointer_to_other
\r
230 <VoidPointer, const node>::type const_node_ptr;
\r
231 typedef iset_auto_base_hook
\r
232 <Tag, VoidPointer> this_type;
\r
234 typedef typename boost::pointer_to_other
\r
235 <VoidPointer, this_type>::type this_type_ptr;
\r
237 typedef typename boost::pointer_to_other
\r
238 <VoidPointer, const this_type>::type const_this_type_ptr;
\r
241 node_ptr this_as_node()
\r
242 { return node_ptr(static_cast<node *const>(this)); }
\r
244 const_node_ptr this_as_node() const
\r
245 { return const_node_ptr(static_cast<const node *const>(this)); }
\r
249 //! <b>Effects</b>: Initializes the node
\r
250 //! to an unlinked state.
\r
252 //! <b>Throws</b>: Nothing.
\r
253 iset_auto_base_hook()
\r
255 { node_algorithms::init(this_as_node()); }
\r
257 //! <b>Effects</b>: Initializes the node
\r
258 //! to an unlinked state. The argument is ignored.
\r
260 //! <b>Throws</b>: Nothing.
\r
262 //! <b>Rationale</b>: Providing a copy-constructor
\r
263 //! makes classes using iset_auto_base_hook STL-compliant without forcing the
\r
264 //! user to do some additional work.
\r
265 iset_auto_base_hook(const iset_auto_base_hook& )
\r
267 { node_algorithms::init(this_as_node()); }
\r
269 //! <b>Effects</b>: Removes the node if it's inserted in a container.
\r
270 //! The argument is ignored.
\r
272 //! <b>Throws</b>: Nothing.
\r
274 //! <b>Rationale</b>: Providing an assignment operator
\r
275 //! makes classes using iset_auto_base_hook STL-compliant without forcing the
\r
276 //! user to do some additional work.
\r
277 iset_auto_base_hook& operator=(const iset_auto_base_hook& )
\r
278 { this->unlink(); return *this; }
\r
280 //! <b>Effects</b>: Removes the node if it's inserted in a container.
\r
282 //! <b>Throws</b>: Nothing.
\r
283 ~iset_auto_base_hook()
\r
284 { this->unlink(); }
\r
286 //! <b>Effects</b>: Swapping two nodes swaps the position of the elements
\r
287 //! related to those nodes in one or two containers. That is, if the node
\r
288 //! this is part of the element e1, the node x is part of the element e2
\r
289 //! and both elements are included in the containers s1 and s2, then after
\r
290 //! the swap-operation e1 is in s2 at the position of e2 and e2 is in s1
\r
291 //! at the position of e1. If one element is not in a container, then
\r
292 //! after the swap-operation the other element is not in a container.
\r
293 //! Iterators to e1 and e2 related to those nodes are invalidated.
\r
295 //! <b>Complexity</b>: Constant
\r
297 //! <b>Throws</b>: Nothing.
\r
298 void swap_nodes(iset_auto_base_hook& other)
\r
299 { node_algorithms::swap_nodes(this_as_node(), other.this_as_node()); }
\r
301 //! <b>Returns</b>: true, if the node belongs to a container, false
\r
302 //! otherwise. This function can be used to test whether iset::current
\r
303 //! will return a valid iterator.
\r
305 //! <b>Complexity</b>: Constant
\r
306 bool linked() const
\r
307 { return !node_algorithms::unique(this_as_node()); }
\r
309 //! <b>Effects</b>: Removes the node if it's inserted in a container.
\r
311 //! <b>Throws</b>: Nothing.
\r
314 node_algorithms::unlink_and_rebalance(this_as_node());
\r
315 node_algorithms::init(this_as_node());
\r
318 //! The value_traits class is used as the first template argument for iset.
\r
319 //! The template argument T defines the class type stored in iset. Objects
\r
320 //! of type T and of types derived from T can be stored. T doesn't need to be
\r
321 //! copy-constructible or assignable.
\r
323 struct value_traits
\r
324 : detail::derivation_value_traits<T, this_type, Tag>
\r
327 //! <b>Effects</b>: Converts a pointer to a node into
\r
328 //! a pointer to the hook that holds that node.
\r
330 //! <b>Throws</b>: Nothing.
\r
331 static this_type_ptr to_hook_ptr(node_ptr p)
\r
333 using boost::get_pointer;
\r
334 return this_type_ptr(static_cast<iset_auto_base_hook*> (get_pointer(p)));
\r
337 //! <b>Effects</b>: Converts a const pointer to a node stored in a container into
\r
338 //! a const pointer to the hook that holds that node.
\r
340 //! <b>Throws</b>: Nothing.
\r
341 static const_this_type_ptr to_hook_ptr(const_node_ptr p)
\r
343 using boost::get_pointer;
\r
344 return const_this_type_ptr(static_cast<const iset_auto_base_hook*> (get_pointer(p)));
\r
347 //! <b>Effects</b>: Returns a pointer to the node that this hook holds.
\r
349 //! <b>Throws</b>: Nothing.
\r
350 node_ptr to_node_ptr()
\r
351 { return this_as_node(); }
\r
353 //! <b>Effects</b>: Returns a const pointer to the node that this hook holds.
\r
355 //! <b>Throws</b>: Nothing.
\r
356 const_node_ptr to_node_ptr() const
\r
357 { return this_as_node(); }
\r
361 //! Put a public data member iset_member_hook in order to store objects of this class in
\r
362 //! an iset/imultiset. iset_member_hook holds the data necessary for maintaining the
\r
363 //! set/multiset and provides an appropriate value_traits class for iset/imultiset.
\r
365 //! The template argument T defines the class type stored in iset/imultiset. Objects of
\r
366 //! type T and of types derived from T can be stored. T doesn't need to be
\r
367 //! copy-constructible or assignable.
\r
369 //! The second boolean template parameter will activate the safe-mode checks
\r
370 //! if it's configured as "true".
\r
372 //! The third argument is the pointer type that will be used internally in the hook
\r
373 //! and the iset/imultiset configured from this hook.
\r
374 template<class T, bool SafeMode = true, class VoidPointer = void*>
\r
375 class iset_member_hook
\r
376 : private detail::rbtree_node_traits<VoidPointer>::node
\r
379 typedef detail::rbtree_node_traits<VoidPointer> node_traits;
\r
380 enum { linking_policy = SafeMode? safe_mode_link : normal_link};
\r
383 typedef rbtree_algorithms<node_traits> node_algorithms;
\r
386 typedef typename node_traits::node node;
\r
387 typedef typename boost::pointer_to_other
\r
388 <VoidPointer, node>::type node_ptr;
\r
389 typedef typename boost::pointer_to_other
\r
390 <VoidPointer, const node>::type const_node_ptr;
\r
391 typedef iset_member_hook
\r
392 <T, SafeMode, VoidPointer> this_type;
\r
394 typedef typename boost::pointer_to_other
\r
395 <VoidPointer, this_type >::type this_type_ptr;
\r
397 typedef typename boost::pointer_to_other
\r
398 <VoidPointer, const this_type >::type const_this_type_ptr;
\r
401 node_ptr this_as_node()
\r
402 { return node_ptr(static_cast<node *const>(this)); }
\r
404 const_node_ptr this_as_node() const
\r
405 { return const_node_ptr(static_cast<const node *const>(this)); }
\r
408 //! <b>Effects</b>: If SafeMode is true initializes the node
\r
409 //! to an unlinked state.
\r
411 //! <b>Throws</b>: Nothing.
\r
416 node_algorithms::init(this_as_node());
\r
420 //! <b>Effects</b>: If SafeMode is true initializes the node
\r
421 //! to an unlinked state. The argument is ignored.
\r
423 //! <b>Throws</b>: Nothing.
\r
425 //! <b>Rationale</b>: Providing a copy-constructor
\r
426 //! makes classes using iset_member_hook STL-compliant without forcing the
\r
427 //! user to do some additional work.
\r
428 iset_member_hook(const iset_member_hook& )
\r
432 node_algorithms::init(this_as_node());
\r
436 //! <b>Effects</b>: If SafeMode is true, an assertion is raised
\r
437 //! if the node is still linked. After that, the node is initialized
\r
438 //! to an unlinked state. The argument is ignored.
\r
440 //! <b>Throws</b>: Nothing.
\r
442 //! <b>Rationale</b>: Providing an assignment operator
\r
443 //! makes classes using iset_member_hook STL-compliant without forcing the
\r
444 //! user to do some additional work.
\r
445 iset_member_hook& operator=(const iset_member_hook& )
\r
448 BOOST_ASSERT(!this->linked());
\r
453 //! <b>Effects</b>: If SafeMode is set to false, the destructor does
\r
454 //! nothing (ie. no code is generated). Otherwise, if the object is
\r
455 //! stored in an imultiset using the appropriate node, the object is removed
\r
456 //! from that imultiset.
\r
458 //! <b>Throws</b>: Nothing.
\r
459 ~iset_member_hook()
\r
462 BOOST_ASSERT(!this->linked());
\r
466 //! <b>Returns</b>: true, if the node belongs to a container, false
\r
467 //! otherwise. This function can be used to test whether iset::current
\r
468 //! will return a valid iterator.
\r
470 //! <b>Complexity</b>: Constant
\r
471 bool linked() const
\r
473 //We must be in safe-mode to know if we are really linked
\r
474 //Otherwise, this would lead to an unknown state
\r
475 BOOST_ASSERT(SafeMode);
\r
476 return !node_algorithms::unique(this_as_node());
\r
479 //! The value_traits class is used as the first template argument for imultiset.
\r
480 //! The template argument is a pointer to member pointing to the node in
\r
481 //! the class. Objects of type T and of types derived from T can be stored.
\r
482 //! T don't need to be copy-constructible or assignable.
\r
483 template<this_type T::* P>
\r
484 struct value_traits
\r
485 : detail::member_value_traits<T, this_type, P>
\r
488 //! <b>Effects</b>: Converts a pointer to a node into
\r
489 //! a pointer to the hook that holds that node.
\r
491 //! <b>Throws</b>: Nothing.
\r
492 static this_type_ptr to_hook_ptr(node_ptr p)
\r
494 using boost::get_pointer;
\r
495 return this_type_ptr(static_cast<this_type*> (get_pointer(p)));
\r
498 //! <b>Effects</b>: Converts a const pointer to a node stored in a container into
\r
499 //! a const pointer to the hook that holds that node.
\r
501 //! <b>Throws</b>: Nothing.
\r
502 static const_this_type_ptr to_hook_ptr(const_node_ptr p)
\r
504 using boost::get_pointer;
\r
505 return const_this_type_ptr(static_cast<const this_type*> (get_pointer(p)));
\r
508 //! <b>Effects</b>: Returns a pointer to the node that this hook holds.
\r
510 //! <b>Throws</b>: Nothing.
\r
511 node_ptr to_node_ptr()
\r
512 { return this_as_node(); }
\r
514 //! <b>Effects</b>: Returns a const pointer to the node that this hook holds.
\r
516 //! <b>Throws</b>: Nothing.
\r
517 const_node_ptr to_node_ptr() const
\r
518 { return this_as_node(); }
\r
521 //! Put a public data member iset_auto_member_hook in order to store objects of this
\r
522 //! class in an iset/imultiset. iset_auto_member_hook holds the data necessary for
\r
523 //! maintaining the set/multiset and provides an appropriate value_traits class for
\r
524 //! iset/imultiset.
\r
526 //! The difference between iset_auto_member_hook and iset_member_hook is that
\r
527 //! iset_auto_member_hook removes itself automatically from the container
\r
528 //! in the assignment operator and the destructor. It also provides a new
\r
529 //! "unlink" method so that the user can unlink its class without using
\r
532 //! iset_auto_member_hook can only be used with non constant-time iset/imultisets.
\r
534 //! The first template argument T defines the class type stored in iset/imultisets.
\r
535 //! Objects of type T and of types derived from T can be stored. T doesn't need to
\r
536 //! be copy-constructible or assignable.
\r
538 //! The second argument is the pointer type that will be used internally in the hook
\r
539 //! and the iset/imultiset configured from this hook.
\r
540 template<class T, class VoidPointer = void *>
\r
541 class iset_auto_member_hook
\r
542 : private detail::rbtree_node_traits<VoidPointer>::node
\r
545 typedef detail::rbtree_node_traits<VoidPointer> node_traits;
\r
546 enum { linking_policy = auto_unlink };
\r
549 typedef rbtree_algorithms<node_traits> node_algorithms;
\r
552 typedef typename node_traits::node node;
\r
553 typedef typename boost::pointer_to_other
\r
554 <VoidPointer, node>::type node_ptr;
\r
555 typedef typename boost::pointer_to_other
\r
556 <VoidPointer, const node>::type const_node_ptr;
\r
557 typedef iset_auto_member_hook
\r
558 <T, VoidPointer> this_type;
\r
560 typedef typename boost::pointer_to_other
\r
561 <VoidPointer, this_type >::type this_type_ptr;
\r
563 typedef typename boost::pointer_to_other
\r
564 <VoidPointer, const this_type >::type const_this_type_ptr;
\r
567 node_ptr this_as_node()
\r
568 { return node_ptr(static_cast<node *const>(this)); }
\r
570 const_node_ptr this_as_node() const
\r
571 { return const_node_ptr(static_cast<const node *const>(this)); }
\r
574 //! <b>Effects</b>: Initializes the node
\r
575 //! to an unlinked state.
\r
577 //! <b>Throws</b>: Nothing.
\r
578 iset_auto_member_hook()
\r
580 { node_algorithms::init(this_as_node()); }
\r
582 //! <b>Effects</b>: Initializes the node
\r
583 //! to an unlinked state. The argument is ignored.
\r
585 //! <b>Throws</b>: Nothing.
\r
587 //! <b>Rationale</b>: Providing a copy-constructor
\r
588 //! makes classes using iset_auto_base_hook STL-compliant without forcing the
\r
589 //! user to do some additional work.
\r
590 iset_auto_member_hook(const iset_auto_member_hook& )
\r
592 { node_algorithms::init(this_as_node()); }
\r
594 //! <b>Effects</b>: Removes the node if it's inserted in a container.
\r
595 //! The argument is ignored.
\r
597 //! <b>Throws</b>: Nothing.
\r
599 //! <b>Rationale</b>: Providing an assignment operator
\r
600 //! makes classes using iset_auto_base_hook STL-compliant without forcing the
\r
601 //! user to do some additional work.
\r
602 iset_auto_member_hook& operator=(const iset_auto_member_hook& )
\r
603 { this->unlink(); return *this; }
\r
605 //! <b>Effects</b>: Removes the node if it's inserted in a container.
\r
607 //! <b>Throws</b>: Nothing.
\r
608 ~iset_auto_member_hook()
\r
609 { this->unlink(); }
\r
611 //! <b>Effects</b>: Swapping two nodes swaps the position of the elements
\r
612 //! related to those nodes in one or two containers. That is, if the node
\r
613 //! this is part of the element e1, the node x is part of the element e2
\r
614 //! and both elements are included in the containers s1 and s2, then after
\r
615 //! the swap-operation e1 is in s2 at the position of e2 and e2 is in s1
\r
616 //! at the position of e1. If one element is not in a container, then
\r
617 //! after the swap-operation the other element is not in a container.
\r
618 //! Iterators to e1 and e2 related to those nodes are invalidated.
\r
620 //! <b>Complexity</b>: Constant
\r
622 //! <b>Throws</b>: Nothing.
\r
623 void swap_nodes(iset_auto_member_hook& other)
\r
624 { node_algorithms::swap_nodes(this_as_node(), other.this_as_node()); }
\r
626 //! <b>Returns</b>: true, if the node belongs to a container, false
\r
627 //! otherwise. This function can be used to test whether iset::current
\r
628 //! will return a valid iterator.
\r
630 //! <b>Complexity</b>: Constant
\r
631 bool linked() const
\r
632 { return !node_algorithms::unique(this_as_node()); }
\r
634 //! The value_traits class is used as the first template argument for iset.
\r
635 //! The template argument is a pointer to member pointing to the node in
\r
636 //! the class. Objects of type T and of types derived from T can be stored.
\r
637 //! T doesn't need to be copy-constructible or assignable.
\r
638 template<this_type T::* M>
\r
639 struct value_traits
\r
640 : detail::member_value_traits<T, this_type, M>
\r
643 //! <b>Effects</b>: Removes the node if it's inserted in a container.
\r
645 //! <b>Throws</b>: Nothing.
\r
648 node_algorithms::unlink_and_rebalance(this_as_node());
\r
649 node_algorithms::init(this_as_node());
\r
652 //! <b>Effects</b>: Converts a pointer to a node into
\r
653 //! a pointer to the hook that holds that node.
\r
655 //! <b>Throws</b>: Nothing.
\r
656 static this_type_ptr to_hook_ptr(node_ptr p)
\r
658 using boost::get_pointer;
\r
659 return this_type_ptr(static_cast<this_type*> (get_pointer(p)));
\r
662 //! <b>Effects</b>: Converts a const pointer to a node stored in a container into
\r
663 //! a const pointer to the hook that holds that node.
\r
665 //! <b>Throws</b>: Nothing.
\r
666 static const_this_type_ptr to_hook_ptr(const_node_ptr p)
\r
668 using boost::get_pointer;
\r
669 return const_this_type_ptr(static_cast<const this_type*> (get_pointer(p)));
\r
672 //! <b>Effects</b>: Returns a pointer to the node that this hook holds.
\r
674 //! <b>Throws</b>: Nothing.
\r
675 node_ptr to_node_ptr()
\r
676 { return this_as_node(); }
\r
678 //! <b>Effects</b>: Returns a const pointer to the node that this hook holds.
\r
680 //! <b>Throws</b>: Nothing.
\r
681 const_node_ptr to_node_ptr() const
\r
682 { return this_as_node(); }
\r
685 } //namespace intrusive
\r
686 } //namespace boost
\r
688 #include "detail/config_end.hpp"
\r
690 #endif //BOOST_INTRUSIVE_ISET_HOOK_HPP
\r