Move boost/intrusive to senf/boost_intrusive
[senf.git] / senf / boost_intrusive / ilist_hook.hpp
diff --git a/senf/boost_intrusive/ilist_hook.hpp b/senf/boost_intrusive/ilist_hook.hpp
new file mode 100644 (file)
index 0000000..32a2dc6
--- /dev/null
@@ -0,0 +1,725 @@
+/////////////////////////////////////////////////////////////////////////////\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_ILIST_HOOK_HPP\r
+#define BOOST_INTRUSIVE_ILIST_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/list_node.hpp"\r
+#include "list_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 ilist_base_hook in order to store objects in \r
+//! in an ilist. ilist_base_hook holds the data necessary to maintain the \r
+//! list and provides an appropriate value_traits class for ilist.\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 ilist_base_hook, then each ilist_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 ilist configured from this hook.\r
+template< typename Tag\r
+        , bool SafeMode = true\r
+        , class VoidPointer = void *\r
+        >\r
+class ilist_base_hook\r
+   :  private detail::list_node_traits<VoidPointer>::node\r
+{\r
+   public:\r
+   typedef detail::list_node_traits<VoidPointer>      node_traits;\r
+   enum { linking_policy = SafeMode ? safe_mode_link : normal_link};\r
+\r
+   private:\r
+   typedef list_algorithms<node_traits>               node_algorithms;\r
+\r
+   public:\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 ilist_base_hook\r
+      <Tag, SafeMode, VoidPointer>                    this_type;\r
+\r
+   typedef typename boost::pointer_to_other\r
+      <VoidPointer, this_type>::type                  this_type_ptr;\r
+\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
+   ilist_base_hook()\r
+      :  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 ilist_base_hook STL-compliant without forcing the \r
+   //!   user to do some additional work. "swap" can be used to emulate\r
+   //!   move-semantics.\r
+   ilist_base_hook(const ilist_base_hook& ) \r
+      :  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 ilist_base_hook STL-compliant without forcing the \r
+   //!   user to do some additional work. "swap" can be used to emulate\r
+   //!   move-semantics.\r
+   ilist_base_hook& operator=(const ilist_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 ilist an assertion is raised.\r
+   //! \r
+   //! <b>Throws</b>: Nothing. \r
+   ~ilist_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>: Constant \r
+   //!\r
+   //! <b>Throws</b>: Nothing. \r
+   void swap_nodes(ilist_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 ilist::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 ilist. \r
+   //! The template argument T defines the class type stored in ilist. 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<ilist_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 const_this_type_ptr(static_cast<const ilist_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 ilist_auto_base_hook in order to store objects in \r
+//! in an ilist. ilist_auto_base_hook holds the data necessary to maintain the \r
+//! list and provides an appropriate value_traits class for ilist.\r
+//!\r
+//! The difference between ilist_auto_base_hook and ilist_base_hook is that\r
+//! ilist_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
+//! ilist_auto_base_hook can only be used with non constant-time ilists.\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 ilist_auto_base_hook, then each ilist_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 ilist configured from this hook.\r
+template< typename Tag\r
+        , class VoidPointer = void *\r
+        >\r
+class ilist_auto_base_hook\r
+   :  private detail::list_node_traits<VoidPointer>::node\r
+{\r
+   public:\r
+   typedef detail::list_node_traits<VoidPointer>      node_traits;\r
+   enum { linking_policy = auto_unlink  };\r
+\r
+   private:\r
+   typedef list_algorithms<node_traits>               node_algorithms;\r
+\r
+   public:\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 ilist_auto_base_hook\r
+      <Tag, VoidPointer>                              this_type;\r
+\r
+   typedef typename boost::pointer_to_other\r
+      <VoidPointer, this_type>::type                  this_type_ptr;\r
+\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
+   ilist_auto_base_hook()\r
+      :  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 ilist_auto_base_hook STL-compliant without forcing the \r
+   //!   user to do some additional work.\r
+   ilist_auto_base_hook(const ilist_auto_base_hook& ) \r
+      :  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 ilist_auto_base_hook STL-compliant without forcing the \r
+   //!   user to do some additional work.\r
+   ilist_auto_base_hook& operator=(const ilist_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
+   ~ilist_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>: Constant \r
+   //!\r
+   //! <b>Throws</b>: Nothing. \r
+   void swap_nodes(ilist_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 ilist::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 ilist. \r
+   //! The template argument T defines the class type stored in ilist. 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<ilist_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 const_this_type_ptr(static_cast<const ilist_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
+//! Put a public data member ilist_member_hook in order to store objects of this class in\r
+//! an ilist. ilist_member_hook holds the data necessary for maintaining the list and \r
+//! provides an appropriate value_traits class for ilist.\r
+//! \r
+//! The template argument T defines the class type stored in ilist. 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 ilist configured from this hook.\r
+template<class T, bool SafeMode = true, class VoidPointer = void *>\r
+class ilist_member_hook\r
+   :  private detail::list_node_traits<VoidPointer>::node\r
+{\r
+   public:\r
+   typedef detail::list_node_traits<VoidPointer>      node_traits;\r
+   enum { linking_policy = SafeMode? safe_mode_link : normal_link};\r
+\r
+   private:\r
+   typedef list_algorithms<node_traits>  node_algorithms;\r
+\r
+   public:\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 ilist_member_hook\r
+      <T, SafeMode, VoidPointer>                      this_type;\r
+\r
+   typedef typename boost::pointer_to_other\r
+      <VoidPointer, this_type >::type                 this_type_ptr;\r
+\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
+   ilist_member_hook()\r
+      :  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 ilist_member_hook STL-compliant without forcing the \r
+   //!   user to do some additional work. "swap" can be used to emulate\r
+   //!   move-semantics.\r
+   ilist_member_hook(const ilist_member_hook& ) \r
+      :  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 ilist_member_hook STL-compliant without forcing the \r
+   //!   user to do some additional work. "swap" can be used to emulate\r
+   //!   move-semantics.\r
+   ilist_member_hook& operator=(const ilist_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 ilist an assertion is raised.\r
+   //! \r
+   //! <b>Throws</b>: Nothing. \r
+   ~ilist_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>: Constant \r
+   //!\r
+   //! <b>Throws</b>: Nothing.\r
+   void swap_nodes(ilist_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 ilist::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 ilist. \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 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
+//! Put a public data member ilist_auto_member_hook in order to store objects of this class in\r
+//! an ilist. ilist_auto_member_hook holds the data necessary for maintaining the list and \r
+//! provides an appropriate value_traits class for ilist.\r
+//!\r
+//! The difference between ilist_auto_member_hook and ilist_member_hook is that\r
+//! ilist_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
+//! ilist_auto_member_hook can only be used with non constant-time ilists.\r
+//! \r
+//! The first template argument T defines the class type stored in ilist. 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 ilist configured from this hook.\r
+template<class T, class VoidPointer = void *>\r
+class ilist_auto_member_hook\r
+   :  private detail::list_node_traits<VoidPointer>::node\r
+{\r
+   public:\r
+   typedef detail::list_node_traits<VoidPointer>      node_traits;\r
+   enum { linking_policy = auto_unlink  };\r
+\r
+   private:\r
+   typedef list_algorithms<node_traits>  node_algorithms;\r
+\r
+   public:\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 ilist_auto_member_hook\r
+      <T, VoidPointer>                                this_type;\r
+\r
+   typedef typename boost::pointer_to_other\r
+      <VoidPointer, this_type >::type                 this_type_ptr;\r
+\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
+   ilist_auto_member_hook()\r
+      :  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 ilist_auto_base_hook STL-compliant without forcing the \r
+   //!   user to do some additional work.\r
+   ilist_auto_member_hook(const ilist_auto_member_hook& ) \r
+      :  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 ilist_auto_base_hook STL-compliant without forcing the \r
+   //!   user to do some additional work.\r
+   ilist_auto_member_hook& operator=(const ilist_auto_member_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
+   ~ilist_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(ilist_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 ilist::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 ilist. \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 "detail/config_end.hpp"\r
+\r
+#endif //BOOST_INTRUSIVE_ILIST_HOOK_HPP\r