Move boost/intrusive to senf/boost_intrusive
[senf.git] / senf / boost_intrusive / iunordered_set_hook.hpp
diff --git a/senf/boost_intrusive/iunordered_set_hook.hpp b/senf/boost_intrusive/iunordered_set_hook.hpp
new file mode 100644 (file)
index 0000000..c79ac2c
--- /dev/null
@@ -0,0 +1,570 @@
+/////////////////////////////////////////////////////////////////////////////\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