--- /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_IHASHSET_HOOK_HPP\r
+#define BOOST_INTRUSIVE_IHASHSET_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 "islist_hook.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 iunordered_set_base_hook in order to store objects in \r
+//! in an iunordered_set/iunordered_multi_set. iunordered_set_base_hook holds the data necessary to maintain \r
+//! the unordered_set/unordered_multi_set and provides an appropriate value_traits class for iunordered_set/iunordered_multi_set.\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 iunordered_set_base_hook, then each iunordered_set_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 iunordered_set/iunordered_multi_set configured from this hook.\r
+template<typename Tag, bool SafeMode = true, class VoidPointer = void*>\r
+class iunordered_set_base_hook\r
+{\r
+ typedef islist_base_hook<Tag, SafeMode, VoidPointer> IsListHook;\r
+ IsListHook m_islisthook;\r
+ typedef IsListHook implementation_defined;\r
+\r
+ public:\r
+ enum { linking_policy = SafeMode? safe_mode_link : normal_link};\r
+ typedef typename implementation_defined::node_traits node_traits;\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 iunordered_set_base_hook\r
+ <Tag, SafeMode, VoidPointer> this_type;\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
+ //! <b>Effects</b>: If SafeMode is true initializes the node\r
+ //! to an unlinked state.\r
+ //! \r
+ //! <b>Throws</b>: Nothing.\r
+ iunordered_set_base_hook()\r
+ : m_islisthook()\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 iunordered_set_base_hook STL-compliant without forcing the \r
+ //! user to do some additional work. "swap" can be used to emulate\r
+ //! move-semantics.\r
+ iunordered_set_base_hook(const iunordered_set_base_hook &other)\r
+ : m_islisthook(other.m_islisthook)\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 iunordered_set_base_hook STL-compliant without forcing the \r
+ //! user to do some additional work. "swap" can be used to emulate\r
+ //! move-semantics.\r
+ iunordered_set_base_hook& operator=(const iunordered_set_base_hook &other)\r
+ { m_islisthook = other.m_islisthook; 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 iunordered_set/iunordered_multiset an assertion is raised.\r
+ //! \r
+ //! <b>Throws</b>: Nothing.\r
+ ~iunordered_set_base_hook() \r
+ {}\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 iunordered_set/iunordered_multiset::current \r
+ //! will return a valid iterator. \r
+ //!\r
+ //! <b>Complexity</b>: Constant\r
+ bool linked() const \r
+ { return m_islisthook.linked(); }\r
+\r
+ //! The value_traits class is used as the first template argument for iunordered_set/iunordered_multiset. \r
+ //! The template argument T defines the class type stored in iunordered_set/iunordered_multiset. 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((this_type*)get_pointer(IsListHook::to_hook_ptr(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((const this_type*)get_pointer(IsListHook::to_hook_ptr(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 m_islisthook.to_node_ptr(); }\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 m_islisthook.to_node_ptr(); }\r
+};\r
+\r
+\r
+//! Derive a class from iunordered_set_auto_base_hook in order to store objects in an \r
+//! iunordered_set/iunordered_multi_set. iunordered_set_auto_base_hook holds the data necessary to maintain the \r
+//! unordered_set and provides an appropriate value_traits class for iunordered_set/iunordered_multi_set.\r
+//!\r
+//! The difference between iunordered_set_auto_base_hook and iunordered_set_base_hook is that\r
+//! iunordered_set_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
+//! iunordered_set_auto_base_hook can only be used with non constant-time iunordered_set/iunordered_multi_sets.\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 iunordered_set_auto_base_hook, then each iunordered_set_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 iunordered_set/unordered_multi_set configured from this hook.\r
+template<typename Tag, class VoidPointer = void*>\r
+class iunordered_set_auto_base_hook\r
+{\r
+ typedef islist_auto_base_hook<Tag, VoidPointer> IsListHook;\r
+ IsListHook m_islisthook;\r
+ typedef IsListHook implementation_defined;\r
+\r
+ public:\r
+ enum { linking_policy = auto_unlink };\r
+ typedef typename implementation_defined::node_traits node_traits;\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 iunordered_set_auto_base_hook\r
+ <Tag,VoidPointer> this_type;\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
+ public:\r
+\r
+ //! <b>Effects</b>: Initializes the node\r
+ //! to an unlinked state.\r
+ //! \r
+ //! <b>Throws</b>: Nothing. \r
+ iunordered_set_auto_base_hook()\r
+ : m_islisthook()\r
+ {}\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 iunordered_set_auto_base_hook STL-compliant without forcing the \r
+ //! user to do some additional work.\r
+ iunordered_set_auto_base_hook(const iunordered_set_auto_base_hook &other)\r
+ : m_islisthook(other.m_islisthook)\r
+ {}\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 iunordered_set_auto_base_hook STL-compliant without forcing the \r
+ //! user to do some additional work.\r
+ iunordered_set_auto_base_hook& operator=(const iunordered_set_auto_base_hook &other)\r
+ { m_islisthook = other.m_islisthook; return *this; }\r
+\r
+ //! <b>Effects</b>: Removes the node if it's inserted in a container.\r
+ //! \r
+ //! <b>Throws</b>: Nothing. \r
+ ~iunordered_set_auto_base_hook() \r
+ {}\r
+\r
+ //! <b>Returns</b>: true, if the node belongs to a container, false\r
+ //! otherwise. This function can be used to test whether iunordered_set/iunordered_multiset::current \r
+ //! will return a valid iterator. \r
+ //!\r
+ //! <b>Complexity</b>: Constant \r
+ bool linked() const \r
+ { return m_islisthook.linked(); }\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
+ { return m_islisthook.unlink(); }\r
+\r
+ //! The value_traits class is used as the first template argument for iunordered_set/iunordered_multiset. \r
+ //! The template argument T defines the class type stored in iunordered_set/iunordered_multiset. 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((this_type*)get_pointer(IsListHook::to_hook_ptr(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((const this_type*)get_pointer(IsListHook::to_hook_ptr(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 m_islisthook.to_node_ptr(); }\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 m_islisthook.to_node_ptr(); }\r
+};\r
+\r
+\r
+//! Put a public data member iunordered_set_member_hook in order to store objects of this class in\r
+//! an iunordered_set/iunordered_multi_set. iunordered_set_member_hook holds the data necessary for maintaining the\r
+//! unordered_set/unordered_multi_set and provides an appropriate value_traits class for iunordered_set/iunordered_multi_set.\r
+//! \r
+//! The template argument T defines the class type stored in iunordered_set/iunordered_multi_set. 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 boolean template argument SafeMode controls initializes\r
+//! the node to a safe state in the constructor and asserts if the node is destroyed\r
+//! or it's assigned but it's still inserted in a iunordered_set/iunordered_multi_set.\r
+//!\r
+//! The third argument is the pointer type that will be used internally in the hook\r
+//! and the iunordered_set/iunordered_multi_set configured from this hook.\r
+template<class T, bool SafeMode = true, class VoidPointer = void*>\r
+class iunordered_set_member_hook\r
+{\r
+ typedef islist_member_hook<T, SafeMode, VoidPointer> IsListHook;\r
+ IsListHook m_islisthook;\r
+ typedef IsListHook implementation_defined;\r
+\r
+ public:\r
+ enum { linking_policy = SafeMode? safe_mode_link : normal_link};\r
+ typedef typename implementation_defined::node_traits node_traits;\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 iunordered_set_member_hook\r
+ <T, SafeMode, VoidPointer> this_type;\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
+ public:\r
+ //! <b>Effects</b>: If SafeMode is true initializes the node\r
+ //! to an unlinked state.\r
+ //! \r
+ //! <b>Throws</b>: Nothing. \r
+ iunordered_set_member_hook()\r
+ : m_islisthook()\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 iunordered_set_member_hook STL-compliant without forcing the \r
+ //! user to do some additional work.\r
+ iunordered_set_member_hook(const iunordered_set_member_hook &other)\r
+ : m_islisthook(other.m_islisthook)\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 iunordered_set_member_hook STL-compliant without forcing the \r
+ //! user to do some additional work.\r
+ iunordered_set_member_hook& operator=(const iunordered_set_member_hook &other) \r
+ { m_islisthook = other.m_islisthook; 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 iunordered_set/iunordered_multiset an assertion is raised.\r
+ //! \r
+ //! <b>Throws</b>: Nothing. \r
+ ~iunordered_set_member_hook() \r
+ {}\r
+\r
+ //! <b>Returns</b>: true, if the node belongs to a container, false\r
+ //! otherwise. This function can be used to test whether iunordered_set/iunordered_multiset::current \r
+ //! will return a valid iterator. \r
+ //!\r
+ //! <b>Complexity</b>: Constant \r
+ bool linked() const \r
+ { return m_islisthook.linked(); }\r
+\r
+ //! The value_traits class is used as the first template argument for iunordered_set/iunordered_multiset. \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
+ { m_islisthook.unlink(); }\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((this_type*)get_pointer(IsListHook::to_hook_ptr(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((const this_type*)get_pointer(IsListHook::to_hook_ptr(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 m_islisthook.to_node_ptr(); }\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 m_islisthook.to_node_ptr(); }\r
+};\r
+\r
+//! Put a public data member iunordered_set_auto_member_hook in order to store objects of this class in\r
+//! an iunordered_set/iunordered_multiset. iunordered_set_auto_member_hook holds the data necessary for maintaining the list and \r
+//! provides an appropriate value_traits class for iunordered_set/iunordered_multiset.\r
+//!\r
+//! The difference between iunordered_set_auto_member_hook and iunordered_set_member_hook is that\r
+//! iunordered_set_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
+//! iunordered_set_auto_member_hook can only be used with non constant-time iunordered_sets/iunordered_multisets.\r
+//! \r
+//! The first template argument T defines the class type stored in iunordered_set/iunordered_multiset. 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 iunordered_set/iunordered_multiset configured from this hook.\r
+template<class T, class VoidPointer = void*>\r
+class iunordered_set_auto_member_hook\r
+{\r
+ typedef islist_auto_member_hook<T, VoidPointer> IsListHook;\r
+ IsListHook m_islisthook;\r
+ typedef IsListHook implementation_defined;\r
+\r
+ public:\r
+ enum { linking_policy = auto_unlink };\r
+ typedef typename implementation_defined::node_traits node_traits;\r
+ typedef typename node_traits::node node;\r
+ typedef iunordered_set_auto_member_hook\r
+ <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
+ public:\r
+\r
+ //! <b>Effects</b>: Initializes the node\r
+ //! to an unlinked state.\r
+ //! \r
+ //! <b>Throws</b>: Nothing. \r
+ iunordered_set_auto_member_hook()\r
+ : m_islisthook()\r
+ {}\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 iunordered_set_auto_base_hook STL-compliant without forcing the \r
+ //! user to do some additional work.\r
+ iunordered_set_auto_member_hook(const iunordered_set_auto_member_hook &other)\r
+ : m_islisthook(other.m_islisthook)\r
+ {}\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 iunordered_set_auto_base_hook STL-compliant without forcing the \r
+ //! user to do some additional work.\r
+ iunordered_set_auto_member_hook& operator=(const iunordered_set_auto_member_hook &other)\r
+ { m_islisthook = other.m_islisthook; return *this; }\r
+\r
+ //! <b>Effects</b>: Removes the node if it's inserted in a container.\r
+ //! \r
+ //! <b>Throws</b>: Nothing. \r
+ ~iunordered_set_auto_member_hook() \r
+ {}\r
+\r
+ //! <b>Returns</b>: true, if the node belongs to a container, false\r
+ //! otherwise. This function can be used to test whether iunordered_set/iunordered_multiset::current \r
+ //! will return a valid iterator. \r
+ //!\r
+ //! <b>Complexity</b>: Constant \r
+ bool linked() const \r
+ { return m_islisthook.linked(); }\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
+ { return m_islisthook.unlink(); }\r
+\r
+ //! The value_traits class is used as the first template argument for iunordered_set/iunordered_multiset. \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((this_type*)get_pointer(IsListHook::to_hook_ptr(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((const this_type*)get_pointer(IsListHook::to_hook_ptr(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 m_islisthook.to_node_ptr(); }\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 m_islisthook.to_node_ptr(); }\r
+};\r
+\r
+} //namespace intrusive \r
+} //namespace boost \r
+\r
+#include "detail/config_end.hpp"\r
+\r
+#endif //BOOST_INTRUSIVE_IHASHSET_HOOK_HPP\r