--- /dev/null
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// (C) Copyright Olaf Krzikalla 2004-2006.\r
+// (C) Copyright Ion GaztaƱaga 2006-2007\r
+//\r
+// Distributed under the Boost Software License, Version 1.0.\r
+// (See accompanying file LICENSE_1_0.txt or copy at\r
+// http://www.boost.org/LICENSE_1_0.txt)\r
+//\r
+// See http://www.boost.org/libs/intrusive for documentation.\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+#ifndef BOOST_INTRUSIVE_ISLIST_HOOK_HPP\r
+#define BOOST_INTRUSIVE_ISLIST_HOOK_HPP\r
+\r
+#include "detail/config_begin.hpp"\r
+#include "detail/utilities.hpp"\r
+#include "detail/pointer_type.hpp"\r
+#include "detail/pointer_to_other.hpp"\r
+#include "detail/slist_node.hpp"\r
+#include "slist_algorithms.hpp"\r
+#include "linking_policy.hpp"\r
+#include <boost/get_pointer.hpp>\r
+#include <stdexcept>\r
+\r
+namespace boost {\r
+namespace intrusive {\r
+\r
+//! Derive a class from islist_base_hook in order to store objects in \r
+//! in an islist. islist_base_hook holds the data necessary to maintain the \r
+//! list and provides an appropriate value_traits class for islist.\r
+//! \r
+//! The first integer template argument defines a tag to identify the node. \r
+//! The same tag value can be used in different classes, but if a class is \r
+//! derived from more than one islist_base_hook, then each islist_base_hook needs its \r
+//! unique tag.\r
+//!\r
+//! The second boolean template parameter will activate the safe-mode checks\r
+//! if it's configured as "true".\r
+//!\r
+//! The third argument is the pointer type that will be used internally in the hook\r
+//! and the islist configured from this hook.\r
+template<typename Tag, bool SafeMode = true, class VoidPointer = void*>\r
+class islist_base_hook\r
+ : private detail::slist_node_traits<VoidPointer>::node\r
+{\r
+ public:\r
+ typedef detail::slist_node_traits<VoidPointer> node_traits;\r
+ enum { linking_policy = SafeMode? safe_mode_link : normal_link};\r
+\r
+ private:\r
+ typedef slist_algorithms<node_traits> node_algorithms;\r
+\r
+ public:\r
+ typedef typename node_traits::node node;\r
+ typedef islist_base_hook\r
+ <Tag, SafeMode, VoidPointer> this_type;\r
+ typedef typename boost::pointer_to_other\r
+ <VoidPointer, node>::type node_ptr;\r
+ typedef typename boost::pointer_to_other\r
+ <VoidPointer, const node>::type const_node_ptr;\r
+ typedef typename boost::pointer_to_other\r
+ <VoidPointer, this_type>::type this_type_ptr;\r
+ typedef typename boost::pointer_to_other\r
+ <VoidPointer, const this_type>::type const_this_type_ptr;\r
+\r
+ private:\r
+ node_ptr this_as_node()\r
+ { return node_ptr(static_cast<node *const>(this)); }\r
+\r
+ const_node_ptr this_as_node() const\r
+ { return const_node_ptr(static_cast<const node *const>(this)); }\r
+\r
+ public:\r
+\r
+ //! <b>Effects</b>: If SafeMode is true initializes the node\r
+ //! to an unlinked state.\r
+ //! \r
+ //! <b>Throws</b>: Nothing.\r
+ islist_base_hook()\r
+ : node_traits::node()\r
+ {\r
+ if(SafeMode){\r
+ node_algorithms::init(this_as_node());\r
+ }\r
+ }\r
+\r
+ //! <b>Effects</b>: If SafeMode is true initializes the node\r
+ //! to an unlinked state. The argument is ignored.\r
+ //! \r
+ //! <b>Throws</b>: Nothing.\r
+ //! \r
+ //! <b>Rationale</b>: Providing a copy-constructor\r
+ //! makes classes using islist_base_hook STL-compliant without forcing the \r
+ //! user to do some additional work. "swap" can be used to emulate\r
+ //! move-semantics.\r
+ islist_base_hook(const islist_base_hook& )\r
+ : node_traits::node()\r
+ {\r
+ if(SafeMode){\r
+ node_algorithms::init(this_as_node());\r
+ }\r
+ }\r
+\r
+ //! <b>Effects</b>: If SafeMode is true, an assertion is raised\r
+ //! if the node is still linked. After that, the node is initialized\r
+ //! to an unlinked state. The argument is ignored.\r
+ //! \r
+ //! <b>Throws</b>: Nothing.\r
+ //! \r
+ //! <b>Rationale</b>: Providing an assignment operator \r
+ //! makes classes using islist_base_hook STL-compliant without forcing the \r
+ //! user to do some additional work. "swap" can be used to emulate\r
+ //! move-semantics.\r
+ islist_base_hook& operator=(const islist_base_hook& )\r
+ { \r
+ if(SafeMode){\r
+ BOOST_ASSERT(!this->linked());\r
+ }\r
+ return *this; \r
+ }\r
+\r
+ //! <b>Effects</b>: If SafeMode is set to false, the destructor does\r
+ //! nothing (ie. no code is generated). If SafeMode is true and the\r
+ //! object is stored in an islist an assertion is raised.\r
+ //! \r
+ //! <b>Throws</b>: Nothing.\r
+ ~islist_base_hook() \r
+ { \r
+ if(SafeMode){\r
+ BOOST_ASSERT(!this->linked());\r
+ }\r
+ }\r
+\r
+ //! <b>Effects</b>: Swapping two nodes swaps the position of the elements \r
+ //! related to those nodes in one or two containers. That is, if the node \r
+ //! this is part of the element e1, the node x is part of the element e2 \r
+ //! and both elements are included in the containers s1 and s2, then after \r
+ //! the swap-operation e1 is in s2 at the position of e2 and e2 is in s1 \r
+ //! at the position of e1. If one element is not in a container, then \r
+ //! after the swap-operation the other element is not in a container. \r
+ //! Iterators to e1 and e2 related to those nodes are invalidated. \r
+ //!\r
+ //! <b>Complexity</b>: Linear\r
+ //!\r
+ //! <b>Throws</b>: Nothing. \r
+ void swap_nodes(islist_base_hook& other) \r
+ { node_algorithms::swap_nodes(this_as_node(), other.this_as_node()); }\r
+\r
+ //! <b>Precondition</b>: The hook must be in safe-mode.\r
+ //!\r
+ //! <b>Returns</b>: true, if the node belongs to a container, false\r
+ //! otherwise. This function can be used to test whether islist::current \r
+ //! will return a valid iterator. \r
+ //!\r
+ //! <b>Complexity</b>: Constant\r
+ bool linked() const \r
+ {\r
+ //linked() can be only used in safe-mode\r
+ BOOST_ASSERT(SafeMode);\r
+ return !node_algorithms::unique(this_as_node());\r
+ }\r
+\r
+ //! The value_traits class is used as the first template argument for islist. \r
+ //! The template argument T defines the class type stored in islist. Objects \r
+ //! of type T and of types derived from T can be stored. T doesn't need to be \r
+ //! copy-constructible or assignable.\r
+ template<class T>\r
+ struct value_traits\r
+ : detail::derivation_value_traits<T, this_type, Tag>\r
+ {};\r
+\r
+ //! <b>Effects</b>: Converts a pointer to a node into\r
+ //! a pointer to the hook that holds that node.\r
+ //! \r
+ //! <b>Throws</b>: Nothing.\r
+ static this_type_ptr to_hook_ptr(node_ptr p)\r
+ {\r
+ using boost::get_pointer;\r
+ return this_type_ptr(static_cast<islist_base_hook*> (get_pointer(p))); \r
+ }\r
+\r
+ //! <b>Effects</b>: Converts a const pointer to a node stored in a container into\r
+ //! a const pointer to the hook that holds that node.\r
+ //! \r
+ //! <b>Throws</b>: Nothing.\r
+ static const_this_type_ptr to_hook_ptr(const_node_ptr p)\r
+ {\r
+ using boost::get_pointer;\r
+ return this_type_ptr(static_cast<const islist_base_hook*> (get_pointer(p))); \r
+ }\r
+\r
+ //! <b>Effects</b>: Returns a pointer to the node that this hook holds.\r
+ //! \r
+ //! <b>Throws</b>: Nothing.\r
+ node_ptr to_node_ptr()\r
+ { return this_as_node(); }\r
+\r
+ //! <b>Effects</b>: Returns a const pointer to the node that this hook holds.\r
+ //! \r
+ //! <b>Throws</b>: Nothing.\r
+ const_node_ptr to_node_ptr() const\r
+ { return this_as_node(); }\r
+};\r
+\r
+\r
+//! Derive a class from islist_auto_base_hook in order to store objects in \r
+//! in an islist. islist_auto_base_hook holds the data necessary to maintain the \r
+//! list and provides an appropriate value_traits class for islist.\r
+//!\r
+//! The difference between islist_auto_base_hook and islist_base_hook is that\r
+//! islist_auto_base_hook removes itself automatically from the container\r
+//! in the assignment operator and the destructor. It also provides a new\r
+//! "unlink" method so that the user can unlink its class without using\r
+//! the container.\r
+//!\r
+//! islist_auto_base_hook can only be used with non constant-time islists.\r
+//! \r
+//! The first integer template argument defines a tag to identify the node. \r
+//! The same tag value can be used in different classes, but if a class is \r
+//! derived from more than one islist_auto_base_hook, then each islist_auto_base_hook needs its \r
+//! unique tag.\r
+//!\r
+//! The second argument is the pointer type that will be used internally in the hook\r
+//! and the islist configured from this hook.\r
+template<typename Tag, class VoidPointer = void*>\r
+class islist_auto_base_hook\r
+ : private detail::slist_node_traits<VoidPointer>::node\r
+{\r
+ public:\r
+ typedef detail::slist_node_traits<VoidPointer> node_traits;\r
+ enum { linking_policy = auto_unlink };\r
+\r
+ private:\r
+ typedef slist_algorithms<node_traits> node_algorithms;\r
+\r
+ public:\r
+ typedef islist_auto_base_hook\r
+ <Tag, VoidPointer> this_type;\r
+ typedef typename node_traits::node node;\r
+ typedef typename boost::pointer_to_other\r
+ <VoidPointer, node>::type node_ptr;\r
+ typedef typename boost::pointer_to_other\r
+ <VoidPointer, const node>::type const_node_ptr;\r
+ typedef typename boost::pointer_to_other\r
+ <VoidPointer, this_type>::type this_type_ptr;\r
+ typedef typename boost::pointer_to_other\r
+ <VoidPointer, const this_type>::type const_this_type_ptr;\r
+\r
+ private:\r
+ node_ptr this_as_node()\r
+ { return node_ptr(static_cast<node *const>(this)); }\r
+\r
+ const_node_ptr this_as_node() const\r
+ { return const_node_ptr(static_cast<const node *const>(this)); }\r
+\r
+ public:\r
+\r
+ //! <b>Effects</b>: Initializes the node\r
+ //! to an unlinked state.\r
+ //! \r
+ //! <b>Throws</b>: Nothing. \r
+ islist_auto_base_hook()\r
+ : node_traits::node()\r
+ { node_algorithms::init(this_as_node()); }\r
+\r
+ //! <b>Effects</b>: Initializes the node\r
+ //! to an unlinked state. The argument is ignored.\r
+ //! \r
+ //! <b>Throws</b>: Nothing. \r
+ //! \r
+ //! <b>Rationale</b>: Providing a copy-constructor\r
+ //! makes classes using islist_auto_base_hook STL-compliant without forcing the \r
+ //! user to do some additional work.\r
+ islist_auto_base_hook(const islist_auto_base_hook& )\r
+ : node_traits::node()\r
+ { node_algorithms::init(this_as_node()); }\r
+\r
+ //! <b>Effects</b>: Removes the node if it's inserted in a container.\r
+ //! The argument is ignored.\r
+ //! \r
+ //! <b>Throws</b>: Nothing. \r
+ //! \r
+ //! <b>Rationale</b>: Providing an assignment operator \r
+ //! makes classes using islist_auto_base_hook STL-compliant without forcing the \r
+ //! user to do some additional work.\r
+ islist_auto_base_hook& operator=(const islist_auto_base_hook& )\r
+ { this->unlink(); return *this; }\r
+\r
+ //! <b>Effects</b>: Removes the node if it's inserted in a container.\r
+ //! \r
+ //! <b>Throws</b>: Nothing. \r
+ ~islist_auto_base_hook() \r
+ { this->unlink(); }\r
+\r
+ //! <b>Effects</b>: Swapping two nodes swaps the position of the elements \r
+ //! related to those nodes in one or two containers. That is, if the node \r
+ //! this is part of the element e1, the node x is part of the element e2 \r
+ //! and both elements are included in the containers s1 and s2, then after \r
+ //! the swap-operation e1 is in s2 at the position of e2 and e2 is in s1 \r
+ //! at the position of e1. If one element is not in a container, then \r
+ //! after the swap-operation the other element is not in a container. \r
+ //! Iterators to e1 and e2 related to those nodes are invalidated. \r
+ //!\r
+ //! <b>Complexity</b>: Linear \r
+ //!\r
+ //! <b>Throws</b>: Nothing.\r
+ void swap_nodes(islist_auto_base_hook& other) \r
+ { node_algorithms::swap_nodes(this_as_node(), other.this_as_node()); }\r
+\r
+ //! <b>Returns</b>: true, if the node belongs to a container, false\r
+ //! otherwise. This function can be used to test whether islist::current \r
+ //! will return a valid iterator. \r
+ //!\r
+ //! <b>Complexity</b>: Constant \r
+ bool linked() const \r
+ { return !node_algorithms::unique(this_as_node()); }\r
+\r
+ //! <b>Effects</b>: Removes the node if it's inserted in a container.\r
+ //! \r
+ //! <b>Throws</b>: Nothing. \r
+ void unlink()\r
+ {\r
+ node_algorithms::unlink(this_as_node());\r
+ node_algorithms::init(this_as_node());\r
+ }\r
+\r
+ //! The value_traits class is used as the first template argument for islist. \r
+ //! The template argument T defines the class type stored in islist. Objects \r
+ //! of type T and of types derived from T can be stored. T doesn't need to be \r
+ //! copy-constructible or assignable.\r
+ template<class T>\r
+ struct value_traits\r
+ : detail::derivation_value_traits<T, this_type, Tag>\r
+ {};\r
+\r
+ //! <b>Effects</b>: Converts a pointer to a node into\r
+ //! a pointer to the hook that holds that node.\r
+ //! \r
+ //! <b>Throws</b>: Nothing. \r
+ static this_type_ptr to_hook_ptr(node_ptr p)\r
+ {\r
+ using boost::get_pointer;\r
+ return this_type_ptr(static_cast<islist_auto_base_hook*> (get_pointer(p))); \r
+ }\r
+\r
+ //! <b>Effects</b>: Converts a const pointer to a node stored in a container into\r
+ //! a const pointer to the hook that holds that node.\r
+ //! \r
+ //! <b>Throws</b>: Nothing. \r
+ static const_this_type_ptr to_hook_ptr(const_node_ptr p)\r
+ {\r
+ using boost::get_pointer;\r
+ return this_type_ptr(static_cast<const islist_auto_base_hook*> (get_pointer(p))); \r
+ }\r
+\r
+ //! <b>Effects</b>: Returns a pointer to the node that this hook holds.\r
+ //! \r
+ //! <b>Throws</b>: Nothing.\r
+ node_ptr to_node_ptr()\r
+ { return this_as_node(); }\r
+\r
+ //! <b>Effects</b>: Returns a const pointer to the node that this hook holds.\r
+ //! \r
+ //! <b>Throws</b>: Nothing.\r
+ const_node_ptr to_node_ptr() const\r
+ { return this_as_node(); }\r
+};\r
+\r
+\r
+//! Put a public data member islist_member_hook in order to store objects of this class in\r
+//! an islist. islist_member_hook holds the data necessary for maintaining the list and \r
+//! provides an appropriate value_traits class for islist.\r
+//! \r
+//! The template argument T defines the class type stored in islist. Objects of type \r
+//! T and of types derived from T can be stored. T doesn't need to be \r
+//! copy-constructible or assignable.\r
+//! \r
+//! The second boolean template parameter will activate the safe-mode checks\r
+//! if it's configured as "true".\r
+//!\r
+//! The third argument is the pointer type that will be used internally in the hook\r
+//! and the islist configured from this hook.\r
+template<class T, bool SafeMode = true, class VoidPointer = void*>\r
+class islist_member_hook \r
+ : private detail::slist_node_traits<VoidPointer>::node\r
+{\r
+ public:\r
+ typedef detail::slist_node_traits<VoidPointer> node_traits;\r
+ enum { linking_policy = SafeMode? safe_mode_link : normal_link};\r
+\r
+ private:\r
+ typedef slist_algorithms<node_traits> node_algorithms;\r
+\r
+ public:\r
+ typedef typename node_traits::node node;\r
+ typedef islist_member_hook<T, SafeMode, VoidPointer> this_type;\r
+ typedef typename boost::pointer_to_other\r
+ <VoidPointer, node>::type node_ptr;\r
+ typedef typename boost::pointer_to_other\r
+ <VoidPointer, const node>::type const_node_ptr;\r
+ typedef typename boost::pointer_to_other\r
+ <VoidPointer, this_type >::type this_type_ptr;\r
+ typedef typename boost::pointer_to_other\r
+ <VoidPointer, const this_type >::type const_this_type_ptr;\r
+\r
+ private:\r
+ node_ptr this_as_node()\r
+ { return node_ptr(static_cast<node *const>(this)); }\r
+\r
+ const_node_ptr this_as_node() const\r
+ { return const_node_ptr(static_cast<const node *const>(this)); }\r
+\r
+ public:\r
+ //! <b>Effects</b>: If SafeMode is true initializes the node\r
+ //! to an unlinked state.\r
+ //! \r
+ //! <b>Throws</b>: Nothing. \r
+ islist_member_hook()\r
+ : node_traits::node()\r
+ {\r
+ if(SafeMode){\r
+ node_algorithms::init(this_as_node());\r
+ }\r
+ }\r
+\r
+ //! <b>Effects</b>: If SafeMode is true initializes the node\r
+ //! to an unlinked state. The argument is ignored.\r
+ //! \r
+ //! <b>Throws</b>: Nothing. \r
+ //! \r
+ //! <b>Rationale</b>: Providing a copy-constructor\r
+ //! makes classes using islist_member_hook STL-compliant without forcing the \r
+ //! user to do some additional work. "swap" can be used to emulate\r
+ //! move-semantics.\r
+ islist_member_hook(const islist_member_hook& )\r
+ : node_traits::node()\r
+ {\r
+ if(SafeMode){\r
+ node_algorithms::init(this_as_node());\r
+ }\r
+ }\r
+\r
+ //! <b>Effects</b>: If SafeMode is true, an assertion is raised\r
+ //! if the node is still linked. After that, the node is initialized\r
+ //! to an unlinked state. The argument is ignored.\r
+ //! \r
+ //! <b>Throws</b>: Nothing. \r
+ //! \r
+ //! <b>Rationale</b>: Providing an assignment operator \r
+ //! makes classes using islist_member_hook STL-compliant without forcing the \r
+ //! user to do some additional work. "swap" can be used to emulate\r
+ //! move-semantics.\r
+ islist_member_hook& operator=(const islist_member_hook& ) \r
+ { \r
+ if(SafeMode){\r
+ BOOST_ASSERT(!this->linked());\r
+ }\r
+ return *this; \r
+ }\r
+\r
+ //! <b>Effects</b>: If SafeMode is set to false, the destructor does\r
+ //! nothing (ie. no code is generated). If SafeMode is true and the\r
+ //! object is stored in an islist an assertion is raised.\r
+ //! \r
+ //! <b>Throws</b>: Nothing. \r
+ ~islist_member_hook() \r
+ { \r
+ if(SafeMode){\r
+ BOOST_ASSERT(!this->linked());\r
+ }\r
+ }\r
+\r
+ //! <b>Effects</b>: Swapping two nodes swaps the position of the elements \r
+ //! related to those nodes in one or two containers. That is, if the node \r
+ //! this is part of the element e1, the node x is part of the element e2 \r
+ //! and both elements are included in the containers s1 and s2, then after \r
+ //! the swap-operation e1 is in s2 at the position of e2 and e2 is in s1 \r
+ //! at the position of e1. If one element is not in a container, then \r
+ //! after the swap-operation the other element is not in a container. \r
+ //! Iterators to e1 and e2 related to those nodes are invalidated. \r
+ //!\r
+ //! <b>Complexity</b>: Linear \r
+ //!\r
+ //! <b>Throws</b>: Nothing.\r
+ void swap_nodes(islist_member_hook& other) \r
+ { node_algorithms::swap_nodes(this_as_node(), other.this_as_node()); }\r
+\r
+ //! <b>Precondition</b>: The hook must be in safe-mode.\r
+ //!\r
+ //! <b>Returns</b>: true, if the node belongs to a container, false\r
+ //! otherwise. This function can be used to test whether islist::current \r
+ //! will return a valid iterator. \r
+ //!\r
+ //! <b>Complexity</b>: Constant\r
+ bool linked() const \r
+ {\r
+ //We must be in safe-mode to know if we are really linked\r
+ //Otherwise, this would lead to an unknown state\r
+ BOOST_ASSERT(SafeMode);\r
+ return !node_algorithms::unique(this_as_node()); \r
+ }\r
+\r
+ //! The value_traits class is used as the first template argument for islist. \r
+ //! The template argument is a pointer to member pointing to the node in \r
+ //! the class. Objects of type T and of types derived from T can be stored. \r
+ //! T doesn't need to be copy-constructible or assignable.\r
+ template<this_type T::* M>\r
+ struct value_traits\r
+ : detail::member_value_traits<T, this_type, M>\r
+ {};\r
+\r
+ //! <b>Effects</b>: Converts a pointer to a node into\r
+ //! a pointer to the hook that holds that node.\r
+ //! \r
+ //! <b>Throws</b>: Nothing. \r
+ static this_type_ptr to_hook_ptr(node_ptr p)\r
+ {\r
+ using boost::get_pointer;\r
+ return this_type_ptr(static_cast<this_type*> (get_pointer(p))); \r
+ }\r
+\r
+ //! <b>Effects</b>: Converts a const pointer to a node stored in a container into\r
+ //! a const pointer to the hook that holds that node.\r
+ //! \r
+ //! <b>Throws</b>: Nothing. \r
+ static const_this_type_ptr to_hook_ptr(const_node_ptr p)\r
+ {\r
+ using boost::get_pointer;\r
+ return this_type_ptr(static_cast<this_type*> (get_pointer(p))); \r
+ }\r
+\r
+ //! <b>Effects</b>: Returns a pointer to the node that this hook holds.\r
+ //! \r
+ //! <b>Throws</b>: Nothing. \r
+ node_ptr to_node_ptr()\r
+ { return this_as_node(); }\r
+\r
+ //! <b>Effects</b>: Returns a const pointer to the node that this hook holds.\r
+ //! \r
+ //! <b>Throws</b>: Nothing. \r
+ const_node_ptr to_node_ptr() const\r
+ { return this_as_node(); }\r
+};\r
+\r
+\r
+//! Put a public data member islist_auto_member_hook in order to store objects of this class in\r
+//! an islist. islist_auto_member_hook holds the data necessary for maintaining the list and \r
+//! provides an appropriate value_traits class for islist.\r
+//!\r
+//! The difference between islist_auto_member_hook and islist_member_hook is that\r
+//! islist_auto_member_hook removes itself automatically from the container\r
+//! in the assignment operator and the destructor. It also provides a new\r
+//! "unlink" method so that the user can unlink its class without using\r
+//! the container.\r
+//!\r
+//! islist_auto_member_hook can only be used with non constant-time islists.\r
+//! \r
+//! The first template argument T defines the class type stored in islist. Objects of\r
+//! type T and of types derived from T can be stored. T doesn't need to be \r
+//! copy-constructible or assignable.\r
+//!\r
+//! The second argument is the pointer type that will be used internally in the hook\r
+//! and the islist configured from this hook.\r
+template<class T, class VoidPointer = void*>\r
+class islist_auto_member_hook \r
+ : private detail::slist_node_traits<VoidPointer>::node\r
+{\r
+ public:\r
+ typedef detail::slist_node_traits<VoidPointer> node_traits;\r
+ enum { linking_policy = auto_unlink };\r
+\r
+ private:\r
+ typedef slist_algorithms<node_traits> node_algorithms;\r
+\r
+ public:\r
+ typedef typename node_traits::node node;\r
+ typedef islist_auto_member_hook<T, VoidPointer> this_type;\r
+ typedef typename boost::pointer_to_other\r
+ <VoidPointer, node>::type node_ptr;\r
+ typedef typename boost::pointer_to_other\r
+ <VoidPointer, const node>::type const_node_ptr;\r
+ typedef typename boost::pointer_to_other\r
+ <VoidPointer, this_type >::type this_type_ptr;\r
+ typedef typename boost::pointer_to_other\r
+ <VoidPointer, const this_type >::type const_this_type_ptr;\r
+\r
+ private:\r
+ node_ptr this_as_node()\r
+ { return node_ptr(static_cast<node *const>(this)); }\r
+\r
+ const_node_ptr this_as_node() const\r
+ { return const_node_ptr(static_cast<const node *const>(this)); }\r
+\r
+ public:\r
+ //! <b>Effects</b>: Initializes the node\r
+ //! to an unlinked state.\r
+ //! \r
+ //! <b>Throws</b>: Nothing. \r
+ islist_auto_member_hook()\r
+ : node_traits::node()\r
+ { node_algorithms::init(this_as_node()); }\r
+\r
+ //! <b>Effects</b>: Initializes the node\r
+ //! to an unlinked state. The argument is ignored.\r
+ //! \r
+ //! <b>Throws</b>: Nothing. \r
+ //! \r
+ //! <b>Rationale</b>: Providing a copy-constructor\r
+ //! makes classes using islist_auto_base_hook STL-compliant without forcing the \r
+ //! user to do some additional work.\r
+ islist_auto_member_hook(const islist_auto_member_hook& )\r
+ : node_traits::node()\r
+ { node_algorithms::init(this_as_node()); }\r
+\r
+ //! <b>Effects</b>: Removes the node if it's inserted in a container.\r
+ //! The argument is ignored.\r
+ //! \r
+ //! <b>Throws</b>: Nothing. \r
+ //! \r
+ //! <b>Rationale</b>: Providing an assignment operator \r
+ //! makes classes using islist_auto_base_hook STL-compliant without forcing the \r
+ //! user to do some additional work.\r
+ islist_auto_member_hook& operator=(const islist_auto_member_hook& ) \r
+ { this->unlink(); return *this; }\r
+\r
+ //! <b>Effects</b>: If SafeMode is set to false, the destructor does\r
+ //! nothing (ie. no code is generated). If SafeMode is true and the\r
+ //! object is stored in an islist an assertion is raised.\r
+ //! \r
+ //! <b>Throws</b>: Nothing. \r
+ ~islist_auto_member_hook() \r
+ { this->unlink(); }\r
+\r
+ //! <b>Effects</b>: Swapping two nodes swaps the position of the elements \r
+ //! related to those nodes in one or two containers. That is, if the node \r
+ //! this is part of the element e1, the node x is part of the element e2 \r
+ //! and both elements are included in the containers s1 and s2, then after \r
+ //! the swap-operation e1 is in s2 at the position of e2 and e2 is in s1 \r
+ //! at the position of e1. If one element is not in a container, then \r
+ //! after the swap-operation the other element is not in a container. \r
+ //! Iterators to e1 and e2 related to those nodes are invalidated. \r
+ //!\r
+ //! <b>Complexity</b>: Constant \r
+ //!\r
+ //! <b>Throws</b>: Nothing.\r
+ void swap_nodes(islist_auto_member_hook& other) \r
+ { node_algorithms::swap_nodes(this_as_node(), other.this_as_node()); }\r
+\r
+ //! <b>Returns</b>: true, if the node belongs to a container, false\r
+ //! otherwise. This function can be used to test whether islist::current \r
+ //! will return a valid iterator. \r
+ //!\r
+ //! <b>Complexity</b>: Constant \r
+ bool linked() const \r
+ { return !node_algorithms::unique(this_as_node()); }\r
+\r
+ //! The value_traits class is used as the first template argument for islist. \r
+ //! The template argument is a pointer to member pointing to the node in \r
+ //! the class. Objects of type T and of types derived from T can be stored. \r
+ //! T doesn't need to be copy-constructible or assignable.\r
+ template<this_type T::* M>\r
+ struct value_traits\r
+ : detail::member_value_traits<T, this_type, M>\r
+ {};\r
+\r
+ //! <b>Effects</b>: Removes the node if it's inserted in a container.\r
+ //! \r
+ //! <b>Throws</b>: Nothing. \r
+ void unlink()\r
+ {\r
+ node_algorithms::unlink(this_as_node());\r
+ node_algorithms::init(this_as_node());\r
+ }\r
+\r
+ //! <b>Effects</b>: Converts a pointer to a node into\r
+ //! a pointer to the hook that holds that node.\r
+ //! \r
+ //! <b>Throws</b>: Nothing. \r
+ static this_type_ptr to_hook_ptr(node_ptr p)\r
+ {\r
+ using boost::get_pointer;\r
+ return this_type_ptr(static_cast<this_type*> (get_pointer(p))); \r
+ }\r
+\r
+ //! <b>Effects</b>: Converts a const pointer to a node stored in a container into\r
+ //! a const pointer to the hook that holds that node.\r
+ //! \r
+ //! <b>Throws</b>: Nothing. \r
+ static const_this_type_ptr to_hook_ptr(const_node_ptr p)\r
+ {\r
+ using boost::get_pointer;\r
+ return const_this_type_ptr(static_cast<const this_type*> (get_pointer(p))); \r
+ }\r
+\r
+ //! <b>Effects</b>: Returns a pointer to the node that this hook holds.\r
+ //! \r
+ //! <b>Throws</b>: Nothing. \r
+ node_ptr to_node_ptr()\r
+ { return this_as_node(); }\r
+\r
+ //! <b>Effects</b>: Returns a const pointer to the node that this hook holds.\r
+ //! \r
+ //! <b>Throws</b>: Nothing. \r
+ const_node_ptr to_node_ptr() const\r
+ { return this_as_node(); }\r
+};\r
+\r
+} //namespace intrusive \r
+} //namespace boost \r
+\r
+#include<boost/intrusive/detail/config_end.hpp>\r
+\r
+#endif //BOOST_INTRUSIVE_ISLIST_HOOK_HPP\r