$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
From: igaztanaga_at_[hidden]
Date: 2007-09-26 11:26:38
Author: igaztanaga
Date: 2007-09-26 11:26:35 EDT (Wed, 26 Sep 2007)
New Revision: 39548
URL: http://svn.boost.org/trac/boost/changeset/39548
Log:
Changes introduced by the new intrusive version.
Added:
   trunk/boost/intrusive/detail/generic_hook.hpp   (contents, props changed)
   trunk/boost/intrusive/detail/no_exceptions_support.hpp   (contents, props changed)
   trunk/boost/intrusive/detail/transform_iterator.hpp   (contents, props changed)
   trunk/boost/intrusive/link_mode.hpp   (contents, props changed)
   trunk/boost/intrusive/options.hpp   (contents, props changed)
Removed:
   trunk/boost/intrusive/linking_policy.hpp
   trunk/boost/intrusive/tag.hpp
Text files modified: 
   trunk/boost/intrusive/circular_slist_algorithms.hpp |     1                                         
   trunk/boost/intrusive/derivation_value_traits.hpp   |     7                                         
   trunk/boost/intrusive/detail/config_begin.hpp       |     6                                         
   trunk/boost/intrusive/detail/ebo_functor_holder.hpp |     2                                         
   trunk/boost/intrusive/detail/hashtable_node.hpp     |   296 +++-------                              
   trunk/boost/intrusive/detail/list_node.hpp          |   220 ++----                                  
   trunk/boost/intrusive/detail/mpl.hpp                |   128 ++++                                    
   trunk/boost/intrusive/detail/parent_from_member.hpp |    13                                         
   trunk/boost/intrusive/detail/rbtree_node.hpp        |   209 ++----                                  
   trunk/boost/intrusive/detail/slist_node.hpp         |   206 ++----                                  
   trunk/boost/intrusive/detail/utilities.hpp          |   435 ++++++++++----                          
   trunk/boost/intrusive/hashtable.hpp                 |  1172 ++++++++++++++++++++++++++++----------- 
   trunk/boost/intrusive/intrusive_fwd.hpp             |   203 ++++--                                  
   trunk/boost/intrusive/list.hpp                      |   574 ++++++++++++++-----                     
   trunk/boost/intrusive/list_hook.hpp                 |   393 ++++--------                            
   trunk/boost/intrusive/member_value_traits.hpp       |     7                                         
   trunk/boost/intrusive/pointer_plus_bit.hpp          |     4                                         
   trunk/boost/intrusive/rbtree.hpp                    |   704 +++++++++++++++++------                 
   trunk/boost/intrusive/rbtree_algorithms.hpp         |   547 ++++++++++++++++--                      
   trunk/boost/intrusive/set.hpp                       |   691 +++++++++++++++++------                 
   trunk/boost/intrusive/set_hook.hpp                  |   392 ++++--------                            
   trunk/boost/intrusive/slist.hpp                     |   570 +++++++++++++-----                      
   trunk/boost/intrusive/slist_hook.hpp                |   386 ++++---------                           
   trunk/boost/intrusive/trivial_value_traits.hpp      |    12                                         
   trunk/boost/intrusive/unordered_set.hpp             |   616 +++++++++++++-------                    
   trunk/boost/intrusive/unordered_set_hook.hpp        |   348 +++++------                             
   26 files changed, 4994 insertions(+), 3148 deletions(-)
Modified: trunk/boost/intrusive/circular_slist_algorithms.hpp
==============================================================================
--- trunk/boost/intrusive/circular_slist_algorithms.hpp	(original)
+++ trunk/boost/intrusive/circular_slist_algorithms.hpp	2007-09-26 11:26:35 EDT (Wed, 26 Sep 2007)
@@ -48,6 +48,7 @@
    public:
    typedef typename NodeTraits::node_ptr        node_ptr;
    typedef typename NodeTraits::const_node_ptr  const_node_ptr;
+   typedef NodeTraits                           node_traits;
 
    //! <b>Requires</b>: this_node must be in a circular list or be an empty circular list.
    //! 
Modified: trunk/boost/intrusive/derivation_value_traits.hpp
==============================================================================
--- trunk/boost/intrusive/derivation_value_traits.hpp	(original)
+++ trunk/boost/intrusive/derivation_value_traits.hpp	2007-09-26 11:26:35 EDT (Wed, 26 Sep 2007)
@@ -13,7 +13,7 @@
 #ifndef BOOST_INTRUSIVE_DERIVATION_VALUE_TRAITS_HPP
 #define BOOST_INTRUSIVE_DERIVATION_VALUE_TRAITS_HPP
 
-#include <boost/intrusive/linking_policy.hpp>
+#include <boost/intrusive/link_mode.hpp>
 #include <iterator>
 
 namespace boost {
@@ -22,7 +22,7 @@
 //!This value traits template is used to create value traits
 //!from user defined node traits where value_traits::value_type will
 //!derive from node_traits::node
-template<class T, class NodeTraits, linking_policy Policy>
+template<class T, class NodeTraits, link_mode_type LinkMode = safe_link>
 struct derivation_value_traits
 {
    public:
@@ -35,8 +35,7 @@
    typedef typename boost::pointer_to_other<node_ptr, const T>::type const_pointer;
    typedef typename std::iterator_traits<pointer>::reference         reference;
    typedef typename std::iterator_traits<const_pointer>::reference   const_reference;
-
-   enum { linking_policy = Policy };
+   static const link_mode_type link_mode = LinkMode;
 
    static node_ptr to_node_ptr(reference value)
    { return node_ptr(&value); }
Modified: trunk/boost/intrusive/detail/config_begin.hpp
==============================================================================
--- trunk/boost/intrusive/detail/config_begin.hpp	(original)
+++ trunk/boost/intrusive/detail/config_begin.hpp	2007-09-26 11:26:35 EDT (Wed, 26 Sep 2007)
@@ -10,12 +10,10 @@
 //
 /////////////////////////////////////////////////////////////////////////////
 
-#ifndef BOOST_INTRUSIVE_SELECT_COMPILER_INCLUDED
-#ifndef BOOST_COMPILER_CONFIG
+#ifndef BOOST_INTRUSIVE_CONFIG_INCLUDED
+#define BOOST_INTRUSIVE_CONFIG_INCLUDED
 #include <boost/config.hpp>
 #endif
-#define BOOST_INTRUSIVE_SELECT_COMPILER_INCLUDED
-#endif
 
 #ifdef BOOST_MSVC
 
Modified: trunk/boost/intrusive/detail/ebo_functor_holder.hpp
==============================================================================
--- trunk/boost/intrusive/detail/ebo_functor_holder.hpp	(original)
+++ trunk/boost/intrusive/detail/ebo_functor_holder.hpp	2007-09-26 11:26:35 EDT (Wed, 26 Sep 2007)
@@ -35,7 +35,7 @@
 
 template<typename T>
 class ebo_functor_holder_impl<T, false>
-   :  private T
+   :  public T
 {
    public:
    ebo_functor_holder_impl(){}
Added: trunk/boost/intrusive/detail/generic_hook.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/intrusive/detail/generic_hook.hpp	2007-09-26 11:26:35 EDT (Wed, 26 Sep 2007)
@@ -0,0 +1,185 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2007
+//
+// Distributed under the Boost Software License, Version 1.0.
+//    (See accompanying file LICENSE_1_0.txt or copy at
+//          http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/intrusive for documentation.
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTRUSIVE_GENERIC_HOOK_HPP
+#define BOOST_INTRUSIVE_GENERIC_HOOK_HPP
+
+#include <boost/intrusive/detail/config_begin.hpp>
+#include <boost/intrusive/intrusive_fwd.hpp>
+#include <boost/intrusive/detail/pointer_to_other.hpp>
+#include <boost/intrusive/link_mode.hpp>
+#include <boost/intrusive/detail/utilities.hpp>
+#include <boost/static_assert.hpp>
+
+namespace boost {
+namespace intrusive {
+namespace detail {
+
+/// @cond
+
+enum
+{  NoBaseHook
+,  ListBaseHook
+,  SlistBaseHook
+,  SetBaseHook
+,  UsetBaseHook
+};
+
+struct no_default_definer{};
+
+template <class Hook, unsigned int>
+struct default_definer;
+
+template <class Hook>
+struct default_definer<Hook, ListBaseHook>
+{  typedef Hook default_list_hook;  };
+
+template <class Hook>
+struct default_definer<Hook, SlistBaseHook>
+{  typedef Hook default_slist_hook;  };
+
+template <class Hook>
+struct default_definer<Hook, SetBaseHook>
+{  typedef Hook default_set_hook;  };
+
+template <class Hook>
+struct default_definer<Hook, UsetBaseHook>
+{  typedef Hook default_uset_hook;  };
+
+template <class Hook, unsigned int BaseHookType>
+struct make_default_definer
+{
+   typedef typename detail::if_c
+      < BaseHookType != 0
+      , default_definer<Hook, BaseHookType>
+      , no_default_definer>::type type;
+};
+
+template
+   < class GetNodeAlgorithms
+   , class Tag
+   , link_mode_type LinkMode
+   , int HookType
+   >
+struct make_node_holder
+{
+   typedef typename detail::if_c
+      <!detail::is_same<Tag, member_tag>::value
+      , detail::node_holder
+         < typename GetNodeAlgorithms::type::node_traits::node
+         , Tag
+         , LinkMode
+         , HookType>
+      , typename GetNodeAlgorithms::type::node_traits::node
+      >::type type;
+};
+
+/// @endcond
+
+template
+   < class GetNodeAlgorithms
+   , class Tag
+   , link_mode_type LinkMode
+   , int HookType
+   >
+class generic_hook
+   /// @cond
+
+   //If the hook is a base hook, derive generic hook from detail::node_holder
+   //so that a unique base class is created to convert from the node
+   //to the type. This mechanism will be used by base_hook_traits.
+   //
+   //If the hook is a member hook, generic hook will directly derive
+   //from the hook.
+   : public make_default_definer
+      < generic_hook<GetNodeAlgorithms, Tag, LinkMode, HookType>
+      , detail::is_same<Tag, default_tag>::value*HookType
+      >::type
+   , public make_node_holder<GetNodeAlgorithms, Tag, LinkMode, HookType>::type
+   /// @endcond
+{
+   public:
+   /// @cond
+   struct boost_intrusive_tags
+   {
+      static const int hook_type = HookType;
+      static const link_mode_type link_mode = LinkMode;
+      typedef Tag                                     tag;
+      typedef typename GetNodeAlgorithms::type        node_algorithms;
+      typedef typename node_algorithms::node_traits    node_traits;
+      typedef typename node_traits::node              node;
+      typedef typename node_traits::node_ptr          node_ptr;
+      typedef typename node_traits::const_node_ptr    const_node_ptr;
+      static const bool is_base_hook = !detail::is_same<Tag, member_tag>::value;
+      enum { safemode_or_autounlink = 
+               (int)link_mode == (int)auto_unlink   ||
+               (int)link_mode == (int)safe_link     };
+   };
+   /// @endcond
+
+   generic_hook()
+   {
+      if(boost_intrusive_tags::safemode_or_autounlink){
+         boost_intrusive_tags::node_algorithms::init
+            (static_cast<typename boost_intrusive_tags::node*>(this));
+      }
+   }
+
+   generic_hook(const generic_hook& ) 
+   {
+      if(boost_intrusive_tags::safemode_or_autounlink){
+         boost_intrusive_tags::node_algorithms::init
+            (static_cast<typename boost_intrusive_tags::node*>(this));
+      }
+   }
+
+   generic_hook& operator=(const generic_hook& ) 
+   {  return *this;  }
+
+   ~generic_hook()
+   {
+      destructor_impl
+         (*this, detail::link_dispatch<boost_intrusive_tags::link_mode>());
+   }
+
+   void swap_nodes(generic_hook &other) 
+   {
+      boost_intrusive_tags::node_algorithms::swap_nodes
+         ( static_cast<typename boost_intrusive_tags::node*>(this)
+         , static_cast<typename boost_intrusive_tags::node*>(&other));
+   }
+
+   bool is_linked() const 
+   {
+      //is_linked() can be only used in safe-mode or auto-unlink
+      BOOST_STATIC_ASSERT(( boost_intrusive_tags::safemode_or_autounlink ));
+      return !boost_intrusive_tags::node_algorithms::unique
+         (static_cast<const typename boost_intrusive_tags::node*>(this));
+   }
+
+   void unlink()
+   {
+      BOOST_STATIC_ASSERT(( (int)boost_intrusive_tags::link_mode == (int)auto_unlink ));
+      boost_intrusive_tags::node_algorithms::unlink
+         (static_cast<typename boost_intrusive_tags::node*>(this));
+      boost_intrusive_tags::node_algorithms::init
+         (static_cast<typename boost_intrusive_tags::node*>(this));
+   }
+};
+
+} //namespace detail
+} //namespace intrusive 
+} //namespace boost 
+
+#include <boost/intrusive/detail/config_end.hpp>
+
+#endif //BOOST_INTRUSIVE_GENERIC_HOOK_HPP
Modified: trunk/boost/intrusive/detail/hashtable_node.hpp
==============================================================================
--- trunk/boost/intrusive/detail/hashtable_node.hpp	(original)
+++ trunk/boost/intrusive/detail/hashtable_node.hpp	2007-09-26 11:26:35 EDT (Wed, 26 Sep 2007)
@@ -18,14 +18,9 @@
 #include <boost/intrusive/detail/assert.hpp>
 #include <boost/intrusive/detail/pointer_to_other.hpp>
 #include <boost/intrusive/circular_list_algorithms.hpp>
-#ifdef BOOST_INTRUSIVE_USE_ITERATOR_FACADE
-#include <boost/iterator/iterator_facade.hpp>
-#endif
-#ifdef BOOST_INTRUSIVE_USE_ITERATOR_ENABLE_IF_CONVERTIBLE
-#include <boost/utility/enable_if.hpp>
-#include <boost/type_traits/is_convertible.hpp>
-#endif
 #include <boost/intrusive/detail/mpl.hpp>
+#include <boost/intrusive/detail/utilities.hpp>
+#include <boost/intrusive/detail/slist_node.hpp> //remove-me
 #include <cstddef>
 
 namespace boost {
@@ -52,27 +47,34 @@
 const std::size_t prime_list_holder<Dummy>::prime_list_size
    = sizeof(prime_list)/sizeof(std::size_t);
 
-template <class SlistImpl>
-struct bucket_type_impl
-   :  public SlistImpl
+template <class Slist>
+struct bucket_impl : public Slist
 {
-   bucket_type_impl()
+   bucket_impl()
    {}
 
-   bucket_type_impl(const bucket_type_impl &)
+   bucket_impl(const bucket_impl &)
    {}
 
-   bucket_type_impl &operator=(const bucket_type_impl&)
-   {  SlistImpl::clear();   }
+   ~bucket_impl()
+   {
+      //This bucket is still being used!
+      BOOST_INTRUSIVE_INVARIANT_ASSERT(Slist::empty());
+   }
+
+   bucket_impl &operator=(const bucket_impl&)
+   {
+      //This bucket is still in use!
+      BOOST_INTRUSIVE_INVARIANT_ASSERT(Slist::empty());
+      //Slist::clear();
+   }
 
-   static typename std::iterator_traits
-      <typename SlistImpl::const_iterator>::difference_type
-         get_bucket_num
-      ( typename SlistImpl::const_iterator it
-      , const bucket_type_impl<SlistImpl> &first_bucket
-      , const bucket_type_impl<SlistImpl> &last_bucket)
+   static typename Slist::difference_type get_bucket_num
+      ( typename Slist::const_iterator it
+      , const bucket_impl<Slist> &first_bucket
+      , const bucket_impl<Slist> &last_bucket)
    {
-      typename SlistImpl::const_iterator
+      typename Slist::const_iterator
          first(first_bucket.cend()), last(last_bucket.cend());
 
       //The end node is embedded in the singly linked list:
@@ -81,252 +83,130 @@
               it.pointed_node() <= last.pointed_node())){
          ++it;
       }
-      //Now get the bucket_type_impl from the iterator
-      const bucket_type_impl &b = static_cast<const bucket_type_impl&>
-         (SlistImpl::container_from_end_iterator(it));
+      //Now get the bucket_impl from the iterator
+      const bucket_impl &b = static_cast<const bucket_impl&>
+         (Slist::container_from_end_iterator(it));
 
       //Now just calculate the index b has in the bucket array
       return &b - &first_bucket;
    }
-
-   static SlistImpl &bucket_to_slist(bucket_type_impl<SlistImpl> &b)
-   {  return static_cast<SlistImpl &>(b);  }
-
-   static const SlistImpl &bucket_to_slist(const bucket_type_impl<SlistImpl> &b)
-   {  return static_cast<const SlistImpl &>(b);  }
-};
-
-template<class SlistImpl>
-struct bucket_info_impl
-{
-   typedef typename boost::pointer_to_other
-      < typename SlistImpl::pointer
-      , bucket_type_impl<SlistImpl> >::type bucket_ptr;
-   typedef typename SlistImpl::size_type size_type;
-   bucket_ptr  buckets_;
-   size_type   buckets_len_;
 };
 
-#ifdef BOOST_INTRUSIVE_USE_ITERATOR_FACADE
-
-template<class Value, class SlistImpl>
-class hashtable_iterator
-  : public boost::iterator_facade
-         < hashtable_iterator<Value, SlistImpl>
-         , Value
-         , boost::forward_traversal_tag
-         , Value&
-         , typename std::iterator_traits<typename SlistImpl::iterator>::difference_type
-         >
+template<class Slist>
+struct bucket_traits_impl
 {
-   typedef typename SlistImpl::iterator                        local_iterator;
-   typedef typename SlistImpl::const_iterator                  const_local_iterator;
-   typedef typename SlistImpl::value_traits::node_ptr          node_ptr;
-   typedef typename SlistImpl::value_traits::const_node_ptr    const_node_ptr;
-
-   typedef bucket_type_impl<SlistImpl>                         bucket_type;
+   /// @cond
    typedef typename boost::pointer_to_other
-      < typename SlistImpl::pointer, bucket_type>::type        bucket_ptr;
-   typedef typename boost::pointer_to_other
-      < typename SlistImpl::pointer, const bucket_type>::type  const_bucket_ptr;
-   typedef detail::bucket_info_impl<SlistImpl>                 bucket_info_t;
-   typedef typename boost::pointer_to_other
-      <bucket_ptr, bucket_info_t>::type                        bucket_info_ptr;
-   typedef typename boost::pointer_to_other
-      <bucket_ptr, const bucket_info_t>::type                  const_bucket_info_ptr;
-   typedef typename SlistImpl::size_type                       size_type;
-   struct enabler {};
+      < typename Slist::pointer, bucket_impl<Slist> >::type bucket_ptr;
+   typedef typename Slist::size_type size_type;
+   /// @endcond
 
-   public:
-   hashtable_iterator ()
-   {}
-
-   explicit hashtable_iterator(local_iterator ptr, const_bucket_info_ptr bucket_info)
-      :  local_it_ (ptr),   bucket_info_ (bucket_info)
-   {}
-
-
-   #ifdef BOOST_INTRUSIVE_USE_ITERATOR_ENABLE_IF_CONVERTIBLE
-   template <class OtherValue>
-   hashtable_iterator(hashtable_iterator<OtherValue, SlistImpl> const& other
-                     ,typename boost::enable_if<
-                              boost::is_convertible<OtherValue*,Value*>
-                           , enabler
-                           >::type = enabler()
-                      )
-      :  local_it_(other.local_it_), bucket_info_(other.bucket_info_)
-   {}
-   #else
-   template <class OtherValue>
-   hashtable_iterator(hashtable_iterator<OtherValue, SlistImpl> const& other,
-                     typename enable_if<
-                           is_convertible<OtherValue*,T*>
-                     >::type* = 0)
-      :  local_it_(other.local_it_), bucket_info_(other.bucket_info_)
+   bucket_traits_impl(bucket_ptr buckets, size_type len)
+      :  buckets_(buckets), buckets_len_(len)
    {}
-   #endif
 
-   const local_iterator &local() const
-   { return local_it_; }
+   bucket_ptr bucket_begin() const
+   {  return buckets_;  }
 
-   const_node_ptr pointed_node() const
-   { return local_it_.pointed_node(); }
-
-   const const_bucket_info_ptr &bucket_info() const
-   { return bucket_info_; }
+   size_type  bucket_count() const
+   {  return buckets_len_;  }
 
    private:
-   friend class boost::iterator_core_access;
-   template <class, class> friend class hashtable_iterator;
-
-   template <class OtherValue>
-   bool equal(hashtable_iterator<OtherValue, SlistImpl> const& other) const
-   {  return other.local() == local_it_;  }
-
-   void increment()
-   {
-      size_type   buckets_len    = bucket_info_->buckets_len_;
-      const_bucket_ptr  buckets  = bucket_info_->buckets_;
-      const_local_iterator first = bucket_type::bucket_to_slist(buckets[0]).cend();
-      const_local_iterator last  = bucket_type::bucket_to_slist(buckets[buckets_len]).cend();
-
-      ++local_it_;
-      if(first.pointed_node() <= local_it_.pointed_node() && 
-         local_it_.pointed_node() <= last.pointed_node()){
-         size_type n_bucket = (size_type)
-               bucket_type::get_bucket_num(local_it_, buckets[0], buckets[buckets_len]);
-         do{
-            if (++n_bucket == buckets_len){
-               local_it_ = bucket_info_->buckets_->end();
-               break;
-            }
-            local_it_ = bucket_type::bucket_to_slist(bucket_info_->buckets_[n_bucket]).begin();
-         }
-         while (local_it_ == bucket_type::bucket_to_slist(bucket_info_->buckets_[n_bucket]).end());
-      }
-   }
-
-   Value& dereference() const
-   { return *local_it_; }
-
-   local_iterator          local_it_;
-   const_bucket_info_ptr   bucket_info_;
+   bucket_ptr  buckets_;
+   size_type   buckets_len_;
 };
 
-#else
-
-template<class T, class SlistImpl>
+template<class Container, bool IsConst>
 class hashtable_iterator
-  : public std::iterator<std::forward_iterator_tag, T>
+   :  public std::iterator
+         < std::forward_iterator_tag
+         , typename detail::add_const_if_c
+            <typename Container::value_type, IsConst>::type
+         >
 {
-   typedef typename SlistImpl::iterator                        local_iterator;
-   typedef typename SlistImpl::const_iterator                  const_local_iterator;
-   typedef typename SlistImpl::value_traits::node_ptr          node_ptr;
-   typedef typename SlistImpl::value_traits::const_node_ptr    const_node_ptr;
-
-   typedef bucket_type_impl<SlistImpl>                         bucket_type;
-   typedef typename boost::pointer_to_other
-      < typename SlistImpl::pointer, bucket_type>::type        bucket_ptr;
-   typedef typename boost::pointer_to_other
-      < typename SlistImpl::pointer, const bucket_type>::type  const_bucket_ptr;
-   typedef detail::bucket_info_impl<SlistImpl>                 bucket_info_t;
-   typedef typename boost::pointer_to_other
-      <bucket_ptr, bucket_info_t>::type                        bucket_info_ptr;
+   typedef typename Container::real_value_traits               real_value_traits;
+   typedef typename Container::siterator                       siterator;
+   typedef typename Container::const_siterator                 const_siterator;
+   typedef typename Container::bucket_type                     bucket_type;
    typedef typename boost::pointer_to_other
-      <bucket_ptr, const bucket_info_t>::type                  const_bucket_info_ptr;
-   typedef typename SlistImpl::size_type                       size_type;
-   struct enabler {};
+      < typename Container::pointer, const Container>::type    const_cont_ptr;
+   typedef typename Container::size_type                       size_type;
 
    public:
-   typedef T & reference;
-   typedef T * pointer;
+   typedef typename detail::add_const_if_c
+      <typename Container::value_type, IsConst>::type          value_type;
 
    hashtable_iterator ()
    {}
 
-   explicit hashtable_iterator(local_iterator ptr, const_bucket_info_ptr bucket_info)
-      :  local_it_ (ptr),   bucket_info_ (bucket_info)
+   explicit hashtable_iterator(siterator ptr, const Container *cont)
+      :  slist_it_ (ptr),   cont_ (cont)
    {}
 
-
-   #ifdef BOOST_INTRUSIVE_USE_ITERATOR_ENABLE_IF_CONVERTIBLE
-   template <class OtherValue>
-   hashtable_iterator(hashtable_iterator<OtherValue, SlistImpl> const& other
-                     ,typename boost::enable_if<
-                              boost::is_convertible<OtherValue*,T*>
-                           , enabler
-                           >::type = enabler()
-                      )
-      :  local_it_(other.local_it_), bucket_info_(other.bucket_info_)
-   {}
-   #else
-   template <class OtherValue>
-   hashtable_iterator(hashtable_iterator<OtherValue, SlistImpl> const& other,
-                     typename enable_if<is_convertible<OtherValue*, T*> >::type* = 0)
-      :  local_it_(other.local_it_), bucket_info_(other.bucket_info_)
+   hashtable_iterator(const hashtable_iterator<Container, false> &other)
+      :  slist_it_(other.slist_it()), cont_(other.get_container())
    {}
-   #endif
-
-   const local_iterator &local() const
-   { return local_it_; }
-
-   const_node_ptr pointed_node() const
-   { return local_it_.pointed_node(); }
 
-   const const_bucket_info_ptr &bucket_info() const
-   { return bucket_info_; }
+   const siterator &slist_it() const
+   { return slist_it_; }
 
    public:
    hashtable_iterator& operator++() 
-   { increment();   return *this;   }
+   {  this->increment();   return *this;   }
    
    hashtable_iterator operator++(int)
    {
       hashtable_iterator result (*this);
-      increment();
+      this->increment();
       return result;
    }
 
    friend bool operator== (const hashtable_iterator& i, const hashtable_iterator& i2)
-   { return i.pointed_node() == i2.pointed_node(); }
+   { return i.slist_it_ == i2.slist_it_; }
 
    friend bool operator!= (const hashtable_iterator& i, const hashtable_iterator& i2)
    { return !(i == i2); }
 
-   T& operator*() const
-   { return *local_it_; }
+   value_type& operator*() const
+   { return *this->operator ->(); }
 
-   pointer operator->() const
-   { return &(*local_it_); }
+   value_type* operator->() const
+   { return detail::get_pointer(this->get_real_value_traits()->to_value_ptr(slist_it_.pointed_node())); }
+
+   const Container *get_container() const
+   {  return detail::get_pointer(cont_);  }
+
+   const real_value_traits *get_real_value_traits() const
+   {  return &this->get_container()->get_real_value_traits();  }
 
    private:
    void increment()
    {
-      size_type   buckets_len    = bucket_info_->buckets_len_;
-      const_bucket_ptr  buckets  = bucket_info_->buckets_;
-      const_local_iterator first = bucket_type::bucket_to_slist(buckets[0]).cend();
-      const_local_iterator last  = bucket_type::bucket_to_slist(buckets[buckets_len]).cend();
-
-      ++local_it_;
-      if(first.pointed_node() <= local_it_.pointed_node() && 
-         local_it_.pointed_node() <= last.pointed_node()){
+      const Container *cont =  detail::get_pointer(cont_);
+      bucket_type* buckets = detail::get_pointer(cont->bucket_pointer());
+      size_type   buckets_len    = cont->bucket_count();
+      const_siterator first(buckets[0].cend());
+      const_siterator last (buckets[buckets_len].cend());
+
+      ++slist_it_;
+      if(first.pointed_node()    <= slist_it_.pointed_node() && 
+         slist_it_.pointed_node()<= last.pointed_node()      ){
          size_type n_bucket = (size_type)
-               bucket_type::get_bucket_num(local_it_, buckets[0], buckets[buckets_len]);
+               bucket_type::get_bucket_num(slist_it_, buckets[0], buckets[buckets_len]);
          do{
             if (++n_bucket == buckets_len){
-               local_it_ = bucket_info_->buckets_->end();
+               slist_it_ = buckets->end();
                break;
             }
-            local_it_ = bucket_type::bucket_to_slist(bucket_info_->buckets_[n_bucket]).begin();
+            slist_it_ = buckets[n_bucket].begin();
          }
-         while (local_it_ == bucket_type::bucket_to_slist(bucket_info_->buckets_[n_bucket]).end());
+         while (slist_it_ == buckets[n_bucket].end());
       }
    }
 
-   local_iterator          local_it_;
-   const_bucket_info_ptr   bucket_info_;
+   siterator      slist_it_;
+   const_cont_ptr cont_;
 };
-#endif
 
 }  //namespace detail {
 }  //namespace intrusive {
Modified: trunk/boost/intrusive/detail/list_node.hpp
==============================================================================
--- trunk/boost/intrusive/detail/list_node.hpp	(original)
+++ trunk/boost/intrusive/detail/list_node.hpp	2007-09-26 11:26:35 EDT (Wed, 26 Sep 2007)
@@ -19,35 +19,31 @@
 #include <boost/intrusive/detail/assert.hpp>
 #include <boost/intrusive/detail/pointer_to_other.hpp>
 #include <boost/intrusive/circular_list_algorithms.hpp>
-#ifdef BOOST_INTRUSIVE_USE_ITERATOR_FACADE
-#include <boost/iterator/iterator_facade.hpp>
-#endif
-#ifdef BOOST_INTRUSIVE_USE_ITERATOR_ENABLE_IF_CONVERTIBLE
-#include <boost/utility/enable_if.hpp>
-#include <boost/type_traits/is_convertible.hpp>
-#endif
 
 namespace boost {
 namespace intrusive {
-namespace detail {
 
 // list_node_traits can be used with circular_list_algorithms and supplies
 // a list_node holding the pointers needed for a double-linked list
 // it is used by list_derived_node and list_member_node
+
+template<class VoidPointer>
+struct list_node
+{
+   typedef typename boost::pointer_to_other
+      <VoidPointer, list_node>::type   node_ptr;
+   node_ptr prev_, next_;
+};
+
 template<class VoidPointer>
 struct list_node_traits
 {
-   struct node;
+   typedef list_node<VoidPointer> node;
    typedef typename boost::pointer_to_other
       <VoidPointer, node>::type          node_ptr;
    typedef typename boost::pointer_to_other
       <VoidPointer, const node>::type    const_node_ptr;
 
-   struct node
-   {
-      node_ptr prev_, next_;
-   };
-
    static node_ptr get_previous(const_node_ptr n)
    {  return n->prev_;  }
 
@@ -61,178 +57,126 @@
    {  n->next_ = next;  }
 };
 
-#ifdef BOOST_INTRUSIVE_USE_ITERATOR_FACADE
-
-// list_iterator provides some basic functions for a 
-// node oriented forward iterator:
-template<class T, class ValueTraits>
-class list_iterator
-  : public boost::iterator_facade
-         < list_iterator<T, ValueTraits>
-         , T
-         , boost::bidirectional_traversal_tag
-         , T&
-         , typename std::iterator_traits<typename ValueTraits::node_ptr>::difference_type
-         >
-{
-   typedef typename ValueTraits::node_traits    node_traits;
-   typedef typename node_traits::node           node;
-   typedef typename node_traits::node_ptr       node_ptr;
-   typedef typename node_traits::const_node_ptr const_node_ptr;
-   struct enabler{};
-
-   public:
-   typedef typename pointer_to_other<typename ValueTraits::node_ptr, T>::type pointer;
-   typedef typename std::iterator_traits<node_ptr>::difference_type difference_type;
-
-   list_iterator ()
-      :  node_ (0)
-   {}
-
-   explicit list_iterator(node_ptr node)
-      :  node_ (node)
-   {}
-
-   #ifdef BOOST_INTRUSIVE_USE_ITERATOR_ENABLE_IF_CONVERTIBLE
-   template <class OtherValue>
-   list_iterator(list_iterator<OtherValue, ValueTraits> const& other
-                ,typename boost::enable_if<
-                        boost::is_convertible<OtherValue*,T*>
-                     , enabler
-                     >::type = enabler()
-                 )
-      :  node_(other.pointed_node())
-   {}
-   #else
-   template <class OtherValue>
-   list_iterator(list_iterator<OtherValue, ValueTraits> const& other,
-                  typename enable_if<
-                        is_convertible<OtherValue*,T*>
-                  >::type* = 0)
-      :  node_(other.pointed_node())
-   {}
-   #endif
-
-   const node_ptr &pointed_node() const
-   { return node_; }
-
-   private:
-   friend class boost::iterator_core_access;
-   template <class, class> friend class list_iterator;
-
-   template <class OtherValue>
-   bool equal(list_iterator<OtherValue, ValueTraits> const& other) const
-   {  return other.pointed_node() == node_;  }
-
-   void increment()
-   {  node_ = node_traits::get_next(node_);   }
-
-   void decrement()
-   {  node_ = node_traits::get_previous(node_);   }
-
-   T& dereference() const
-   { return *ValueTraits::to_value_ptr(node_); }
-
-   node_ptr node_;
-};
-
-#else //BOOST_INTRUSIVE_USE_ITERATOR_FACADE
-
 // list_iterator provides some basic functions for a 
 // node oriented bidirectional iterator:
-template<class T, class ValueTraits>
+template<class Container, bool IsConst>
 class list_iterator
-   :  public std::iterator<std::bidirectional_iterator_tag, T>
+   :  public std::iterator
+         < std::bidirectional_iterator_tag
+         , typename detail::add_const_if_c
+            <typename Container::value_type, IsConst>::type
+         >
 {
-   struct enabler{};
    protected:
-   typedef typename ValueTraits::node_traits    node_traits;
-   typedef typename node_traits::node           node;
-   typedef typename node_traits::node_ptr       node_ptr;
- 
+   typedef typename Container::real_value_traits   real_value_traits;
+   typedef typename real_value_traits::node_traits node_traits;
+   typedef typename node_traits::node              node;
+   typedef typename node_traits::node_ptr          node_ptr;
+   typedef typename boost::pointer_to_other
+      <node_ptr, void>::type                       void_pointer;
+   static const bool store_container_ptr = 
+      detail::store_cont_ptr_on_it<Container>::value;
+
    public:
-   typedef T & reference;
-   typedef T * pointer;
+   typedef typename detail::add_const_if_c
+      <typename Container::value_type, IsConst>
+      ::type                                       value_type;
+   typedef value_type & reference;
+   typedef value_type * pointer;
 
    list_iterator()
-      : node_ (0)
+      : members_ (0, 0)
    {}
 
-   explicit list_iterator(node_ptr node)
-      : node_ (node)
+   explicit list_iterator(node_ptr node, const Container *cont_ptr)
+      : members_ (node, cont_ptr)
    {}
-   #ifdef BOOST_INTRUSIVE_USE_ITERATOR_ENABLE_IF_CONVERTIBLE
-   template <class OtherValue>
-   list_iterator(list_iterator<OtherValue, ValueTraits> const& other
-                ,typename boost::enable_if<
-                        boost::is_convertible<OtherValue*,T*>
-                     , enabler
-                     >::type = enabler()
-                 )
-      :  node_(other.pointed_node())
-   {}
-   #else
-   template <class OtherValue>
-   list_iterator(list_iterator<OtherValue, ValueTraits> const& other,
-                  typename enable_if<
-                        is_convertible<OtherValue*,T*>
-                  >::type* = 0)
-      :  node_(other.pointed_node())
+
+   list_iterator(list_iterator<Container, false> const& other)
+      :  members_(other.pointed_node(), other.get_container())
    {}
-   #endif
 
    const node_ptr &pointed_node() const
-   { return node_; }
+   { return members_.nodeptr_; }
 
    list_iterator &operator=(const node_ptr &node)
-   {  node_ = node;  return static_cast<list_iterator&>(*this);  }
+   {  members_.nodeptr_ = node;  return static_cast<list_iterator&>(*this);  }
 
    public:
    list_iterator& operator++() 
    { 
-      node_ = node_traits::get_next(node_); 
+      members_.nodeptr_ = node_traits::get_next(members_.nodeptr_); 
       return static_cast<list_iterator&> (*this); 
    }
    
    list_iterator operator++(int)
    {
-      list_iterator result (node_);
-      node_ = node_traits::get_next(node_);
+      list_iterator result (*this);
+      members_.nodeptr_ = node_traits::get_next(members_.nodeptr_);
       return result;
    }
 
    list_iterator& operator--() 
    { 
-      node_ = node_traits::get_previous(node_); 
+      members_.nodeptr_ = node_traits::get_previous(members_.nodeptr_); 
       return static_cast<list_iterator&> (*this); 
    }
    
    list_iterator operator--(int)
    {
-      list_iterator result (node_);
-      node_ = node_traits::get_previous(node_);
+      list_iterator result (*this);
+      members_.nodeptr_ = node_traits::get_previous(members_.nodeptr_);
       return result;
    }
 
    bool operator== (const list_iterator& i) const
-   { return node_ == i.pointed_node(); }
+   {  return members_.nodeptr_ == i.pointed_node();   }
 
    bool operator!= (const list_iterator& i) const
-   { return !operator== (i); }
+   {  return !operator== (i); }
 
-   T& operator*() const
-   { return *ValueTraits::to_value_ptr(node_); }
+   value_type& operator*() const
+   {  return *operator->();   }
 
    pointer operator->() const
-   { return detail::get_pointer(ValueTraits::to_value_ptr(node_)); }
+   { return detail::get_pointer(this->get_real_value_traits()->to_value_ptr(members_.nodeptr_)); }
+
+   const Container *get_container() const
+   {
+      if(store_container_ptr){
+         const Container* c = static_cast<const Container*>(members_.get_ptr());
+         BOOST_INTRUSIVE_INVARIANT_ASSERT(c != 0);
+         return c;
+      }
+      else{
+         return 0;
+      }
+   }
+
+   const real_value_traits *get_real_value_traits() const
+   {
+      if(store_container_ptr)
+         return &this->get_container()->get_real_value_traits();
+      else
+         return 0;
+   }
 
    private:
-   node_ptr node_;
-};
+   struct members
+      :  public detail::select_constptr
+         <void_pointer, store_container_ptr>::type
+   {
+      typedef typename detail::select_constptr
+         <void_pointer, store_container_ptr>::type Base;
+
+      members(const node_ptr &n_ptr, const void *cont)
+         :  Base(cont), nodeptr_(n_ptr)
+      {}
 
-#endif
+      node_ptr nodeptr_;
+   } members_;
+};
 
-} //namespace detail 
 } //namespace intrusive 
 } //namespace boost 
 
Modified: trunk/boost/intrusive/detail/mpl.hpp
==============================================================================
--- trunk/boost/intrusive/detail/mpl.hpp	(original)
+++ trunk/boost/intrusive/detail/mpl.hpp	2007-09-26 11:26:35 EDT (Wed, 26 Sep 2007)
@@ -17,6 +17,9 @@
 namespace intrusive {
 namespace detail {
 
+typedef char one;
+struct two {one _[2];};
+
 template< bool C_ >
 struct bool_
 {
@@ -55,7 +58,61 @@
    static false_t dispatch(...);
    static T trigger();
    public:
-   enum { value = sizeof(dispatch(trigger())) == sizeof(true_t) };
+   static const bool value = sizeof(dispatch(trigger())) == sizeof(true_t);
+};
+
+template<
+      bool C
+    , typename T1
+    , typename T2
+    >
+struct if_c
+{
+    typedef T1 type;
+};
+
+template<
+      typename T1
+    , typename T2
+    >
+struct if_c<false,T1,T2>
+{
+    typedef T2 type;
+};
+
+template<
+      typename C
+    , typename T1
+    , typename T2
+    >
+struct if_
+{
+   typedef typename if_c<0 != C::value, T1, T2>::type type;
+};
+
+template<
+      bool C
+    , typename F1
+    , typename F2
+    >
+struct eval_if_c
+    : if_c<C,F1,F2>::type
+{};
+
+template<
+      typename C
+    , typename T1
+    , typename T2
+    >
+struct eval_if
+    : if_<C,T1,T2>::type
+{};
+
+// identity is an extension: it is not part of the standard.
+template <class T>
+struct identity
+{
+   typedef T type;
 };
 
 #if defined(BOOST_MSVC) || defined(__BORLANDC_)
@@ -130,18 +187,20 @@
 template <typename T>
 struct is_unary_or_binary_function_impl
 {
-    static T* t;
-    enum{ value = sizeof(is_function_ptr_tester(t)) == sizeof(yes_type) };
+   static T* t;
+   static const bool value = sizeof(is_function_ptr_tester(t)) == sizeof(yes_type);
 };
 
 template <typename T>
 struct is_unary_or_binary_function_impl<T&>
-{  enum {value = false }; };
+{
+   static const bool value = false;
+};
 
 template<typename T>
 struct is_unary_or_binary_function
 {
-   enum{ value = is_unary_or_binary_function_impl<T>::value }; 
+   static const bool value = is_unary_or_binary_function_impl<T>::value;
 };
 
 //boost::alignment_of yields to 10K lines of preprocessed code, so we
@@ -159,15 +218,68 @@
 template <unsigned A, unsigned S>
 struct alignment_logic
 {
-    enum{   value = A < S ? A : S  };
+   static const std::size_t value = A < S ? A : S;
 };
 
 template< typename T >
 struct alignment_of
 {
-   enum{ value = alignment_logic
+   static const std::size_t value = alignment_logic
             < sizeof(alignment_of_hack<T>) - sizeof(T)
-            , sizeof(T)>::value   };
+            , sizeof(T)
+            >::value;
+};
+
+template <typename T, typename U>
+struct is_same
+{
+   typedef char yes_type;
+   struct no_type
+   {
+      char padding[8];
+   };
+
+   template <typename V>
+   static yes_type is_same_tester(V*, V*);
+   static no_type is_same_tester(...);
+
+   static T *t;
+   static U *u;
+
+   static const bool value = sizeof(yes_type) == sizeof(is_same_tester(t,u));
+};
+
+template<typename T>
+struct add_const
+{  typedef const T type;   };
+
+template<class T>
+struct remove_reference
+{
+   typedef T type;
+};
+
+template<class T>
+struct remove_reference<T&>
+{
+   typedef T type;
+};
+
+template<class Class>
+class is_empty_class
+{
+   template <typename T>
+   struct empty_helper_t1 : public T
+   {
+      empty_helper_t1();
+      int i[256];
+   };
+
+   struct empty_helper_t2
+   { int i[256]; };
+
+   public:
+   static const bool value = sizeof(empty_helper_t1<Class>) == sizeof(empty_helper_t2);
 };
 
 } //namespace detail 
Added: trunk/boost/intrusive/detail/no_exceptions_support.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/intrusive/detail/no_exceptions_support.hpp	2007-09-26 11:26:35 EDT (Wed, 26 Sep 2007)
@@ -0,0 +1,28 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga  2007
+//
+// Distributed under the Boost Software License, Version 1.0.
+//    (See accompanying file LICENSE_1_0.txt or copy at
+//          http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/intrusive for documentation.
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTRUSIVE_NO_EXCEPTION_SUPPORT_HPP
+
+#if !(defined BOOST_INTRUSIVE_DISABLE_EXCEPTION_HANDLING)
+#    include <boost/detail/no_exceptions_support.hpp>
+#    define BOOST_INTRUSIVE_TRY        BOOST_TRY
+#    define BOOST_INTRUSIVE_CATCH(x)   BOOST_CATCH(x)
+#    define BOOST_INTRUSIVE_RETHROW    BOOST_RETHROW
+#    define BOOST_INTRUSIVE_CATCH_END  BOOST_CATCH_END
+#else
+#    define BOOST_INTRUSIVE_TRY        { if (true)
+#    define BOOST_INTRUSIVE_CATCH(x)   else if (false)
+#    define BOOST_INTRUSIVE_RETHROW
+#    define BOOST_INTRUSIVE_CATCH_END  }
+#endif
+
+#endif   //#ifndef BOOST_INTRUSIVE_NO_EXCEPTION_SUPPORT_HPP
Modified: trunk/boost/intrusive/detail/parent_from_member.hpp
==============================================================================
--- trunk/boost/intrusive/detail/parent_from_member.hpp	(original)
+++ trunk/boost/intrusive/detail/parent_from_member.hpp	2007-09-26 11:26:35 EDT (Wed, 26 Sep 2007)
@@ -13,6 +13,7 @@
 #define BOOST_INTRUSIVE_PARENT_FROM_MEMBER_HPP
 
 #include <boost/intrusive/detail/config_begin.hpp>
+#include <boost/static_assert.hpp>
 #include <cstddef>
 
 namespace boost {
@@ -22,14 +23,18 @@
 template<class Parent, class Member>
 inline std::size_t offset_from_pointer_to_member(const Member Parent::* ptr_to_member)
 {
+   //BOOST_STATIC_ASSERT(( sizeof(std::ptrdiff_t) == sizeof(ptr_to_member) ));
    //The implementation of a pointer to member is compiler dependent.
-   #if (defined(_MSC_VER)  || defined(__GNUC__) || \
-        defined(BOOST_INTEL) || defined(__HP_aCC))
-   //This works with gcc, msvc, ac++
+   #if defined(BOOST_MSVC) || (defined (BOOST_WINDOWS) && defined(BOOST_INTEL))
+   //This works with gcc, msvc, ac++, ibmcpp
    return *(const std::ptrdiff_t*)(void*)&ptr_to_member;
+   #elif defined(__GNUC__) || defined(__HP_aCC) || defined(BOOST_INTEL) || defined (__IBMCPP__)
+   const Parent * const parent = 0;
+   const char *const member = reinterpret_cast<const char*>(&(parent->*ptr_to_member));
+   return std::size_t(member - reinterpret_cast<const char*>(parent));
    #else
    //This is the traditional C-front approach: __MWERKS__, __DMC__, __SUNPRO_CC
-   return *(const std::ptrdiff_t*)(void*)&ptr_to_member - 1;
+   return (*(const std::ptrdiff_t*)(void*)&ptr_to_member) - 1;
    #endif
 }
 
Modified: trunk/boost/intrusive/detail/rbtree_node.hpp
==============================================================================
--- trunk/boost/intrusive/detail/rbtree_node.hpp	(original)
+++ trunk/boost/intrusive/detail/rbtree_node.hpp	2007-09-26 11:26:35 EDT (Wed, 26 Sep 2007)
@@ -18,19 +18,11 @@
 #include <iterator>
 #include <boost/intrusive/detail/pointer_to_other.hpp>
 #include <boost/intrusive/rbtree_algorithms.hpp>
-#ifdef BOOST_INTRUSIVE_USE_ITERATOR_FACADE
-#include <boost/iterator/iterator_facade.hpp>
-#endif
-#ifdef BOOST_INTRUSIVE_USE_ITERATOR_ENABLE_IF_CONVERTIBLE
-#include <boost/utility/enable_if.hpp>
-#include <boost/type_traits/is_convertible.hpp>
-#endif
 #include <boost/intrusive/pointer_plus_bit.hpp>
 #include <boost/intrusive/detail/mpl.hpp>
 
 namespace boost {
 namespace intrusive {
-namespace detail {
 
 /////////////////////////////////////////////////////////////////////////////
 //                                                                         //
@@ -164,14 +156,14 @@
    :  public compact_rbtree_node_traits_impl<VoidPointer>
 {};
 
-//Inherit from the dispatcher depending on the embedding capabilities
+//Inherit from the detail::link_dispatch depending on the embedding capabilities
 template<class VoidPointer>
 struct rbtree_node_traits
    :  public rbtree_node_traits_dispatch
-         <VoidPointer
-         ,has_pointer_plus_bit
-            <VoidPointer, detail::alignment_of<compact_rbtree_node<VoidPointer> 
-                                             >::value 
+         < VoidPointer
+         , has_pointer_plus_bit
+            < VoidPointer
+            , detail::alignment_of<compact_rbtree_node<VoidPointer> >::value 
             >::value
          >
 {};
@@ -182,179 +174,124 @@
 //                                                                         //
 /////////////////////////////////////////////////////////////////////////////
 
-#ifdef BOOST_INTRUSIVE_USE_ITERATOR_FACADE
-
-template<class T, class ValueTraits>
-class rbtree_iterator
-  : public boost::iterator_facade
-         < rbtree_iterator<T, ValueTraits>
-         , T
-         , boost::bidirectional_traversal_tag
-         , T&
-         , typename std::iterator_traits<typename ValueTraits::node_ptr>::difference_type
-         >
-{
-   typedef typename ValueTraits::node_traits    node_traits;
-   typedef typename node_traits::node           node;
-   typedef typename node_traits::node_ptr       node_ptr;
-   typedef typename node_traits::const_node_ptr const_node_ptr;
-   typedef rbtree_algorithms<node_traits>       node_algorithms;
-   struct enabler{};
-
-   public:
-   typedef typename pointer_to_other<typename ValueTraits::node_ptr, T>::type pointer;
-   typedef typename std::iterator_traits<node_ptr>::difference_type difference_type;
-
-   rbtree_iterator ()
-      :  node_ (0)
-   {}
-
-   explicit rbtree_iterator(node_ptr node)
-      :  node_ (node)
-   {}
-
-   #ifdef BOOST_INTRUSIVE_USE_ITERATOR_ENABLE_IF_CONVERTIBLE
-   template <class OtherValue>
-   rbtree_iterator(rbtree_iterator<OtherValue, ValueTraits> const& other
-                ,typename boost::enable_if<
-                        boost::is_convertible<OtherValue*,T*>
-                     , enabler
-                     >::type = enabler()
-                 )
-      :  node_(other.pointed_node())
-   {}
-   #else
-   template <class OtherValue>
-   rbtree_iterator(rbtree_iterator<OtherValue, ValueTraits> const& other,
-                  typename enable_if<
-                        is_convertible<OtherValue*,T*>
-                  >::type* = 0)
-      :  node_(other.pointed_node())
-   {}
-   #endif
-
-   const node_ptr &pointed_node() const
-   { return node_; }
-
-   private:
-   friend class boost::iterator_core_access;
-   template <class, class> friend class rbtree_iterator;
-
-   template <class OtherValue>
-   bool equal(rbtree_iterator<OtherValue, ValueTraits> const& other) const
-   {  return other.pointed_node() == node_;  }
-
-   void increment()
-   {  node_ = node_algorithms::next_node(node_);   }
-
-   void decrement()
-   {  node_ = node_algorithms::prev_node(node_);   }
-
-   T& dereference() const
-   { return *ValueTraits::to_value_ptr(node_); }
-
-   node_ptr node_;
-};
-
-#else
-
 // rbtree_iterator provides some basic functions for a 
 // node oriented bidirectional iterator:
-template<class T, class ValueTraits>
+template<class Container, bool IsConst>
 class rbtree_iterator
-   :  public std::iterator<std::bidirectional_iterator_tag, T>
+   :  public std::iterator
+         < std::bidirectional_iterator_tag
+         , typename detail::add_const_if_c
+            <typename Container::value_type, IsConst>::type
+         >
 {
-   struct enabler{};
    protected:
-   typedef typename ValueTraits::node_traits    node_traits;
-   typedef typename node_traits::node           node;
-   typedef typename node_traits::node_ptr       node_ptr;
-   typedef rbtree_algorithms<node_traits>       node_algorithms;
- 
+   typedef typename Container::real_value_traits   real_value_traits;
+   typedef typename real_value_traits::node_traits node_traits;
+   typedef typename node_traits::node              node;
+   typedef typename node_traits::node_ptr          node_ptr;
+   typedef rbtree_algorithms<node_traits>          node_algorithms;
+   typedef typename boost::pointer_to_other
+      <node_ptr, void>::type                       void_pointer;
+   static const bool store_container_ptr = 
+      detail::store_cont_ptr_on_it<Container>::value;
+
    public:
-   typedef T & reference;
-   typedef T * pointer;
+   public:
+   typedef typename detail::add_const_if_c
+      <typename Container::value_type, IsConst>
+      ::type                                       value_type;
+   typedef value_type & reference;
+   typedef value_type * pointer;
 
    rbtree_iterator()
-      : node_ (0)
+      : members_ (0, 0)
    {}
 
-   explicit rbtree_iterator(node_ptr node)
-      : node_ (node)
+   explicit rbtree_iterator(node_ptr node, const Container *cont_ptr)
+      : members_ (node, cont_ptr)
    {}
 
-   #ifdef BOOST_INTRUSIVE_USE_ITERATOR_ENABLE_IF_CONVERTIBLE
-   template <class OtherValue>
-   rbtree_iterator(rbtree_iterator<OtherValue, ValueTraits> const& other
-                ,typename boost::enable_if<
-                        boost::is_convertible<OtherValue*,T*>
-                     , enabler
-                     >::type = enabler()
-                 )
-      :  node_(other.pointed_node())
-   {}
-   #else
-   template <class OtherValue>
-   rbtree_iterator(rbtree_iterator<OtherValue, ValueTraits> const& other,
-                  typename enable_if<
-                        is_convertible<OtherValue*,T*>
-                  >::type* = 0)
-      :  node_(other.pointed_node())
+   rbtree_iterator(rbtree_iterator<Container, false> const& other)
+      :  members_(other.pointed_node(), other.get_container())
    {}
-   #endif
 
    const node_ptr &pointed_node() const
-   { return node_; }
+   { return members_.nodeptr_; }
 
    rbtree_iterator &operator=(const node_ptr &node)
-   {  node_ = node;  return static_cast<rbtree_iterator&>(*this);  }
+   {  members_.nodeptr_ = node;  return static_cast<rbtree_iterator&>(*this);  }
 
    public:
    rbtree_iterator& operator++() 
    { 
-      node_ = node_algorithms::next_node(node_); 
+      members_.nodeptr_ = node_algorithms::next_node(members_.nodeptr_); 
       return static_cast<rbtree_iterator&> (*this); 
    }
    
    rbtree_iterator operator++(int)
    {
-      rbtree_iterator result (node_);
-      node_ = node_algorithms::next_node(node_);
+      rbtree_iterator result (*this);
+      members_.nodeptr_ = node_algorithms::next_node(members_.nodeptr_);
       return result;
    }
 
    rbtree_iterator& operator--() 
    { 
-      node_ = node_algorithms::prev_node(node_); 
+      members_.nodeptr_ = node_algorithms::prev_node(members_.nodeptr_); 
       return static_cast<rbtree_iterator&> (*this); 
    }
    
    rbtree_iterator operator--(int)
    {
-      rbtree_iterator result (node_);
-      node_ = node_algorithms::prev_node(node_);
+      rbtree_iterator result (*this);
+      members_.nodeptr_ = node_algorithms::prev_node(members_.nodeptr_);
       return result;
    }
 
    bool operator== (const rbtree_iterator& i) const
-   { return node_ == i.pointed_node(); }
+   { return members_.nodeptr_ == i.pointed_node(); }
 
    bool operator!= (const rbtree_iterator& i) const
    { return !operator== (i); }
 
-   T& operator*() const
-   { return *ValueTraits::to_value_ptr(node_); }
+   value_type& operator*() const
+   {  return *operator->();   }
 
    pointer operator->() const
-   { return detail::get_pointer(ValueTraits::to_value_ptr(node_)); }
+   { return detail::get_pointer(this->get_real_value_traits()->to_value_ptr(members_.nodeptr_)); }
+
+   const Container *get_container() const
+   {
+      if(store_container_ptr)
+         return static_cast<const Container*>(members_.get_ptr());
+      else
+         return 0;
+   }
+
+   const real_value_traits *get_real_value_traits() const
+   {
+      if(store_container_ptr)
+         return &this->get_container()->get_real_value_traits();
+      else
+         return 0;
+   }
 
    private:
-   node_ptr node_;
-};
+   struct members
+      :  public detail::select_constptr
+         <void_pointer, store_container_ptr>::type
+   {
+      typedef typename detail::select_constptr
+         <void_pointer, store_container_ptr>::type Base;
 
-#endif
+      members(const node_ptr &n_ptr, const void *cont)
+         :  Base(cont), nodeptr_(n_ptr)
+      {}
+
+      node_ptr nodeptr_;
+   } members_;
+};
 
-} //namespace detail 
 } //namespace intrusive 
 } //namespace boost 
 
Modified: trunk/boost/intrusive/detail/slist_node.hpp
==============================================================================
--- trunk/boost/intrusive/detail/slist_node.hpp	(original)
+++ trunk/boost/intrusive/detail/slist_node.hpp	2007-09-26 11:26:35 EDT (Wed, 26 Sep 2007)
@@ -19,17 +19,17 @@
 #include <boost/intrusive/detail/assert.hpp>
 #include <boost/intrusive/detail/pointer_to_other.hpp>
 #include <boost/intrusive/circular_slist_algorithms.hpp>
-#ifdef BOOST_INTRUSIVE_USE_ITERATOR_FACADE
-#include <boost/iterator/iterator_facade.hpp>
-#endif
-#ifdef BOOST_INTRUSIVE_USE_ITERATOR_ENABLE_IF_CONVERTIBLE
-#include <boost/utility/enable_if.hpp>
-#include <boost/type_traits/is_convertible.hpp>
-#endif
 
 namespace boost {
 namespace intrusive {
-namespace detail {
+
+template<class VoidPointer>
+struct slist_node
+{
+   typedef typename boost::pointer_to_other
+      <VoidPointer, slist_node>::type   node_ptr;
+   node_ptr next_;
+};
 
 // slist_node_traits can be used with circular_slist_algorithms and supplies
 // a slist_node holding the pointers needed for a singly-linked list
@@ -37,18 +37,12 @@
 template<class VoidPointer>
 struct slist_node_traits
 {
-   struct node;
-
+   typedef slist_node<VoidPointer> node;
    typedef typename boost::pointer_to_other
       <VoidPointer, node>::type          node_ptr;
    typedef typename boost::pointer_to_other
       <VoidPointer, const node>::type    const_node_ptr;
 
-   struct node
-   {
-      node_ptr next_;
-   };
-
    static node_ptr get_next(const_node_ptr n)
    {  return n->next_;  }  
 
@@ -56,163 +50,109 @@
    {  n->next_ = next;  }  
 };
 
-#ifdef BOOST_INTRUSIVE_USE_ITERATOR_FACADE
-
-// slist_iterator provides some basic functions for a 
-// node oriented forward iterator:
-template<class T, class ValueTraits>
-class slist_iterator
-  : public boost::iterator_facade
-         < slist_iterator<T, ValueTraits>
-         , T
-         , boost::forward_traversal_tag
-         , T&
-         , typename std::iterator_traits<typename ValueTraits::node_ptr>::difference_type
-         >
-{
-   typedef typename ValueTraits::node_traits    node_traits;
-   typedef typename node_traits::node           node;
-   typedef typename node_traits::node_ptr       node_ptr;
-   typedef typename node_traits::const_node_ptr const_node_ptr;
-   struct enabler{};
-
-   public:
-   typedef typename pointer_to_other<typename ValueTraits::node_ptr, T>::type pointer;
-   typedef typename std::iterator_traits<node_ptr>::difference_type difference_type;
-
-   slist_iterator ()
-      :  node_ (0)
-   {}
-
-   explicit slist_iterator(node_ptr node)
-      :  node_ (node)
-   {}
-
-   #ifdef BOOST_INTRUSIVE_USE_ITERATOR_ENABLE_IF_CONVERTIBLE
-   template <class OtherValue>
-   slist_iterator(slist_iterator<OtherValue, ValueTraits> const& other
-                 ,typename boost::enable_if<
-                        boost::is_convertible<OtherValue*,T*>
-                     , enabler
-                     >::type = enabler()
-                  )
-      :  node_(other.pointed_node())
-   {}
-   #else
-   template <class OtherValue>
-   slist_iterator(slist_iterator<OtherValue, ValueTraits> const& other,
-                  typename enable_if<
-                        is_convertible<OtherValue*,T*>
-                  >::type* = 0)
-      :  node_(other.pointed_node())
-   {}
-   #endif
-
-   const node_ptr &pointed_node() const
-   { return node_; }
-
-   private:
-   friend class boost::iterator_core_access;
-   template <class, class> friend class slist_iterator;
-
-   template <class OtherValue>
-   bool equal(slist_iterator<OtherValue, ValueTraits> const& other) const
-   {  return other.pointed_node() == node_;  }
-
-   void increment()
-   {  node_ = node_traits::get_next(node_);   }
-
-   T& dereference() const
-   { return *ValueTraits::to_value_ptr(node_); }
-
-   node_ptr node_;
-};
-
-#else
-
 // slist_iterator provides some basic functions for a 
 // node oriented bidirectional iterator:
-template<class T, class ValueTraits>
+template<class Container, bool IsConst>
 class slist_iterator
-   :  public std::iterator<std::forward_iterator_tag, T>
+   :  public std::iterator
+         < std::forward_iterator_tag
+         , typename detail::add_const_if_c
+            <typename Container::value_type, IsConst>::type
+         >
 {
-   struct enabler{};
    protected:
-   typedef typename ValueTraits::node_traits    node_traits;
-   typedef typename node_traits::node           node;
-   typedef typename node_traits::node_ptr       node_ptr;
- 
+   typedef typename Container::real_value_traits   real_value_traits;
+   typedef typename real_value_traits::node_traits node_traits;
+   typedef typename node_traits::node              node;
+   typedef typename node_traits::node_ptr          node_ptr;
+   typedef typename boost::pointer_to_other
+      <node_ptr, void>::type                       void_pointer;
+   static const bool store_container_ptr = 
+      detail::store_cont_ptr_on_it<Container>::value;
+
    public:
-   typedef T & reference;
-   typedef T * pointer;
+   typedef typename detail::add_const_if_c
+      <typename Container::value_type, IsConst>
+      ::type                                       value_type;
+   typedef value_type & reference;
+   typedef value_type * pointer;
 
    slist_iterator()
-      : node_ (0)
+      : members_ (0, 0)
    {}
 
-   explicit slist_iterator(node_ptr node)
-      : node_ (node)
+   explicit slist_iterator(node_ptr node, const Container *cont_ptr)
+      : members_ (node, cont_ptr)
    {}
 
-   #ifdef BOOST_INTRUSIVE_USE_ITERATOR_ENABLE_IF_CONVERTIBLE
-   template <class OtherValue>
-   slist_iterator(slist_iterator<OtherValue, ValueTraits> const& other
-                 ,typename boost::enable_if<
-                        boost::is_convertible<OtherValue*,T*>
-                     , enabler
-                     >::type = enabler()
-                  )
-      :  node_(other.pointed_node())
+   slist_iterator(slist_iterator<Container, false> const& other)
+      :  members_(other.pointed_node(), other.get_container())
    {}
-   #else
-   template <class OtherValue>
-   slist_iterator(slist_iterator<OtherValue, ValueTraits> const& other,
-                  typename enable_if<
-                        is_convertible<OtherValue*,T*>
-                  >::type* = 0)
-      :  node_(other.pointed_node())
-   {}
-   #endif
 
    const node_ptr &pointed_node() const
-   { return node_; }
+   { return members_.nodeptr_; }
 
    slist_iterator &operator=(const node_ptr &node)
-   {  node_ = node;  return static_cast<slist_iterator&>(*this);  }
+   {  members_.nodeptr_ = node;  return static_cast<slist_iterator&>(*this);  }
 
    public:
    slist_iterator& operator++() 
    { 
-      node_ = node_traits::get_next(node_); 
+      members_.nodeptr_ = node_traits::get_next(members_.nodeptr_); 
       return static_cast<slist_iterator&> (*this); 
    }
    
    slist_iterator operator++(int)
    {
-      slist_iterator result (node_);
-      node_ = node_traits::get_next(node_);
+      slist_iterator result (*this);
+      members_.nodeptr_ = node_traits::get_next(members_.nodeptr_);
       return result;
    }
 
    bool operator== (const slist_iterator& i) const
-   { return node_ == i.pointed_node(); }
+   {  return members_.nodeptr_ == i.pointed_node();   }
 
    bool operator!= (const slist_iterator& i) const
-   { return !operator== (i); }
+   {  return !operator== (i); }
 
-   T& operator*() const
-   { return *ValueTraits::to_value_ptr(node_); }
+   value_type& operator*() const
+   {  return *operator->();   }
 
    pointer operator->() const
-   { return detail::get_pointer(ValueTraits::to_value_ptr(node_)); }
+   { return detail::get_pointer(this->get_real_value_traits()->to_value_ptr(members_.nodeptr_)); }
+
+   const Container *get_container() const
+   {
+      if(store_container_ptr)
+         return static_cast<const Container*>(members_.get_ptr());
+      else
+         return 0;
+   }
+
+   const real_value_traits *get_real_value_traits() const
+   {
+      if(store_container_ptr)
+         return &this->get_container()->get_real_value_traits();
+      else
+         return 0;
+   }
 
    private:
-   node_ptr node_;
-};
+   struct members
+      :  public detail::select_constptr
+         <void_pointer, store_container_ptr>::type
+   {
+      typedef typename detail::select_constptr
+         <void_pointer, store_container_ptr>::type Base;
 
-#endif
+      members(const node_ptr &n_ptr, const void *cont)
+         :  Base(cont), nodeptr_(n_ptr)
+      {}
+
+      node_ptr nodeptr_;
+   } members_;
+};
 
-} //namespace detail 
 } //namespace intrusive 
 } //namespace boost 
 
Added: trunk/boost/intrusive/detail/transform_iterator.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/intrusive/detail/transform_iterator.hpp	2007-09-26 11:26:35 EDT (Wed, 26 Sep 2007)
@@ -0,0 +1,173 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2007
+//
+// Distributed under the Boost Software License, Version 1.0.
+//    (See accompanying file LICENSE_1_0.txt or copy at
+//          http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/intrusive for documentation.
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTRUSIVE_DETAIL_TRANSFORM_ITERATOR_HPP
+#define BOOST_INTRUSIVE_DETAIL_TRANSFORM_ITERATOR_HPP
+
+#include <boost/intrusive/detail/config_begin.hpp>
+#include <iterator>
+#include <boost/intrusive/detail/mpl.hpp>
+
+namespace boost {
+namespace intrusive {
+namespace detail {
+
+template <class PseudoReference>
+struct operator_arrow_proxy
+{
+   operator_arrow_proxy(const PseudoReference &px)
+      :  m_value(px)
+   {}
+
+   PseudoReference* operator->() const { return &m_value; }
+   // This function is needed for MWCW and BCC, which won't call operator->
+   // again automatically per 13.3.1.2 para 8
+//   operator T*() const { return &m_value; }
+   mutable PseudoReference m_value;
+};
+
+template <class T>
+struct operator_arrow_proxy<T&>
+{
+   operator_arrow_proxy(T &px)
+      :  m_value(px)
+   {}
+
+   T* operator->() const { return &m_value; }
+   // This function is needed for MWCW and BCC, which won't call operator->
+   // again automatically per 13.3.1.2 para 8
+//   operator T*() const { return &m_value; }
+   mutable T &m_value;
+};
+
+template <class Iterator, class UnaryFunction>
+class transform_iterator
+   : public std::iterator
+      < typename Iterator::iterator_category
+      , typename detail::remove_reference<typename UnaryFunction::result_type>::type
+      , typename Iterator::difference_type
+      , operator_arrow_proxy<typename UnaryFunction::result_type>
+      , typename UnaryFunction::result_type>
+{
+   public:
+   explicit transform_iterator(const Iterator &it, const UnaryFunction &f = UnaryFunction())
+      :  members_(it, f)
+   {}
+
+   explicit transform_iterator()
+      :  members_()
+   {}
+
+   Iterator get_it() const
+   {  return members_.m_it;   }
+
+   //Constructors
+   transform_iterator& operator++() 
+   { increment();   return *this;   }
+
+   transform_iterator operator++(int)
+   {
+      transform_iterator result (*this);
+      increment();
+      return result;
+   }
+
+   friend bool operator== (const transform_iterator& i, const transform_iterator& i2)
+   { return i.equal(i2); }
+
+   friend bool operator!= (const transform_iterator& i, const transform_iterator& i2)
+   { return !(i == i2); }
+
+/*
+   friend bool operator> (const transform_iterator& i, const transform_iterator& i2)
+   { return i2 < i; }
+
+   friend bool operator<= (const transform_iterator& i, const transform_iterator& i2)
+   { return !(i > i2); }
+
+   friend bool operator>= (const transform_iterator& i, const transform_iterator& i2)
+   { return !(i < i2); }
+*/
+   friend typename Iterator::difference_type operator- (const transform_iterator& i, const transform_iterator& i2)
+   { return i2.distance_to(i); }
+
+   //Arithmetic
+   transform_iterator& operator+=(typename Iterator::difference_type off)
+   {  this->advance(off); return *this;   }
+
+   transform_iterator operator+(typename Iterator::difference_type off) const
+   {
+      transform_iterator other(*this);
+      other.advance(off);
+      return other;
+   }
+
+   friend transform_iterator operator+(typename Iterator::difference_type off, const transform_iterator& right)
+   {  return right + off; }
+
+   transform_iterator& operator-=(typename Iterator::difference_type off)
+   {  this->advance(-off); return *this;   }
+
+   transform_iterator operator-(typename Iterator::difference_type off) const
+   {  return *this + (-off);  }
+
+   typename UnaryFunction::result_type operator*() const
+   { return dereference(); }
+
+   operator_arrow_proxy<typename UnaryFunction::result_type>
+      operator->() const
+   { return operator_arrow_proxy<typename UnaryFunction::result_type>(dereference());  }
+
+   private:
+   struct members
+      :  UnaryFunction
+   {
+      members(const Iterator &it, const UnaryFunction &f)
+         :  UnaryFunction(f), m_it(it)
+      {}
+
+      members()
+      {}
+
+      Iterator m_it;
+   } members_;
+
+
+   void increment()
+   { ++members_.m_it; }
+
+   void decrement()
+   { --members_.m_it; }
+
+   bool equal(const transform_iterator &other) const
+   {  return members_.m_it == other.members_.m_it;   }
+
+   bool less(const transform_iterator &other) const
+   {  return other.members_.m_it < members_.m_it;   }
+
+   typename UnaryFunction::result_type dereference() const
+   { return members_(*members_.m_it); }
+
+   void advance(typename Iterator::difference_type n)
+   {  std::advance(members_.m_it, n); }
+
+   typename Iterator::difference_type distance_to(const transform_iterator &other)const
+   {  return std::distance(other.members_.m_it, members_.m_it); }
+};
+
+} //namespace detail
+} //namespace intrusive
+} //namespace boost
+
+#include <boost/intrusive/detail/config_end.hpp>
+
+#endif //BOOST_INTRUSIVE_DETAIL_TRANSFORM_ITERATOR_HPP
Modified: trunk/boost/intrusive/detail/utilities.hpp
==============================================================================
--- trunk/boost/intrusive/detail/utilities.hpp	(original)
+++ trunk/boost/intrusive/detail/utilities.hpp	2007-09-26 11:26:35 EDT (Wed, 26 Sep 2007)
@@ -17,7 +17,7 @@
 #include <boost/intrusive/detail/pointer_to_other.hpp>
 #include <boost/intrusive/detail/parent_from_member.hpp>
 #include <boost/intrusive/detail/ebo_functor_holder.hpp>
-#include <boost/intrusive/linking_policy.hpp>
+#include <boost/intrusive/link_mode.hpp>
 #include <boost/intrusive/detail/mpl.hpp>
 #include <cstddef>
 #include <iterator>
@@ -26,6 +26,64 @@
 namespace intrusive {
 namespace detail {
 
+template <class T>
+struct internal_member_value_traits
+{
+   template <class U> static detail::one test(...);
+   template <class U> static detail::two test(typename U::member_value_traits* = 0);
+   static const bool value = sizeof(test<T>(0)) == sizeof(detail::two);
+};
+
+template <class T>
+struct internal_base_hook_bool
+{
+   template<bool Add>
+   struct two_or_three {one _[2 + Add];};
+   template <class U> static one test(...);
+   template <class U> static two_or_three<U::boost_intrusive_tags::is_base_hook>
+      test (detail::bool_<U::boost_intrusive_tags::is_base_hook>* = 0);
+   static const int value = sizeof(test<T>(0));
+};
+
+template <class T>
+struct internal_base_hook_bool_is_true
+{
+   static const bool value = internal_base_hook_bool<T>::value == 3;
+};
+
+template <class T>
+struct external_value_traits_bool
+{
+   template<bool Add>
+   struct two_or_three {one _[2 + Add];};
+   template <class U> static one test(...);
+   template <class U> static two_or_three<U::external_value_traits>
+      test (detail::bool_<U::external_value_traits>* = 0);
+   static const int value = sizeof(test<T>(0));
+};
+
+template <class T>
+struct external_bucket_traits_bool
+{
+   template<bool Add>
+   struct two_or_three {one _[2 + Add];};
+   template <class U> static one test(...);
+   template <class U> static two_or_three<U::external_bucket_traits>
+      test (detail::bool_<U::external_bucket_traits>* = 0);
+   static const int value = sizeof(test<T>(0));
+};
+
+template <class T>
+struct external_value_traits_is_true
+{
+   static const bool value = external_value_traits_bool<T>::value == 3;
+};
+
+template<class Node, class Tag, link_mode_type LinkMode, int>
+struct node_holder
+   :  public Node
+{};
+
 template<class SmartPtr>
 struct smart_ptr_type
 {
@@ -49,7 +107,6 @@
 inline typename smart_ptr_type<Ptr>::pointer
 get_pointer(const Ptr &ptr)
 {  return smart_ptr_type<Ptr>::get(ptr);   }
-//{  using boost::get_pointer;  return get_pointer(ptr);   }
 
 //This functor compares a stored value
 //and the one passed as an argument
@@ -75,10 +132,20 @@
    {}
 };
 
+template<class NodeAlgorithms>
+class init_disposer
+{
+   typedef typename NodeAlgorithms::node_ptr node_ptr;
+
+   public:
+   void operator()(node_ptr p)
+   {  NodeAlgorithms::init(p);   }
+};
+
 template<bool ConstantSize, class SizeType>
 struct size_holder
 {
-   enum {   constant_time_size = ConstantSize  };
+   static const bool constant_time_size = ConstantSize;
    typedef SizeType  size_type;
 
    SizeType get_size() const
@@ -99,7 +166,7 @@
 template<class SizeType>
 struct size_holder<false, SizeType>
 {
-   enum {   constant_time_size = false  };
+   static const bool constant_time_size = false;
    typedef SizeType  size_type;
 
    size_type get_size() const
@@ -115,185 +182,297 @@
    {}
 };
 
-template<class T, class DerivationHookType, typename Tag>
-struct derivation_hook_value_traits
+template<class KeyValueCompare, class Container>
+struct key_nodeptr_comp
+   :  private detail::ebo_functor_holder<KeyValueCompare>
 {
-   public:
-   typedef typename DerivationHookType::node_traits                  node_traits;
-   typedef T                                                         value_type;
-   typedef typename node_traits::node_ptr                            node_ptr;
-   typedef typename node_traits::const_node_ptr                      const_node_ptr;
-   typedef typename boost::pointer_to_other<node_ptr, T>::type       pointer;
-   typedef typename boost::pointer_to_other<node_ptr, const T>::type const_pointer;
-   typedef typename std::iterator_traits<pointer>::reference         reference;
-   typedef typename std::iterator_traits<const_pointer>::reference   const_reference;
-   enum { linking_policy = DerivationHookType::linking_policy };
+   typedef typename Container::real_value_traits         real_value_traits;
+   typedef typename real_value_traits::node_ptr          node_ptr;
+   typedef detail::ebo_functor_holder<KeyValueCompare>   base_t;
+   key_nodeptr_comp(KeyValueCompare kcomp, const Container *cont)
+      :  base_t(kcomp), cont_(cont)
+   {}
 
-   static node_ptr to_node_ptr(reference value)
-   { return static_cast<DerivationHookType &>(value).to_node_ptr(); }
+   template<class KeyType>
+   bool operator()(node_ptr node, const KeyType &key) const
+   {  return base_t::get()(*cont_->get_real_value_traits().to_value_ptr(node), key); }
 
-   static const_node_ptr to_node_ptr(const_reference value)
-   { return static_cast<const DerivationHookType &>(value).to_node_ptr(); }
+   template<class KeyType>
+   bool operator()(const KeyType &key, node_ptr node) const
+   {  return base_t::get()(key, *cont_->get_real_value_traits().to_value_ptr(node)); }
 
-   static pointer to_value_ptr(node_ptr n) 
-   { 
-      return static_cast<T*>(detail::get_pointer(DerivationHookType::to_hook_ptr(n))); 
+   bool operator()(node_ptr node1, node_ptr node2) const
+   {
+      return base_t::get()
+         ( *cont_->get_real_value_traits().to_value_ptr(node1)
+         , *cont_->get_real_value_traits().to_value_ptr(node2)
+         ); 
    }
 
-   static const_pointer to_value_ptr(const_node_ptr n)
-   { 
-      return static_cast<const T*>(detail::get_pointer(DerivationHookType::to_hook_ptr(n))); 
-   }
+   const Container *cont_;
 };
 
-
-template<class T, class MemberHookType, MemberHookType T::* P>
-struct member_hook_value_traits
+template<class F, class Container>
+struct node_cloner
+   :  private detail::ebo_functor_holder<F>
 {
-   public:
-   typedef typename MemberHookType::node_traits                      node_traits;
-   typedef T                                                         value_type;
-   typedef typename node_traits::node_ptr                            node_ptr;
-   typedef typename node_traits::const_node_ptr                      const_node_ptr;
-   typedef typename boost::pointer_to_other<node_ptr, T>::type       pointer;
-   typedef typename boost::pointer_to_other<node_ptr, const T>::type const_pointer;
-   typedef value_type &                                              reference;
-   typedef const value_type &                                        const_reference;
-   enum { linking_policy = MemberHookType::linking_policy };
+   typedef typename Container::real_value_traits         real_value_traits;
+   typedef typename Container::node_algorithms           node_algorithms;
+   typedef typename real_value_traits::value_type        value_type;
+   typedef typename real_value_traits::pointer           pointer;
+   typedef typename real_value_traits::node_traits::node node;
+   typedef typename real_value_traits::node_ptr          node_ptr;
+   typedef typename real_value_traits::const_node_ptr    const_node_ptr;
+   typedef detail::ebo_functor_holder<F>                 base_t;
+   enum { safemode_or_autounlink  = 
+            (int)real_value_traits::link_mode == (int)auto_unlink   ||
+            (int)real_value_traits::link_mode == (int)safe_link     };
 
-   public:
-   static node_ptr to_node_ptr(reference value)
+   node_cloner(F f, const Container *cont)
+      :  base_t(f), cont_(cont)
+   {}
+   
+   node_ptr operator()(node_ptr p)
    {
-      MemberHookType* result = &(value.*P);
-      return result->to_node_ptr();
+      node_ptr n = cont_->get_real_value_traits().to_node_ptr
+         (*base_t::get()(*cont_->get_real_value_traits().to_value_ptr(p)));
+      //Cloned node must be in default mode if the linking mode requires it
+      if(safemode_or_autounlink)
+         BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(n));
+      return n;
    }
 
-   static const_node_ptr to_node_ptr(const_reference value)
+   node_ptr operator()(const node &to_clone)
    {
-      const MemberHookType* result = &(value.*P);
-      return result->to_node_ptr();
+      const value_type &v =
+         *cont_->get_real_value_traits().to_value_ptr(const_node_ptr(&to_clone));
+      node_ptr n = cont_->get_real_value_traits().to_node_ptr(*base_t::get()(v));
+      //Cloned node must be in default mode if the linking mode requires it
+      if(safemode_or_autounlink)
+         BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(n));
+      return n;
    }
 
-   static pointer to_value_ptr(node_ptr n)
-   {
-      return pointer
-      (
-         parent_from_member<value_type, MemberHookType>
-            (detail::get_pointer(MemberHookType::to_hook_ptr(n)), P)
-      ); 
-   }
+   const Container *cont_;
+};
 
-   static const_pointer to_value_ptr(const_node_ptr n)
+template<class F, class Container>
+struct node_disposer
+   :  private detail::ebo_functor_holder<F>
+{
+   typedef typename Container::real_value_traits   real_value_traits;
+   typedef typename real_value_traits::node_ptr    node_ptr;
+   typedef detail::ebo_functor_holder<F>           base_t;
+   typedef typename Container::node_algorithms     node_algorithms;
+   enum { safemode_or_autounlink  = 
+            (int)real_value_traits::link_mode == (int)auto_unlink   ||
+            (int)real_value_traits::link_mode == (int)safe_link     };
+
+   node_disposer(F f, const Container *cont)
+      :  base_t(f), cont_(cont)
+   {}
+
+   void operator()(node_ptr p)
    {
-      return const_pointer
-      (
-         parent_from_member<value_type, MemberHookType>
-            (detail::get_pointer(MemberHookType::to_hook_ptr(n)), P)
-      ); 
+      if(safemode_or_autounlink)
+         node_algorithms::init(p);
+      base_t::get()(cont_->get_real_value_traits().to_value_ptr(p));
    }
+   const Container *cont_;
 };
 
-template<class KeyValueCompare, class ValueTraits>
-struct key_node_ptr_compare
-   :  private detail::ebo_functor_holder<KeyValueCompare>
+struct dummy_constptr
 {
-   typedef typename ValueTraits::node_ptr node_ptr;
-   typedef detail::ebo_functor_holder<KeyValueCompare> base_t;
-   key_node_ptr_compare(KeyValueCompare kcomp)
-      :  base_t(kcomp)
+   dummy_constptr(const void *)
    {}
 
-   template<class KeyType>
-   bool operator()(node_ptr node, const KeyType &key) const
-   {  return base_t::get()(*ValueTraits::to_value_ptr(node), key); }
-
-   template<class KeyType>
-   bool operator()(const KeyType &key, node_ptr node) const
-   {  return base_t::get()(key, *ValueTraits::to_value_ptr(node)); }
-
-   bool operator()(node_ptr node1, node_ptr node2) const
-   {
-      return base_t::get()
-         (*ValueTraits::to_value_ptr(node1), *ValueTraits::to_value_ptr(node2)); 
-   }
+   const void *get_ptr() const
+   {  return 0;  }
 };
 
-template<class F, class ValueTraits>
-struct value_to_node_cloner
-   :  private detail::ebo_functor_holder<F>
+template<class VoidPointer>
+struct constptr
 {
-   typedef typename ValueTraits::node_ptr node_ptr;
-   typedef detail::ebo_functor_holder<F> base_t;
+   typedef typename boost::pointer_to_other
+      <VoidPointer, const void>::type ConstVoidPtr;
 
-   value_to_node_cloner(F f)
-      :  base_t(f)
+   constptr(const void *ptr)
+      :  const_void_ptr_(ptr)
    {}
-   
-   node_ptr operator()(node_ptr p)
-   {  return ValueTraits::to_node_ptr(*base_t::get()(*ValueTraits::to_value_ptr(p))); }
+
+   const void *get_ptr() const
+   {  return detail::get_pointer(const_void_ptr_);  }
+
+   ConstVoidPtr const_void_ptr_;
 };
 
-template<class F, class ValueTraits>
-struct value_to_node_disposer
-   :  private detail::ebo_functor_holder<F>
+template <class VoidPointer, bool store_ptr>
+struct select_constptr
 {
-   typedef typename ValueTraits::node_ptr node_ptr;
-   typedef detail::ebo_functor_holder<F> base_t;
-   value_to_node_disposer(F f)
-      :  base_t(f)
+   typedef typename detail::if_c
+      < store_ptr
+      , constptr<VoidPointer>
+      , dummy_constptr
+      >::type type;
+};
+
+template <class Container>
+struct store_cont_ptr_on_it
+{
+   typedef typename Container::value_traits value_traits;
+   static const bool value = 
+      !detail::is_empty_class<value_traits>::value
+   || detail::external_value_traits_is_true<value_traits>::value
+   ;
+};
+
+template<class T, bool Add>
+struct add_const_if_c
+{
+   typedef typename detail::if_c
+      < Add
+      , typename detail::add_const<T>::type
+      , T
+      >::type type;
+};
+
+template<class Container, bool IsConst>
+struct node_to_value
+   :  public detail::select_constptr
+      < typename boost::pointer_to_other
+            <typename Container::pointer, void>::type
+      , detail::store_cont_ptr_on_it<Container>::value
+      >::type
+{
+   static const bool store_container_ptr = 
+      detail::store_cont_ptr_on_it<Container>::value;
+
+   typedef typename Container::real_value_traits         real_value_traits;
+   typedef typename real_value_traits::value_type        value_type;
+   typedef typename detail::select_constptr
+      < typename boost::pointer_to_other
+         <typename Container::pointer, void>::type
+      , store_container_ptr >::type                      Base;
+   typedef typename real_value_traits::node_traits::node node;
+   typedef typename detail::add_const_if_c
+         <value_type, IsConst>::type                  vtype;
+   typedef typename detail::add_const_if_c
+         <node, IsConst>::type                        ntype;
+   typedef typename boost::pointer_to_other
+      <typename Container::pointer, ntype>::type      npointer;
+
+   node_to_value(const Container *cont)
+      :  Base(cont)
    {}
 
-   void operator()(node_ptr p)
-   {  base_t::get()(ValueTraits::to_value_ptr(p));   }
+   typedef vtype &                                 result_type;
+   typedef ntype &                                 first_argument_type;
+
+   const Container *get_container() const
+   {
+      if(store_container_ptr)
+         return static_cast<const Container*>(Base::get_ptr());
+      else
+         return 0;
+   }
+
+   const real_value_traits *get_real_value_traits() const
+   {
+      if(store_container_ptr)
+         return &this->get_container()->get_real_value_traits();
+      else
+         return 0;
+   }
+
+   result_type operator()(first_argument_type arg) const
+   {  return *(this->get_real_value_traits()->to_value_ptr(npointer(&arg))); }
 };
 
-template <linking_policy Policy>
-struct dispatcher
+template <link_mode_type LinkMode>
+struct link_dispatch
 {};
 
 template<class Container>
-void destructor_impl(Container &cont, dispatcher<safe_link>)
+void destructor_impl(Container &cont, detail::link_dispatch<safe_link>)
 {  (void)cont; BOOST_INTRUSIVE_SAFE_HOOK_DESTRUCTOR_ASSERT(!cont.is_linked());  }
 
 template<class Container>
-void destructor_impl(Container &cont, dispatcher<auto_unlink>)
+void destructor_impl(Container &cont, detail::link_dispatch<auto_unlink>)
 {  cont.unlink();  }
 
 template<class Container>
-void destructor_impl(Container &, dispatcher<normal_link>)
+void destructor_impl(Container &, detail::link_dispatch<normal_link>)
 {}
 
-template<class Node, class MaybeClass>
-struct node_plus_pred
-   :  public ebo_functor_holder<MaybeClass>
-   ,  public Node
+template<class T, class NodeTraits, link_mode_type LinkMode, class Tag, int HookType>
+struct base_hook_traits
 {
-   node_plus_pred()
-      {}
+   public:
+   typedef detail::node_holder
+      <typename NodeTraits::node, Tag, LinkMode, HookType>           node_holder;
+   typedef NodeTraits                                                node_traits;
+   typedef T                                                         value_type;
+   typedef typename node_traits::node_ptr                            node_ptr;
+   typedef typename node_traits::const_node_ptr                      const_node_ptr;
+   typedef typename boost::pointer_to_other<node_ptr, T>::type       pointer;
+   typedef typename boost::pointer_to_other<node_ptr, const T>::type const_pointer;
+   typedef typename std::iterator_traits<pointer>::reference         reference;
+   typedef typename std::iterator_traits<const_pointer>::reference   const_reference;
+   static const link_mode_type link_mode = LinkMode;
 
-   node_plus_pred(const Node &x, const MaybeClass &y)
-      : Node(x), ebo_functor_holder<MaybeClass>(y) {}
+   static node_ptr to_node_ptr(reference value)
+   { return static_cast<node_holder*>(&value); }
+
+   static const_node_ptr to_node_ptr(const_reference value)
+   {  return static_cast<const node_holder*>(&value);  }
+
+   static pointer to_value_ptr(node_ptr n) 
+   {  return static_cast<T*>(static_cast<node_holder*>(&*n));   }
+
+   static const_pointer to_value_ptr(const_node_ptr n)
+   {  return static_cast<const T*>(static_cast<const node_holder*>(&*n));   }
+};
+
+template<class T, class Hook, Hook T::* P>
+struct member_hook_traits
+{
+   public:
+   typedef Hook                                                      hook_type;
+   typedef typename hook_type::boost_intrusive_tags::node_traits     node_traits;
+   typedef typename node_traits::node                                node;
+   typedef T                                                         value_type;
+   typedef typename node_traits::node_ptr                            node_ptr;
+   typedef typename node_traits::const_node_ptr                      const_node_ptr;
+   typedef typename boost::pointer_to_other<node_ptr, T>::type       pointer;
+   typedef typename boost::pointer_to_other<node_ptr, const T>::type const_pointer;
+   typedef typename std::iterator_traits<pointer>::reference         reference;
+   typedef typename std::iterator_traits<const_pointer>::reference   const_reference;
+   static const link_mode_type link_mode = Hook::boost_intrusive_tags::link_mode;
 
-   node_plus_pred(const MaybeClass &y)
-      : ebo_functor_holder<MaybeClass>(y) {}
+   static node_ptr to_node_ptr(reference value)
+   {
+      return reinterpret_cast<node*>(&(value.*P));
+   }
 
-   Node &first()          
-      {  return *this;  }
-   const Node &first() const 
-      {  return *this;  }
-   MaybeClass &second()        
-      {  return ebo_functor_holder<MaybeClass>::get();  }
-   const MaybeClass &second() const  
-      {  return ebo_functor_holder<MaybeClass>::get();  }
+   static const_node_ptr to_node_ptr(const_reference value)
+   {
+      return static_cast<const node*>(&(value.*P));
+   }
 
-   static node_plus_pred *this_from_node(Node *n)
-   {  return static_cast<node_plus_pred*>(n);   }
+   static pointer to_value_ptr(node_ptr n)
+   {
+      return detail::parent_from_member<T, Hook>
+         (static_cast<Hook*>(detail::get_pointer(n)), P);
+   }
 
-   static node_plus_pred *this_from_node(const Node *n)
-   {  return static_cast<const node_plus_pred*>(n);   }
+   static const_pointer to_value_ptr(const_node_ptr n)
+   {
+      return detail::parent_from_member<T, Hook>
+         (static_cast<const Hook*>(detail::get_pointer(n)), P);
+   }
 };
 
-} //namespace detail 
+} //namespace detail
 } //namespace intrusive 
 } //namespace boost 
 
Modified: trunk/boost/intrusive/hashtable.hpp
==============================================================================
--- trunk/boost/intrusive/hashtable.hpp	(original)
+++ trunk/boost/intrusive/hashtable.hpp	2007-09-26 11:26:35 EDT (Wed, 26 Sep 2007)
@@ -22,156 +22,390 @@
 #include <boost/intrusive/detail/assert.hpp>
 #include <boost/static_assert.hpp>
 #include <boost/functional/hash.hpp>
-#ifndef BOOST_INTRUSIVE_DISABLE_EXCEPTION_HANDLING
-#include <boost/detail/no_exceptions_support.hpp>
-#endif
+#include <boost/intrusive/detail/no_exceptions_support.hpp>
 //General intrusive utilities
 #include <boost/intrusive/intrusive_fwd.hpp>
 #include <boost/intrusive/detail/pointer_to_other.hpp>
 #include <boost/intrusive/detail/hashtable_node.hpp>
-#include <boost/intrusive/linking_policy.hpp>
+#include <boost/intrusive/detail/transform_iterator.hpp>
+#include <boost/intrusive/link_mode.hpp>
 #include <boost/intrusive/detail/ebo_functor_holder.hpp>
 //Implementation utilities
+#include <boost/intrusive/trivial_value_traits.hpp>
 #include <boost/intrusive/unordered_set_hook.hpp>
 #include <boost/intrusive/slist.hpp>
 
 namespace boost {
 namespace intrusive {
 
+/// @cond
+
+namespace detail{
+
+template<class Config>
+struct bucket_plus_size
+   : public detail::size_holder
+      < Config::constant_time_size
+      , typename Config::size_type>
+{
+   typedef detail::size_holder
+      < Config::constant_time_size
+      , typename Config::size_type>       size_traits;
+   typedef typename Config::bucket_traits bucket_traits;
+
+   bucket_plus_size(const bucket_traits &b_traits)
+      :  bucket_traits_(b_traits)
+   {}
+   bucket_traits bucket_traits_;
+};
+
+template<class Config>
+struct bucket_hash_t : public detail::ebo_functor_holder<typename Config::hash>
+{
+   typedef typename Config::hash          hasher;
+   typedef detail::size_holder
+      < Config::constant_time_size
+      , typename Config::size_type>       size_traits;
+   typedef typename Config::bucket_traits bucket_traits;
+
+   bucket_hash_t(const bucket_traits &b_traits, const hasher & h)
+      :  detail::ebo_functor_holder<hasher>(h), bucket_plus_size_(b_traits)
+   {}
+
+   bucket_plus_size<Config> bucket_plus_size_;
+};
+
+template<class Config>
+struct bucket_hash_equal_t : public detail::ebo_functor_holder<typename Config::equal>
+{
+   typedef typename Config::equal         equal;
+   typedef typename Config::hash          hasher;
+   typedef typename Config::bucket_traits bucket_traits;
+
+   bucket_hash_equal_t(const bucket_traits &b_traits, const hasher & h, const equal &e)
+      :  detail::ebo_functor_holder<typename Config::equal>(e), bucket_hash(b_traits, h)
+   {}
+   bucket_hash_t<Config> bucket_hash;
+};
+
+template<class Config>
+struct data_t : public Config::value_traits
+{
+   typedef typename Config::value_traits  value_traits;
+   typedef typename Config::equal         equal;
+   typedef typename Config::hash          hasher;
+   typedef typename Config::bucket_traits bucket_traits;
+
+   data_t( const bucket_traits &b_traits, const hasher & h
+         , const equal &e, const value_traits &val_traits)
+      :  Config::value_traits(val_traits), bucket_hash_equal_(b_traits, h, e)
+   {}
+   bucket_hash_equal_t<Config> bucket_hash_equal_;
+};
+
+}  //namespace detail {
+
+template <class T>
+struct internal_default_uset_hook
+{
+   template <class U> static detail::one test(...);
+   template <class U> static detail::two test(typename U::default_uset_hook* = 0);
+   static const bool value = sizeof(test<T>(0)) == sizeof(detail::two);
+};
+
+template <class T>
+struct get_default_uset_hook
+{
+   typedef typename T::default_uset_hook type;
+};
+
+template < class  ValueTraits
+         , class  Hash
+         , class  Equal
+         , class  SizeType
+         , bool   ConstantTimeSize
+         , class  BucketTraits
+         , bool   Power2Buckets
+         >
+struct usetopt
+{
+   typedef ValueTraits  value_traits;
+   typedef Hash         hash;
+   typedef Equal        equal;
+   typedef SizeType     size_type;
+   typedef BucketTraits bucket_traits;
+   static const bool constant_time_size = ConstantTimeSize;
+   static const bool power_2_buckets = Power2Buckets;
+};
+
+struct default_bucket_traits;
+
+template <class T>
+struct uset_defaults
+   :  pack_options
+      < none
+      , base_hook
+         <  typename detail::eval_if_c
+               < internal_default_uset_hook<T>::value
+               , get_default_uset_hook<T>
+               , detail::identity<none>
+               >::type
+         >
+      , constant_time_size<true>
+      , size_type<std::size_t>
+      , equal<std::equal_to<T> >
+      , hash<boost::hash<T> >
+      , bucket_traits<default_bucket_traits>
+      , power_2_buckets<false>
+      >::type
+{};
+
+template<class NodeTraits>
+struct get_slist_impl
+{
+   typedef trivial_value_traits<NodeTraits, normal_link> trivial_traits;
+
+   //Reducing symbol length
+   struct type : make_slist
+      < typename NodeTraits::node
+      , boost::intrusive::value_traits<trivial_traits>
+      , boost::intrusive::constant_time_size<false>
+      , boost::intrusive::size_type<std::size_t>
+      >::type
+   {};
+};
+
+/// @endcond
+
+template<class ValueTraitsOrHookOption>
+struct unordered_bucket
+{
+   /// @cond
+   typedef typename ValueTraitsOrHookOption::
+      template pack<none>::value_traits         supposed_value_traits;
+
+   typedef typename detail::eval_if_c
+      < detail::external_value_traits_is_true
+         <supposed_value_traits>::value
+      , detail::eval_value_traits
+         <supposed_value_traits>
+      , detail::identity
+         <supposed_value_traits>
+      >::type                                   real_value_traits;
+
+   typedef typename detail::get_node_traits
+      <real_value_traits>::type                 node_traits;
+   typedef typename get_slist_impl
+      <node_traits>::type                       slist_impl;
+   typedef detail::bucket_impl<slist_impl>      implementation_defined;
+   /// @endcond
+   typedef implementation_defined               type;
+};
+
+template<class ValueTraitsOrHookOption>
+struct unordered_bucket_ptr
+{
+   /// @cond
+   typedef typename ValueTraitsOrHookOption::
+      template pack<none>::value_traits         supposed_value_traits;
+   typedef typename detail::eval_if_c
+      < detail::external_value_traits_is_true
+         <supposed_value_traits>::value
+      , detail::eval_value_traits
+         <supposed_value_traits>
+      , detail::identity
+         <supposed_value_traits>
+      >::type                                   real_value_traits;
+   typedef typename detail::get_node_traits
+      <supposed_value_traits>::type::node_ptr   node_ptr;
+   typedef typename unordered_bucket
+      <ValueTraitsOrHookOption>::type           bucket_type;
+   typedef typename boost::pointer_to_other
+      <node_ptr, bucket_type>::type             implementation_defined;
+   /// @endcond
+   typedef implementation_defined               type;
+};
+
 //! The class template hashtable is an intrusive hash table container, that
 //! is used to construct intrusive unordered_set and unordered_multiset containers. The
 //! no-throw guarantee holds only, if the Equal object and Hasher don't throw.
-template< class ValueTraits
-        , class Hash             //= boost::hash<typename ValueTraits::value_type>
-        , class Equal            //= std::equal_to<typename ValueTraits::value_type>
-        , bool  ConstantTimeSize //= true
-        , class SizeType         //= std::size_t
-        >
-class hashtable
-   :  private detail::size_holder<ConstantTimeSize, SizeType>
+//!
+//! hashtable is a pseudo-intrusive container: each object to be stored in the
+//! container must contain a proper hook, but the container also needs
+//! additional auxiliary memory to work: hashtable needs a pointer to an array
+//! of type `bucket_type` to be passed in the constructor. This bucket array must
+//! have at least the same lifetime as the container. This makes the use of
+//! hashtable more complicated than purely intrusive containers.
+//! `bucket_type` is default-constructible, copyable and assignable
+//!
+//! The template parameter \c T is the type to be managed by the container.
+//! The user can specify additional options and if no options are provided
+//! default options are used.
+//!
+//! The container supports the following options:
+//! \c base_hook<>/member_hook<>/value_traits<>,
+//! \c constant_time_size<>, \c size_type<>, \c hash<> and \c equal<> .
+//!
+//! hashtable only provides forward iterators but it provides 4 iterator types:
+//! iterator and const_iterator to navigate through the whole container and
+//! local_iterator and const_local_iterator to navigate through the values
+//! stored in a single bucket. Local iterators are faster and smaller.
+//!
+//! It's not recommended to use non constant-time size hashtables because several
+//! key functions, like "empty()", become non-constant time functions. Non
+//! constant_time size hashtables are mainly provided to support auto-unlink hooks.
+//!
+//! hashtables, does not make automatic rehashings nor
+//! offers functions related to a load factor. Rehashing can be explicitly requested
+//! and the user must provide a new bucket array that will be used from that moment.
+//!
+//! Since no automatic rehashing is done, iterators are never invalidated when
+//! inserting or erasing elements. Iterators are only invalidated when rehashing.
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+template<class T, class ...Options>
+#else
+template<class Config>
+#endif
+class hashtable_impl
+   :  private detail::data_t<Config>
 {
+   public:
+   typedef typename Config::value_traits                             value_traits;
+
    /// @cond
-   private:
-   typedef slist<ValueTraits, false, SizeType> slist_impl;
-   typedef hashtable<ValueTraits, Hash, Equal
-                     ,ConstantTimeSize, SizeType>           this_type; 
-   typedef typename ValueTraits::node_traits                node_traits;
-   typedef detail::size_holder<ConstantTimeSize, SizeType>  size_traits;
 
-   //noncopyable
-   hashtable (const hashtable&);
-   hashtable operator =(const hashtable&);
+   static const bool external_value_traits =
+      detail::external_value_traits_is_true<value_traits>::value;
+   typedef typename detail::eval_if_c
+      < external_value_traits
+      , detail::eval_value_traits<value_traits>
+      , detail::identity<value_traits>
+      >::type                                                        real_value_traits;
+   typedef typename Config::bucket_traits                            bucket_traits;
+   static const bool external_bucket_traits =
+      detail::external_bucket_traits_is_true<bucket_traits>::value;
+   typedef typename detail::eval_if_c
+      < external_bucket_traits
+      , detail::eval_bucket_traits<bucket_traits>
+      , detail::identity<bucket_traits>
+      >::type                                                        real_bucket_traits;
+   typedef typename get_slist_impl
+      <typename real_value_traits::node_traits>::type                slist_impl;
    /// @endcond
 
-   public:
-   typedef ValueTraits                                                  value_traits;
-   typedef typename ValueTraits::value_type                             value_type;
-   typedef typename ValueTraits::pointer                                pointer;
-   typedef typename ValueTraits::const_pointer                          const_pointer;
-   typedef typename std::iterator_traits<pointer>::reference            reference;
-   typedef typename std::iterator_traits<const_pointer>::reference      const_reference;
-   typedef typename std::iterator_traits<pointer>::difference_type      difference_type;
-   typedef SizeType                                                     size_type;
-   typedef value_type                                                   key_type;
-   typedef Hash                                                         hasher;
-   typedef Equal                                                        key_equal;
-   typedef detail::bucket_type_impl<slist_impl>                         bucket_type;
+   typedef typename real_value_traits::pointer                       pointer;
+   typedef typename real_value_traits::const_pointer                 const_pointer;
+   typedef typename std::iterator_traits<pointer>::value_type        value_type;
+   typedef typename std::iterator_traits<pointer>::reference         reference;
+   typedef typename std::iterator_traits<const_pointer>::reference   const_reference;
+   typedef typename std::iterator_traits<pointer>::difference_type   difference_type;
+   typedef typename Config::size_type                                size_type;
+   typedef value_type                                                key_type;
+   typedef typename Config::equal                                    key_equal;
+   typedef typename Config::hash                                     hasher;
+   typedef detail::bucket_impl<slist_impl>                           bucket_type;
+   typedef typename boost::pointer_to_other
+      <pointer, bucket_type>::type                                   bucket_ptr;
+   typedef typename slist_impl::iterator                             siterator;
+   typedef typename slist_impl::const_iterator                       const_siterator;
+   typedef detail::hashtable_iterator<hashtable_impl, false>         iterator;
+   typedef detail::hashtable_iterator<hashtable_impl, true>          const_iterator;
+   typedef typename real_value_traits::node_traits                        node_traits;
+   typedef typename node_traits::node                                node;
    typedef typename boost::pointer_to_other
-      <pointer, bucket_type>::type                                      bucket_ptr;
-   typedef typename slist_impl::iterator                                local_iterator;
-   typedef typename slist_impl::const_iterator                          const_local_iterator;
+      <pointer, node>::type                                          node_ptr;
+   typedef typename boost::pointer_to_other
+      <node_ptr, const node>::type                                   const_node_ptr;
+   typedef typename slist_impl::node_algorithms                      node_algorithms;
 
-   typedef detail::hashtable_iterator<value_type, slist_impl>           iterator;
-   typedef detail::hashtable_iterator<value_type, slist_impl>           const_iterator;
+   static const bool constant_time_size = Config::constant_time_size;
+   static const bool stateful_value_traits = detail::store_cont_ptr_on_it<hashtable_impl>::value;
 
    /// @cond
    private:
-   typedef typename node_traits::node                                   node;
-   typedef typename boost::pointer_to_other
-      <pointer, node>::type                                             node_ptr;
-   typedef typename boost::pointer_to_other
-      <node_ptr, const node>::type                                      const_node_ptr;
+   typedef detail::size_holder<constant_time_size, size_type>        size_traits;
+   typedef detail::data_t<Config>                                    base_type;
+   typedef detail::transform_iterator
+      < typename slist_impl::iterator
+      , detail::node_to_value<hashtable_impl, false> >               local_iterator_impl;
+   typedef detail::transform_iterator
+      < typename slist_impl::iterator
+      , detail::node_to_value<hashtable_impl, true> >                const_local_iterator_impl;
+
+   //noncopyable
+   hashtable_impl (const hashtable_impl&);
+   hashtable_impl operator =(const hashtable_impl&);
 
    enum { safemode_or_autounlink  = 
-            (int)ValueTraits::linking_policy == (int)auto_unlink   ||
-            (int)ValueTraits::linking_policy == (int)safe_link     };
+            (int)real_value_traits::link_mode == (int)auto_unlink   ||
+            (int)real_value_traits::link_mode == (int)safe_link     };
 
    //Constant-time size is incompatible with auto-unlink hooks!
-   BOOST_STATIC_ASSERT(!(ConstantTimeSize && ((int)ValueTraits::linking_policy == (int)auto_unlink)));
+   BOOST_STATIC_ASSERT(!(constant_time_size && ((int)real_value_traits::link_mode == (int)auto_unlink)));
 
-   typedef detail::bucket_info_impl<slist_impl>    bucket_info_t;
-   typedef typename boost::pointer_to_other
-      <pointer, bucket_info_t>::type               bucket_info_ptr;
-   typedef typename boost::pointer_to_other
-      <pointer, const bucket_info_t>::type         const_bucket_info_ptr;
+   static const bool power_2_buckets = Config::power_2_buckets;
 
-   //User scattered boost::compressed pair to get EBO all compilers
-//   boost::compressed_pair
-//      <boost::compressed_pair<bucket_info_t, Hash>
-//      ,Equal> members_;
-   struct bucket_hash_t
-      :  public detail::ebo_functor_holder<Hash>
-   {
-      bucket_hash_t(const Hash & h)
-         :  detail::ebo_functor_holder<Hash>(h)
-      {}
-      bucket_info_t bucket_info;
-   };
+   std::size_t from_hash_to_bucket(std::size_t hash_value) const
+   {  return from_hash_to_bucket(hash_value, detail::bool_<power_2_buckets>());  }
 
-   struct bucket_hash_equal_t
-      :  public detail::ebo_functor_holder<Equal>
-   {
-      bucket_hash_equal_t(const Hash & h, const Equal &e)
-         :  detail::ebo_functor_holder<Equal>(e), bucket_hash(h)
-      {}
-      bucket_hash_t bucket_hash;
-   } bucket_hash_equal_;
+   std::size_t from_hash_to_bucket(std::size_t hash_value, detail::bool_<false>) const
+   {  return hash_value % this->get_real_bucket_traits().bucket_count();  }
+
+   std::size_t from_hash_to_bucket(std::size_t hash_value, detail::bool_<true>) const
+   {  return hash_value & (this->get_real_bucket_traits().bucket_count() - 1);   }
+
+   const key_equal &priv_equal() const
+   {  return static_cast<const key_equal&>(this->bucket_hash_equal_.get());  }
+
+   key_equal &priv_equal()
+   {  return static_cast<key_equal&>(this->bucket_hash_equal_.get());  }
 
-   const Equal &priv_equal() const
-   {  return static_cast<const Equal&>(bucket_hash_equal_.get());  }
+   const real_bucket_traits &get_real_bucket_traits(detail::bool_<false>) const
+   {  return this->bucket_hash_equal_.bucket_hash.bucket_plus_size_.bucket_traits_;  }
 
-   Equal &priv_equal()
-   {  return static_cast<Equal&>(bucket_hash_equal_.get());  }
+   const real_bucket_traits &get_real_bucket_traits(detail::bool_<true>) const
+   {  return this->bucket_hash_equal_.bucket_hash.bucket_plus_size_.bucket_traits_.get_bucket_traits(*this);  }
 
-   const bucket_info_t &priv_bucket_info() const
-   {  return bucket_hash_equal_.bucket_hash.bucket_info;  }
+   real_bucket_traits &get_real_bucket_traits(detail::bool_<false>)
+   {  return this->bucket_hash_equal_.bucket_hash.bucket_plus_size_.bucket_traits_;  }
 
-   bucket_info_t &priv_bucket_info()
-   {  return bucket_hash_equal_.bucket_hash.bucket_info;  }
+   real_bucket_traits &get_real_bucket_traits(detail::bool_<true>)
+   {  return this->bucket_hash_equal_.bucket_hash.bucket_plus_size_.bucket_traits_.get_bucket_traits(*this);  }
 
-   const Hash &priv_hasher() const
-   {  return static_cast<const Hash&>(bucket_hash_equal_.bucket_hash.get());  }
+   const real_bucket_traits &get_real_bucket_traits() const
+   {  return this->get_real_bucket_traits(detail::bool_<external_bucket_traits>());  }
 
-   Hash &priv_hasher()
-   {  return static_cast<Hash&>(bucket_hash_equal_.bucket_hash.get());  }
+   real_bucket_traits &get_real_bucket_traits()
+   {  return this->get_real_bucket_traits(detail::bool_<external_bucket_traits>());  }
 
-   const bucket_ptr &priv_buckets() const
-   {  return priv_bucket_info().buckets_;  }
+   const hasher &priv_hasher() const
+   {  return static_cast<const hasher&>(this->bucket_hash_equal_.bucket_hash.get());  }
 
-   bucket_ptr &priv_buckets()
-   {  return priv_bucket_info().buckets_;  }
+   hasher &priv_hasher()
+   {  return static_cast<hasher&>(this->bucket_hash_equal_.bucket_hash.get());  }
 
-   const size_type &priv_buckets_len() const
-   {  return priv_bucket_info().buckets_len_;  }
+   bucket_ptr priv_buckets() const
+   {  return this->get_real_bucket_traits().bucket_begin();  }
 
-   size_type &priv_buckets_len()
-   {  return priv_bucket_info().buckets_len_;  }
+   size_type priv_buckets_len() const
+   {  return this->get_real_bucket_traits().bucket_count();  }
 
    static node_ptr uncast(const_node_ptr ptr)
    {
       return node_ptr(const_cast<node*>(detail::get_pointer(ptr)));
    }
 
-//   static bucket_info_ptr uncast(const_bucket_info_ptr ptr)
-//   {
-//      return bucket_info_ptr(const_cast<bucket_info_t*>(detail::get_pointer(ptr)));
-//   }
+   node &from_value_to_node(value_type &v)
+   {  return *this->get_real_value_traits().to_node_ptr(v);  }
 
-   static slist_impl &bucket_to_slist(bucket_type &b)
-   {  return static_cast<slist_impl &>(b);  }
+   const node &from_value_to_node(const value_type &v) const
+   {  return *this->get_real_value_traits().to_node_ptr(v);  }
 
-   static const slist_impl &bucket_to_slist(const bucket_type &b)
-   {  return static_cast<const slist_impl &>(b);  }
+   size_traits &priv_size_traits()
+   {  return this->bucket_hash_equal_.bucket_hash.bucket_plus_size_;  }
+
+   const size_traits &priv_size_traits() const
+   {  return this->bucket_hash_equal_.bucket_hash.bucket_plus_size_;  }
 
    struct insert_commit_data_impl
    {
@@ -180,33 +414,82 @@
    /// @endcond
 
    public:
+
+   class local_iterator
+      :  public local_iterator_impl
+   {
+      public:
+      local_iterator()
+      {}
+
+      local_iterator(siterator sit, const hashtable_impl *cont)
+         :  local_iterator_impl(sit, cont)
+      {}
+   };
+
+   class const_local_iterator
+      :  public const_local_iterator_impl
+   {
+      public:
+      const_local_iterator()
+      {}
+
+      const_local_iterator(siterator sit, const hashtable_impl *cont)
+         :  const_local_iterator_impl(sit, cont)
+      {}
+   };
+
    typedef insert_commit_data_impl insert_commit_data;
 
+   /// @cond
+
+   const real_value_traits &get_real_value_traits(detail::bool_<false>) const
+   {  return *this;  }
+
+   const real_value_traits &get_real_value_traits(detail::bool_<true>) const
+   {  return base_type::get_value_traits(*this);  }
+
+   real_value_traits &get_real_value_traits(detail::bool_<false>)
+   {  return *this;  }
+
+   real_value_traits &get_real_value_traits(detail::bool_<true>)
+   {  return base_type::get_value_traits(*this);  }
+
+   /// @endcond
+
+   public:
+
+   const real_value_traits &get_real_value_traits() const
+   {  return this->get_real_value_traits(detail::bool_<external_value_traits>());  }
+
+   real_value_traits &get_real_value_traits()
+   {  return this->get_real_value_traits(detail::bool_<external_value_traits>());  }
+
    //! <b>Requires</b>: buckets must not be being used by any other resource.
    //!
    //! <b>Effects</b>: Constructs an empty unordered_set, storing a reference
-   //!   to the bucket array and copies of the hasher and equal functors.
+   //!   to the bucket array and copies of the key_hasher and equal_func functors.
    //!   
    //! <b>Complexity</b>: Constant. 
    //! 
    //! <b>Throws</b>: If value_traits::node_traits::node
    //!   constructor throws (this does not happen with predefined Boost.Intrusive hooks)
-   //!   or the copy constructor or invocation of Hash or Equal throws. 
+   //!   or the copy constructor or invocation of hash_func or equal_func throws. 
    //!
    //! <b>Notes</b>: buckets array must be disposed only after
-   //!   *this is disposed. 
-   hashtable( bucket_ptr buckets
-             , size_type buckets_len
-             , const Hash & hasher = Hash()
-             , const Equal &equal = Equal()) 
-      :  bucket_hash_equal_(hasher, equal)
+   //!   *this is disposed.
+   hashtable_impl ( const bucket_traits &b_traits
+                  , const hasher & hash_func = hasher()
+                  , const key_equal &equal_func = key_equal()
+                  , const value_traits &v_traits = value_traits()) 
+      :  base_type(b_traits, hash_func, equal_func, v_traits)
    {
-      
-      BOOST_INTRUSIVE_INVARIANT_ASSERT(buckets_len != 0);
-      priv_buckets()       = buckets;
-      priv_buckets_len()   = buckets_len;
       priv_clear_buckets();
-      size_traits::set_size(size_type(0));
+      this->priv_size_traits().set_size(size_type(0));
+      BOOST_INTRUSIVE_INVARIANT_ASSERT(this->priv_buckets_len() != 0);
+      //Check power of two bucket array if the option is activated
+      BOOST_INTRUSIVE_INVARIANT_ASSERT
+      (!power_2_buckets || (0 == (this->priv_buckets_len() & (this->priv_buckets_len()-1))));
    }
 
    //! <b>Effects</b>: Detaches all elements from this. The objects in the unordered_set 
@@ -216,7 +499,7 @@
    //!   it's a safe-mode or auto-unlink value. Otherwise constant.
    //! 
    //! <b>Throws</b>: Nothing.
-   ~hashtable() 
+   ~hashtable_impl() 
    {  this->clear(); }
 
    //! <b>Effects</b>: Returns an iterator pointing to the beginning of the unordered_set.
@@ -228,8 +511,7 @@
    iterator begin()
    {
       size_type bucket_num;
-      local_iterator local_it = priv_begin(bucket_num);
-      return iterator(local_it, const_bucket_info_ptr(&this->priv_bucket_info()));
+      return iterator(this->priv_begin(bucket_num), this);
    }
 
    //! <b>Effects</b>: Returns a const_iterator pointing to the beginning
@@ -240,7 +522,7 @@
    //! 
    //! <b>Throws</b>: Nothing.
    const_iterator begin() const
-   {  return cbegin();  }
+   {  return this->cbegin();  }
 
    //! <b>Effects</b>: Returns a const_iterator pointing to the beginning
    //!   of the unordered_set.
@@ -252,8 +534,7 @@
    const_iterator cbegin() const
    {
       size_type bucket_num;
-      local_iterator local_it = priv_begin(bucket_num);
-      return const_iterator( local_it, const_bucket_info_ptr(&this->priv_bucket_info()));
+      return const_iterator(this->priv_begin(bucket_num), this);
    }
 
    //! <b>Effects</b>: Returns an iterator pointing to the end of the unordered_set.
@@ -262,7 +543,7 @@
    //! 
    //! <b>Throws</b>: Nothing.
    iterator end()
-   {  return iterator(invalid_local_it(this->priv_bucket_info()), 0);   }
+   {  return iterator(invalid_local_it(this->get_real_bucket_traits()), 0);   }
 
    //! <b>Effects</b>: Returns a const_iterator pointing to the end of the unordered_set.
    //! 
@@ -270,7 +551,7 @@
    //! 
    //! <b>Throws</b>: Nothing.
    const_iterator end() const
-   {  return cend(); }
+   {  return this->cend(); }
 
    //! <b>Effects</b>: Returns a const_iterator pointing to the end of the unordered_set.
    //! 
@@ -278,7 +559,7 @@
    //! 
    //! <b>Throws</b>: Nothing.
    const_iterator cend() const
-   {  return const_iterator(invalid_local_it(this->priv_bucket_info()), 0);  }
+   {  return const_iterator(invalid_local_it(this->get_real_bucket_traits()), 0);  }
 
    //! <b>Effects</b>: Returns the hasher object used by the unordered_set.
    //! 
@@ -298,15 +579,15 @@
 
    //! <b>Effects</b>: Returns true is the container is empty.
    //! 
-   //! <b>Complexity</b>: if ConstantTimeSize is false, average constant time
+   //! <b>Complexity</b>: if constant_time_size is false, average constant time
    //!   (worst case, with empty() == true): O(this->bucket_count()).
    //!   Otherwise constant.
    //! 
    //! <b>Throws</b>: Nothing.
    bool empty() const
    {
-      if(ConstantTimeSize){
-         return !size();
+      if(constant_time_size){
+         return !this->size();
       }
       else{
          size_type buckets_len = this->priv_buckets_len();
@@ -323,13 +604,13 @@
    //! <b>Effects</b>: Returns the number of elements stored in the unordered_set.
    //! 
    //! <b>Complexity</b>: Linear to elements contained in *this if
-   //!   ConstantTimeSize is false. Constant-time otherwise.
+   //!   constant_time_size is false. Constant-time otherwise.
    //! 
    //! <b>Throws</b>: Nothing.
    size_type size() const
    {
-      if(ConstantTimeSize)
-         return size_traits::get_size();
+      if(constant_time_size)
+         return this->priv_size_traits().get_size();
       else{
          size_type len = 0;
          size_type buckets_len = this->priv_buckets_len();
@@ -351,19 +632,18 @@
    //!
    //! <b>Throws</b>: If the swap() call for the comparison or hash functors
    //!   found using ADL throw. Basic guarantee.
-   void swap(hashtable& other)
+   void swap(hashtable_impl& other)
    {
       using std::swap;
       //These can throw
       swap(this->priv_equal(), other.priv_equal());
       swap(this->priv_hasher(), other.priv_hasher());
       //These can't throw
-      swap(this->priv_buckets(), other.priv_buckets());
-      swap(this->priv_buckets_len(), other.priv_buckets_len());
-      if(ConstantTimeSize){
-         size_type backup = size_traits::get_size();
-         size_traits::set_size(other.get_size());
-         other.set_size(backup);
+      swap(this->get_real_bucket_traits(), other.get_real_bucket_traits());
+      if(constant_time_size){
+         size_type backup = this->priv_size_traits().get_size();
+         this->priv_size_traits().set_size(other.priv_size_traits().get_size());
+         other.priv_size_traits().set_size(backup);
       }
    }
 
@@ -381,12 +661,17 @@
    //! 
    //! <b>Throws</b>: If cloner throws. Basic guarantee.
    template <class Cloner, class Disposer>
-   void clone_from(const hashtable &src, Cloner cloner, Disposer disposer)
+   void clone_from(const hashtable_impl &src, Cloner cloner, Disposer disposer)
    {
       this->clear_and_dispose(disposer);
-      if(!ConstantTimeSize || !src.empty()){
+      if(!constant_time_size || !src.empty()){
          const size_type src_bucket_count = src.bucket_count();
          const size_type dst_bucket_count = this->bucket_count();
+         //Check power of two bucket array if the option is activated
+         BOOST_INTRUSIVE_INVARIANT_ASSERT
+         (!power_2_buckets || (0 == (src_bucket_count & (src_bucket_count-1))));
+         BOOST_INTRUSIVE_INVARIANT_ASSERT
+         (!power_2_buckets || (0 == (dst_bucket_count & (dst_bucket_count-1))));
 
          //If src bucket count is bigger or equal, structural copy is possible
          if(src_bucket_count >= dst_bucket_count){
@@ -394,72 +679,76 @@
             const bucket_ptr src_buckets = src.priv_buckets();
             const bucket_ptr dst_buckets = this->priv_buckets();
             size_type constructed;
-            #ifndef BOOST_INTRUSIVE_DISABLE_EXCEPTION_HANDLING
-            BOOST_TRY{
-            #endif
+            BOOST_INTRUSIVE_TRY{
                for( constructed = 0
                   ; constructed < dst_bucket_count
                   ; ++constructed){
-                  dst_buckets[constructed].clone_from(src_buckets[constructed], cloner, disposer);
+                  dst_buckets[constructed].clone_from
+                     ( src_buckets[constructed]
+                     , detail::node_cloner<Cloner, hashtable_impl>(cloner, this)
+                     , detail::node_disposer<Disposer, hashtable_impl>(disposer, this)
+                     );
                }
                if(src_bucket_count != dst_bucket_count){
                   //Now insert the remaining ones using the modulo trick
                   for(//"constructed" comes from the previous loop
                      ; constructed < src_bucket_count
                      ; ++constructed){
-                     bucket_type &dst_b = dst_buckets[constructed % dst_bucket_count];
+                     bucket_type &dst_b = (power_2_buckets)
+                        ?  dst_buckets[constructed & (dst_bucket_count-1)]
+                        :  dst_buckets[constructed % dst_bucket_count];
                      bucket_type &src_b = src_buckets[constructed];
-                     for( local_iterator b(src_b.begin()), e(src_b.end())
+                     for( siterator b(src_b.begin()), e(src_b.end())
                         ; b != e
                         ; ++b){
-                        dst_b.push_front(*cloner(*b));
+                        dst_b.push_front(*detail::node_cloner<Cloner, hashtable_impl>
+                              (cloner, this)(b.pointed_node()));
                      }
                   }
                }
-            #ifndef BOOST_INTRUSIVE_DISABLE_EXCEPTION_HANDLING
             }
-            BOOST_CATCH(...){
+            BOOST_INTRUSIVE_CATCH(...){
                while(constructed--){
-                  dst_buckets[constructed].clear_and_dispose(disposer);
+                  dst_buckets[constructed].clear_and_dispose
+                  (detail::node_disposer<Disposer, hashtable_impl>(disposer, this));
                }
-               BOOST_RETHROW;
+               BOOST_INTRUSIVE_RETHROW;
             }
-            BOOST_CATCH_END
-            #endif
-            size_traits::set_size(src.get_size());
+            BOOST_INTRUSIVE_CATCH_END
+            this->priv_size_traits().set_size(src.priv_size_traits().get_size());
          }
          else{
             //Unlike previous cloning algorithm, this can throw
             //if cloner, the hasher or comparison functor throw
             const_iterator b(src.begin()), e(src.end());
-            #ifndef BOOST_INTRUSIVE_DISABLE_EXCEPTION_HANDLING
-            BOOST_TRY{
-            #endif
+            BOOST_INTRUSIVE_TRY{
                for(; b != e; ++b){
                   this->insert_equal(*cloner(*b));
                }
-            #ifndef BOOST_INTRUSIVE_DISABLE_EXCEPTION_HANDLING
             }
-            BOOST_CATCH(...){
+            BOOST_INTRUSIVE_CATCH(...){
                this->clear_and_dispose(disposer);
                BOOST_RETHROW;
             }
-            BOOST_CATCH_END
-            #endif
+            BOOST_INTRUSIVE_CATCH_END
          }
       }
    }
 
    iterator insert_equal(reference value)
    {
-      size_type bucket_num, hash;
-      local_iterator it = priv_find(value, this->priv_hasher(), this->priv_equal(), bucket_num, hash);
+      size_type bucket_num, hash_func;
+      siterator it = this->priv_find
+         (value, this->priv_hasher(), this->priv_equal(), bucket_num, hash_func);
       bucket_type &b = this->priv_buckets()[bucket_num];
-      if(it == invalid_local_it(this->priv_bucket_info())){
+      if(it == invalid_local_it(this->get_real_bucket_traits())){
          it = b.before_begin();
       }
-      size_traits::increment();
-      return iterator(b.insert_after(it, value), const_bucket_info_ptr(&this->priv_bucket_info()));
+      node_ptr n = node_ptr(&from_value_to_node(value));
+      if(safemode_or_autounlink)
+         BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(n));
+      this->priv_size_traits().increment();
+      return iterator(b.insert_after(it, *n), this);
    }
 
    template<class Iterator>
@@ -488,10 +777,12 @@
    std::pair<iterator, bool> insert_unique(reference value)
    {
       insert_commit_data commit_data;
-      std::pair<iterator, bool> ret = insert_unique_check(value, this->priv_hasher(), this->priv_equal(), commit_data);
+      std::pair<iterator, bool> ret = this->insert_unique_check
+         (value, this->priv_hasher(), this->priv_equal(), commit_data);
       if(!ret.second)
          return ret;
-      return std::pair<iterator, bool> (insert_unique_commit(value, commit_data), true);
+      return std::pair<iterator, bool> 
+         (this->insert_unique_commit(value, commit_data), true);
    }
 
    //! <b>Requires</b>: Dereferencing iterator must yield an lvalue 
@@ -513,13 +804,13 @@
          this->insert_unique(*b);
    }
 
-   //! <b>Requires</b>: "hasher" must be a hash function that induces 
+   //! <b>Requires</b>: "hash_func" must be a hash function that induces 
    //!   the same hash values as the stored hasher. The difference is that
-   //!   "hasher" hashes the given key instead of the value_type.
+   //!   "hash_func" hashes the given key instead of the value_type.
    //!
-   //!   "key_value_equal" must be a equality function that induces 
+   //!   "equal_func" must be a equality function that induces 
    //!   the same equality as key_equal. The difference is that
-   //!   "key_value_equal" compares an arbitrary key with the contained values.
+   //!   "equal_func" compares an arbitrary key with the contained values.
    //! 
    //! <b>Effects</b>: Checks if a value can be inserted in the unordered_set, using
    //!   a user provided key instead of the value itself.
@@ -532,7 +823,7 @@
    //! 
    //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
    //!
-   //! <b>Throws</b>: If hasher or key_value_equal throw. Strong guarantee.
+   //! <b>Throws</b>: If hash_func or equal_func throw. Strong guarantee.
    //! 
    //! <b>Notes</b>: This function is used to improve performance when constructing
    //!   a value_type is expensive: if there is an equivalent value
@@ -551,20 +842,18 @@
    template<class KeyType, class KeyHasher, class KeyValueEqual>
    std::pair<iterator, bool> insert_unique_check
       ( const KeyType &key
-      , KeyHasher hasher
-      , KeyValueEqual key_value_eq
+      , KeyHasher hash_func
+      , KeyValueEqual equal_func
       , insert_commit_data &commit_data)
    {
       size_type bucket_num;
-      local_iterator prev_pos =
-         priv_find(key, hasher, key_value_eq, bucket_num, commit_data.hash);
-      bool success = prev_pos == invalid_local_it(this->priv_bucket_info());
+      siterator prev_pos =
+         this->priv_find(key, hash_func, equal_func, bucket_num, commit_data.hash);
+      bool success = prev_pos == invalid_local_it(this->get_real_bucket_traits());
       if(success){
          prev_pos = this->priv_buckets()[bucket_num].before_begin();
       }
-      return std::pair<iterator, bool>
-         (iterator(prev_pos, const_bucket_info_ptr(&this->priv_bucket_info()))
-         ,success);
+      return std::pair<iterator, bool>(iterator(prev_pos, this),success);
    }
 
    //! <b>Requires</b>: value must be an lvalue of type value_type. commit_data
@@ -588,11 +877,13 @@
    //!   After a successful rehashing insert_commit_data remains valid.
    iterator insert_unique_commit(reference value, const insert_commit_data &commit_data)
    {
-      size_type bucket_num = commit_data.hash % this->priv_buckets_len();
+      size_type bucket_num = from_hash_to_bucket(commit_data.hash);
       bucket_type &b = this->priv_buckets()[bucket_num];
-      size_traits::increment();
-      return iterator( b.insert_after(b.before_begin(), value)
-                     , const_bucket_info_ptr(&this->priv_bucket_info()));
+      this->priv_size_traits().increment();
+      node_ptr n = node_ptr(&from_value_to_node(value));
+      if(safemode_or_autounlink)
+         BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(n));
+      return iterator( b.insert_after(b.before_begin(), *n), this);
    }
 
    //! <b>Effects</b>: Erases the element pointed to by i. 
@@ -604,7 +895,7 @@
    //! <b>Note</b>: Invalidates the iterators (but not the references)
    //!    to the erased element. No destructors are called.
    void erase(const_iterator i)
-   {  erase_and_dispose(i, detail::null_disposer());  }
+   {  this->erase_and_dispose(i, detail::null_disposer());  }
 
    //! <b>Effects</b>: Erases the range pointed to by b end e. 
    //! 
@@ -616,7 +907,7 @@
    //! <b>Note</b>: Invalidates the iterators (but not the references)
    //!    to the erased elements. No destructors are called.
    void erase(const_iterator b, const_iterator e)
-   {  erase_and_dispose(b, e, detail::null_disposer());  }
+   {  this->erase_and_dispose(b, e, detail::null_disposer());  }
 
    //! <b>Effects</b>: Erases all the elements with the given value.
    //! 
@@ -625,20 +916,21 @@
    //! <b>Complexity</b>: Average case O(this->count(value)).
    //!   Worst case O(this->size()).
    //! 
-   //! <b>Throws</b>: If the internal hasher or the equality functor throws.  Basic guarantee.
+   //! <b>Throws</b>: If the internal hasher or the equality functor throws. 
+   //!   Basic guarantee.
    //! 
    //! <b>Note</b>: Invalidates the iterators (but not the references)
    //!    to the erased elements. No destructors are called.
    size_type erase(const_reference value)
    {  return this->erase(value, this->priv_hasher(), this->priv_equal());  }
 
-   //! <b>Requires</b>: "hasher" must be a hash function that induces 
+   //! <b>Requires</b>: "hash_func" must be a hash function that induces 
    //!   the same hash values as the stored hasher. The difference is that
-   //!   "hasher" hashes the given key instead of the value_type.
+   //!   "hash_func" hashes the given key instead of the value_type.
    //!
-   //!   "key_value_equal" must be a equality function that induces 
+   //!   "equal_func" must be a equality function that induces 
    //!   the same equality as key_equal. The difference is that
-   //!   "key_value_equal" compares an arbitrary key with the contained values.
+   //!   "equal_func" compares an arbitrary key with the contained values.
    //!
    //! <b>Effects</b>: Erases all the elements that have the same hash and
    //!   compare equal with the given key.
@@ -648,13 +940,13 @@
    //! <b>Complexity</b>: Average case O(this->count(value)).
    //!   Worst case O(this->size()).
    //! 
-   //! <b>Throws</b>: If hasher or equal throw. Basic guarantee.
+   //! <b>Throws</b>: If hash_func or equal_func throw. Basic guarantee.
    //! 
    //! <b>Note</b>: Invalidates the iterators (but not the references)
    //!    to the erased elements. No destructors are called.
    template<class KeyType, class KeyHasher, class KeyValueEqual>
-   size_type erase(const KeyType& key, KeyHasher hasher, KeyValueEqual equal)
-   {  return erase_and_dispose(key, hasher, equal, detail::null_disposer()); }
+   size_type erase(const KeyType& key, KeyHasher hash_func, KeyValueEqual equal_func)
+   {  return this->erase_and_dispose(key, hash_func, equal_func, detail::null_disposer()); }
 
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
    //!
@@ -670,11 +962,12 @@
    template<class Disposer>
    void erase_and_dispose(const_iterator i, Disposer disposer)
    {
-      local_iterator to_erase(i.local());
+      siterator to_erase(i.slist_it());
       bucket_ptr f(priv_buckets()), l(f + priv_buckets_len());
       bucket_type &b = this->priv_buckets()[bucket_type::get_bucket_num(to_erase, *f, *l)];
-      b.erase_after_and_dispose(b.previous(to_erase), disposer);
-      size_traits::decrement();
+      b.erase_after_and_dispose
+         (b.previous(to_erase), detail::node_disposer<Disposer, hashtable_impl>(disposer, this));
+      this->priv_size_traits().decrement();
    }
 
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
@@ -696,12 +989,12 @@
 
       //Get the bucket number and local iterator for both iterators
       bucket_ptr f(priv_buckets()), l(f + priv_buckets_len());
-      size_type first_bucket_num = bucket_type::get_bucket_num(b.local(), *f, *l);
+      size_type first_bucket_num = bucket_type::get_bucket_num(b.slist_it(), *f, *l);
 
-      local_iterator before_first_local_it
-         = priv_buckets()[first_bucket_num].previous(b.local());
+      siterator before_first_local_it
+         = priv_buckets()[first_bucket_num].previous(b.slist_it());
       size_type last_bucket_num;
-      local_iterator last_local_it;
+      siterator last_local_it;
 
       //For the end iterator, we will assign the end iterator
       //of the last bucket
@@ -710,7 +1003,7 @@
          last_local_it     = priv_buckets()[last_bucket_num].end();
       }
       else{
-         last_local_it     = e.local();
+         last_local_it     = e.slist_it();
          last_bucket_num  = bucket_type::get_bucket_num(last_local_it, *f, *l);
       }
 
@@ -718,11 +1011,13 @@
       //First erase the nodes of the first bucket
       {
          bucket_type &first_b = buckets[first_bucket_num];
-         local_iterator nxt(before_first_local_it); ++nxt;
-         local_iterator end = first_b.end();
+         siterator nxt(before_first_local_it); ++nxt;
+         siterator end = first_b.end();
          while(nxt != end){
-            nxt = first_b.erase_after_and_dispose(before_first_local_it, disposer);
-            size_traits::decrement();
+            nxt = first_b.erase_after_and_dispose
+               ( before_first_local_it
+               , detail::node_disposer<Disposer, hashtable_impl>(disposer, this));
+            this->priv_size_traits().decrement();
          }
       }
 
@@ -731,23 +1026,26 @@
          bucket_type &b = buckets[i];
          if(b.empty())
             continue;
-         local_iterator b_begin(b.before_begin());
-         local_iterator nxt(b_begin); ++nxt;
-         local_iterator end = b.end();
+         siterator b_begin(b.before_begin());
+         siterator nxt(b_begin); ++nxt;
+         siterator end = b.end();
          while(nxt != end){
-            nxt = b.erase_after_and_dispose(b_begin, disposer);
-            size_traits::decrement();
+            nxt = b.erase_after_and_dispose
+               (b_begin, detail::node_disposer<Disposer, hashtable_impl>(disposer, this));
+            this->priv_size_traits().decrement();
          }
       }
 
       //Now erase nodes from the last bucket
       {
          bucket_type &last_b = buckets[last_bucket_num];
-         local_iterator b_begin(last_b.before_begin());
-         local_iterator nxt(b_begin); ++nxt;
+         siterator b_begin(last_b.before_begin());
+         siterator nxt(b_begin); ++nxt;
          while(nxt != last_local_it){
-            nxt = last_b.erase_after_and_dispose(b_begin, disposer);
-            size_traits::decrement();
+            nxt = last_b.erase_after_and_dispose
+               (b_begin, detail::node_disposer<Disposer, hashtable_impl>
+                              (disposer, this));
+            this->priv_size_traits().decrement();
          }
       }
    }
@@ -762,18 +1060,19 @@
    //! <b>Complexity</b>: Average case O(this->count(value)).
    //!   Worst case O(this->size()).
    //! 
-   //! <b>Throws</b>: If the internal hasher or the equality functor throws. Basic guarantee.
+   //! <b>Throws</b>: If the internal hasher or the equality functor throws.
+   //!   Basic guarantee.
    //! 
    //! <b>Note</b>: Invalidates the iterators (but not the references)
    //!    to the erased elements. No destructors are called.
    template<class Disposer>
    size_type erase_and_dispose(const_reference value, Disposer disposer)
-   {  return erase_and_dispose(value, priv_hasher(), priv_equal(), disposer);   }
+   {  return this->erase_and_dispose(value, priv_hasher(), priv_equal(), disposer);   }
 
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
    //!
    //! <b>Effects</b>: Erases all the elements with the given key.
-   //!   according to the comparison functor "equal".
+   //!   according to the comparison functor "equal_func".
    //!   Disposer::operator()(pointer) is called for the removed elements.
    //!
    //! <b>Returns</b>: The number of erased elements.
@@ -781,28 +1080,30 @@
    //! <b>Complexity</b>: Average case O(this->count(value)).
    //!   Worst case O(this->size()).
    //! 
-   //! <b>Throws</b>: If hasher or key_value_equal throw. Basic guarantee.
+   //! <b>Throws</b>: If hash_func or equal_func throw. Basic guarantee.
    //! 
    //! <b>Note</b>: Invalidates the iterators
    //!    to the erased elements.
    template<class KeyType, class KeyHasher, class KeyValueEqual, class Disposer>
-   size_type erase_and_dispose(const KeyType& key, KeyHasher hasher
-                  ,KeyValueEqual equal, Disposer disposer)
+   size_type erase_and_dispose(const KeyType& key, KeyHasher hash_func
+                              ,KeyValueEqual equal_func, Disposer disposer)
    {
       size_type count(0);
 
-      if(ConstantTimeSize && this->empty()){
+      if(constant_time_size && this->empty()){
          return 0;
       }
 
-      bucket_type &b = this->priv_buckets()[hasher(key) % this->priv_buckets_len()];
-      local_iterator it    = b.begin();
-      local_iterator prev  = b.before_begin();
+      bucket_type &b = this->priv_buckets()[from_hash_to_bucket(hash_func(key))];
+      siterator it    = b.begin();
+      siterator prev  = b.before_begin();
 
       bool found = false;
       //Find equal value
       while(it != b.end()){
-         if(equal(key, *it)){
+         const value_type &v = 
+            *this->get_real_value_traits().to_value_ptr(it.pointed_node());
+         if(equal_func(key, v)){
             found = true;
             break;
          }
@@ -814,9 +1115,12 @@
          return 0;
 
       //If found erase all equal values
-      for(local_iterator end = b.end(); it != end && equal(key, *it); ++count){
-         it = b.erase_after_and_dispose(prev, disposer);
-         size_traits::decrement();
+      for(siterator end = b.end(); it != end && 
+           equal_func(key, *this->get_real_value_traits().to_value_ptr(it.pointed_node()))
+         ; ++count){
+         it = b.erase_after_and_dispose
+            (prev, detail::node_disposer<Disposer, hashtable_impl>(disposer, this));
+         this->priv_size_traits().decrement();
       }
       return count;
    }
@@ -832,10 +1136,8 @@
    //!    to the erased elements. No destructors are called.
    void clear()
    {
-      if(safemode_or_autounlink){
-         priv_clear_buckets();
-      }
-      size_traits::set_size(size_type(0));
+      priv_clear_buckets();
+      this->priv_size_traits().set_size(size_type(0));
    }
 
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
@@ -852,13 +1154,14 @@
    template<class Disposer>
    void clear_and_dispose(Disposer disposer)
    {
-      if(!ConstantTimeSize || !this->empty()){
+      if(!constant_time_size || !this->empty()){
          size_type num_buckets = this->bucket_count();
          bucket_ptr b = this->priv_buckets();
          for(; num_buckets--; ++b){
-            b->clear_and_dispose(disposer);
+            b->clear_and_dispose
+               (detail::node_disposer<Disposer, hashtable_impl>(disposer, this));
          }
-         size_traits::set_size(size_type(0));
+         this->priv_size_traits().set_size(size_type(0));
       }
    }
 
@@ -870,24 +1173,24 @@
    size_type count(const_reference value) const
    {  return this->count(value, this->priv_hasher(), this->priv_equal());  }
 
-   //! <b>Requires</b>: "hasher" must be a hash function that induces 
+   //! <b>Requires</b>: "hash_func" must be a hash function that induces 
    //!   the same hash values as the stored hasher. The difference is that
-   //!   "hasher" hashes the given key instead of the value_type.
+   //!   "hash_func" hashes the given key instead of the value_type.
    //!
-   //!   "key_value_equal" must be a equality function that induces 
+   //!   "equal_func" must be a equality function that induces 
    //!   the same equality as key_equal. The difference is that
-   //!   "key_value_equal" compares an arbitrary key with the contained values.
+   //!   "equal_func" compares an arbitrary key with the contained values.
    //!
    //! <b>Effects</b>: Returns the number of contained elements with the given key
    //!
    //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
    //! 
-   //! <b>Throws</b>: If hasher or equal throw.
+   //! <b>Throws</b>: If hash_func or equal throw.
    template<class KeyType, class KeyHasher, class KeyValueEqual>
-   size_type count(const KeyType &key, const KeyHasher &hasher, const KeyValueEqual &equal) const
+   size_type count(const KeyType &key, const KeyHasher &hash_func, const KeyValueEqual &equal_func) const
    {
       size_type bucket_n1, bucket_n2, count;
-      priv_equal_range(key, hasher, equal, bucket_n1, bucket_n2, count);
+      this->priv_equal_range(key, hash_func, equal_func, bucket_n1, bucket_n2, count);
       return count;
    }
 
@@ -898,34 +1201,33 @@
    //! 
    //! <b>Throws</b>: If the internal hasher or the equality functor throws.
    iterator find(const_reference value)
-   {  return find(value, this->priv_hasher(), this->priv_equal());   }
+   {  return this->find(value, this->priv_hasher(), this->priv_equal());   }
 
-   //! <b>Requires</b>: "hasher" must be a hash function that induces 
+   //! <b>Requires</b>: "hash_func" must be a hash function that induces 
    //!   the same hash values as the stored hasher. The difference is that
-   //!   "hasher" hashes the given key instead of the value_type.
+   //!   "hash_func" hashes the given key instead of the value_type.
    //!
-   //!   "key_value_equal" must be a equality function that induces 
+   //!   "equal_func" must be a equality function that induces 
    //!   the same equality as key_equal. The difference is that
-   //!   "key_value_equal" compares an arbitrary key with the contained values.
+   //!   "equal_func" compares an arbitrary key with the contained values.
    //!
    //! <b>Effects</b>: Finds an iterator to the first element whose key is 
-   //!   "key" according to the given hasher and equality functor or end() if
+   //!   "key" according to the given hash and equality functor or end() if
    //!   that element does not exist.
    //!
    //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
    //! 
-   //! <b>Throws</b>: If hasher or equal throw.
+   //! <b>Throws</b>: If hash_func or equal_func throw.
    //!
    //! <b>Note</b>: This function is used when constructing a value_type
    //!   is expensive and the value_type can be compared with a cheaper
    //!   key type. Usually this key is part of the value_type.
    template<class KeyType, class KeyHasher, class KeyValueEqual>
-   iterator find(const KeyType &key, KeyHasher hasher, KeyValueEqual equal)
+   iterator find(const KeyType &key, KeyHasher hash_func, KeyValueEqual equal_func)
    {
       size_type bucket_n, hash;
-      local_iterator local_it = priv_find(key, hasher, equal, bucket_n, hash);
-      return iterator( local_it
-                      , const_bucket_info_ptr(&this->priv_bucket_info()));
+      siterator local_it = this->priv_find(key, hash_func, equal_func, bucket_n, hash);
+      return iterator(local_it, this);
    }
 
    //! <b>Effects</b>: Finds a const_iterator to the first element whose key is 
@@ -935,15 +1237,15 @@
    //! 
    //! <b>Throws</b>: If the internal hasher or the equality functor throws.
    const_iterator find(const_reference value) const
-   {  return find(value, this->priv_hasher(), this->priv_equal());   }
+   {  return this->find(value, this->priv_hasher(), this->priv_equal());   }
 
-   //! <b>Requires</b>: "hasher" must be a hash function that induces 
+   //! <b>Requires</b>: "hash_func" must be a hash function that induces 
    //!   the same hash values as the stored hasher. The difference is that
-   //!   "hasher" hashes the given key instead of the value_type.
+   //!   "hash_func" hashes the given key instead of the value_type.
    //!
-   //!   "key_value_equal" must be a equality function that induces 
+   //!   "equal_func" must be a equality function that induces 
    //!   the same equality as key_equal. The difference is that
-   //!   "key_value_equal" compares an arbitrary key with the contained values.
+   //!   "equal_func" compares an arbitrary key with the contained values.
    //!
    //! <b>Effects</b>: Finds an iterator to the first element whose key is 
    //!   "key" according to the given hasher and equality functor or end() if
@@ -951,19 +1253,18 @@
    //! 
    //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
    //! 
-   //! <b>Throws</b>: If hasher or equal throw.
+   //! <b>Throws</b>: If hash_func or equal_func throw.
    //!
    //! <b>Note</b>: This function is used when constructing a value_type
    //!   is expensive and the value_type can be compared with a cheaper
    //!   key type. Usually this key is part of the value_type.
    template<class KeyType, class KeyHasher, class KeyValueEqual>
    const_iterator find
-      (const KeyType &key, KeyHasher hasher, KeyValueEqual equal) const
+      (const KeyType &key, KeyHasher hash_func, KeyValueEqual equal_func) const
    {
       size_type bucket_n, hash;
-      local_iterator local_it = priv_find(key, hasher, equal, bucket_n, hash);
-      return const_iterator( local_it
-                           , const_bucket_info_ptr(&this->priv_bucket_info()));
+      siterator sit = this->priv_find(key, hash_func, equal_func, bucket_n, hash);
+      return const_iterator(sit, this);
    }
 
    //! <b>Effects</b>: Returns a range containing all elements with values equivalent
@@ -976,36 +1277,35 @@
    std::pair<iterator,iterator> equal_range(const_reference value)
    {  return this->equal_range(value, this->priv_hasher(), this->priv_equal());  }
 
-   //! <b>Requires</b>: "hasher" must be a hash function that induces 
+   //! <b>Requires</b>: "hash_func" must be a hash function that induces 
    //!   the same hash values as the stored hasher. The difference is that
-   //!   "hasher" hashes the given key instead of the value_type.
+   //!   "hash_func" hashes the given key instead of the value_type.
    //!
-   //!   "key_value_equal" must be a equality function that induces 
+   //!   "equal_func" must be a equality function that induces 
    //!   the same equality as key_equal. The difference is that
-   //!   "key_value_equal" compares an arbitrary key with the contained values.
+   //!   "equal_func" compares an arbitrary key with the contained values.
    //!
    //! <b>Effects</b>: Returns a range containing all elements with equivalent
    //!   keys. Returns std::make_pair(this->end(), this->end()) if no such 
    //!   elements exist.
    //! 
-   //! <b>Complexity</b>: Average case O(this->count(key, hasher, equal)). Worst case O(this->size()).
+   //! <b>Complexity</b>: Average case O(this->count(key, hash_func, equal_func)).
+   //!   Worst case O(this->size()).
    //! 
-   //! <b>Throws</b>: If hasher or the equal throw.
+   //! <b>Throws</b>: If hash_func or the equal_func throw.
    //!
    //! <b>Note</b>: This function is used when constructing a value_type
    //!   is expensive and the value_type can be compared with a cheaper
    //!   key type. Usually this key is part of the value_type.
    template<class KeyType, class KeyHasher, class KeyValueEqual>
    std::pair<iterator,iterator> equal_range
-      (const KeyType &key, KeyHasher hasher, KeyValueEqual equal)
+      (const KeyType &key, KeyHasher hash_func, KeyValueEqual equal_func)
    {
       size_type bucket_n1, bucket_n2, count;
-      std::pair<local_iterator, local_iterator> ret
-         = priv_equal_range(key, hasher, equal, bucket_n1, bucket_n2, count);
-      const_bucket_info_ptr info_ptr (&this->priv_bucket_info());
+      std::pair<siterator, siterator> ret = this->priv_equal_range
+         (key, hash_func, equal_func, bucket_n1, bucket_n2, count);
       return std::pair<iterator, iterator>
-         (  iterator( ret.first, info_ptr)
-         ,  iterator( ret.second, info_ptr) );
+         (iterator(ret.first, this), iterator(ret.second, this));
    }
 
    //! <b>Effects</b>: Returns a range containing all elements with values equivalent
@@ -1019,36 +1319,35 @@
       equal_range(const_reference value) const
    {  return this->equal_range(value, this->priv_hasher(), this->priv_equal());  }
 
-   //! <b>Requires</b>: "hasher" must be a hash function that induces 
+   //! <b>Requires</b>: "hash_func" must be a hash function that induces 
    //!   the same hash values as the stored hasher. The difference is that
-   //!   "hasher" hashes the given key instead of the value_type.
+   //!   "hash_func" hashes the given key instead of the value_type.
    //!
-   //!   "key_value_equal" must be a equality function that induces 
+   //!   "equal_func" must be a equality function that induces 
    //!   the same equality as key_equal. The difference is that
-   //!   "key_value_equal" compares an arbitrary key with the contained values.
+   //!   "equal_func" compares an arbitrary key with the contained values.
    //!
    //! <b>Effects</b>: Returns a range containing all elements with equivalent
    //!   keys. Returns std::make_pair(this->end(), this->end()) if no such 
    //!   elements exist.
    //! 
-   //! <b>Complexity</b>: Average case O(this->count(key, hasher, equal)). Worst case O(this->size()).
+   //! <b>Complexity</b>: Average case O(this->count(key, hash_func, equal_func)).
+   //!   Worst case O(this->size()).
    //! 
-   //! <b>Throws</b>: If the hasher or equal throw.
+   //! <b>Throws</b>: If the hasher or equal_func throw.
    //!
    //! <b>Note</b>: This function is used when constructing a value_type
    //!   is expensive and the value_type can be compared with a cheaper
    //!   key type. Usually this key is part of the value_type.
    template<class KeyType, class KeyHasher, class KeyValueEqual>
    std::pair<const_iterator,const_iterator> equal_range
-      (const KeyType &key, KeyHasher hasher, KeyValueEqual equal) const
+      (const KeyType &key, KeyHasher hash_func, KeyValueEqual equal_func) const
    {
       size_type bucket_n1, bucket_n2, count;
-      std::pair<local_iterator, local_iterator> ret
-         = priv_equal_range(key, hasher, equal, bucket_n1, bucket_n2, count);
-      const_bucket_info_ptr info_ptr (&this->priv_bucket_info());
+      std::pair<siterator, siterator> ret =
+         this->priv_equal_range(key, hash_func, equal_func, bucket_n1, bucket_n2, count);
       return std::pair<const_iterator, const_iterator>
-         ( const_iterator( ret.first, info_ptr)
-         , const_iterator( ret.second, info_ptr) );
+         (const_iterator(ret.first, this), const_iterator(ret.second, this));
    }
 
    //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of
@@ -1062,8 +1361,7 @@
    //! <b>Throws</b>: If the internal hash function throws.
    iterator iterator_to(reference value)
    {
-      return iterator( bucket_type::iterator_to(value)
-                     , const_bucket_info_ptr(&this->priv_bucket_info()));
+      return iterator(bucket_type::s_iterator_to(from_value_to_node(value)), this);
    }
 
    //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of
@@ -1077,10 +1375,12 @@
    //! <b>Throws</b>: If the internal hash function throws.
    const_iterator iterator_to(const_reference value) const
    {
-      return const_iterator( bucket_type::iterator_to(const_cast<reference>(value))
-                           , const_bucket_info_ptr(&this->priv_bucket_info()));
+      return const_iterator(bucket_type::s_iterator_to(from_value_to_node(const_cast<reference>(value))), this);
    }
 
+
+
+
    //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of
    //!   appropriate type. Otherwise the behavior is undefined.
    //! 
@@ -1090,8 +1390,15 @@
    //! <b>Complexity</b>: Constant.
    //! 
    //! <b>Throws</b>: Nothing.
-   static local_iterator local_iterator_to(reference value)
-   {  return bucket_type::iterator_to(value);  }
+   //! 
+   //! <b>Note</b>: This static function is available only if the <i>value traits</i>
+   //!   is stateless.
+   static local_iterator s_local_iterator_to(reference value)
+   {
+      BOOST_STATIC_ASSERT((!stateful_value_traits));
+      siterator sit = bucket_type::s_iterator_to(((hashtable_impl*)0)->from_value_to_node(value));
+      return local_iterator(sit, (hashtable_impl*)0);  
+   }
 
    //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of
    //!   appropriate type. Otherwise the behavior is undefined.
@@ -1102,8 +1409,46 @@
    //! <b>Complexity</b>: Constant.
    //! 
    //! <b>Throws</b>: Nothing.
-   static const_local_iterator local_iterator_to(const_reference value)
-   {  return bucket_type::iterator_to(value);  }
+   //! 
+   //! <b>Note</b>: This static function is available only if the <i>value traits</i>
+   //!   is stateless.
+   static const_local_iterator s_local_iterator_to(const_reference value)
+   {
+      BOOST_STATIC_ASSERT((!stateful_value_traits));
+      siterator sit = bucket_type::s_iterator_to(((hashtable_impl*)0)->from_value_to_node(const_cast<value_type&>(value)));
+      return const_local_iterator(sit, (hashtable_impl*)0);  
+   }
+
+   //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of
+   //!   appropriate type. Otherwise the behavior is undefined.
+   //! 
+   //! <b>Effects</b>: Returns: a valid local_iterator belonging to the unordered_set
+   //!   that points to the value
+   //! 
+   //! <b>Complexity</b>: Constant.
+   //! 
+   //! <b>Throws</b>: Nothing.
+   local_iterator local_iterator_to(reference value)
+   {
+      siterator sit = bucket_type::s_iterator_to(this->from_value_to_node(value));
+      return local_iterator(sit, this);  
+   }
+
+   //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of
+   //!   appropriate type. Otherwise the behavior is undefined.
+   //! 
+   //! <b>Effects</b>: Returns: a valid const_local_iterator belonging to
+   //!   the unordered_set that points to the value
+   //! 
+   //! <b>Complexity</b>: Constant.
+   //! 
+   //! <b>Throws</b>: Nothing.
+   const_local_iterator local_iterator_to(const_reference value) const
+   {
+      siterator sit = bucket_type::s_iterator_to
+         (const_cast<node &>(this->from_value_to_node(value)));
+      return const_local_iterator(sit, this);  
+   }
 
    //! <b>Effects</b>: Returns the number of buckets passed in the constructor
    //!   or the last rehash function.
@@ -1135,21 +1480,21 @@
    size_type bucket(const key_type& k)  const
    {  return this->bucket(k, this->priv_hasher());   }
 
-   //! <b>Requires</b>: "hasher" must be a hash function that induces 
+   //! <b>Requires</b>: "hash_func" must be a hash function that induces 
    //!   the same hash values as the stored hasher. The difference is that
-   //!   "hasher" hashes the given key instead of the value_type.
+   //!   "hash_func" hashes the given key instead of the value_type.
    //!
    //! <b>Effects</b>: Returns the index of the bucket in which elements
    //!   with keys equivalent to k would be found, if any such element existed.
    //! 
    //! <b>Complexity</b>: Constant.
    //! 
-   //! <b>Throws</b>: If hasher throws.
+   //! <b>Throws</b>: If hash_func throws.
    //!
    //! <b>Note</b>: the return value is in the range [0, this->bucket_count()).
    template<class KeyType, class KeyHasher>
-   size_type bucket(const KeyType& k, const KeyHasher &hasher)  const
-   {  return hasher(k) % this->priv_buckets_len();   }
+   size_type bucket(const KeyType& k, const KeyHasher &hash_func)  const
+   {  return from_hash_to_bucket(hash_func(k));   }
 
    //! <b>Effects</b>: Returns the bucket array pointer passed in the constructor
    //!   or the last rehash function.
@@ -1172,7 +1517,7 @@
    //! <b>Note</b>:  [this->begin(n), this->end(n)) is a valid range
    //!   containing all of the elements in the nth bucket. 
    local_iterator begin(size_type n)
-   {  return this->priv_buckets()[n].begin();  }
+   {  return local_iterator(this->priv_buckets()[n].begin(), this);  }
 
    //! <b>Requires</b>: n is in the range [0, this->bucket_count()).
    //!
@@ -1200,7 +1545,10 @@
    //! <b>Note</b>:  [this->begin(n), this->end(n)) is a valid range
    //!   containing all of the elements in the nth bucket. 
    const_local_iterator cbegin(size_type n) const
-   {  return const_cast<const bucket_type&>(this->priv_buckets()[n]).begin();  }
+   {
+      siterator sit = const_cast<bucket_type&>(this->priv_buckets()[n]).begin();
+      return const_local_iterator(sit, this);
+   }
 
    //! <b>Requires</b>: n is in the range [0, this->bucket_count()).
    //!
@@ -1214,7 +1562,7 @@
    //! <b>Note</b>:  [this->begin(n), this->end(n)) is a valid range
    //!   containing all of the elements in the nth bucket. 
    local_iterator end(size_type n)
-   {  return this->priv_buckets()[n].end();  }
+   {  return local_iterator(this->priv_buckets()[n].end(), this);  }
 
    //! <b>Requires</b>: n is in the range [0, this->bucket_count()).
    //!
@@ -1242,7 +1590,7 @@
    //! <b>Note</b>:  [this->begin(n), this->end(n)) is a valid range
    //!   containing all of the elements in the nth bucket. 
    const_local_iterator cend(size_type n) const
-   {  return const_cast<const bucket_type&>(this->priv_buckets()[n]).end();  }
+   {  return const_local_iterator(const_cast<bucket_type&>(this->priv_buckets()[n]).end(), this);  }
 
    //! <b>Requires</b>: new_buckets must be a pointer to a new bucket array
    //!   or the same as the old bucket array. new_size is the length of the
@@ -1255,19 +1603,23 @@
    //! <b>Complexity</b>: Average case linear in this->size(), worst case quadratic.
    //! 
    //! <b>Throws</b>: If the hasher functor throws. Basic guarantee.
-   void rehash(bucket_ptr new_buckets, size_type new_buckets_len)
+   void rehash(const bucket_traits &new_bucket_traits)
    {
+      bucket_ptr new_buckets     = new_bucket_traits.bucket_begin();
+      size_type  new_buckets_len = new_bucket_traits.bucket_count();
       bucket_ptr old_buckets     = this->priv_buckets();
       size_type  old_buckets_len = this->priv_buckets_len();
-      #ifndef BOOST_INTRUSIVE_DISABLE_EXCEPTION_HANDLING
-      BOOST_TRY{
-      #endif
+      //Check power of two bucket array if the option is activated      
+      BOOST_INTRUSIVE_INVARIANT_ASSERT
+      (!power_2_buckets || (0 == (new_buckets_len & (new_buckets_len-1u))));
+
+      BOOST_INTRUSIVE_TRY{
          size_type n = 0;
          const bool same_buffer = old_buckets == new_buckets;
          //If the new bucket length is a common factor
          //of the old one we can avoid hash calculations.
          const bool fast_shrink = (old_buckets_len > new_buckets_len) && 
-                                  (old_buckets_len % new_buckets_len) == 0;
+            (power_2_buckets ||(old_buckets_len % new_buckets_len) == 0);
          //If we are shrinking the same bucket array and it's
          //is a fast shrink, just rehash the last nodes
          if(same_buffer && fast_shrink){
@@ -1279,11 +1631,15 @@
             bucket_type &old_bucket = old_buckets[n];
 
             if(!fast_shrink){
-               local_iterator before_i(old_bucket.before_begin());
-               local_iterator end(old_bucket.end());
-               local_iterator i(old_bucket.begin());
+               siterator before_i(old_bucket.before_begin());
+               siterator end(old_bucket.end());
+               siterator i(old_bucket.begin());
                for(;i != end; ++i){
-                  const size_type new_n = (this->priv_hasher()(*i) % new_buckets_len);
+                  const value_type &v = *this->get_real_value_traits().to_value_ptr(i.pointed_node());
+                  const std::size_t hash_value = this->priv_hasher()(v);
+                  const size_type new_n = (power_2_buckets)
+                     ?  ( hash_value & (new_buckets_len-1))
+                     :  ( hash_value % new_buckets_len);
                   //If this is a buffer expansion don't move if it's not necessary
                   if(same_buffer && new_n == n){
                      ++before_i;
@@ -1296,26 +1652,33 @@
                }
             }
             else{
-               const size_type new_n = n % new_buckets_len;
+               const size_type new_n = (power_2_buckets)
+                  ?  (n & (new_buckets_len-1))
+                  :  (n % new_buckets_len);
                bucket_type &new_b = new_buckets[new_n];
                new_b.splice_after(new_b.before_begin(), old_bucket);
             }
          }
 
-         this->priv_buckets()      = new_buckets;
-         this->priv_buckets_len()  = new_buckets_len;
-      #ifndef BOOST_INTRUSIVE_DISABLE_EXCEPTION_HANDLING
+         this->get_real_bucket_traits()= new_bucket_traits;
       }
-      BOOST_CATCH(...){
+      BOOST_INTRUSIVE_CATCH(...){
          for(size_type n = 0; n < new_buckets_len; ++n){
-            new_buckets[n].clear();
-            old_buckets[n].clear();
+            if(safemode_or_autounlink){
+               new_buckets[n].clear_and_dispose
+                  (detail::init_disposer<node_algorithms>());
+               old_buckets[n].clear_and_dispose
+                  (detail::init_disposer<node_algorithms>());
+            }
+            else{
+               new_buckets[n].clear();
+               old_buckets[n].clear();
+            }
          }
-         size_traits::set_size(size_type(0));
-         BOOST_RETHROW;
+         this->priv_size_traits().set_size(size_type(0));
+         BOOST_INTRUSIVE_RETHROW;
       }
-      BOOST_CATCH_END
-      #endif
+      BOOST_INTRUSIVE_CATCH_END
    }
 
    //! <b>Effects</b>: Returns the nearest new bucket count optimized for
@@ -1360,10 +1723,10 @@
 
    /// @cond
    private:
-   static local_iterator invalid_local_it(const bucket_info_t &b)
-   {  return b.buckets_->end();  }
+   static siterator invalid_local_it(const real_bucket_traits &b)
+   {  return b.bucket_begin()->end();  }
 
-   local_iterator priv_begin(size_type &bucket_num) const
+   siterator priv_begin(size_type &bucket_num) const
    {
       size_type buckets_len = this->priv_buckets_len();
       for (bucket_num = 0; bucket_num < buckets_len; ++bucket_num){
@@ -1371,7 +1734,7 @@
          if(!b.empty())
             return b.begin();
       }
-      return invalid_local_it(this->priv_bucket_info());
+      return invalid_local_it(this->get_real_bucket_traits());
    }
 
    void priv_clear_buckets()
@@ -1380,41 +1743,46 @@
    static void priv_clear_buckets(bucket_ptr buckets_ptr, size_type buckets_len)
    {
       for(; buckets_len--; ++buckets_ptr){
-         buckets_ptr->clear();
+         if(safemode_or_autounlink){
+            buckets_ptr->clear_and_dispose(detail::init_disposer<node_algorithms>());
+         }
+         else{
+            buckets_ptr->clear();
+         }
       }
    }
 
    template<class KeyType, class KeyHasher, class KeyValueEqual>
-   local_iterator priv_find
-      ( const KeyType &key,  KeyHasher hasher
-      , KeyValueEqual equal, size_type &bucket_number, size_type &h) const
-   {
-      size_type b_len(this->priv_buckets_len());
-      h = hasher(key);
-      bucket_number = h % b_len;
+   siterator priv_find
+      ( const KeyType &key,  KeyHasher hash_func
+      , KeyValueEqual equal_func, size_type &bucket_number, size_type &h) const
+   {
+      bucket_number = from_hash_to_bucket((h = hash_func(key)));
 
-      if(ConstantTimeSize && this->empty()){
-         return invalid_local_it(this->priv_bucket_info());
+      if(constant_time_size && this->empty()){
+         return invalid_local_it(this->get_real_bucket_traits());
       }
       
       bucket_type &b = this->priv_buckets()[bucket_number];
-      local_iterator it = b.begin();
+      siterator it = b.begin();
 
       while(it != b.end()){
-         if(equal(key, *it)){
+         const value_type &v = 
+            *this->get_real_value_traits().to_value_ptr(it.pointed_node());
+         if(equal_func(key, v)){
             return it;
          }
          ++it;
       }
 
-      return invalid_local_it(this->priv_bucket_info());
+      return invalid_local_it(this->get_real_bucket_traits());
    }
 
    template<class KeyType, class KeyHasher, class KeyValueEqual>
-   std::pair<local_iterator, local_iterator> priv_equal_range
+   std::pair<siterator, siterator> priv_equal_range
       ( const KeyType &key
-      , KeyHasher hasher
-      , KeyValueEqual equal
+      , KeyHasher hash_func
+      , KeyValueEqual equal_func
       , size_type &bucket_number_first
       , size_type &bucket_number_second
       , size_type &count) const
@@ -1422,9 +1790,9 @@
       size_type h;
       count = 0;
       //Let's see if the element is present
-      std::pair<local_iterator, local_iterator> to_return
-         ( priv_find(key, hasher, equal, bucket_number_first, h)
-         , invalid_local_it(this->priv_bucket_info()));
+      std::pair<siterator, siterator> to_return
+         ( priv_find(key, hash_func, equal_func, bucket_number_first, h)
+         , invalid_local_it(this->get_real_bucket_traits()));
       if(to_return.first == to_return.second){
          bucket_number_second = bucket_number_first;
          return to_return;
@@ -1433,11 +1801,13 @@
       //If it's present, find the first that it's not equal in
       //the same bucket
       bucket_type &b = this->priv_buckets()[bucket_number_first];
-      local_iterator it = to_return.first;
+      siterator it = to_return.first;
       ++it;
 
       while(it != b.end()){
-         if(!equal(key, *it)){
+         const value_type &v = 
+            *this->get_real_value_traits().to_value_ptr(it.pointed_node());
+         if(!equal_func(key, v)){
             to_return.second = it;
             bucket_number_second = bucket_number_first;
             return to_return;
@@ -1458,12 +1828,116 @@
       }
 
       //Otherwise, return the end node
-      to_return.second = invalid_local_it(this->priv_bucket_info());
+      to_return.second = invalid_local_it(this->get_real_bucket_traits());
       return to_return;
    }
    /// @endcond
 };
 
+/// @cond
+template<class T, class O1 = none, class O2 = none
+                , class O3 = none, class O4 = none
+                , class O5 = none, class O6 = none
+                , class O7 = none
+                >
+struct make_hashtable_opt
+{
+   typedef typename pack_options
+      < uset_defaults<T>, O1, O2, O3, O4, O5, O6, O7>::type packed_options;
+
+   //Real value traits must be calculated from options
+   typedef typename detail::get_value_traits
+      <T, typename packed_options::value_traits>::type   value_traits;
+   /// @cond
+   static const bool external_value_traits =
+      detail::external_value_traits_is_true<value_traits>::value;
+   typedef typename detail::eval_if_c
+      < external_value_traits
+      , detail::eval_value_traits<value_traits>
+      , detail::identity<value_traits>
+      >::type                                            real_value_traits;
+   typedef typename packed_options::bucket_traits        specified_bucket_traits;   
+   /// @endcond
+   //Real bucket traits must be calculated from options and calculated valute_traits
+   typedef typename get_slist_impl
+      <typename real_value_traits::node_traits>::type    slist_impl;
+   typedef typename
+      detail::if_c< detail::is_same
+                     < specified_bucket_traits
+                     , default_bucket_traits
+                     >::value
+                  , detail::bucket_traits_impl<slist_impl>
+                  , specified_bucket_traits
+                  >::type                                real_bucket_traits;
+
+   typedef usetopt
+      < value_traits
+      , typename packed_options::hash
+      , typename packed_options::equal
+      , typename packed_options::size_type
+      , packed_options::constant_time_size
+      , real_bucket_traits
+      , packed_options::power_2_buckets
+      > type;
+};
+/// @endcond
+
+//! Helper metafunction to define a \c hashtable that yields to the same type when the
+//! same options (either explicitly or implicitly) are used.
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+template<class T, class ...Options>
+#else
+template<class T, class O1 = none, class O2 = none
+                , class O3 = none, class O4 = none
+                , class O5 = none, class O6 = none
+                , class O7 = none
+                >
+#endif
+struct make_hashtable
+{
+   /// @cond
+   typedef hashtable_impl
+      <  typename make_hashtable_opt
+            <T, O1, O2, O3, O4, O5, O6, O7>::type
+      > implementation_defined;
+
+   /// @endcond
+   typedef implementation_defined type;
+};
+
+#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+template<class T, class O1, class O2, class O3, class O4, class O5, class O6, class O7>
+class hashtable
+   :  public make_hashtable<T, O1, O2, O3, O4, O5, O6, O7>::type
+{
+   typedef typename make_hashtable
+      <T, O1, O2, O3, O4, O5, O6, O7>::type   Base;
+
+   public:
+   typedef typename Base::value_traits       value_traits;
+   typedef typename Base::real_value_traits  real_value_traits;
+   typedef typename Base::iterator           iterator;
+   typedef typename Base::const_iterator     const_iterator;
+   typedef typename Base::bucket_ptr         bucket_ptr;
+   typedef typename Base::size_type          size_type;
+   typedef typename Base::hasher             hasher;
+   typedef typename Base::bucket_traits      bucket_traits;
+   typedef typename Base::key_equal          key_equal;
+
+   //Assert if passed value traits are compatible with the type
+   BOOST_STATIC_ASSERT((detail::is_same<typename real_value_traits::value_type, T>::value));
+
+   hashtable ( const bucket_traits &b_traits
+             , const hasher & hash_func = hasher()
+             , const key_equal &equal_func = key_equal()
+             , const value_traits &v_traits = value_traits())
+      :  Base(b_traits, hash_func, equal_func, v_traits)
+   {}
+};
+
+#endif
+
+
 } //namespace intrusive 
 } //namespace boost 
 
Modified: trunk/boost/intrusive/intrusive_fwd.hpp
==============================================================================
--- trunk/boost/intrusive/intrusive_fwd.hpp	(original)
+++ trunk/boost/intrusive/intrusive_fwd.hpp	2007-09-26 11:26:35 EDT (Wed, 26 Sep 2007)
@@ -14,8 +14,9 @@
 #define BOOST_INTRUSIVE_FWD_HPP
 
 #include <cstddef>
-#include <boost/intrusive/tag.hpp>
-#include <boost/intrusive/linking_policy.hpp>
+#include <boost/intrusive/link_mode.hpp>
+
+/// @cond
 
 //std predeclarations
 namespace std{
@@ -36,6 +37,14 @@
 
 namespace intrusive {
 
+struct none;
+
+}  //namespace intrusive{
+}  //namespace boost{
+
+namespace boost {
+namespace intrusive {
+
 ////////////////////////////
 //     Node algorithms
 ////////////////////////////
@@ -55,104 +64,148 @@
 ////////////////////////////
 
 //slist
-template < class ValueTraits
-         , bool ConstantTimeSize = true
-         , class SizeType        = std::size_t>
+template
+   < class T
+   , class O1  = none
+   , class O2  = none
+   , class O3  = none
+   >
 class slist;
 
-template< class Tag              = tag
-        , linking_policy Policy  = safe_link
-        , class VoidPointer      = void *
-        >
+template
+   < class O1  = none
+   , class O2  = none
+   , class O3  = none
+   >
 class slist_base_hook;
 
-template< linking_policy Policy  = safe_link
-        , class VoidPointer      = void *>
+template
+   < class O1  = none
+   , class O2  = none
+   , class O3  = none
+   >
 class slist_member_hook;
 
 //list
-template< class ValueTraits
-        , bool  ConstantTimeSize = true
-        , class SizeType         = std::size_t>
+template
+   < class T
+   , class O1  = none
+   , class O2  = none
+   , class O3  = none
+   >
 class list;
 
-template< class Tag              = tag
-        , linking_policy Policy  = safe_link
-        , class VoidPointer      = void *
-        >
+template
+   < class O1  = none
+   , class O2  = none
+   , class O3  = none
+   >
 class list_base_hook;
 
-template< linking_policy Policy  = safe_link
-        , class VoidPointer      = void *>
+template
+   < class O1  = none
+   , class O2  = none
+   , class O3  = none
+   >
 class list_member_hook;
 
+//rbtree/set/multiset
+template
+   < class T
+   , class O1  = none
+   , class O2  = none
+   , class O3  = none
+   , class O4  = none
+   >
+class rbtree;
+
+template
+   < class T
+   , class O1  = none
+   , class O2  = none
+   , class O3  = none
+   , class O4  = none
+   >
+class set;
+
+template
+   < class T
+   , class O1  = none
+   , class O2  = none
+   , class O3  = none
+   , class O4  = none
+   >
+class multiset;
+
+template
+   < class O1  = none
+   , class O2  = none
+   , class O3  = none
+   >
+class set_base_hook;
+
+template
+   < class O1  = none
+   , class O2  = none
+   , class O3  = none
+   >
+class set_member_hook;
+
 //hash/unordered
-template< class ValueTraits
-        , class Hash             = boost::hash<typename ValueTraits::value_type>
-        , class Equal            = std::equal_to<typename ValueTraits::value_type>
-        , bool  ConstantTimeSize = true
-        , class SizeType         = std::size_t
-        >
+//rbtree/set/multiset
+template
+   < class T
+   , class O1  = none
+   , class O2  = none
+   , class O3  = none
+   , class O4  = none
+   , class O5  = none
+   , class O6  = none
+   , class O7  = none
+   >
 class hashtable;
 
-template< class ValueTraits
-        , class Hash             = boost::hash<typename ValueTraits::value_type>
-        , class Equal            = std::equal_to<typename ValueTraits::value_type>
-        , bool  ConstantTimeSize = true
-        , class SizeType         = std::size_t
-        >
+template
+   < class T
+   , class O1  = none
+   , class O2  = none
+   , class O3  = none
+   , class O4  = none
+   , class O5  = none
+   , class O6  = none
+   , class O7  = none
+   >
 class unordered_set;
 
-template< class ValueTraits
-        , class Hash             = boost::hash<typename ValueTraits::value_type>
-        , class Equal            = std::equal_to<typename ValueTraits::value_type>
-        , bool  ConstantTimeSize = true
-        , class SizeType         = std::size_t
-        >
+template
+   < class T
+   , class O1  = none
+   , class O2  = none
+   , class O3  = none
+   , class O4  = none
+   , class O5  = none
+   , class O6  = none
+   , class O7  = none
+   >
 class unordered_multiset;
 
-template< class Tag              = tag
-        , linking_policy Policy  = safe_link
-        , class VoidPointer      = void *
-        >
+template
+   < class O1  = none
+   , class O2  = none
+   , class O3  = none
+   >
 class unordered_set_base_hook;
 
-template< linking_policy Policy  = safe_link
-        , class VoidPointer      = void *>
+template
+   < class O1  = none
+   , class O2  = none
+   , class O3  = none
+   >
 class unordered_set_member_hook;
 
-
-//rbtree/set
-template < class ValueTraits
-         , class Compare         = std::less<typename ValueTraits::value_type>
-         , bool ConstantTimeSize = true
-         , class SizeType        = std::size_t
-         >
-class rbtree;
-
-template < class ValueTraits
-         , class Compare         = std::less<typename ValueTraits::value_type>
-         , bool ConstantTimeSize = true
-         , class SizeType        = std::size_t>
-class set;
-
-template < class ValueTraits
-         , class Compare         = std::less<typename ValueTraits::value_type>
-         , bool ConstantTimeSize = true
-         , class SizeType        = std::size_t>
-class multiset;
-
-template< class Tag              = tag
-        , linking_policy Policy  = safe_link
-        , class VoidPointer      = void *
-        >
-class set_base_hook;
-
-template< linking_policy Policy  = safe_link
-        , class VoidPointer      = void *>
-class set_member_hook;
-
 }  //namespace intrusive {
 }  //namespace boost {
 
+/// @endcond
+
 #endif   //#ifndef BOOST_INTRUSIVE_FWD_HPP
Added: trunk/boost/intrusive/link_mode.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/intrusive/link_mode.hpp	2007-09-26 11:26:35 EDT (Wed, 26 Sep 2007)
@@ -0,0 +1,46 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga  2006-2007
+//
+// Distributed under the Boost Software License, Version 1.0.
+//    (See accompanying file LICENSE_1_0.txt or copy at
+//          http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/intrusive for documentation.
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTRUSIVE_VALUE_LINK_TYPE_HPP
+#define BOOST_INTRUSIVE_VALUE_LINK_TYPE_HPP
+
+namespace boost {
+namespace intrusive {
+
+//!This enumeration defines the type of value_traits that can be defined
+//!for Boost.Intrusive containers
+enum link_mode_type{
+   //!If this linking policy is specified in a value_traits class
+   //!as the link_mode, containers
+   //!configured with such value_traits won't set the hooks
+   //!of the erased values to a default state. Containers also won't
+   //!check that the hooks of the new values are default initialized.
+   normal_link,
+
+   //!If this linking policy is specified in a value_traits class
+   //!as the link_mode, containers
+   //!configured with such value_traits will set the hooks
+   //!of the erased values to a default state. Containers also will
+   //!check that the hooks of the new values are default initialized.
+   safe_link,
+
+   //!Same as "safe_link" but the user type is an auto-unlink
+   //!type, so the containers with constant-time size features won't be
+   //!compatible with value_traits configured with this policy.
+   //!Containers also know that the a value can be silently erased from
+   //!the container without using any function provided by the containers.
+   auto_unlink
+};
+} //namespace intrusive 
+} //namespace boost 
+
+#endif //BOOST_INTRUSIVE_VALUE_LINK_TYPE_HPP
Deleted: trunk/boost/intrusive/linking_policy.hpp
==============================================================================
--- trunk/boost/intrusive/linking_policy.hpp	2007-09-26 11:26:35 EDT (Wed, 26 Sep 2007)
+++ (empty file)
@@ -1,46 +0,0 @@
-/////////////////////////////////////////////////////////////////////////////
-//
-// (C) Copyright Ion Gaztanaga  2006-2007
-//
-// Distributed under the Boost Software License, Version 1.0.
-//    (See accompanying file LICENSE_1_0.txt or copy at
-//          http://www.boost.org/LICENSE_1_0.txt)
-//
-// See http://www.boost.org/libs/intrusive for documentation.
-//
-/////////////////////////////////////////////////////////////////////////////
-
-#ifndef BOOST_INTRUSIVE_VALUE_LINKING_POLICY_HPP
-#define BOOST_INTRUSIVE_VALUE_LINKING_POLICY_HPP
-
-namespace boost {
-namespace intrusive {
-
-//!This enumeration defines the type of value_traits that can be defined
-//!for Boost.Intrusive containers
-enum linking_policy{
-   //!If this linking policy is specified in a value_traits class
-   //!as the linking_policy, containers
-   //!configured with such value_traits won't set the hooks
-   //!of the erased values to a default state. Containers also won't
-   //!check that the hooks of the new values are default initialized.
-   normal_link,
-
-   //!If this linking policy is specified in a value_traits class
-   //!as the linking_policy, containers
-   //!configured with such value_traits will set the hooks
-   //!of the erased values to a default state. Containers also will
-   //!check that the hooks of the new values are default initialized.
-   safe_link,
-
-   //!Same as "safe_link" but the user type is an auto-unlink
-   //!type, so the containers with constant-time size features won't be
-   //!compatible with value_traits configured with this policy.
-   //!Containers also know that the a value can be silently erased from
-   //!the container without using any function provided by the containers.
-   auto_unlink
-};
-} //namespace intrusive 
-} //namespace boost 
-
-#endif //BOOST_INTRUSIVE_VALUE_LINKING_POLICY_HPP
Modified: trunk/boost/intrusive/list.hpp
==============================================================================
--- trunk/boost/intrusive/list.hpp	(original)
+++ trunk/boost/intrusive/list.hpp	2007-09-26 11:26:35 EDT (Wed, 26 Sep 2007)
@@ -20,79 +20,127 @@
 #include <boost/intrusive/list_hook.hpp>
 #include <boost/intrusive/circular_list_algorithms.hpp>
 #include <boost/intrusive/detail/pointer_to_other.hpp>
-#include <boost/intrusive/linking_policy.hpp>
+#include <boost/intrusive/detail/mpl.hpp>
+#include <boost/intrusive/link_mode.hpp>
 #include <boost/static_assert.hpp>
-#ifndef BOOST_INTRUSIVE_DISABLE_EXCEPTION_HANDLING
-#include <boost/detail/no_exceptions_support.hpp>
-#endif
+#include <boost/intrusive/options.hpp>
+#include <boost/intrusive/detail/no_exceptions_support.hpp>
 #include <iterator>
 #include <algorithm>
 #include <functional>
 #include <cstddef>
-#include <iterator>
 
 namespace boost {
 namespace intrusive {
 
+/// @cond
+
+template <class T>
+struct internal_default_list_hook
+{
+   template <class U> static detail::one test(...);
+   template <class U> static detail::two test(typename U::default_list_hook* = 0);
+   static const bool value = sizeof(test<T>(0)) == sizeof(detail::two);
+};
+
+template <class T>
+struct get_default_list_hook
+{
+   typedef typename T::default_list_hook type;
+};
+
+template <class ValueTraits, class SizeType, bool ConstantTimeSize>
+struct listopt
+{
+   typedef ValueTraits  value_traits;
+   typedef SizeType     size_type;
+   static const bool constant_time_size = ConstantTimeSize;
+};
+
+template <class T>
+struct list_defaults
+   :  pack_options
+      < none
+      , base_hook
+         <  typename detail::eval_if_c
+               < internal_default_list_hook<T>::value
+               , get_default_list_hook<T>
+               , detail::identity<none>
+               >::type
+         >
+      , constant_time_size<true>
+      , size_type<std::size_t>
+      >::type
+{};
+
+/// @endcond
+
 //! The class template list is an intrusive container that mimics most of the 
 //! interface of std::list as described in the C++ standard.
 //!
-//! The template parameter ValueTraits is called "value traits". It stores
-//! information and operations about the type to be stored in the container.
+//! The template parameter \c T is the type to be managed by the container.
+//! The user can specify additional options and if no options are provided
+//! default options are used.
 //!
-//! If the user specifies ConstantTimeSize as "true", a member of type SizeType
-//! will be embedded in the class, that will keep track of the number of stored objects.
-//! This will allow constant-time O(1) size() member, instead of default O(N) size.
-template< class ValueTraits
-        , bool  ConstantTimeSize //= true
-        , class SizeType         //= std::size_t
-        >
-class list
-   :  private detail::size_holder<ConstantTimeSize, SizeType>
+//! The container supports the following options:
+//! \c base_hook<>/member_hook<>/value_traits<>,
+//! \c constant_time_size<> and \c size_type<>.
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+template<class T, class ...Options>
+#else
+template<class Config>
+#endif
+class list_impl
 {
-   /// @cond
-   private:
-   typename ValueTraits::node_traits::node root_;
-   typedef list<ValueTraits, ConstantTimeSize, SizeType>   this_type; 
-   typedef typename ValueTraits::node_traits                node_traits;
-   typedef detail::size_holder<ConstantTimeSize, SizeType>  size_traits;
-
-   //! This class is
-   //! non-copyable
-   list (const list&);
-
-   //! This class is
-   //! non-assignable
-   list &operator =(const list&);
-   /// @endcond
-
    //Public typedefs
    public:
-   typedef ValueTraits                                               value_traits;
-   typedef typename ValueTraits::value_type                          value_type;
-   typedef typename ValueTraits::pointer                             pointer;
-   typedef typename ValueTraits::const_pointer                       const_pointer;
+   typedef typename Config::value_traits                             value_traits;
+   /// @cond
+   static const bool external_value_traits =
+      detail::external_value_traits_is_true<value_traits>::value;
+   typedef typename detail::eval_if_c
+      < external_value_traits
+      , detail::eval_value_traits<value_traits>
+      , detail::identity<value_traits>
+      >::type                                                        real_value_traits;
+   /// @endcond
+   typedef typename real_value_traits::pointer                       pointer;
+   typedef typename real_value_traits::const_pointer                 const_pointer;
+   typedef typename std::iterator_traits<pointer>::value_type        value_type;
    typedef typename std::iterator_traits<pointer>::reference         reference;
    typedef typename std::iterator_traits<const_pointer>::reference   const_reference;
    typedef typename std::iterator_traits<pointer>::difference_type   difference_type;
-   typedef SizeType                                                  size_type;
-   typedef detail::list_iterator<value_type, ValueTraits>            iterator;
-   typedef detail::list_iterator<const value_type, ValueTraits>      const_iterator;
+   typedef typename Config::size_type                                size_type;
+   typedef list_iterator<list_impl, false>                           iterator;
+   typedef list_iterator<list_impl, true>                            const_iterator;
    typedef std::reverse_iterator<iterator>                           reverse_iterator;
    typedef std::reverse_iterator<const_iterator>                     const_reverse_iterator;
+   typedef typename real_value_traits::node_traits                   node_traits;
+   typedef typename node_traits::node                                node;
+   typedef typename node_traits::node_ptr                            node_ptr;
+   typedef typename node_traits::const_node_ptr                      const_node_ptr;
+   typedef circular_list_algorithms<node_traits>                     node_algorithms;
+
+   static const bool constant_time_size = Config::constant_time_size;
+   static const bool stateful_value_traits = detail::store_cont_ptr_on_it<list_impl>::value;
 
    /// @cond
+
    private:
-   typedef typename node_traits::node              node;
-   typedef typename node_traits::node_ptr          node_ptr;
-   typedef typename node_traits::const_node_ptr    const_node_ptr;
-   typedef circular_list_algorithms<node_traits>            node_algorithms;
+   typedef detail::size_holder<constant_time_size, size_type>          size_traits;
+
+   //Non-copyable and non-moveable
+   list_impl (const list_impl&);
+   list_impl &operator =(const list_impl&);
+
    enum { safemode_or_autounlink  = 
-            (int)ValueTraits::linking_policy == (int)auto_unlink   ||
-            (int)ValueTraits::linking_policy == (int)safe_link     };
+            (int)real_value_traits::link_mode == (int)auto_unlink   ||
+            (int)real_value_traits::link_mode == (int)safe_link     };
 
    //Constant-time size is incompatible with auto-unlink hooks!
-   BOOST_STATIC_ASSERT(!(ConstantTimeSize && ((int)ValueTraits::linking_policy == (int)auto_unlink)));
+   BOOST_STATIC_ASSERT(!(constant_time_size && 
+                        ((int)real_value_traits::link_mode == (int)auto_unlink)
+                      ));
 
    //Const cast emulation for smart pointers
    static node_ptr uncast(const_node_ptr ptr)
@@ -102,22 +150,64 @@
    }
 
    node_ptr get_root_node()
-   {  return node_ptr(&root_);  }
+   {  return node_ptr(&data_.root_plus_size_.root_);  }
 
    const_node_ptr get_root_node() const
-   {  return const_node_ptr(&root_);  }
+   {  return const_node_ptr(&data_.root_plus_size_.root_);  }
+
+   struct root_plus_size : public size_traits
+   {
+      node root_;
+   };
+
+   struct data_t : public value_traits
+   {
+      typedef typename list_impl::value_traits value_traits;
+      data_t(const value_traits &val_traits)
+         :  value_traits(val_traits)
+      {}
+
+      root_plus_size root_plus_size_;
+   } data_;
+
+   size_traits &priv_size_traits()
+   {  return data_.root_plus_size_;  }
+
+   const size_traits &priv_size_traits() const
+   {  return data_.root_plus_size_;  }
+
+   const real_value_traits &get_real_value_traits(detail::bool_<false>) const
+   {  return data_;  }
+
+   const real_value_traits &get_real_value_traits(detail::bool_<true>) const
+   {  return data_.get_value_traits(*this);  }
+
+   real_value_traits &get_real_value_traits(detail::bool_<false>)
+   {  return data_;  }
+
+   real_value_traits &get_real_value_traits(detail::bool_<true>)
+   {  return data_.get_value_traits(*this);  }
+
    /// @endcond
 
    public:
+
+   const real_value_traits &get_real_value_traits() const
+   {  return this->get_real_value_traits(detail::bool_<external_value_traits>());  }
+
+   real_value_traits &get_real_value_traits()
+   {  return this->get_real_value_traits(detail::bool_<external_value_traits>());  }
+
    //! <b>Effects</b>: constructs an empty list. 
    //! 
    //! <b>Complexity</b>: Constant 
    //! 
-   //! <b>Throws</b>: If value_traits::node_traits::node
+   //! <b>Throws</b>: If real_value_traits::node_traits::node
    //!   constructor throws (this does not happen with predefined Boost.Intrusive hooks).
-   list()
+   list_impl(const value_traits &v_traits = value_traits())
+      :  data_(v_traits)
    {  
-      size_traits::set_size(size_type(0));
+      this->priv_size_traits().set_size(size_type(0));
       node_algorithms::init(this->get_root_node());  
    }
 
@@ -127,12 +217,13 @@
    //! 
    //! <b>Complexity</b>: Linear in std::distance(b, e). No copy constructors are called.  
    //! 
-   //! <b>Throws</b>: If value_traits::node_traits::node
+   //! <b>Throws</b>: If real_value_traits::node_traits::node
    //!   constructor throws (this does not happen with predefined Boost.Intrusive hooks).
    template<class Iterator>
-   list(Iterator b, Iterator e)
+   list_impl(Iterator b, Iterator e, const value_traits &v_traits = value_traits())
+      :  data_(v_traits)
    {
-      size_traits::set_size(size_type(0));
+      this->priv_size_traits().set_size(size_type(0));
       node_algorithms::init(this->get_root_node());
       this->insert(this->end(), b, e);
    }
@@ -146,7 +237,7 @@
    //! 
    //! <b>Complexity</b>: Linear to the number of elements in the list, if 
    //!   it's a safe-mode or auto-unlink value . Otherwise constant. 
-   ~list() 
+   ~list_impl() 
    {
       if(safemode_or_autounlink){
          this->clear(); 
@@ -165,11 +256,11 @@
    //! <b>Note</b>: Does not affect the validity of iterators and references.
    void push_back(reference value) 
    {
-      node_ptr to_insert = ValueTraits::to_node_ptr(value);
+      node_ptr to_insert = get_real_value_traits().to_node_ptr(value);
       if(safemode_or_autounlink)
          BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
       node_algorithms::link_before(this->get_root_node(), to_insert);
-      size_traits::increment();
+      this->priv_size_traits().increment();
    }
 
    //! <b>Requires</b>: value must be an lvalue.
@@ -184,11 +275,11 @@
    //! <b>Note</b>: Does not affect the validity of iterators and references.
    void push_front(reference value) 
    {
-      node_ptr to_insert = ValueTraits::to_node_ptr(value);
+      node_ptr to_insert = get_real_value_traits().to_node_ptr(value);
       if(safemode_or_autounlink)
          BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
       node_algorithms::link_before(node_traits::get_next(this->get_root_node()), to_insert); 
-      size_traits::increment();
+      this->priv_size_traits().increment();
    }
 
    //! <b>Effects</b>: Erases the last element of the list.
@@ -203,7 +294,7 @@
    {
       node_ptr to_erase = node_traits::get_previous(this->get_root_node());
       node_algorithms::unlink(to_erase);
-      size_traits::decrement();
+      this->priv_size_traits().decrement();
       if(safemode_or_autounlink)
          node_algorithms::init(to_erase);
    }
@@ -224,10 +315,10 @@
    {
       node_ptr to_erase = node_traits::get_previous(this->get_root_node());
       node_algorithms::unlink(to_erase);
-      size_traits::decrement();
+      this->priv_size_traits().decrement();
       if(safemode_or_autounlink)
          node_algorithms::init(to_erase);
-      disposer(ValueTraits::to_value_ptr(to_erase));
+      disposer(get_real_value_traits().to_value_ptr(to_erase));
    }
 
    //! <b>Effects</b>: Erases the first element of the list.
@@ -242,7 +333,7 @@
    { 
       node_ptr to_erase = node_traits::get_next(this->get_root_node());
       node_algorithms::unlink(to_erase);
-      size_traits::decrement();
+      this->priv_size_traits().decrement();
       if(safemode_or_autounlink)
          node_algorithms::init(to_erase);
    }
@@ -263,10 +354,10 @@
    { 
       node_ptr to_erase = node_traits::get_next(this->get_root_node());
       node_algorithms::unlink(to_erase);
-      size_traits::decrement();
+      this->priv_size_traits().decrement();
       if(safemode_or_autounlink)
          node_algorithms::init(to_erase);
-      disposer(ValueTraits::to_value_ptr(to_erase));
+      disposer(get_real_value_traits().to_value_ptr(to_erase));
    }
 
    //! <b>Effects</b>: Returns a reference to the first element of the list.
@@ -275,7 +366,7 @@
    //! 
    //! <b>Complexity</b>: Constant.
    reference front() 
-   { return *ValueTraits::to_value_ptr(node_traits::get_next(this->get_root_node())); }
+   { return *get_real_value_traits().to_value_ptr(node_traits::get_next(this->get_root_node())); }
 
    //! <b>Effects</b>: Returns a const_reference to the first element of the list.
    //! 
@@ -283,7 +374,7 @@
    //! 
    //! <b>Complexity</b>: Constant.
    const_reference front() const 
-   { return *ValueTraits::to_value_ptr(uncast(node_traits::get_next(this->get_root_node()))); }
+   { return *get_real_value_traits().to_value_ptr(uncast(node_traits::get_next(this->get_root_node()))); }
 
    //! <b>Effects</b>: Returns a reference to the last element of the list.
    //! 
@@ -291,7 +382,7 @@
    //! 
    //! <b>Complexity</b>: Constant.
    reference back() 
-   { return *ValueTraits::to_value_ptr(node_traits::get_previous(this->get_root_node())); }
+   { return *get_real_value_traits().to_value_ptr(node_traits::get_previous(this->get_root_node())); }
 
    //! <b>Effects</b>: Returns a const_reference to the last element of the list.
    //! 
@@ -299,7 +390,7 @@
    //! 
    //! <b>Complexity</b>: Constant.
    const_reference back() const 
-   { return *ValueTraits::to_value_ptr(uncast(node_traits::get_previous(this->get_root_node()))); }
+   { return *get_real_value_traits().to_value_ptr(uncast(node_traits::get_previous(this->get_root_node()))); }
 
    //! <b>Effects</b>: Returns an iterator to the first element contained in the list.
    //! 
@@ -307,7 +398,7 @@
    //! 
    //! <b>Complexity</b>: Constant.
    iterator begin() 
-   { return iterator(node_traits::get_next(this->get_root_node())); }
+   { return iterator(node_traits::get_next(this->get_root_node()), this); }
 
    //! <b>Effects</b>: Returns a const_iterator to the first element contained in the list.
    //! 
@@ -323,7 +414,7 @@
    //! 
    //! <b>Complexity</b>: Constant.
    const_iterator cbegin() const 
-   { return const_iterator(node_traits::get_next(this->get_root_node())); }
+   { return const_iterator(node_traits::get_next(this->get_root_node()), this); }
 
    //! <b>Effects</b>: Returns an iterator to the end of the list.
    //! 
@@ -331,7 +422,7 @@
    //! 
    //! <b>Complexity</b>: Constant.
    iterator end() 
-   { return iterator(this->get_root_node()); }
+   { return iterator(this->get_root_node(), this); }
 
    //! <b>Effects</b>: Returns a const_iterator to the end of the list.
    //! 
@@ -347,7 +438,7 @@
    //! 
    //! <b>Complexity</b>: Constant.
    const_iterator cend() const
-   { return const_iterator(uncast(this->get_root_node())); }
+   { return const_iterator(uncast(this->get_root_node()), this); }
 
    //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning 
    //! of the reversed list. 
@@ -411,11 +502,8 @@
    //! <b>Throws</b>: Nothing.
    //! 
    //! <b>Complexity</b>: Constant.
-   static list &container_from_end_iterator(iterator end_iterator)
-   {
-      return *detail::parent_from_member<list, node>
-         ( detail::get_pointer(end_iterator.pointed_node()), &list::root_);
-   }
+   static list_impl &container_from_end_iterator(iterator end_iterator)
+   {  return priv_container_from_end_iterator(end_iterator);   }
 
    //! <b>Precondition</b>: end_iterator must be a valid end const_iterator
    //!   of list.
@@ -425,24 +513,21 @@
    //! <b>Throws</b>: Nothing.
    //! 
    //! <b>Complexity</b>: Constant.
-   static const list &container_from_end_iterator(const_iterator end_iterator)
-   {
-      return *detail::parent_from_member<list, node>
-         ( detail::get_pointer(end_iterator.pointed_node()), &list::root_);
-   }
+   static const list_impl &container_from_end_iterator(const_iterator end_iterator)
+   {  return priv_container_from_end_iterator(end_iterator);   }
 
    //! <b>Effects</b>: Returns the number of the elements contained in the list.
    //! 
    //! <b>Throws</b>: Nothing.
    //! 
    //! <b>Complexity</b>: Linear to the number of elements contained in the list.
-   //!   if ConstantTimeSize is false. Constant time otherwise.
+   //!   if constant-time size option is disabled. Constant time otherwise.
    //! 
    //! <b>Note</b>: Does not affect the validity of iterators and references.
    size_type size() const
    {
-      if(ConstantTimeSize)
-         return size_traits::get_size();
+      if(constant_time_size)
+         return this->priv_size_traits().get_size();
       else
          return node_algorithms::count(this->get_root_node()) - 1; 
    }
@@ -464,13 +549,13 @@
    //! <b>Complexity</b>: Constant.
    //! 
    //! <b>Note</b>: Does not affect the validity of iterators and references.
-   void swap(list& other)
+   void swap(list_impl& other)
    {
       node_algorithms::swap_nodes(this->get_root_node(), other.get_root_node()); 
-      if(ConstantTimeSize){
-         size_type backup = size_traits::get_size();
-         size_traits::set_size(other.get_size());
-         other.set_size(backup);
+      if(constant_time_size){
+         size_type backup = this->priv_size_traits().get_size();
+         this->priv_size_traits().set_size(other.priv_size_traits().get_size());
+         other.priv_size_traits().set_size(backup);
       }
    }
 
@@ -543,7 +628,7 @@
       ++i;
       node_ptr to_erase = erase.pointed_node();
       node_algorithms::unlink(to_erase);
-      size_traits::decrement();
+      this->priv_size_traits().decrement();
       if(safemode_or_autounlink)
          node_algorithms::init(to_erase);
       return i;
@@ -566,7 +651,7 @@
    //!   erased elements.
    iterator erase(iterator b, iterator e)
    {
-      if(safemode_or_autounlink || ConstantTimeSize){
+      if(safemode_or_autounlink || constant_time_size){
          while(b != e){
             b = this->erase(b);
          }
@@ -599,10 +684,10 @@
       ++i;
       node_ptr to_erase = erase.pointed_node();
       node_algorithms::unlink(to_erase);
-      size_traits::decrement();
+      this->priv_size_traits().decrement();
       if(safemode_or_autounlink)
          node_algorithms::init(to_erase);
-      disposer(ValueTraits::to_value_ptr(to_erase));
+      disposer(get_real_value_traits().to_value_ptr(to_erase));
       return i;
    }
 
@@ -645,7 +730,7 @@
       }
       else{
          node_algorithms::init(this->get_root_node());
-         size_traits::set_size(size_type(0));
+         this->priv_size_traits().set_size(size_type(0));
       }
    }
 
@@ -678,24 +763,20 @@
    //! 
    //! <b>Throws</b>: If cloner throws. Basic guarantee.
    template <class Cloner, class Disposer>
-   void clone_from(const list &src, Cloner cloner, Disposer disposer)
+   void clone_from(const list_impl &src, Cloner cloner, Disposer disposer)
    {
       this->clear_and_dispose(disposer);
-      #ifndef BOOST_INTRUSIVE_DISABLE_EXCEPTION_HANDLING
-      BOOST_TRY{
-      #endif
+      BOOST_INTRUSIVE_TRY{
          const_iterator b(src.begin()), e(src.end());
          for(; b != e; ++b){
             this->push_back(*cloner(*b));
          }
-      #ifndef BOOST_INTRUSIVE_DISABLE_EXCEPTION_HANDLING
       }
-      BOOST_CATCH(...){
-         clear_and_dispose(disposer);
-         BOOST_RETHROW;
+      BOOST_INTRUSIVE_CATCH(...){
+         this->clear_and_dispose(disposer);
+         BOOST_INTRUSIVE_RETHROW;
       }
-      BOOST_CATCH_END
-      #endif
+      BOOST_INTRUSIVE_CATCH_END
    }
 
    //! <b>Requires</b>: value must be an lvalue and p must be a valid iterator of *this.
@@ -711,12 +792,12 @@
    //! <b>Note</b>: Does not affect the validity of iterators and references.
    iterator insert(iterator p, reference value)
    {
-      node_ptr to_insert = ValueTraits::to_node_ptr(value);
+      node_ptr to_insert = get_real_value_traits().to_node_ptr(value);
       if(safemode_or_autounlink)
          BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
       node_algorithms::link_before(p.pointed_node(), to_insert);
-      size_traits::increment();
-      return iterator(to_insert);
+      this->priv_size_traits().increment();
+      return iterator(to_insert, this);
    }
 
    //! <b>Requires</b>: Dereferencing iterator must yield 
@@ -793,13 +874,15 @@
    //! 
    //! <b>Note</b>: Iterators of values obtained from list x now point to elements of
    //!    this list. Iterators of this list and all the references are not invalidated.
-   void splice(iterator p, list& x)
+   void splice(iterator p, list_impl& x)
    {
       if(!x.empty()){
+         size_traits &thist = this->priv_size_traits();
+         size_traits &xt = x.priv_size_traits();
          node_algorithms::transfer
             (p.pointed_node(), x.begin().pointed_node(), x.end().pointed_node());
-         size_traits::set_size(size_traits::get_size() + x.get_size());
-         x.set_size(size_type(0));
+         thist.set_size(thist.get_size() + xt.get_size());
+         xt.set_size(size_type(0));
       }
    }
 
@@ -816,11 +899,11 @@
    //! 
    //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
    //!   list. Iterators of this list and all the references are not invalidated.
-   void splice(iterator p, list&x, iterator new_ele)
+   void splice(iterator p, list_impl&x, iterator new_ele)
    {
       node_algorithms::transfer(p.pointed_node(), new_ele.pointed_node());
-      x.decrement();
-      size_traits::increment();
+      x.priv_size_traits().decrement();
+      this->priv_size_traits().increment();
    }
 
    //! <b>Requires</b>: p must be a valid iterator of *this.
@@ -832,18 +915,20 @@
    //! <b>Throws</b>: Nothing.
    //! 
    //! <b>Complexity</b>: Linear to the number of elements transferred
-   //!   if ConstantTimeSize is true. Constant-time otherwise.
+   //!   if constant-time size option is enabled. Constant-time otherwise.
    //! 
    //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
    //!   list. Iterators of this list and all the references are not invalidated.
-   void splice(iterator p, list&x, iterator start, iterator end)
+   void splice(iterator p, list_impl&x, iterator start, iterator end)
    {
       if(start != end){
-         if(ConstantTimeSize){
+         if(constant_time_size){
+            size_traits &thist = this->priv_size_traits();
+            size_traits &xt = x.priv_size_traits();
             size_type increment = std::distance(start, end);
             node_algorithms::transfer(p.pointed_node(), start.pointed_node(), end.pointed_node());
-            size_traits::set_size(size_traits::get_size() + increment);
-            x.set_size(x.get_size() - increment);
+            thist.set_size(thist.get_size() + increment);
+            xt.set_size(xt.get_size() - increment);
          }
          else{
             node_algorithms::transfer(p.pointed_node(), start.pointed_node(), end.pointed_node());
@@ -864,14 +949,16 @@
    //! 
    //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
    //!   list. Iterators of this list and all the references are not invalidated.
-   void splice(iterator p, list&x, iterator start, iterator end, difference_type n)
+   void splice(iterator p, list_impl&x, iterator start, iterator end, difference_type n)
    {
       if(n){
-         if(ConstantTimeSize){
+         if(constant_time_size){
+            size_traits &thist = this->priv_size_traits();
+            size_traits &xt = x.priv_size_traits();
             BOOST_INTRUSIVE_INVARIANT_ASSERT(n == std::distance(start, end));
             node_algorithms::transfer(p.pointed_node(), start.pointed_node(), end.pointed_node());
-            size_traits::set_size(size_traits::get_size() + n);
-            x.set_size(x.get_size() - n);
+            thist.set_size(thist.get_size() + n);
+            xt.set_size(xt.get_size() - n);
          }
          else{
             node_algorithms::transfer(p.pointed_node(), start.pointed_node(), end.pointed_node());
@@ -882,7 +969,7 @@
    //! <b>Effects</b>: This function sorts the list *this according to std::less<value_type>. 
    //!   The sort is stable, that is, the relative order of equivalent elements is preserved.
    //! 
-   //! <b>Throws</b>: If value_traits::node_traits::node
+   //! <b>Throws</b>: If real_value_traits::node_traits::node
    //!   constructor throws (this does not happen with predefined Boost.Intrusive hooks)
    //!   or std::less<value_type> throws. Basic guarantee.
    //!
@@ -898,12 +985,12 @@
    //! <b>Effects</b>: This function sorts the list *this according to p. The sort is 
    //!   stable, that is, the relative order of equivalent elements is preserved.
    //! 
-   //! <b>Throws</b>: If value_traits::node_traits::node
+   //! <b>Throws</b>: If real_value_traits::node_traits::node
    //!   constructor throws (this does not happen with predefined Boost.Intrusive hooks)
    //!   or the predicate throws. Basic guarantee.
    //!
-   //! <b>Notes</b>: This won't throw if list_base_hook<>::value_traits or
-   //!   list_member_hook::::value_traits are used as value traits.
+   //! <b>Notes</b>: This won't throw if list_base_hook<> or
+   //!   list_member_hook are used.
    //!   Iterators and references are not invalidated.
    //! 
    //! <b>Complexity</b>: The number of comparisons is approximately N log N, where N
@@ -913,8 +1000,8 @@
    {
       if(node_traits::get_next(this->get_root_node()) 
          != node_traits::get_previous(this->get_root_node())){
-         list carry;
-         list counter[64];
+         list_impl carry;
+         list_impl counter[64];
          int fill = 0;
          while(!this->empty()){
             carry.splice(carry.begin(), *this, this->begin());
@@ -943,7 +1030,7 @@
    //!   size() + x.size() - 1 comparisons.
    //! 
    //! <b>Note</b>: Iterators and references are not invalidated
-   void merge(list& x)
+   void merge(list_impl& x)
    { merge(x, std::less<value_type>()); }
 
    //! <b>Requires</b>: p must be a comparison function that induces a strict weak
@@ -961,7 +1048,7 @@
    //! 
    //! <b>Note</b>: Iterators and references are not invalidated.
    template<class Predicate>
-   void merge(list& x, Predicate p)
+   void merge(list_impl& x, Predicate p)
    {
       iterator e = this->end();
       iterator bx = x.begin();
@@ -1142,10 +1229,46 @@
    //! <b>Complexity</b>: Constant time.
    //! 
    //! <b>Note</b>: Iterators and references are not invalidated.
-   static iterator iterator_to(reference value)
+   //!   This static function is available only if the <i>value traits</i>
+   //!   is stateless.
+   static iterator s_iterator_to(reference value)
+   {
+      BOOST_STATIC_ASSERT((!stateful_value_traits));
+      BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::unique(real_value_traits::to_node_ptr(value)));
+      return iterator(real_value_traits::to_node_ptr(value), 0);
+   }
+
+   //! <b>Requires</b>: value must be a const reference to a value inserted in a list.
+   //! 
+   //! <b>Effects</b>: This function returns an iterator pointing to the element.
+   //! 
+   //! <b>Throws</b>: Nothing.
+   //! 
+   //! <b>Complexity</b>: Constant time.
+   //! 
+   //! <b>Note</b>: Iterators and references are not invalidated.
+   //!   This static function is available only if the <i>value traits</i>
+   //!   is stateless.
+   static const_iterator s_iterator_to(const_reference value) 
+   {
+      BOOST_STATIC_ASSERT((!stateful_value_traits));
+      BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::unique(real_value_traits::to_node_ptr(const_cast<reference> (value))));
+      return const_iterator(real_value_traits::to_node_ptr(const_cast<reference> (value)), 0);
+   }
+
+   //! <b>Requires</b>: value must be a reference to a value inserted in a list.
+   //! 
+   //! <b>Effects</b>: This function returns a const_iterator pointing to the element
+   //! 
+   //! <b>Throws</b>: Nothing.
+   //! 
+   //! <b>Complexity</b>: Constant time.
+   //! 
+   //! <b>Note</b>: Iterators and references are not invalidated.
+   iterator iterator_to(reference value)
    { 
-      BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::unique(ValueTraits::to_node_ptr(value)));
-      return iterator(ValueTraits::to_node_ptr(value)); 
+      BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::unique(real_value_traits::to_node_ptr(value)));
+      return iterator(real_value_traits::to_node_ptr(value), this);
    }
 
    //! <b>Requires</b>: value must be a const reference to a value inserted in a list.
@@ -1157,20 +1280,58 @@
    //! <b>Complexity</b>: Constant time.
    //! 
    //! <b>Note</b>: Iterators and references are not invalidated.
-   static const_iterator iterator_to(const_reference value) 
+   const_iterator iterator_to(const_reference value) const
    { 
-      BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::unique(ValueTraits::to_node_ptr(const_cast<reference> (value))));
-      return const_iterator(ValueTraits::to_node_ptr(const_cast<reference> (value))); 
+      BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::unique(real_value_traits::to_node_ptr(const_cast<reference> (value))));
+      return const_iterator(real_value_traits::to_node_ptr(const_cast<reference> (value)), this);
    }
+
+   /// @cond
+
+   private:
+   static list_impl &priv_container_from_end_iterator(const const_iterator &end_iterator)
+   {
+      root_plus_size *r = detail::parent_from_member<root_plus_size, node>
+         ( detail::get_pointer(end_iterator.pointed_node()), &root_plus_size::root_);
+      data_t *d = detail::parent_from_member<data_t, root_plus_size>
+         ( r, &data_t::root_plus_size_);
+      list_impl *s  = detail::parent_from_member<list_impl, data_t>(d, &list_impl::data_);
+      return *s;
+   }
+   /// @endcond
 };
 
-template <class V, bool C, class S>
-inline bool operator==(const list<V, C, S>& x, const list<V, C, S>& y)
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+template<class T, class ...Options>
+#else
+template<class Config>
+#endif
+inline bool operator<
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+(const list_impl<T, Options...> &x, const list_impl<T, Options...> &y)
+#else
+(const list_impl<Config> &x, const list_impl<Config> &y)
+#endif
+{  return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());  }
+
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+template<class T, class ...Options>
+#else
+template<class Config>
+#endif
+bool operator==
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+(const list_impl<T, Options...> &x, const list_impl<T, Options...> &y)
+#else
+(const list_impl<Config> &x, const list_impl<Config> &y)
+#endif
 {
+   typedef list_impl<Config> list_type;
+   typedef typename list_type::const_iterator const_iterator;
+   const bool C = list_type::constant_time_size;
    if(C && x.size() != y.size()){
       return false;
    }
-   typedef typename list<V, C, S>::const_iterator const_iterator;
    const_iterator end1 = x.end();
 
    const_iterator i1 = x.begin();
@@ -1192,31 +1353,132 @@
    }
 }
 
-template <class V, bool C, class S>
-inline bool operator<(const list<V, C, S>& x,
-                      const list<V, C, S>& y)
-{  return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());  }
-
-template <class V, bool C, class S>
-inline bool operator!=(const list<V, C, S>& x, const list<V, C, S>& y) 
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+template<class T, class ...Options>
+#else
+template<class Config>
+#endif
+inline bool operator!=
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+(const list_impl<T, Options...> &x, const list_impl<T, Options...> &y)
+#else
+(const list_impl<Config> &x, const list_impl<Config> &y)
+#endif
 {  return !(x == y); }
 
-template <class V, bool C, class S>
-inline bool operator>(const list<V, C, S>& x, const list<V, C, S>& y) 
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+template<class T, class ...Options>
+#else
+template<class Config>
+#endif
+inline bool operator>
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+(const list_impl<T, Options...> &x, const list_impl<T, Options...> &y)
+#else
+(const list_impl<Config> &x, const list_impl<Config> &y)
+#endif
 {  return y < x;  }
 
-template <class V, bool C, class S>
-inline bool operator<=(const list<V, C, S>& x, const list<V, C, S>& y) 
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+template<class T, class ...Options>
+#else
+template<class Config>
+#endif
+inline bool operator<=
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+(const list_impl<T, Options...> &x, const list_impl<T, Options...> &y)
+#else
+(const list_impl<Config> &x, const list_impl<Config> &y)
+#endif
 {  return !(y < x);  }
 
-template <class V, bool C, class S>
-inline bool operator>=(const list<V, C, S>& x, const list<V, C, S>& y) 
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+template<class T, class ...Options>
+#else
+template<class Config>
+#endif
+inline bool operator>=
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+(const list_impl<T, Options...> &x, const list_impl<T, Options...> &y)
+#else
+(const list_impl<Config> &x, const list_impl<Config> &y)
+#endif
 {  return !(x < y);  }
 
-template <class V, bool C, class S>
-inline void swap(list<V, C, S>& x, list<V, C, S>& y)
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+template<class T, class ...Options>
+#else
+template<class Config>
+#endif
+inline void swap
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+(list_impl<T, Options...> &x, list_impl<T, Options...> &y)
+#else
+(list_impl<Config> &x, list_impl<Config> &y)
+#endif
 {  x.swap(y);  }
 
+//! Helper metafunction to define a \c list that yields to the same type when the
+//! same options (either explicitly or implicitly) are used.
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+template<class T, class ...Options>
+#else
+template<class T, class O1 = none, class O2 = none, class O3 = none>
+#endif
+struct make_list
+{
+   /// @cond
+   typedef typename pack_options
+      < list_defaults<T>, O1, O2, O3>::type packed_options;
+   typedef typename detail::get_value_traits
+      <T, typename packed_options::value_traits>::type value_traits;
+
+   typedef list_impl
+      <
+         listopt
+         < value_traits
+         , typename packed_options::size_type
+         , packed_options::constant_time_size
+         >
+      > implementation_defined;
+   /// @endcond
+   typedef implementation_defined type;
+};
+
+
+#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+template<class T, class O1, class O2, class O3>
+class list
+   :  public make_list<T, O1, O2, O3>::type
+{
+   typedef typename make_list
+      <T, O1, O2, O3>::type      Base;
+   typedef typename Base::real_value_traits     real_value_traits;
+   //Assert if passed value traits are compatible with the type
+   BOOST_STATIC_ASSERT((detail::is_same<typename real_value_traits::value_type, T>::value));
+   public:
+   typedef typename Base::value_traits          value_traits;
+   typedef typename Base::iterator              iterator;
+   typedef typename Base::const_iterator        const_iterator;
+
+   list(const value_traits &v_traits = value_traits())
+      :  Base(v_traits)
+   {}
+
+   template<class Iterator>
+   list(Iterator b, Iterator e, const value_traits &v_traits = value_traits())
+      :  Base(b, e, v_traits)
+   {}
+
+   static list &container_from_end_iterator(iterator end_iterator)
+   {  return static_cast<list &>(Base::container_from_end_iterator(end_iterator));   }
+
+   static const list &container_from_end_iterator(const_iterator end_iterator)
+   {  return static_cast<const list &>(Base::container_from_end_iterator(end_iterator));   }
+};
+
+#endif
+
 } //namespace intrusive 
 } //namespace boost 
 
Modified: trunk/boost/intrusive/list_hook.hpp
==============================================================================
--- trunk/boost/intrusive/list_hook.hpp	(original)
+++ trunk/boost/intrusive/list_hook.hpp	2007-09-26 11:26:35 EDT (Wed, 26 Sep 2007)
@@ -17,116 +17,104 @@
 #include <boost/intrusive/detail/config_begin.hpp>
 #include <boost/intrusive/intrusive_fwd.hpp>
 #include <boost/intrusive/detail/utilities.hpp>
-#include <boost/intrusive/detail/pointer_to_other.hpp>
 #include <boost/intrusive/detail/list_node.hpp>
 #include <boost/intrusive/circular_list_algorithms.hpp>
-#include <boost/intrusive/linking_policy.hpp>
-#include <boost/intrusive/tag.hpp>
-#include <boost/static_assert.hpp>
+#include <boost/intrusive/options.hpp>
+#include <boost/intrusive/detail/generic_hook.hpp>
 
 namespace boost {
 namespace intrusive {
 
-//! Derive a class from list_base_hook in order to store objects in 
-//! in an list. list_base_hook holds the data necessary to maintain the 
-//! list and provides an appropriate value_traits class for list.
+/// @cond
+template<class VoidPointer>
+struct get_list_node_algo
+{
+   typedef circular_list_algorithms<list_node_traits<VoidPointer> > type;
+};
+/// @endcond
+
+//! Helper metafunction to define a \c \c list_base_hook that yields to the same
+//! type when the same options (either explicitly or implicitly) are used.
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+template<class ...Options>
+#else
+template<class O1 = none, class O2 = none, class O3 = none>
+#endif
+struct make_list_base_hook
+{
+   /// @cond
+   typedef typename pack_options
+      < hook_defaults, O1, O2, O3>::type packed_options;
+
+   typedef detail::generic_hook
+   < get_list_node_algo<typename packed_options::void_pointer>
+   , typename packed_options::tag
+   , packed_options::link_mode
+   , detail::ListBaseHook
+   > implementation_defined;
+   /// @endcond
+   typedef implementation_defined type;
+};
+
+//! Derive a class from this hook in order to store objects of that class
+//! in an list.
 //! 
-//! The first integer template argument defines a tag to identify the node. 
+//! The hook admits the following options: \c tag<>, \c void_pointer<> and
+//! \c link_mode<>.
+//!
+//! \c tag<> defines a tag to identify the node. 
 //! The same tag value can be used in different classes, but if a class is 
-//! derived from more than one list_base_hook, then each list_base_hook needs its 
+//! derived from more than one \c list_base_hook, then each \c list_base_hook needs its 
 //! unique tag.
 //!
-//! The second boolean template parameter will specify the linking mode of the hook.
+//! \c link_mode<> will specify the linking mode of the hook (\c normal_link,
+//! \c auto_unlink or \c safe_link).
 //!
-//! The third argument is the pointer type that will be used internally in the hook
-//! and the list configured from this hook.
-template< class Tag              //= tag
-        , linking_policy Policy  //= safe_link
-        , class VoidPointer      //= void *
-        >
+//! \c void_pointer<> is the pointer type that will be used internally in the hook
+//! and the the container configured to use this hook.
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+template<class ...Options>
+#else
+template<class O1, class O2, class O3>
+#endif
 class list_base_hook
-   :  private detail::list_node_traits<VoidPointer>::node
+   :  public make_list_base_hook<O1, O2, O3>::type
 {
-   public:
-   typedef detail::list_node_traits<VoidPointer>      node_traits;
-   enum {   linking_policy = Policy   };
-
-   /// @cond
-   private:
-   typedef circular_list_algorithms<node_traits>      node_algorithms;
-
-   public:
-   typedef typename node_traits::node                 node;
-   typedef typename boost::pointer_to_other
-      <VoidPointer, node>::type                       node_ptr;
-   typedef typename boost::pointer_to_other
-      <VoidPointer, const node>::type                 const_node_ptr;
-   typedef list_base_hook
-      <Tag, Policy, VoidPointer>                      this_type;
-
-   typedef typename boost::pointer_to_other
-      <VoidPointer, this_type>::type                  this_type_ptr;
-
-   typedef typename boost::pointer_to_other
-      <VoidPointer, const this_type>::type            const_this_type_ptr;
-
-   private:
-   node_ptr this_as_node()
-   {  return node_ptr(static_cast<node *const>(this)); }
-
-   const_node_ptr this_as_node() const
-   {  return const_node_ptr(static_cast<const node *const>(this)); }
-   /// @endcond
-
-   public:
-   //! <b>Effects</b>: If Policy is auto_unlink or safe_mode_linnk
+   #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+   //! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
    //!   initializes the node to an unlinked state.
    //! 
    //! <b>Throws</b>: Nothing. 
-   list_base_hook()
-      :  node()
-   {
-      if(Policy == safe_link || Policy == auto_unlink){
-         node_algorithms::init(this_as_node());
-      }
-   }
+   list_base_hook();
 
-   //! <b>Effects</b>: If Policy is auto_unlink or safe_mode_linnk
+   //! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
    //!   initializes the node to an unlinked state. The argument is ignored.
    //! 
    //! <b>Throws</b>: Nothing. 
    //! 
    //! <b>Rationale</b>: Providing a copy-constructor
-   //!   makes classes using list_base_hook STL-compliant without forcing the 
-   //!   user to do some additional work. "swap" can be used to emulate
+   //!   makes classes using the hook STL-compliant without forcing the 
+   //!   user to do some additional work. \c swap can be used to emulate
    //!   move-semantics.
-   list_base_hook(const list_base_hook& ) 
-      :  node()
-   {
-      if(Policy == safe_link || Policy == auto_unlink){
-         node_algorithms::init(this_as_node());
-      }
-   }
+   list_base_hook(const list_base_hook& );
 
    //! <b>Effects</b>: Empty function. The argument is ignored.
    //! 
    //! <b>Throws</b>: Nothing. 
    //! 
    //! <b>Rationale</b>: Providing an assignment operator 
-   //!   makes classes using list_base_hook STL-compliant without forcing the 
-   //!   user to do some additional work. "swap" can be used to emulate
+   //!   makes classes using the hook STL-compliant without forcing the 
+   //!   user to do some additional work. \c swap can be used to emulate
    //!   move-semantics.
-   list_base_hook& operator=(const list_base_hook& ) 
-   {  return *this;  }
+   list_base_hook& operator=(const list_base_hook& );
 
-   //! <b>Effects</b>: If Policy is normal_link, the destructor does
-   //!   nothing (ie. no code is generated). If Policy is safe_link and the
-   //!   object is stored in an list an assertion is raised. If Policy is
-   //!   auto_unlink and "is_linked()" is true, the node is unlinked.
+   //! <b>Effects</b>: If link_mode is \c normal_link, the destructor does
+   //!   nothing (ie. no code is generated). If link_mode is \c safe_link and the
+   //!   object is stored in an list an assertion is raised. If link_mode is
+   //!   \c auto_unlink and \c is_linked() is true, the node is unlinked.
    //! 
    //! <b>Throws</b>: Nothing. 
-   ~list_base_hook()
-   {  detail::destructor_impl(*this, detail::dispatcher<Policy>());  }
+   ~list_base_hook();
 
    //! <b>Effects</b>: Swapping two nodes swaps the position of the elements 
    //!   related to those nodes in one or two containers. That is, if the node 
@@ -140,170 +128,102 @@
    //! <b>Complexity</b>: Constant 
    //!
    //! <b>Throws</b>: Nothing. 
-   void swap_nodes(list_base_hook &other) 
-   { node_algorithms::swap_nodes(this_as_node(), other.this_as_node()); }
+   void swap_nodes(list_base_hook &other);
 
-   //! <b>Precondition</b>: Policy must be safe_link or auto_unlink.
+   //! <b>Precondition</b>: link_mode must be \c safe_link or \c auto_unlink.
    //!
    //! <b>Returns</b>: true, if the node belongs to a container, false
-   //!   otherwise. This function can be used to test whether list::iterator_to 
+   //!   otherwise. This function can be used to test whether \c list::iterator_to 
    //!   will return a valid iterator. 
    //!
    //! <b>Complexity</b>: Constant 
-   bool is_linked() const 
-   {
-      //is_linked() can be only used in safe-mode or auto-unlink
-      BOOST_STATIC_ASSERT((Policy == safe_link || Policy == auto_unlink));
-      return !node_algorithms::unique(this_as_node()); 
-   }
+   bool is_linked() const;
 
    //! <b>Effects</b>: Removes the node if it's inserted in a container.
-   //!   This function is only allowed if Policy is auto_unlink.
-   //! 
-   //! <b>Throws</b>: Nothing. 
-   void unlink()
-   {
-      BOOST_STATIC_ASSERT((Policy == auto_unlink));
-      node_algorithms::unlink(this_as_node());
-      node_algorithms::init(this_as_node());
-   }
-
-   //! The value_traits class is used as the first template argument for list. 
-   //! The template argument T defines the class type stored in list. Objects 
-   //! of type T and of types derived from T can be stored. T doesn't need to be 
-   //! copy-constructible or assignable.
-   template<class T>
-   struct value_traits
-      : detail::derivation_hook_value_traits<T, this_type, Tag>
-   {};
-
-   //! <b>Effects</b>: Converts a pointer to a node into
-   //!   a pointer to the hook that holds that node.
-   //! 
-   //! <b>Throws</b>: Nothing. 
-   static this_type_ptr to_hook_ptr(node_ptr p)
-   {
-      return this_type_ptr(static_cast<list_base_hook*> (detail::get_pointer(p))); 
-   }
-
-   //! <b>Effects</b>: Converts a const pointer to a node stored in a container into
-   //!   a const pointer to the hook that holds that node.
+   //!   This function is only allowed if link_mode is \c auto_unlink.
    //! 
    //! <b>Throws</b>: Nothing. 
-   static const_this_type_ptr to_hook_ptr(const_node_ptr p)
-   {
-      return const_this_type_ptr(static_cast<const list_base_hook*> (detail::get_pointer(p))); 
-   }
+   void unlink();
+   #endif
+};
 
-   //! <b>Effects</b>: Returns a pointer to the node that this hook holds.
-   //! 
-   //! <b>Throws</b>: Nothing. 
-   node_ptr to_node_ptr()
-   { return this_as_node(); }
+//! Helper metafunction to define a \c \c list_member_hook that yields to the same
+//! type when the same options (either explicitly or implicitly) are used.
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+template<class ...Options>
+#else
+template<class O1 = none, class O2 = none, class O3 = none>
+#endif
+struct make_list_member_hook
+{
+   /// @cond
+   typedef typename pack_options
+      < hook_defaults, O1, O2, O3>::type packed_options;
 
-   //! <b>Effects</b>: Returns a const pointer to the node that this hook holds.
-   //! 
-   //! <b>Throws</b>: Nothing. 
-   const_node_ptr to_node_ptr() const
-   { return this_as_node(); }
+   typedef detail::generic_hook
+   < get_list_node_algo<typename packed_options::void_pointer>
+   , member_tag
+   , packed_options::link_mode
+   , detail::NoBaseHook
+   > implementation_defined;
+   /// @endcond
+   typedef implementation_defined type;
 };
 
-//! Put a public data member list_member_hook in order to store objects of this class in
-//! an list. list_member_hook holds the data necessary for maintaining the list and 
-//! provides an appropriate value_traits class for list.
+//! Store this hook in a class to be inserted
+//! in an list.
 //! 
-//! The first boolean template parameter will specify the linking mode of the hook.
+//! The hook admits the following options: \c void_pointer<> and
+//! \c link_mode<>.
+//! 
+//! \c link_mode<> will specify the linking mode of the hook (\c normal_link,
+//! \c auto_unlink or \c safe_link).
 //!
-//! The second argument is the pointer type that will be used internally in the hook
-//! and the list configured from this hook.
-template< linking_policy Policy  //= safe_link
-        , class VoidPointer      //= void *
-        >
+//! \c void_pointer<> is the pointer type that will be used internally in the hook
+//! and the the container configured to use this hook.
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+template<class ...Options>
+#else
+template<class O1, class O2, class O3>
+#endif
 class list_member_hook
-   :  private detail::list_node_traits<VoidPointer>::node
+   :  public make_list_member_hook<O1, O2, O3>::type
 {
-   public:
-   typedef detail::list_node_traits<VoidPointer>      node_traits;
-   enum { linking_policy = Policy };
-
-   /// @cond
-   private:
-   typedef circular_list_algorithms<node_traits>               node_algorithms;
-   /// @endcond
-
-   public:
-   typedef typename node_traits::node                 node;
-   typedef typename boost::pointer_to_other
-      <VoidPointer, node>::type                       node_ptr;
-   typedef typename boost::pointer_to_other
-      <VoidPointer, const node>::type                 const_node_ptr;
-   typedef list_member_hook
-      <Policy, VoidPointer>                           this_type;
-
-   typedef typename boost::pointer_to_other
-      <VoidPointer, this_type >::type                 this_type_ptr;
-
-   typedef typename boost::pointer_to_other
-      <VoidPointer, const this_type >::type           const_this_type_ptr;
-
-   /// @cond
-   private:
-   node_ptr this_as_node()
-   {  return node_ptr(static_cast<node *const>(this)); }
-
-   const_node_ptr this_as_node() const
-   {  return const_node_ptr(static_cast<const node *const>(this)); }
-   /// @endcond
-
-   public:
-   //! <b>Effects</b>: If Policy is auto_unlink or safe_mode_linnk
+   #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+   //! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
    //!   initializes the node to an unlinked state.
    //! 
    //! <b>Throws</b>: Nothing. 
-   list_member_hook()
-      :  node()
-   {
-      if(Policy == safe_link || Policy == auto_unlink){
-         node_algorithms::init(this_as_node());
-      }
-   }
+   list_member_hook();
 
-   //! <b>Effects</b>: If Policy is auto_unlink or safe_mode_linnk
+   //! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
    //!   initializes the node to an unlinked state. The argument is ignored.
    //! 
    //! <b>Throws</b>: Nothing. 
    //! 
    //! <b>Rationale</b>: Providing a copy-constructor
-   //!   makes classes using list_member_hook STL-compliant without forcing the 
-   //!   user to do some additional work. "swap" can be used to emulate
+   //!   makes classes using the hook STL-compliant without forcing the 
+   //!   user to do some additional work. \c swap can be used to emulate
    //!   move-semantics.
-   list_member_hook(const list_member_hook& ) 
-      :  node()
-   {
-      if(Policy == safe_link || Policy == auto_unlink){
-         node_algorithms::init(this_as_node());
-      }
-   }
+   list_member_hook(const list_member_hook& );
 
    //! <b>Effects</b>: Empty function. The argument is ignored.
    //! 
    //! <b>Throws</b>: Nothing. 
    //! 
    //! <b>Rationale</b>: Providing an assignment operator 
-   //!   makes classes using list_member_hook STL-compliant without forcing the 
-   //!   user to do some additional work. "swap" can be used to emulate
+   //!   makes classes using the hook STL-compliant without forcing the 
+   //!   user to do some additional work. \c swap can be used to emulate
    //!   move-semantics.
-   list_member_hook& operator=(const list_member_hook& )
-   {  return *this;  }
+   list_member_hook& operator=(const list_member_hook& );
 
-   //! <b>Effects</b>: If Policy is normal_link, the destructor does
-   //!   nothing (ie. no code is generated). If Policy is safe_link and the
-   //!   object is stored in an list an assertion is raised. If Policy is
-   //!   auto_unlink and "is_linked()" is true, the node is unlinked.
+   //! <b>Effects</b>: If link_mode is \c normal_link, the destructor does
+   //!   nothing (ie. no code is generated). If link_mode is \c safe_link and the
+   //!   object is stored in an list an assertion is raised. If link_mode is
+   //!   \c auto_unlink and \c is_linked() is true, the node is unlinked.
    //! 
    //! <b>Throws</b>: Nothing. 
-   ~list_member_hook()
-   {  detail::destructor_impl(*this, detail::dispatcher<Policy>());  }
+   ~list_member_hook();
 
    //! <b>Effects</b>: Swapping two nodes swaps the position of the elements 
    //!   related to those nodes in one or two containers. That is, if the node 
@@ -316,73 +236,24 @@
    //!
    //! <b>Complexity</b>: Constant 
    //!
-   //! <b>Throws</b>: Nothing.
-   void swap_nodes(list_member_hook& other) 
-   { node_algorithms::swap_nodes(this_as_node(), other.this_as_node()); }
+   //! <b>Throws</b>: Nothing. 
+   void swap_nodes(list_member_hook &other);
 
-   //! <b>Precondition</b>: Policy must be safe_link or auto_unlink.
+   //! <b>Precondition</b>: link_mode must be \c safe_link or \c auto_unlink.
    //!
    //! <b>Returns</b>: true, if the node belongs to a container, false
-   //!   otherwise. This function can be used to test whether list::iterator_to 
+   //!   otherwise. This function can be used to test whether \c list::iterator_to 
    //!   will return a valid iterator. 
    //!
-   //! <b>Complexity</b>: Constant
-   bool is_linked() const 
-   {
-      //is_linked() can be only used in safe-mode or auto-unlink
-      BOOST_STATIC_ASSERT((Policy == safe_link || Policy == auto_unlink));
-      return !node_algorithms::unique(this_as_node()); 
-   }
+   //! <b>Complexity</b>: Constant 
+   bool is_linked() const;
 
    //! <b>Effects</b>: Removes the node if it's inserted in a container.
-   //!   This function is only allowed if Policy is auto_unlink.
-   //! 
-   //! <b>Throws</b>: Nothing. 
-   void unlink()
-   {
-      BOOST_STATIC_ASSERT((Policy == auto_unlink));
-      node_algorithms::unlink(this_as_node());
-      node_algorithms::init(this_as_node());
-   }
-
-   //! The value_traits class is used as the first template argument for list. 
-   //! The template argument is a pointer to member pointing to the node in 
-   //! the class. Objects of type T and of types derived from T can be stored. 
-   //! T doesn't need to be copy-constructible or assignable.
-   template<class T, this_type T::* M>
-   struct value_traits
-      : detail::member_hook_value_traits<T, this_type, M>
-   {};
-
-   //! <b>Effects</b>: Converts a pointer to a node into
-   //!   a pointer to the hook that holds that node.
-   //! 
-   //! <b>Throws</b>: Nothing. 
-   static this_type_ptr to_hook_ptr(node_ptr p)
-   {
-      return this_type_ptr(static_cast<this_type*> (detail::get_pointer(p))); 
-   }
-
-   //! <b>Effects</b>: Converts a const pointer to a node stored in a container into
-   //!   a const pointer to the hook that holds that node.
-   //! 
-   //! <b>Throws</b>: Nothing. 
-   static const_this_type_ptr to_hook_ptr(const_node_ptr p)
-   {
-      return const_this_type_ptr(static_cast<const this_type*> (detail::get_pointer(p))); 
-   }
-
-   //! <b>Effects</b>: Returns a pointer to the node that this hook holds.
-   //! 
-   //! <b>Throws</b>: Nothing. 
-   node_ptr to_node_ptr()
-   { return this_as_node(); }
-
-   //! <b>Effects</b>: Returns a const pointer to the node that this hook holds.
+   //!   This function is only allowed if link_mode is \c auto_unlink.
    //! 
    //! <b>Throws</b>: Nothing. 
-   const_node_ptr to_node_ptr() const
-   { return this_as_node(); }
+   void unlink();
+   #endif
 };
 
 } //namespace intrusive 
Modified: trunk/boost/intrusive/member_value_traits.hpp
==============================================================================
--- trunk/boost/intrusive/member_value_traits.hpp	(original)
+++ trunk/boost/intrusive/member_value_traits.hpp	2007-09-26 11:26:35 EDT (Wed, 26 Sep 2007)
@@ -13,7 +13,7 @@
 #ifndef BOOST_INTRUSIVE_MEMBER_VALUE_TRAITS_HPP
 #define BOOST_INTRUSIVE_MEMBER_VALUE_TRAITS_HPP
 
-#include <boost/intrusive/linking_policy.hpp>
+#include <boost/intrusive/link_mode.hpp>
 #include <iterator>
 #include <boost/intrusive/detail/parent_from_member.hpp>
 
@@ -25,7 +25,7 @@
 //!store a node_traits::node
 template< class T, class NodeTraits
         , typename NodeTraits::node T::* PtrToMember
-        , linking_policy Policy>
+        , link_mode_type LinkMode = safe_link>
 struct member_value_traits
 {
    public:
@@ -38,8 +38,7 @@
    typedef typename boost::pointer_to_other<node_ptr, const T>::type const_pointer;
    typedef typename std::iterator_traits<pointer>::reference         reference;
    typedef typename std::iterator_traits<const_pointer>::reference   const_reference;
-
-   enum { linking_policy = Policy };
+   static const link_mode_type link_mode = LinkMode;
 
    static node_ptr to_node_ptr(reference value)
    {  return node_ptr(&(value.*PtrToMember));   }
Added: trunk/boost/intrusive/options.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/intrusive/options.hpp	2007-09-26 11:26:35 EDT (Wed, 26 Sep 2007)
@@ -0,0 +1,429 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga  2007
+//
+// Distributed under the Boost Software License, Version 1.0.
+//    (See accompanying file LICENSE_1_0.txt or copy at
+//          http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/intrusive for documentation.
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTRUSIVE_OPTIONS_HPP
+#define BOOST_INTRUSIVE_OPTIONS_HPP
+
+#include <boost/intrusive/detail/config_begin.hpp>
+#include <boost/intrusive/intrusive_fwd.hpp>
+#include <boost/intrusive/link_mode.hpp>
+#include <boost/intrusive/detail/mpl.hpp>
+#include <boost/intrusive/detail/utilities.hpp>
+#include <boost/static_assert.hpp>
+
+
+namespace boost {
+namespace intrusive {
+
+/// @cond
+
+struct default_tag;
+struct member_tag;
+
+namespace detail{
+
+template <class ValueTraits>
+struct eval_value_traits
+{
+   typedef typename ValueTraits::value_traits type;
+};
+
+template <class T>
+struct external_bucket_traits_is_true
+{
+   static const bool value = external_bucket_traits_bool<T>::value == 3;
+};
+
+template <class BucketTraits>
+struct eval_bucket_traits
+{
+   typedef typename BucketTraits::bucket_traits type;
+};
+
+template<class T, class BaseHook>
+struct get_base_value_traits
+{
+   typedef detail::base_hook_traits
+      < T
+      , typename BaseHook::boost_intrusive_tags::node_traits
+      , BaseHook::boost_intrusive_tags::link_mode
+      , typename BaseHook::boost_intrusive_tags::tag
+      , BaseHook::boost_intrusive_tags::hook_type> type;
+};
+
+template<class T, class MemberHook>
+struct get_member_value_traits
+{
+   typedef typename MemberHook::member_value_traits type;
+};
+
+template<class T, class SupposedValueTraits>
+struct get_value_traits
+{
+   typedef SupposedValueTraits supposed_value_traits;
+   //...if it's a base hook
+   typedef typename detail::eval_if_c
+      < internal_base_hook_bool_is_true<supposed_value_traits>::value
+      //...get it's internal value traits using
+      //the provided T value type.
+      , get_base_value_traits<T, supposed_value_traits>
+      //...else use it's internal value traits tag
+      //(member hooks and custom value traits are in this group)
+      , detail::eval_if_c
+         < internal_member_value_traits<supposed_value_traits>::value
+         , get_member_value_traits<T, supposed_value_traits>
+         , detail::identity<supposed_value_traits>
+         >
+      >::type type;
+};
+
+template<class BaseHook>
+struct get_base_node_traits
+{
+   typedef typename BaseHook::boost_intrusive_tags::node_traits type;
+};
+
+template<class MemberHook>
+struct get_member_node_traits
+{
+   typedef typename MemberHook::member_value_traits::node_traits type;
+};
+
+template<class ValueTraits>
+struct get_explicit_node_traits
+{
+   typedef typename ValueTraits::node_traits type;
+};
+
+
+template<class SupposedValueTraits>
+struct get_node_traits
+{
+   typedef SupposedValueTraits supposed_value_traits;
+   //...if it's a base hook
+   typedef typename detail::eval_if_c
+      < internal_base_hook_bool_is_true<supposed_value_traits>::value
+      //...get it's internal value traits using
+      //the provided T value type.
+      , get_base_node_traits<supposed_value_traits>
+      //...else use it's internal value traits tag
+      //(member hooks and custom value traits are in this group)
+      , detail::eval_if_c
+         < internal_member_value_traits<supposed_value_traits>::value
+         , get_member_node_traits<supposed_value_traits>
+         , get_explicit_node_traits<supposed_value_traits>
+         >
+      >::type type;
+};
+
+
+}  //namespace detail{
+
+
+//!This type indicates that no option is being used
+//!and that the default options should be used
+struct none
+{
+    template<class Base>
+    struct pack : Base
+    { };
+};
+
+/// @endcond
+
+//!This option setter specifies if the intrusive
+//!container stores its size as a member to
+//!obtain constant-time size() member.
+template<bool Enabled>
+struct constant_time_size
+{
+/// @cond
+    template<class Base>
+    struct pack : Base
+    {
+        static const bool constant_time_size = Enabled;
+    };
+/// @endcond
+};
+
+//!This option setter specifies the type that
+//!the container will use to store its size.
+template<class SizeType>
+struct size_type
+{
+/// @cond
+    template<class Base>
+    struct pack : Base
+    {
+        typedef SizeType size_type;
+    };
+/// @endcond
+};
+
+//!This option setter specifies the strict weak ordering
+//!comparison functor for the value type
+template<class Compare>
+struct compare
+{
+/// @cond
+    template<class Base>
+    struct pack : Base
+    {
+        typedef Compare compare;
+    };
+/// @endcond
+};
+
+//!This option setter specifies the equality
+//!functor for the value type
+template<class Equal>
+struct equal
+{
+/// @cond
+    template<class Base>
+    struct pack : Base
+    {
+        typedef Equal equal;
+    };
+/// @endcond
+};
+
+//!This option setter specifies the hash
+//!functor for the value type
+template<class Hash>
+struct hash
+{
+/// @cond
+    template<class Base>
+    struct pack : Base
+    {
+        typedef Hash hash;
+    };
+/// @endcond
+};
+
+//!This option setter specifies the relationship between the type
+//!to be managed by the container (the value type) and the node to be
+//!used in the node algorithms. It also specifies the linking policy.
+template<typename ValueTraits>
+struct value_traits
+{
+/// @cond
+    template<class Base>
+    struct pack : Base
+    {
+        typedef ValueTraits value_traits;
+    };
+/// @endcond
+};
+
+//!This option setter specifies the member hook the
+//!container must use.
+template< typename Parent
+        , typename MemberHook
+        , MemberHook Parent::* PtrToMember>
+struct member_hook
+{
+/// @cond
+   typedef char Parent::* GenericPtrToMember;
+   typedef detail::member_hook_traits
+      < Parent
+      , MemberHook
+      , PtrToMember
+      > member_value_traits;
+   template<class Base>
+   struct pack : Base
+   {
+      typedef member_value_traits value_traits;
+   };
+/// @endcond
+};
+
+//!This option setter specifies that the container
+//!must use the specified base hook
+template<typename BaseHook>
+struct base_hook
+{
+/// @cond
+   template<class Base>
+   struct pack : Base
+   {
+      typedef BaseHook value_traits;
+   };
+/// @endcond
+};
+
+//!This option setter specifies the type of
+//!a void pointer. This will instruct the hook
+//!to use this type of pointer instead of the
+//!default one
+template<class VoidPointer>
+struct void_pointer
+{
+/// @cond
+   template<class Base>
+   struct pack : Base
+   {
+      typedef VoidPointer void_pointer;
+   };
+/// @endcond
+};
+
+//!This option setter specifies the type of
+//!the tag of a base hook. A type can not have two
+//!base hooks of the same type, so a tag can be used
+//!to differentiate two base hooks with otherwise same type
+template<class BaseTag>
+struct tag
+{
+/// @cond
+   template<class Base>
+   struct pack : Base
+   {
+      typedef BaseTag tag;
+   };
+/// @endcond
+};
+
+//!This option setter specifies the type of
+//!a void pointer. This will instruct the hook
+//!to use this type of pointer instead of the
+//!default one
+template<link_mode_type LinkType>
+struct link_mode
+{
+/// @cond
+   template<class Base>
+   struct pack : Base
+   {
+      static const link_mode_type link_mode = LinkType;
+   };
+/// @endcond
+};
+
+//!This option setter specifies the bucket traits
+//!class for unordered associative containers. When this option is specified,
+//!instead of using the default bucket traits, a user defined holder will be defined
+template<class BucketTraits>
+struct bucket_traits
+{
+/// @cond
+   template<class Base>
+   struct pack : Base
+   {
+      typedef BucketTraits bucket_traits;
+   };
+/// @endcond
+};
+
+//!This option setter specifies if the bucket array will be always power of two.
+//!This allows using masks instead of the default modulo operation to determine
+//!the bucket number from the hash value, leading to better performance.
+//!In debug mode, if power of two buckets mode is activated, the bucket length
+//!will be checked to through assertions to assure the bucket length is power of two.
+template<bool Enabled>
+struct power_2_buckets
+{
+/// @cond
+   template<class Base>
+   struct pack : Base
+   {
+      static const bool power_2_buckets = Enabled;
+   };
+/// @endcond
+};
+
+/// @cond
+
+template<class Prev, class Next>
+struct do_pack
+{
+   //Use "pack" member template to pack options
+   typedef typename Next::template pack<Prev> type;
+};
+
+template<class Prev>
+struct do_pack<Prev, none>
+{
+   //Avoid packing "none" to shorten template names
+   typedef Prev type;
+};
+
+
+template
+   < class DefaultOptions
+   , class O1         = none
+   , class O2         = none
+   , class O3         = none
+   , class O4         = none
+   , class O5         = none
+   , class O6         = none
+   , class O7         = none
+   , class O8         = none
+   , class O9         = none
+   , class Option10        = none
+   >
+struct pack_options
+{
+   // join options
+   typedef
+      typename do_pack
+      <  typename do_pack
+         <  typename do_pack
+            <  typename do_pack
+               <  typename do_pack
+                  <  typename do_pack
+                     <  typename do_pack
+                        <  typename do_pack
+                           <  typename do_pack
+                              <  typename do_pack
+                                 < DefaultOptions
+                                 , O1
+                                 >::type
+                              , O2
+                              >::type
+                           , O3
+                           >::type
+                        , O4
+                        >::type
+                     , O5
+                     >::type
+                  , O6
+                  >::type
+               , O7
+               >::type
+            , O8
+            >::type
+         , O9
+         >::type
+      , Option10
+      >::type 
+   type;
+};
+
+struct hook_defaults
+   :  public pack_options
+      < none
+      , void_pointer<void*>
+      , link_mode<safe_link>
+      , tag<default_tag>
+      >::type
+{};
+
+/// @endcond
+
+}  //namespace intrusive {
+}  //namespace boost {
+
+#include <boost/intrusive/detail/config_end.hpp>
+
+#endif   //#ifndef BOOST_INTRUSIVE_OPTIONS_HPP
Modified: trunk/boost/intrusive/pointer_plus_bit.hpp
==============================================================================
--- trunk/boost/intrusive/pointer_plus_bit.hpp	(original)
+++ trunk/boost/intrusive/pointer_plus_bit.hpp	2007-09-26 11:26:35 EDT (Wed, 26 Sep 2007)
@@ -23,7 +23,7 @@
 template<class VoidPointer, std::size_t Alignment>
 struct has_pointer_plus_bit
 {
-   enum  {  value = false  };
+   static const bool value = false;
 };
 
 //!This is an specialization for raw pointers.
@@ -32,7 +32,7 @@
 template<std::size_t N>
 struct has_pointer_plus_bit<void*, N>
 {
-   enum  {  value = N % 2u == 0  };
+   static const bool value = (N % 2u == 0);
 };
 
 //!This is class that is supposed to have static methods
Modified: trunk/boost/intrusive/rbtree.hpp
==============================================================================
--- trunk/boost/intrusive/rbtree.hpp	(original)
+++ trunk/boost/intrusive/rbtree.hpp	2007-09-26 11:26:35 EDT (Wed, 26 Sep 2007)
@@ -23,123 +23,228 @@
 #include <boost/intrusive/set_hook.hpp>
 #include <boost/intrusive/detail/rbtree_node.hpp>
 #include <boost/intrusive/detail/ebo_functor_holder.hpp>
+#include <boost/intrusive/options.hpp>
 #include <boost/intrusive/rbtree_algorithms.hpp>
-#include <boost/intrusive/linking_policy.hpp>
+#include <boost/intrusive/link_mode.hpp>
 #include <cstddef>
 #include <iterator>
 
 namespace boost {
 namespace intrusive {
 
+/// @cond
+
+template <class T>
+struct internal_default_set_hook
+{
+   template <class U> static detail::one test(...);
+   template <class U> static detail::two test(typename U::default_set_hook* = 0);
+   static const bool value = sizeof(test<T>(0)) == sizeof(detail::two);
+};
+
+template <class T>
+struct get_default_set_hook
+{
+   typedef typename T::default_set_hook type;
+};
+
+template <class ValueTraits, class Compare, class SizeType, bool ConstantTimeSize>
+struct setopt
+{
+   typedef ValueTraits  value_traits;
+   typedef Compare      compare;
+   typedef SizeType     size_type;
+   static const bool constant_time_size = ConstantTimeSize;
+};
+
+template <class T>
+struct set_defaults
+   :  pack_options
+      < none
+      , base_hook
+         <  typename detail::eval_if_c
+               < internal_default_set_hook<T>::value
+               , get_default_set_hook<T>
+               , detail::identity<none>
+               >::type
+         >
+      , constant_time_size<true>
+      , size_type<std::size_t>
+      , compare<std::less<T> >
+      >::type
+{};
+
+/// @endcond
+
 //! The class template rbtree is an intrusive red-black tree container, that
 //! is used to construct intrusive set and tree containers. The no-throw 
-//! guarantee holds only, if the Compare object 
+//! guarantee holds only, if the value_compare object 
 //! doesn't throw.
-template < class ValueTraits
-         , class Compare         //= std::less<typename ValueTraits::value_type>
-         , bool ConstantTimeSize //= true
-         , class SizeType        //= std::size_t
-         >
-class rbtree
-   :  private detail::size_holder<ConstantTimeSize, SizeType>
+//!
+//! The template parameter \c T is the type to be managed by the container.
+//! The user can specify additional options and if no options are provided
+//! default options are used.
+//!
+//! The container supports the following options:
+//! \c base_hook<>/member_hook<>/value_traits<>,
+//! \c constant_time_size<>, \c size_type<> and
+//! \c compare<>.
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+template<class T, class ...Options>
+#else
+template<class Config>
+#endif
+class rbtree_impl
 {
+   public:
+   typedef typename Config::value_traits                             value_traits;
    /// @cond
-   private:
-   typename ValueTraits::node_traits::node root_;
-   typedef rbtree<ValueTraits, Compare
-                  ,ConstantTimeSize, SizeType>              this_type; 
-   typedef typename ValueTraits::node_traits                node_traits;
-   typedef detail::size_holder<ConstantTimeSize, SizeType>  size_traits;
-
-   //noncopyable
-   rbtree (const rbtree&);
-   rbtree operator =(const rbtree&);
+   static const bool external_value_traits =
+      detail::external_value_traits_is_true<value_traits>::value;
+   typedef typename detail::eval_if_c
+      < external_value_traits
+      , detail::eval_value_traits<value_traits>
+      , detail::identity<value_traits>
+      >::type                                                        real_value_traits;
    /// @endcond
+   typedef typename real_value_traits::pointer                       pointer;
+   typedef typename real_value_traits::const_pointer                 const_pointer;
+   typedef typename std::iterator_traits<pointer>::value_type        value_type;
+   typedef value_type                                                key_type;
+   typedef typename std::iterator_traits<pointer>::reference         reference;
+   typedef typename std::iterator_traits<const_pointer>::reference   const_reference;
+   typedef typename std::iterator_traits<pointer>::difference_type   difference_type;
+   typedef typename Config::size_type                                size_type;
+   typedef typename Config::compare                                  value_compare;
+   typedef value_compare                                             key_compare;
+   typedef rbtree_iterator<rbtree_impl, false>                       iterator;
+   typedef rbtree_iterator<rbtree_impl, true>                        const_iterator;
+   typedef std::reverse_iterator<iterator>                           reverse_iterator;
+   typedef std::reverse_iterator<const_iterator>                     const_reverse_iterator;
+   typedef typename real_value_traits::node_traits                        node_traits;
+   typedef typename node_traits::node                                node;
+   typedef typename boost::pointer_to_other
+      <pointer, node>::type                                          node_ptr;
+   typedef typename boost::pointer_to_other
+      <node_ptr, const node>::type                                   const_node_ptr;
+   typedef rbtree_algorithms<node_traits>                            node_algorithms;
 
-   public:
-   typedef ValueTraits                                                  value_traits;
-   typedef typename ValueTraits::value_type                             value_type;
-   typedef typename ValueTraits::pointer                                pointer;
-   typedef typename ValueTraits::const_pointer                          const_pointer;
-   typedef typename std::iterator_traits<pointer>::reference            reference;
-   typedef typename std::iterator_traits<const_pointer>::reference      const_reference;
-   typedef typename std::iterator_traits<pointer>::difference_type      difference_type;
-   typedef SizeType                                                     size_type;
-   typedef value_type                                                   key_type;
-   typedef Compare                                                      value_compare;
-   typedef detail::rbtree_iterator<value_type, ValueTraits>             iterator;
-   typedef detail::rbtree_iterator<const value_type, ValueTraits>       const_iterator;
-   typedef std::reverse_iterator<iterator>                              reverse_iterator;
-   typedef std::reverse_iterator<const_iterator>                        const_reverse_iterator;
+   static const bool constant_time_size = Config::constant_time_size;
+   static const bool stateful_value_traits = detail::store_cont_ptr_on_it<rbtree_impl>::value;
 
    /// @cond
    private:
-   typedef typename node_traits::node              node;
-   typedef typename boost::pointer_to_other
-      <pointer, node>::type                        node_ptr;
-   typedef typename boost::pointer_to_other
-      <node_ptr, const node>::type                 const_node_ptr;
-   typedef rbtree_algorithms<node_traits>          node_algorithms;
+   typedef detail::size_holder<constant_time_size, size_type>        size_traits;
+
+   //noncopyable
+   rbtree_impl (const rbtree_impl&);
+   rbtree_impl operator =(const rbtree_impl&);
+
    enum { safemode_or_autounlink  = 
-            (int)ValueTraits::linking_policy == (int)auto_unlink   ||
-            (int)ValueTraits::linking_policy == (int)safe_link     };
+            (int)real_value_traits::link_mode == (int)auto_unlink   ||
+            (int)real_value_traits::link_mode == (int)safe_link     };
 
    //Constant-time size is incompatible with auto-unlink hooks!
-   BOOST_STATIC_ASSERT(!(ConstantTimeSize && ((int)ValueTraits::linking_policy == (int)auto_unlink)));
+   BOOST_STATIC_ASSERT(!(constant_time_size && ((int)real_value_traits::link_mode == (int)auto_unlink)));
 
-   //Use EBO if possible
-   typedef detail::node_plus_pred<node, Compare> members_t;
-   members_t members_;
-   
-   const Compare &priv_comp() const
-   {  return members_.second();  }
+   struct header_plus_size : public size_traits
+   {  node header_;  };
 
-   Compare &priv_comp()
-   {  return members_.second();  }
+   struct node_plus_pred_t : public detail::ebo_functor_holder<value_compare>
+   {
+      node_plus_pred_t(const value_compare &comp)
+         :  detail::ebo_functor_holder<value_compare>(comp)
+      {}
+      header_plus_size header_plus_size_;
+   };
+
+   struct data_t : public rbtree_impl::value_traits
+   {
+      typedef typename rbtree_impl::value_traits value_traits;
+      data_t(const value_compare & comp, const value_traits &val_traits)
+         :  value_traits(val_traits), node_plus_pred_(comp)
+      {}
+      node_plus_pred_t node_plus_pred_;
+   } data_;
+  
+   const value_compare &priv_comp() const
+   {  return data_.node_plus_pred_.get();  }
+
+   value_compare &priv_comp()
+   {  return data_.node_plus_pred_.get();  }
 
    const node &priv_header() const
-   {  return members_.first();  }
+   {  return data_.node_plus_pred_.header_plus_size_.header_;  }
 
    node &priv_header()
-   {  return members_.first();  }
+   {  return data_.node_plus_pred_.header_plus_size_.header_;  }
 
    static node_ptr uncast(const_node_ptr ptr)
    {
       return node_ptr(const_cast<node*>(detail::get_pointer(ptr)));
    }
+
+   size_traits &priv_size_traits()
+   {  return data_.node_plus_pred_.header_plus_size_;  }
+
+   const size_traits &priv_size_traits() const
+   {  return data_.node_plus_pred_.header_plus_size_;  }
+
+   const real_value_traits &get_real_value_traits(detail::bool_<false>) const
+   {  return data_;  }
+
+   const real_value_traits &get_real_value_traits(detail::bool_<true>) const
+   {  return data_.get_value_traits(*this);  }
+
+   real_value_traits &get_real_value_traits(detail::bool_<false>)
+   {  return data_;  }
+
+   real_value_traits &get_real_value_traits(detail::bool_<true>)
+   {  return data_.get_value_traits(*this);  }
+
    /// @endcond
 
    public:
+
+   const real_value_traits &get_real_value_traits() const
+   {  return this->get_real_value_traits(detail::bool_<external_value_traits>());  }
+
+   real_value_traits &get_real_value_traits()
+   {  return this->get_real_value_traits(detail::bool_<external_value_traits>());  }
+
    typedef typename node_algorithms::insert_commit_data insert_commit_data;
 
    //! <b>Effects</b>: Constructs an empty tree. 
    //!   
    //! <b>Complexity</b>: Constant. 
    //! 
-   //! <b>Throws</b>: Nothing unless the copy constructor of the Compare object throws. 
-   rbtree(Compare cmp = Compare()) 
-      :  members_(cmp)
+   //! <b>Throws</b>: Nothing unless the copy constructor of the value_compare object throws. 
+   rbtree_impl( value_compare cmp = value_compare()
+              , const value_traits &v_traits = value_traits()) 
+      :  data_(cmp, v_traits)
    {  
       node_algorithms::init_header(&priv_header());  
-      size_traits::set_size(size_type(0));
+      this->priv_size_traits().set_size(size_type(0));
    }
 
-   //! <b>Requires</b>: Dereferencing iterator must yield an lvalue of type value_type. 
+   //! <b>Requires</b>: Dereferencing iterator must yield an lvalue of type value_type.
    //!   cmp must be a comparison function that induces a strict weak ordering.
-   //! 
-   //! <b>Effects</b>: Constructs an empty tree and inserts elements from 
+   //!
+   //! <b>Effects</b>: Constructs an empty tree and inserts elements from
    //!   [b, e).
-   //! 
-   //! <b>Complexity</b>: Linear in N if [b, e) is already sorted using 
+   //!
+   //! <b>Complexity</b>: Linear in N if [b, e) is already sorted using
    //!   comp and otherwise N * log N, where N is last  first.
    //! 
-   //! <b>Throws</b>: Nothing unless the copy constructor of the Compare object throws. 
+   //! <b>Throws</b>: Nothing unless the copy constructor of the value_compare object throws.
    template<class Iterator>
-   rbtree(bool unique, Iterator b, Iterator e, Compare cmp = Compare())
-      : members_(cmp)
+   rbtree_impl( bool unique, Iterator b, Iterator e
+              , value_compare cmp = value_compare()
+              , const value_traits &v_traits = value_traits())
+      : data_(cmp, v_traits)
    {
       node_algorithms::init_header(&priv_header());
-      size_traits::set_size(size_type(0));
+      this->priv_size_traits().set_size(size_type(0));
       if(unique)
          this->insert_unique(b, e);
       else
@@ -148,12 +253,12 @@
 
    //! <b>Effects</b>: Detaches all elements from this. The objects in the set 
    //!   are not deleted (i.e. no destructors are called), but the nodes according to 
-   //!   the ValueTraits template parameter are reinitialized and thus can be reused. 
+   //!   the value_traits template parameter are reinitialized and thus can be reused. 
    //! 
    //! <b>Complexity</b>: Linear to elements contained in *this. 
    //! 
    //! <b>Throws</b>: Nothing.
-   ~rbtree() 
+   ~rbtree_impl() 
    {  this->clear(); }
 
    //! <b>Effects</b>: Returns an iterator pointing to the beginning of the tree.
@@ -162,7 +267,7 @@
    //! 
    //! <b>Throws</b>: Nothing.
    iterator begin()
-   {  return iterator (node_traits::get_left(node_ptr(&priv_header())));   }
+   {  return iterator (node_traits::get_left(node_ptr(&priv_header())), this);   }
 
    //! <b>Effects</b>: Returns a const_iterator pointing to the beginning of the tree.
    //! 
@@ -178,7 +283,7 @@
    //! 
    //! <b>Throws</b>: Nothing.
    const_iterator cbegin() const
-   {  return const_iterator (node_traits::get_left(const_node_ptr(&priv_header())));   }
+   {  return const_iterator (node_traits::get_left(const_node_ptr(&priv_header())), this);   }
 
    //! <b>Effects</b>: Returns an iterator pointing to the end of the tree.
    //! 
@@ -186,10 +291,10 @@
    //! 
    //! <b>Throws</b>: Nothing.
    iterator end()
-   {  return iterator (node_ptr(&priv_header()));  }
+   {  return iterator (node_ptr(&priv_header()), this);  }
 
    //! <b>Effects</b>: Returns a const_iterator pointing to the end of the tree.
-   //! 
+   //!
    //! <b>Complexity</b>: Constant.
    //! 
    //! <b>Throws</b>: Nothing.
@@ -202,7 +307,7 @@
    //! 
    //! <b>Throws</b>: Nothing.
    const_iterator cend() const
-   {  return const_iterator (uncast(const_node_ptr(&priv_header())));  }
+   {  return const_iterator (uncast(const_node_ptr(&priv_header())), this);  }
 
    //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning of the
    //!    reversed tree.
@@ -266,12 +371,8 @@
    //! <b>Throws</b>: Nothing.
    //! 
    //! <b>Complexity</b>: Constant.
-   static rbtree &container_from_end_iterator(iterator end_iterator)
-   {
-      return *detail::parent_from_member<rbtree, members_t>
-         ( members_t::this_from_node(detail::get_pointer(end_iterator.pointed_node()))
-         , &rbtree::members_);
-   }
+   static rbtree_impl &container_from_end_iterator(iterator end_iterator)
+   {  return priv_container_from_end_iterator(end_iterator);   }
 
    //! <b>Precondition</b>: end_iterator must be a valid end const_iterator
    //!   of rbtree.
@@ -281,12 +382,8 @@
    //! <b>Throws</b>: Nothing.
    //! 
    //! <b>Complexity</b>: Constant.
-   static const rbtree &container_from_end_iterator(const_iterator end_iterator)
-   {
-      return *detail::parent_from_member<rbtree, members_t>
-         ( members_t::this_from_node(detail::get_pointer(end_iterator.pointed_node()))
-         , &rbtree::members_);
-   }
+   static const rbtree_impl &container_from_end_iterator(const_iterator end_iterator)
+   {  return priv_container_from_end_iterator(end_iterator);   }
 
    //! <b>Effects</b>: Returns the value_compare object used by the tree.
    //! 
@@ -311,8 +408,8 @@
    //! <b>Throws</b>: Nothing.
    size_type size() const
    {
-      if(ConstantTimeSize)
-         return size_traits::get_size();
+      if(constant_time_size)
+         return this->priv_size_traits().get_size();
       else
          return empty() ? 0 : node_algorithms::count(node_traits::get_parent(const_node_ptr(&priv_header())));
    }
@@ -321,18 +418,18 @@
    //! 
    //! <b>Complexity</b>: Constant.
    //! 
-   //! <b>Throws</b>: If the comparison functor's unspecified swap call throws.
-   void swap(rbtree& other)
+   //! <b>Throws</b>: If the comparison functor's none swap call throws.
+   void swap(rbtree_impl& other)
    {
       //This can throw
       using std::swap;
       swap(priv_comp(), priv_comp());
       //These can't throw
       node_algorithms::swap_tree(node_ptr(&priv_header()), node_ptr(&other.priv_header()));
-      if(ConstantTimeSize){
-         size_type backup = size_traits::get_size();
-         size_traits::set_size(other.get_size());
-         other.set_size(backup);
+      if(constant_time_size){
+         size_type backup = this->priv_size_traits().get_size();
+         this->priv_size_traits().set_size(other.priv_size_traits().get_size());
+         other.priv_size_traits().set_size(backup);
       }
    }
 
@@ -349,13 +446,14 @@
    //!   No copy-constructors are called.
    iterator insert_equal_upper_bound(reference value)
    {
-      detail::key_node_ptr_compare<value_compare, ValueTraits> key_node_comp(priv_comp());
-      node_ptr to_insert(ValueTraits::to_node_ptr(value));
+      detail::key_nodeptr_comp<value_compare, rbtree_impl>
+         key_node_comp(priv_comp(), this);
+      node_ptr to_insert(get_real_value_traits().to_node_ptr(value));
       if(safemode_or_autounlink)
          BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
-      size_traits::increment();
+      this->priv_size_traits().increment();
       return iterator(node_algorithms::insert_equal_upper_bound
-         (node_ptr(&priv_header()), to_insert, key_node_comp));
+         (node_ptr(&priv_header()), to_insert, key_node_comp), this);
    }
 
    //! <b>Requires</b>: value must be an lvalue
@@ -371,13 +469,14 @@
    //!   No copy-constructors are called.
    iterator insert_equal_lower_bound(reference value)
    {
-      detail::key_node_ptr_compare<value_compare, ValueTraits> key_node_comp(priv_comp());
-      node_ptr to_insert(ValueTraits::to_node_ptr(value));
+      detail::key_nodeptr_comp<value_compare, rbtree_impl>
+         key_node_comp(priv_comp(), this);
+      node_ptr to_insert(get_real_value_traits().to_node_ptr(value));
       if(safemode_or_autounlink)
          BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
-      size_traits::increment();
+      this->priv_size_traits().increment();
       return iterator(node_algorithms::insert_equal_lower_bound
-         (node_ptr(&priv_header()), to_insert, key_node_comp));
+         (node_ptr(&priv_header()), to_insert, key_node_comp), this);
    }
 
    //! <b>Requires</b>: value must be an lvalue, and "hint" must be
@@ -396,13 +495,14 @@
    //!   No copy-constructors are called.
    iterator insert_equal(const_iterator hint, reference value)
    {
-      detail::key_node_ptr_compare<value_compare, ValueTraits> key_node_comp(priv_comp());
-      node_ptr to_insert(ValueTraits::to_node_ptr(value));
+      detail::key_nodeptr_comp<value_compare, rbtree_impl>
+         key_node_comp(priv_comp(), this);
+      node_ptr to_insert(get_real_value_traits().to_node_ptr(value));
       if(safemode_or_autounlink)
          BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
-      size_traits::increment();
+      this->priv_size_traits().increment();
       return iterator(node_algorithms::insert_equal
-         (node_ptr(&priv_header()), hint.pointed_node(), to_insert, key_node_comp));
+         (node_ptr(&priv_header()), hint.pointed_node(), to_insert, key_node_comp), this);
    }
 
    //! <b>Requires</b>: Dereferencing iterator must yield an lvalue 
@@ -411,8 +511,8 @@
    //! <b>Effects</b>: Inserts a each element of a range into the tree
    //!   before the upper bound of the key of each element.
    //! 
-   //! <b>Complexity</b>: Insert range is in general O(N * log(N)), where N is the 
-   //!   size of the range. However, it is linear in N if the range is already sorted 
+   //! <b>Complexity</b>: Insert range is in general O(N * log(N)), where N is the
+   //!   size of the range. However, it is linear in N if the range is already sorted
    //!   by value_comp().
    //! 
    //! <b>Throws</b>: Nothing.
@@ -512,11 +612,12 @@
    std::pair<iterator, bool> insert_unique_check
       (const KeyType &key, KeyValueCompare key_value_comp, insert_commit_data &commit_data)
    {
-      detail::key_node_ptr_compare<KeyValueCompare, ValueTraits> comp(key_value_comp);
+      detail::key_nodeptr_comp<KeyValueCompare, rbtree_impl>
+         comp(key_value_comp, this);
       std::pair<node_ptr, bool> ret = 
          (node_algorithms::insert_unique_check
             (node_ptr(&priv_header()), key, comp, commit_data));
-      return std::pair<iterator, bool>(iterator(ret.first), ret.second);
+      return std::pair<iterator, bool>(iterator(ret.first, this), ret.second);
    }
 
    std::pair<iterator, bool> insert_unique_check
@@ -528,22 +629,23 @@
       (const_iterator hint, const KeyType &key
       ,KeyValueCompare key_value_comp, insert_commit_data &commit_data)
    {
-      detail::key_node_ptr_compare<KeyValueCompare, ValueTraits> comp(key_value_comp);
+      detail::key_nodeptr_comp<KeyValueCompare, rbtree_impl>
+         comp(key_value_comp, this);
       std::pair<node_ptr, bool> ret = 
          (node_algorithms::insert_unique_check
             (node_ptr(&priv_header()), hint.pointed_node(), key, comp, commit_data));
-      return std::pair<iterator, bool>(iterator(ret.first), ret.second);
+      return std::pair<iterator, bool>(iterator(ret.first, this), ret.second);
    }
 
    iterator insert_unique_commit(reference value, const insert_commit_data &commit_data)
    {
-      node_ptr to_insert(ValueTraits::to_node_ptr(value));
+      node_ptr to_insert(get_real_value_traits().to_node_ptr(value));
       if(safemode_or_autounlink)
          BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
-      size_traits::increment();
+      this->priv_size_traits().increment();
       node_algorithms::insert_unique_commit
                (node_ptr(&priv_header()), to_insert, commit_data);
-      return iterator(to_insert);
+      return iterator(to_insert, this);
    }
 
    //! <b>Effects</b>: Erases the element pointed to by pos. 
@@ -562,7 +664,7 @@
       if(safemode_or_autounlink)
          BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!node_algorithms::unique(to_erase));
       node_algorithms::erase(&priv_header(), to_erase);
-      size_traits::decrement();
+      this->priv_size_traits().decrement();
       if(safemode_or_autounlink)
          node_algorithms::init(to_erase);
       return ret;
@@ -629,7 +731,7 @@
    {
       node_ptr to_erase(i.pointed_node());
       iterator ret(this->erase(i));
-      disposer(ValueTraits::to_value_ptr(to_erase));
+      disposer(get_real_value_traits().to_value_ptr(to_erase));
       return ret;
    }
 
@@ -706,20 +808,11 @@
    void clear()
    {
       if(safemode_or_autounlink){
-         while(1){
-            node_ptr leftmost
-               (node_algorithms::unlink_leftmost_without_rebalance
-                  (node_ptr(&priv_header())));
-            if(!leftmost)
-               break;
-            size_traits::decrement();
-            if(safemode_or_autounlink)
-               node_algorithms::init(leftmost);
-         }
+         this->clear_and_dispose(detail::null_disposer());
       }
       else{
          node_algorithms::init_header(&priv_header());
-         size_traits::set_size(0);
+         this->priv_size_traits().set_size(0);
       }
    }
 
@@ -735,17 +828,10 @@
    template<class Disposer>
    void clear_and_dispose(Disposer disposer)
    {
-      while(1){
-         node_ptr leftmost
-            (node_algorithms::unlink_leftmost_without_rebalance
-               (node_ptr(&priv_header())));
-         if(!leftmost)
-            break;
-         size_traits::decrement();
-         if(safemode_or_autounlink)
-            node_algorithms::init(leftmost);
-         disposer(ValueTraits::to_value_ptr(leftmost));
-      }
+      node_algorithms::clear_and_dispose(node_ptr(&priv_header())
+         , detail::node_disposer<Disposer, rbtree_impl>(disposer, this));
+      node_algorithms::init_header(&priv_header());
+      this->priv_size_traits().set_size(0);
    }
 
    //! <b>Effects</b>: Returns the number of contained elements with the given value
@@ -797,9 +883,10 @@
    template<class KeyType, class KeyValueCompare>
    iterator lower_bound(const KeyType &key, KeyValueCompare comp)
    {
-      detail::key_node_ptr_compare<KeyValueCompare, ValueTraits> key_node_comp(comp);
+      detail::key_nodeptr_comp<KeyValueCompare, rbtree_impl>
+         key_node_comp(comp, this);
       return iterator(node_algorithms::lower_bound
-         (const_node_ptr(&priv_header()), key, key_node_comp));
+         (const_node_ptr(&priv_header()), key, key_node_comp), this);
    }
 
    //! <b>Effects</b>: Returns a const iterator to the first element whose
@@ -811,9 +898,10 @@
    template<class KeyType, class KeyValueCompare>
    const_iterator lower_bound(const KeyType &key, KeyValueCompare comp) const
    {
-      detail::key_node_ptr_compare<KeyValueCompare, ValueTraits> key_node_comp(comp);
+      detail::key_nodeptr_comp<KeyValueCompare, rbtree_impl>
+         key_node_comp(comp, this);
       return const_iterator(node_algorithms::lower_bound
-         (const_node_ptr(&priv_header()), key, key_node_comp));
+         (const_node_ptr(&priv_header()), key, key_node_comp), this);
    }
 
    //! <b>Effects</b>: Returns an iterator to the first element whose
@@ -835,9 +923,10 @@
    template<class KeyType, class KeyValueCompare>
    iterator upper_bound(const KeyType &key, KeyValueCompare comp)
    {
-      detail::key_node_ptr_compare<KeyValueCompare, ValueTraits> key_node_comp(comp);
+      detail::key_nodeptr_comp<KeyValueCompare, rbtree_impl>
+         key_node_comp(comp, this);
       return iterator(node_algorithms::upper_bound
-         (const_node_ptr(&priv_header()), key, key_node_comp));
+         (const_node_ptr(&priv_header()), key, key_node_comp), this);
    }
 
    //! <b>Effects</b>: Returns an iterator to the first element whose
@@ -859,9 +948,10 @@
    template<class KeyType, class KeyValueCompare>
    const_iterator upper_bound(const KeyType &key, KeyValueCompare comp) const
    {
-      detail::key_node_ptr_compare<KeyValueCompare, ValueTraits> key_node_comp(comp);
+      detail::key_nodeptr_comp<KeyValueCompare, rbtree_impl>
+         key_node_comp(comp, this);
       return const_iterator(node_algorithms::upper_bound
-         (const_node_ptr(&priv_header()), key, key_node_comp));
+         (const_node_ptr(&priv_header()), key, key_node_comp), this);
    }
 
    //! <b>Effects</b>: Finds an iterator to the first element whose key is 
@@ -882,9 +972,10 @@
    template<class KeyType, class KeyValueCompare>
    iterator find(const KeyType &key, KeyValueCompare comp)
    {
-      detail::key_node_ptr_compare<KeyValueCompare, ValueTraits> key_node_comp(comp);
+      detail::key_nodeptr_comp<KeyValueCompare, rbtree_impl>
+         key_node_comp(comp, this);
       return iterator
-         (node_algorithms::find(const_node_ptr(&priv_header()), key, key_node_comp));
+         (node_algorithms::find(const_node_ptr(&priv_header()), key, key_node_comp), this);
    }
 
    //! <b>Effects</b>: Finds a const_iterator to the first element whose key is 
@@ -905,9 +996,10 @@
    template<class KeyType, class KeyValueCompare>
    const_iterator find(const KeyType &key, KeyValueCompare comp) const
    {
-      detail::key_node_ptr_compare<KeyValueCompare, ValueTraits> key_node_comp(comp);
+      detail::key_nodeptr_comp<KeyValueCompare, rbtree_impl>
+         key_node_comp(comp, this);
       return const_iterator
-         (node_algorithms::find(const_node_ptr(&priv_header()), key, key_node_comp));
+         (node_algorithms::find(const_node_ptr(&priv_header()), key, key_node_comp), this);
    }
 
    //! <b>Effects</b>: Finds a range containing all elements whose key is k or
@@ -930,10 +1022,11 @@
    template<class KeyType, class KeyValueCompare>
    std::pair<iterator,iterator> equal_range(const KeyType &key, KeyValueCompare comp)
    {
-      detail::key_node_ptr_compare<KeyValueCompare, ValueTraits> key_node_comp(comp);
+      detail::key_nodeptr_comp<KeyValueCompare, rbtree_impl>
+         key_node_comp(comp, this);
       std::pair<node_ptr, node_ptr> ret
          (node_algorithms::equal_range(const_node_ptr(&priv_header()), key, key_node_comp));
-      return std::pair<iterator, iterator>(iterator(ret.first), iterator(ret.second));
+      return std::pair<iterator, iterator>(iterator(ret.first, this), iterator(ret.second, this));
    }
 
    //! <b>Effects</b>: Finds a range containing all elements whose key is k or
@@ -958,23 +1051,24 @@
    std::pair<const_iterator, const_iterator>
       equal_range(const KeyType &key, KeyValueCompare comp) const
    {
-      detail::key_node_ptr_compare<KeyValueCompare, ValueTraits> key_node_comp(comp);
+      detail::key_nodeptr_comp<KeyValueCompare, rbtree_impl>
+         key_node_comp(comp, this);
       std::pair<node_ptr, node_ptr> ret
          (node_algorithms::equal_range(const_node_ptr(&priv_header()), key, key_node_comp));
-      return std::pair<const_iterator, const_iterator>(const_iterator(ret.first), const_iterator(ret.second));
+      return std::pair<const_iterator, const_iterator>(const_iterator(ret.first, this), const_iterator(ret.second, this));
    }
 
    template <class Cloner, class Disposer>
-   void clone_from(const rbtree &src, Cloner cloner, Disposer disposer)
+   void clone_from(const rbtree_impl &src, Cloner cloner, Disposer disposer)
    {
       this->clear_and_dispose(disposer);
       if(!src.empty()){
-         node_algorithms::clone_tree
+         node_algorithms::clone
             (const_node_ptr(&src.priv_header())
             ,node_ptr(&this->priv_header())
-            ,detail::value_to_node_cloner<Cloner, ValueTraits>(cloner)
-            ,detail::value_to_node_disposer<Disposer, ValueTraits>(disposer));
-         size_traits::set_size(src.get_size());
+            ,detail::node_cloner<Cloner, rbtree_impl>(cloner, this)
+            ,detail::node_disposer<Disposer, rbtree_impl>(disposer, this));
+         this->priv_size_traits().set_size(src.priv_size_traits().get_size());
       }
    }
 
@@ -984,10 +1078,31 @@
                            (node_ptr(&priv_header())));
       if(!to_be_disposed)
          return 0;
-      size_traits::decrement();
-      if(safemode_or_autounlink)
+      this->priv_size_traits().decrement();
+      if(safemode_or_autounlink)//If this is commented does not work with normal_link
          node_algorithms::init(to_be_disposed);
-      return ValueTraits::to_value_ptr(to_be_disposed);
+      return get_real_value_traits().to_value_ptr(to_be_disposed);
+   }
+
+   //! <b>Requires</b>: replace_this must be a valid iterator of *this
+   //!   and with_this must not be inserted in any tree.
+   //! 
+   //! <b>Effects</b>: Replaces replace_this in its position in the
+   //!   tree with with_this. The tree does not need to be rebalanced.
+   //! 
+   //! <b>Complexity</b>: Constant. 
+   //! 
+   //! <b>Throws</b>: Nothing.
+   //! 
+   //! <b>Note</b>: This function will break container ordering invariants if
+   //!   with_this is not equivalent to *replace_this according to the
+   //!   ordering rules. This function is faster than erasing and inserting
+   //!   the node, since no rebalancing or comparison is needed.
+   void replace_node(iterator replace_this, reference with_this)
+   {
+      node_algorithms::replace_node( get_real_value_traits().to_node_ptr(*replace_this)
+                                   , node_ptr(&priv_header())
+                                   , get_real_value_traits().to_node_ptr(with_this));
    }
 
    //! <b>Requires</b>: value must be an lvalue and shall be in a set of
@@ -999,8 +1114,14 @@
    //! <b>Complexity</b>: Constant.
    //! 
    //! <b>Throws</b>: Nothing.
-   static iterator iterator_to(reference value)
-   {  return iterator (ValueTraits::to_node_ptr(value));  }
+   //! 
+   //! <b>Note</b>: This static function is available only if the <i>value traits</i>
+   //!   is stateless.
+   static iterator s_iterator_to(reference value)
+   {
+      BOOST_STATIC_ASSERT((!stateful_value_traits));
+      return iterator (value_traits::to_node_ptr(value), 0);
+   }
 
    //! <b>Requires</b>: value must be an lvalue and shall be in a set of
    //!   appropriate type. Otherwise the behavior is undefined.
@@ -1010,26 +1131,55 @@
    //! 
    //! <b>Complexity</b>: Constant.
    //! 
+   //! <b>Throws</b>: Nothing.ç
+   //! 
+   //! <b>Note</b>: This static function is available only if the <i>value traits</i>
+   //!   is stateless.
+   static const_iterator s_iterator_to(const_reference value) 
+   {
+      BOOST_STATIC_ASSERT((!stateful_value_traits));
+      return const_iterator (value_traits::to_node_ptr(const_cast<reference> (value)), 0);
+   }
+
+   //! <b>Requires</b>: value must be an lvalue and shall be in a set of
+   //!   appropriate type. Otherwise the behavior is undefined.
+   //! 
+   //! <b>Effects</b>: Returns: a valid iterator i belonging to the set
+   //!   that points to the value
+   //! 
+   //! <b>Complexity</b>: Constant.
+   //! 
    //! <b>Throws</b>: Nothing.
-   static const_iterator iterator_to(const_reference value) 
-   {  return const_iterator (ValueTraits::to_node_ptr(const_cast<reference> (value))); }
-/*
-   //! <b>Requires</b>: value shall not be in a tree of the appropriate type.
+   iterator iterator_to(reference value)
+   {  return iterator (value_traits::to_node_ptr(value), this); }
+
+   //! <b>Requires</b>: value must be an lvalue and shall be in a set of
+   //!   appropriate type. Otherwise the behavior is undefined.
    //! 
-   //! <b>Effects</b>: init_node post-constructs the node data in x used by multisets of 
-   //! the appropriate type. For the accessors multiset_derived_node and multiset_member_node 
-   //! init_node has no effect, since the constructors of multiset_node_d and multiset_node_m 
-   //! have already initialized the node data. 
+   //! <b>Effects</b>: Returns: a valid const_iterator i belonging to the
+   //!   set that points to the value
+   //! 
+   //! <b>Complexity</b>: Constant.
+   //! 
+   //! <b>Throws</b>: Nothing.
+   const_iterator iterator_to(const_reference value) const
+   {  return const_iterator (value_traits::to_node_ptr(const_cast<reference> (value)), this); }
+
+   //! <b>Requires</b>: value shall not be in a tree.
+   //! 
+   //! <b>Effects</b>: init_node puts the hook of a value in a well-known default
+   //!   state.
    //! 
    //! <b>Throws</b>: Nothing.
    //! 
    //! <b>Complexity</b>: Constant time.
    //! 
-   //! <b>Note</b>: This function is meant to be used mainly with the member value_traits, 
-   //! where no implicit node initialization during construction occurs.
+   //! <b>Note</b>: This function puts the hook in the well-known default state
+   //!   used by auto_unlink and safe hooks.
    static void init_node(reference value)
-   { node_algorithms::init(node_ptr(&*ValueTraits::to_node_ptr(value))); }
+   { node_algorithms::init(value_traits::to_node_ptr(value)); }
 
+/*
    //! <b>Effects</b>: removes x from a tree of the appropriate type. It has no effect,
    //! if x is not in such a tree. 
    //! 
@@ -1047,15 +1197,16 @@
    {
       //This function is only usable for safe mode hooks and non-constant
       //time lists. 
-      //BOOST_STATIC_ASSERT((!(safemode_or_autounlink && ConstantTimeSize)));
-      BOOST_STATIC_ASSERT((!ConstantTimeSize));
+      //BOOST_STATIC_ASSERT((!(safemode_or_autounlink && constant_time_size)));
+      BOOST_STATIC_ASSERT((!constant_time_size));
       BOOST_STATIC_ASSERT((boost::is_convertible<T, value_type>::value));
-      node_ptr to_remove(ValueTraits::to_node_ptr(value));
+      node_ptr to_remove(value_traits::to_node_ptr(value));
       node_algorithms::unlink_and_rebalance(to_remove);
       if(safemode_or_autounlink)
          node_algorithms::init(to_remove);
    }
 */
+
    /// @cond
    private:
    template<class Disposer>
@@ -1073,20 +1224,55 @@
       return b;
    }
    /// @endcond
+
+   private:
+   static rbtree_impl &priv_container_from_end_iterator(const const_iterator &end_iterator)
+   {
+      header_plus_size *r = detail::parent_from_member<header_plus_size, node>
+         ( detail::get_pointer(end_iterator.pointed_node()), &header_plus_size::header_);
+      node_plus_pred_t *n = detail::parent_from_member
+         <node_plus_pred_t, header_plus_size>(r, &node_plus_pred_t::header_plus_size_);
+      data_t *d = detail::parent_from_member<data_t, node_plus_pred_t>(n, &data_t::node_plus_pred_);
+      rbtree_impl *rb  = detail::parent_from_member<rbtree_impl, data_t>(d, &rbtree_impl::data_);
+      return *rb;
+   }
 };
 
-template <class V, class P, bool C, class S>
-inline bool operator==(const rbtree<V, P, C, S>& x, const rbtree<V, P, C, S>& y)
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+template<class T, class ...Options>
+#else
+template<class Config>
+#endif
+inline bool operator<
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+(const rbtree_impl<T, Options...> &x, const rbtree_impl<T, Options...> &y)
+#else
+(const rbtree_impl<Config> &x, const rbtree_impl<Config> &y)
+#endif
+{  return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());  }
+
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+template<class T, class ...Options>
+#else
+template<class Config>
+#endif
+bool operator==
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+(const rbtree_impl<T, Options...> &x, const rbtree_impl<T, Options...> &y)
+#else
+(const rbtree_impl<Config> &x, const rbtree_impl<Config> &y)
+#endif
 {
-   if(C && x.size() != y.size()){
+   typedef rbtree_impl<Config> tree_type;
+   typedef typename tree_type::const_iterator const_iterator;
+   const bool CS = tree_type::constant_time_size;
+   if(CS && x.size() != y.size()){
       return false;
    }
-   typedef typename rbtree<V, P, C, S>::const_iterator const_iterator;
    const_iterator end1 = x.end();
-
    const_iterator i1 = x.begin();
    const_iterator i2 = y.begin();
-   if(C){
+   if(CS){
       while (i1 != end1 && *i1 == *i2) {
          ++i1;
          ++i2;
@@ -1103,31 +1289,151 @@
    }
 }
 
-template <class V, class P, bool C, class S>
-inline bool operator<(const rbtree<V, P, C, S>& x,
-                      const rbtree<V, P, C, S>& y)
-{  return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());  }
-
-template <class V, class P, bool C, class S>
-inline bool operator!=(const rbtree<V, P, C, S>& x, const rbtree<V, P, C, S>& y) 
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+template<class T, class ...Options>
+#else
+template<class Config>
+#endif
+inline bool operator!=
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+(const rbtree_impl<T, Options...> &x, const rbtree_impl<T, Options...> &y)
+#else
+(const rbtree_impl<Config> &x, const rbtree_impl<Config> &y)
+#endif
 {  return !(x == y); }
 
-template <class V, class P, bool C, class S>
-inline bool operator>(const rbtree<V, P, C, S>& x, const rbtree<V, P, C, S>& y) 
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+template<class T, class ...Options>
+#else
+template<class Config>
+#endif
+inline bool operator>
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+(const rbtree_impl<T, Options...> &x, const rbtree_impl<T, Options...> &y)
+#else
+(const rbtree_impl<Config> &x, const rbtree_impl<Config> &y)
+#endif
 {  return y < x;  }
 
-template <class V, class P, bool C, class S>
-inline bool operator<=(const rbtree<V, P, C, S>& x, const rbtree<V, P, C, S>& y) 
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+template<class T, class ...Options>
+#else
+template<class Config>
+#endif
+inline bool operator<=
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+(const rbtree_impl<T, Options...> &x, const rbtree_impl<T, Options...> &y)
+#else
+(const rbtree_impl<Config> &x, const rbtree_impl<Config> &y)
+#endif
 {  return !(y < x);  }
 
-template <class V, class P, bool C, class S>
-inline bool operator>=(const rbtree<V, P, C, S>& x, const rbtree<V, P, C, S>& y) 
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+template<class T, class ...Options>
+#else
+template<class Config>
+#endif
+inline bool operator>=
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+(const rbtree_impl<T, Options...> &x, const rbtree_impl<T, Options...> &y)
+#else
+(const rbtree_impl<Config> &x, const rbtree_impl<Config> &y)
+#endif
 {  return !(x < y);  }
 
-template <class V, class P, bool C, class S>
-inline void swap(rbtree<V, P, C, S>& x, rbtree<V, P, C, S>& y)
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+template<class T, class ...Options>
+#else
+template<class Config>
+#endif
+inline void swap
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+(rbtree_impl<T, Options...> &x, rbtree_impl<T, Options...> &y)
+#else
+(rbtree_impl<Config> &x, rbtree_impl<Config> &y)
+#endif
 {  x.swap(y);  }
 
+/// @cond
+template<class T, class O1 = none, class O2 = none
+                , class O3 = none, class O4 = none
+                , class O5 = none, class O6 = none
+                , class O7 = none
+                >
+struct make_rbtree_opt
+{
+   typedef typename pack_options
+      < set_defaults<T>, O1, O2, O3, O4>::type packed_options;
+   typedef typename detail::get_value_traits
+      <T, typename packed_options::value_traits>::type value_traits;
+
+   typedef setopt
+         < value_traits
+         , typename packed_options::compare
+         , typename packed_options::size_type
+         , packed_options::constant_time_size
+         > type;
+};
+/// @endcond
+
+//! Helper metafunction to define a \c rbtree that yields to the same type when the
+//! same options (either explicitly or implicitly) are used.
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+template<class T, class ...Options>
+#else
+template<class T, class O1 = none, class O2 = none
+                , class O3 = none, class O4 = none>
+#endif
+struct make_rbtree
+{
+   /// @cond
+   typedef rbtree_impl
+      < typename make_rbtree_opt<T, O1, O2, O3, O4>::type
+      > implementation_defined;
+   /// @endcond
+   typedef implementation_defined type;
+};
+
+#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+template<class T, class O1, class O2, class O3, class O4>
+class rbtree
+   :  public make_rbtree<T, O1, O2, O3, O4>::type
+{
+   typedef typename make_rbtree
+      <T, O1, O2, O3, O4>::type   Base;
+
+   public:
+   typedef typename Base::value_compare      value_compare;
+   typedef typename Base::value_traits       value_traits;
+   typedef typename Base::real_value_traits  real_value_traits;
+   typedef typename Base::iterator           iterator;
+   typedef typename Base::const_iterator     const_iterator;
+
+   //Assert if passed value traits are compatible with the type
+   BOOST_STATIC_ASSERT((detail::is_same<typename real_value_traits::value_type, T>::value));
+
+   rbtree( const value_compare &cmp = value_compare()
+         , const value_traits &v_traits = value_traits())
+      :  Base(cmp, v_traits)
+   {}
+
+   template<class Iterator>
+   rbtree( bool unique, Iterator b, Iterator e
+         , const value_compare &cmp = value_compare()
+         , const value_traits &v_traits = value_traits())
+      :  Base(unique, b, e, cmp, v_traits)
+   {}
+
+   static rbtree &container_from_end_iterator(iterator end_iterator)
+   {  return static_cast<rbtree &>(Base::container_from_end_iterator(end_iterator));   }
+
+   static const rbtree &container_from_end_iterator(const_iterator end_iterator)
+   {  return static_cast<const rbtree &>(Base::container_from_end_iterator(end_iterator));   }
+};
+
+#endif
+
+
 } //namespace intrusive 
 } //namespace boost 
 
Modified: trunk/boost/intrusive/rbtree_algorithms.hpp
==============================================================================
--- trunk/boost/intrusive/rbtree_algorithms.hpp	(original)
+++ trunk/boost/intrusive/rbtree_algorithms.hpp	2007-09-26 11:26:35 EDT (Wed, 26 Sep 2007)
@@ -35,6 +35,15 @@
 // in supporting documentation.  Hewlett-Packard Company makes no
 // representations about the suitability of this software for any
 // purpose.  It is provided "as is" without express or implied warranty.
+//
+// The tree destruction algorithm is based on Julienne Walker and The EC Team code: 
+// 
+// This code is in the public domain. Anyone may use it or change it in any way that
+// they see fit. The author assumes no responsibility for damages incurred through
+// use of the original code or any variations thereof. 
+// 
+// It is requested, but not required, that due credit is given to the original author
+// and anyone who has modified the code through a header comment, such as this one. 
 
 #ifndef BOOST_INTRUSIVE_RBTREE_ALGORITHMS_HPP
 #define BOOST_INTRUSIVE_RBTREE_ALGORITHMS_HPP
@@ -43,9 +52,7 @@
 #include <boost/intrusive/detail/assert.hpp>
 #include <boost/intrusive/intrusive_fwd.hpp>
 #include <cstddef>
-#ifndef BOOST_INTRUSIVE_DISABLE_EXCEPTION_HANDLING
-#include <boost/detail/no_exceptions_support.hpp>
-#endif
+#include <boost/intrusive/detail/no_exceptions_support.hpp>
 #include <boost/intrusive/detail/utilities.hpp>
 
 
@@ -67,7 +74,7 @@
 //! relinked into its place, rather than copied, so that the only
 //! pointers invalidated are those referring to the deleted node.
 //!
-//! rbtree_algorithms is configured with a NodeTraits class, which capsulates the
+//! rbtree_algorithms is configured with a NodeTraits class, which encapsulates the
 //! information about the node to be manipulated. NodeTraits must support the
 //! following interface:
 //!
@@ -111,6 +118,7 @@
    /// @endcond
 
    public:
+   typedef NodeTraits                           node_traits;
    typedef typename NodeTraits::node_ptr        node_ptr;
    typedef typename NodeTraits::const_node_ptr  const_node_ptr;
    typedef typename NodeTraits::color           color;
@@ -121,6 +129,27 @@
    {
       return node_ptr(const_cast<node*>(::boost::intrusive::detail::get_pointer(ptr)));
    }
+
+   static void swap_left(node_ptr this_node, node_ptr other_node) 
+   { 
+      node_ptr temp(NodeTraits::get_left(this_node)); 
+      NodeTraits::set_left(this_node, NodeTraits::get_left(other_node)); 
+      NodeTraits::set_left(other_node, temp); 
+   }
+
+   static void swap_right(node_ptr this_node, node_ptr other_node) 
+   { 
+      node_ptr temp(NodeTraits::get_right(this_node)); 
+      NodeTraits::set_right(this_node, NodeTraits::get_right(other_node)); 
+      NodeTraits::set_right(other_node, temp); 
+   }
+
+   static void swap_parent(node_ptr this_node, node_ptr other_node) 
+   { 
+      node_ptr temp(NodeTraits::get_parent(this_node)); 
+      NodeTraits::set_parent(this_node, NodeTraits::get_parent(other_node)); 
+      NodeTraits::set_parent(other_node, temp); 
+   }
    /// @endcond
 
    public:
@@ -146,7 +175,14 @@
    //! 
    //! <b>Throws</b>: Nothing.
    static void swap_tree(node_ptr header1, node_ptr header2)
-   {
+   {/*
+      if(NodeTraits::get_parent(header1)){
+         NodeTraits::node n1;
+         node_ptr n2(NodeTraits::get_parent(header1));
+         init(&n1);
+         swap_nodes(&n1, n2);
+         swap_nodes(&n1, n2);
+      }*/
       if(header1 == header2)
          return;
    
@@ -185,6 +221,276 @@
       }
    }
 
+   static node_ptr get_header(const_node_ptr node)
+   {
+      node_ptr h = uncast(node);
+      if(NodeTraits::get_parent(node)){
+         h = NodeTraits::get_parent(node);
+         while(!is_header(h))
+            h = NodeTraits::get_parent(h);
+      }
+      return h;
+   }
+
+   //! <b>Requires</b>: node1 and node2 can't be header nodes
+   //!  of two trees.
+   //! 
+   //! <b>Effects</b>: Swaps two nodes. After the function node1 will be inserted
+   //!   in the position node2 before the function. node2 will be inserted in the
+   //!   position node1 had before the function.
+   //! 
+   //! <b>Complexity</b>: Logarithmic. 
+   //! 
+   //! <b>Throws</b>: Nothing.
+   //! 
+   //! <b>Note</b>: This function will break container ordering invariants if
+   //!   node1 and node2 are not equivalent according to the ordering rules.
+   //!
+   //!Experimental function
+   static void swap_nodes(node_ptr node1, node_ptr node2)
+   {
+      if(node1 == node2)
+         return;
+   
+      node_ptr header1(get_header(node1)), header2(get_header(node2));
+      swap_nodes(node1, header1, node2, header2);
+   }
+
+   //! <b>Requires</b>: node1 and node2 can't be header nodes
+   //!  of two trees with header header1 and header2.
+   //! 
+   //! <b>Effects</b>: Swaps two nodes. After the function node1 will be inserted
+   //!   in the position node2 before the function. node2 will be inserted in the
+   //!   position node1 had before the function.
+   //! 
+   //! <b>Complexity</b>: Constant. 
+   //! 
+   //! <b>Throws</b>: Nothing.
+   //! 
+   //! <b>Note</b>: This function will break container ordering invariants if
+   //!   node1 and node2 are not equivalent according to the ordering rules.
+   //!
+   //!Experimental function
+   static void swap_nodes(node_ptr node1, node_ptr header1, node_ptr node2, node_ptr header2)
+   {
+      if(node1 == node2)
+         return;
+   
+      //node1 and node2 must not be header nodes 
+      //BOOST_INTRUSIVE_INVARIANT_ASSERT((header1 != node1 && header2 != node2));
+      if(header1 != header2){
+         //Update header1 if necessary
+         if(node1 == NodeTraits::get_left(header1)){
+            NodeTraits::set_left(header1, node2);
+         }
+
+         if(node1 == NodeTraits::get_right(header1)){
+            NodeTraits::set_right(header1, node2);
+         }
+
+         if(node1 == NodeTraits::get_parent(header1)){
+            NodeTraits::set_parent(header1, node2);
+         }
+
+         //Update header2 if necessary
+         if(node2 == NodeTraits::get_left(header2)){
+            NodeTraits::set_left(header2, node1);
+         }
+
+         if(node2 == NodeTraits::get_right(header2)){
+            NodeTraits::set_right(header2, node1);
+         }
+
+         if(node2 == NodeTraits::get_parent(header2)){
+            NodeTraits::set_parent(header2, node1);
+         }
+      }
+      else{
+         //If both nodes are from the same tree
+         //Update header if necessary
+         if(node1 == NodeTraits::get_left(header1)){
+            NodeTraits::set_left(header1, node2);
+         }
+         else if(node2 == NodeTraits::get_left(header2)){
+            NodeTraits::set_left(header2, node1);
+         }
+
+         if(node1 == NodeTraits::get_right(header1)){
+            NodeTraits::set_right(header1, node2);
+         }
+         else if(node2 == NodeTraits::get_right(header2)){
+            NodeTraits::set_right(header2, node1);
+         }
+
+         if(node1 == NodeTraits::get_parent(header1)){
+            NodeTraits::set_parent(header1, node2);
+         }
+         else if(node2 == NodeTraits::get_parent(header2)){
+            NodeTraits::set_parent(header2, node1);
+         }
+
+         //Adjust data in nodes to be swapped
+         //so that final link swap works as expected
+         if(node1 == NodeTraits::get_parent(node2)){
+            NodeTraits::set_parent(node2, node2);
+
+            if(node2 == NodeTraits::get_right(node1)){
+               NodeTraits::set_right(node1, node1);
+            }
+            else{
+               NodeTraits::set_left(node1, node1);
+            }
+         }
+         else if(node2 == NodeTraits::get_parent(node1)){
+            NodeTraits::set_parent(node1, node1);
+
+            if(node1 == NodeTraits::get_right(node2)){
+               NodeTraits::set_right(node2, node2);
+            }
+            else{
+               NodeTraits::set_left(node2, node2);
+            }
+         }
+      }
+
+      //Now swap all the links
+      node_ptr temp;
+      //swap left link
+      temp = NodeTraits::get_left(node1);
+      NodeTraits::set_left(node1, NodeTraits::get_left(node2));
+      NodeTraits::set_left(node2, temp);
+      //swap right link
+      temp = NodeTraits::get_right(node1);
+      NodeTraits::set_right(node1, NodeTraits::get_right(node2));
+      NodeTraits::set_right(node2, temp);
+      //swap parent link
+      temp = NodeTraits::get_parent(node1);
+      NodeTraits::set_parent(node1, NodeTraits::get_parent(node2));
+      NodeTraits::set_parent(node2, temp);
+      //Swap color
+      color c = NodeTraits::get_color(node1);
+      NodeTraits::set_color(node1, NodeTraits::get_color(node2)); 
+      NodeTraits::set_color(node2, c); 
+
+      //Now adjust adjacent nodes for newly inserted node 1
+      if((temp = NodeTraits::get_left(node1))){
+         NodeTraits::set_parent(temp, node1);
+      }
+      if((temp = NodeTraits::get_right(node1))){
+         NodeTraits::set_parent(temp, node1);
+      }
+      if((temp = NodeTraits::get_parent(node1)) &&
+         //The header has been already updated so avoid it
+         temp != header2){
+         if(NodeTraits::get_left(temp) == node2){
+            NodeTraits::set_left(temp, node1);
+         }
+         if(NodeTraits::get_right(temp) == node2){
+            NodeTraits::set_right(temp, node1);
+         }
+      }
+      //Now adjust adjacent nodes for newly inserted node 2
+      if((temp = NodeTraits::get_left(node2))){
+         NodeTraits::set_parent(temp, node2);
+      }
+      if((temp = NodeTraits::get_right(node2))){
+         NodeTraits::set_parent(temp, node2);
+      }
+      if((temp = NodeTraits::get_parent(node2)) &&
+         //The header has been already updated so avoid it
+         temp != header1){
+         if(NodeTraits::get_left(temp) == node1){
+            NodeTraits::set_left(temp, node2);
+         }
+         if(NodeTraits::get_right(temp) == node1){
+            NodeTraits::set_right(temp, node2);
+         }
+      }
+   }
+
+   //! <b>Requires</b>: node_to_be_replaced must be inserted in a tree
+   //!   and new_node must not be inserted in a tree.
+   //! 
+   //! <b>Effects</b>: Replaces node_to_be_replaced in its position in the
+   //!   tree with new_node. The tree does not need to be rebalanced
+   //! 
+   //! <b>Complexity</b>: Logarithmic. 
+   //! 
+   //! <b>Throws</b>: Nothing.
+   //! 
+   //! <b>Note</b>: This function will break container ordering invariants if
+   //!   new_node is not equivalent to node_to_be_replaced according to the
+   //!   ordering rules. This function is faster than erasing and inserting
+   //!   the node, since no rebalancing and comparison is needed.
+   //!
+   //!Experimental function
+   static void replace_node(node_ptr node_to_be_replaced, node_ptr new_node)
+   {
+      if(node_to_be_replaced == new_node)
+         return;
+      replace_node(node_to_be_replaced, get_header(node_to_be_replaced), new_node);
+   }
+
+   //! <b>Requires</b>: node_to_be_replaced must be inserted in a tree
+   //!   with header "header" and new_node must not be inserted in a tree.
+   //! 
+   //! <b>Effects</b>: Replaces node_to_be_replaced in its position in the
+   //!   tree with new_node. The tree does not need to be rebalanced
+   //! 
+   //! <b>Complexity</b>: Constant. 
+   //! 
+   //! <b>Throws</b>: Nothing.
+   //! 
+   //! <b>Note</b>: This function will break container ordering invariants if
+   //!   new_node is not equivalent to node_to_be_replaced according to the
+   //!   ordering rules. This function is faster than erasing and inserting
+   //!   the node, since no rebalancing or comparison is needed.
+   //!
+   //!Experimental function
+   static void replace_node(node_ptr node_to_be_replaced, node_ptr header, node_ptr new_node)
+   {
+      if(node_to_be_replaced == new_node)
+         return;
+   
+      //Update header if necessary
+      if(node_to_be_replaced == NodeTraits::get_left(header)){
+         NodeTraits::set_left(header, new_node);
+      }
+
+      if(node_to_be_replaced == NodeTraits::get_right(header)){
+         NodeTraits::set_right(header, new_node);
+      }
+
+      if(node_to_be_replaced == NodeTraits::get_parent(header)){
+         NodeTraits::set_parent(header, new_node);
+      }
+
+      //Now set data from the original node
+      node_ptr temp;
+      NodeTraits::set_left(new_node, NodeTraits::get_left(node_to_be_replaced));
+      NodeTraits::set_right(new_node, NodeTraits::get_right(node_to_be_replaced));
+      NodeTraits::set_parent(new_node, NodeTraits::get_parent(node_to_be_replaced));
+      NodeTraits::set_color(new_node, NodeTraits::get_color(node_to_be_replaced)); 
+
+      //Now adjust adjacent nodes for newly inserted node
+      if((temp = NodeTraits::get_left(new_node))){
+         NodeTraits::set_parent(temp, new_node);
+      }
+      if((temp = NodeTraits::get_right(new_node))){
+         NodeTraits::set_parent(temp, new_node);
+      }
+      if((temp = NodeTraits::get_parent(new_node)) &&
+         //The header has been already updated so avoid it
+         temp != header){
+         if(NodeTraits::get_left(temp) == node_to_be_replaced){
+            NodeTraits::set_left(temp, new_node);
+         }
+         if(NodeTraits::get_right(temp) == node_to_be_replaced){
+            NodeTraits::set_right(temp, new_node);
+         }
+      }
+   }
+
    //! <b>Requires</b>: node is a tree node but not the header.
    //! 
    //! <b>Effects</b>: Unlinks the node and rebalances the tree.
@@ -202,6 +508,10 @@
       }
    }
 
+   static void unlink(node_ptr node)
+   {  unlink_and_rebalance(node);   }
+
+
    //! <b>Requires</b>: header is the header of a tree.
    //! 
    //! <b>Effects</b>: Unlinks the leftmost node from the tree, and
@@ -508,25 +818,42 @@
    //! 
    //! <b>Throws</b>: If cloner functor throws. If this happens target nodes are disposed.
    template <class Cloner, class Disposer>
-   static void clone_tree
+   static void clone
       (const_node_ptr source_header, node_ptr target_header, Cloner cloner, Disposer disposer)
    {
       if(!unique(target_header)){
-         node_ptr p;
-         while((p = unlink_leftmost_without_rebalance(target_header))){
-            disposer(p);
-         }
+         clear_and_dispose(target_header, disposer);
       }
 
-      node_ptr source_root = NodeTraits::get_parent(source_header);
+      node_ptr leftmost, rightmost;
+      node_ptr new_root = clone_subtree
+         (source_header, target_header, cloner, disposer, leftmost, rightmost);
+
+      //Now update header node
+      NodeTraits::set_parent(target_header, new_root);
+      NodeTraits::set_left  (target_header, leftmost);
+      NodeTraits::set_right (target_header, rightmost);
+   }
+
+   //! <b>Requires</b>: "disposer" must be an object function
+   //!   taking a node_ptr parameter and shouldn't throw.
+   //!
+   //! <b>Effects</b>: Empties the target tree calling 
+   //!   <tt>void disposer::operator()(node_ptr)</tt> for every node of the tree
+   //!    except the header.
+   //! 
+   //! <b>Complexity</b>: Linear to the number of element of the source tree plus the.
+   //!   number of elements of tree target tree when calling this function.
+   //! 
+   //! <b>Throws</b>: If cloner functor throws. If this happens target nodes are disposed.
+   template<class Disposer>
+   static void clear_and_dispose(node_ptr header, Disposer disposer)
+   {
+      node_ptr source_root = NodeTraits::get_parent(header);
       if(!source_root)
          return;
-
-      NodeTraits::set_parent
-         ( target_header
-         , deep_clone_node(source_root, target_header, cloner, disposer));
-      NodeTraits::set_left(target_header, minimum(NodeTraits::get_parent(target_header)));
-      NodeTraits::set_right(target_header, maximum(NodeTraits::get_parent(target_header)));
+      dispose_subtree(source_root, disposer);
+      init_header(header);
    }
 
    //! <b>Requires</b>: "header" must be the header node of a tree.
@@ -694,6 +1021,17 @@
       bool link_left = (y == h) || 
                         comp(new_node, y);
       link_and_balance(new_node, y, link_left, h);
+/*
+      //erase me
+      NodeTraits::node n;
+      init(&n);
+      if(y!=h)
+         x = x;
+      node_ptr n1(y!=h ? y : &n);
+      node_ptr n2(new_node);
+      swap_nodes(n2, n1);
+      swap_nodes(n2, n1);
+*/
       return new_node;
    }
 
@@ -725,6 +1063,17 @@
       bool link_left = (y == h) || 
                         !comp(y, new_node);
       link_and_balance(new_node, y, link_left, h);
+/*
+      //erase me
+      NodeTraits::node n;
+      init(&n);
+      if(y!=h)
+         x = x;
+      node_ptr n1(y!=h ? y : &n);
+      node_ptr n2(new_node);
+      swap_nodes(n2, n1);
+      swap_nodes(n2, n1);
+*/
       return new_node;
    }
 
@@ -752,6 +1101,14 @@
             !comp(new_node, (prev = prev_node(hint)))){
             bool link_left = unique(header) || !NodeTraits::get_left(hint);
             link_and_balance(new_node, link_left ? hint : prev, link_left, header);
+/*
+            //erase me
+            NodeTraits::node n1;
+            node_ptr n2(new_node);
+            init(&n1);
+            swap_nodes(n2, &n1);
+            swap_nodes(&n1, n2);
+*/
             return new_node;
          }
          else{
@@ -922,6 +1279,109 @@
 
    /// @cond
 
+   template <class Cloner, class Disposer>
+   static node_ptr clone_subtree
+      ( const_node_ptr source_parent,  node_ptr target_parent
+      , Cloner cloner,                 Disposer disposer
+      , node_ptr &leftmost_out,        node_ptr &rightmost_out
+      )
+   {
+      node_ptr target_sub_root = target_parent;
+      node_ptr source_root = NodeTraits::get_parent(source_parent);
+      if(!source_root){
+         leftmost_out = rightmost_out = source_root;
+      }
+      else{
+         //We'll calculate leftmost and rightmost nodes while iterating
+         node_ptr current = source_root;
+         node_ptr insertion_point = target_sub_root = cloner(current);
+
+         //We'll calculate leftmost and rightmost nodes while iterating
+         node_ptr leftmost  = target_sub_root;
+         node_ptr rightmost = target_sub_root;
+
+         //First set the subroot
+         NodeTraits::set_left(target_sub_root, 0);
+         NodeTraits::set_right(target_sub_root, 0);
+         NodeTraits::set_parent(target_sub_root, target_parent);
+         NodeTraits::set_color(target_sub_root, NodeTraits::get_color(current));
+
+         try {
+            while(true) {
+               //First clone left nodes
+               if( NodeTraits::get_left(current) &&
+                  !NodeTraits::get_left(insertion_point)) {
+                  current = NodeTraits::get_left(current);
+                  node_ptr temp = insertion_point;
+                  //Clone and mark as leaf
+                  insertion_point = cloner(current);
+                  NodeTraits::set_left  (insertion_point, 0);
+                  NodeTraits::set_right (insertion_point, 0);
+                  NodeTraits::set_color (insertion_point, NodeTraits::get_color(current));
+                  //Insert left
+                  NodeTraits::set_parent(insertion_point, temp);
+                  NodeTraits::set_left  (temp, insertion_point);
+                  //Update leftmost
+                  if(rightmost == target_sub_root)
+                     leftmost = insertion_point;
+               }
+               //Then clone right nodes
+               else if( NodeTraits::get_right(current) && 
+                       !NodeTraits::get_right(insertion_point)){
+                  current = NodeTraits::get_right(current);
+                  node_ptr temp = insertion_point;
+                  //Clone and mark as leaf
+                  insertion_point = cloner(current);
+                  NodeTraits::set_left  (insertion_point, 0);
+                  NodeTraits::set_right (insertion_point, 0);
+                  NodeTraits::set_color (insertion_point, NodeTraits::get_color(current));
+                  //Insert right
+                  NodeTraits::set_parent(insertion_point, temp);
+                  NodeTraits::set_right (temp, insertion_point);
+                  //Update rightmost
+                  rightmost = insertion_point;
+               }
+               //If not, go up
+               else if(current == source_root){
+                  break;
+               }
+               else{
+                  //Branch completed, go up searching more nodes to clone
+                  current = NodeTraits::get_parent(current);
+                  insertion_point = NodeTraits::get_parent(insertion_point);
+               }
+            }
+         }
+         catch(...) {
+            dispose_subtree(target_sub_root, disposer);
+            throw;
+         }
+         leftmost_out   = leftmost;
+         rightmost_out  = rightmost;
+      }
+      return target_sub_root;
+   }
+
+   template<class Disposer>
+   static void dispose_subtree(node_ptr x, Disposer disposer)
+   {
+      node_ptr save;
+      while (x){
+         save = NodeTraits::get_left(x);
+         if (save) {
+            // Right rotation
+            NodeTraits::set_left(x, NodeTraits::get_right(save));
+            NodeTraits::set_right(save, x);
+         }
+         else {
+            save = NodeTraits::get_right(x);
+            init(x);
+            disposer(x);
+         }
+         x = save;
+      }
+   }
+
    //! <b>Requires</b>: z is the node to be inserted, par is its parent,
    //!   left, indicates if z should be a left node of par and header is the header
    //!   of the tree.
@@ -1106,59 +1566,6 @@
       }
       NodeTraits::set_color(NodeTraits::get_parent(header), NodeTraits::black());
    }
-
-   template <class Cloner, class Disposer>
-   static node_ptr deep_clone_node
-      (node_ptr source_root, node_ptr new_parent, Cloner cloner, Disposer disposer)
-   {
-      // structural copy.  source_root and new_parent must be non-null.
-      node_ptr top = cloner(source_root);
-      NodeTraits::set_parent(top, new_parent);
-      #ifndef BOOST_INTRUSIVE_DISABLE_EXCEPTION_HANDLING
-      BOOST_TRY {
-      #endif
-         if(NodeTraits::get_right(source_root)){
-            NodeTraits::set_right
-               (top, deep_clone_node(NodeTraits::get_right(source_root), top
-                                    ,cloner, disposer));
-         }
-         new_parent = top;
-         source_root = NodeTraits::get_left(source_root);
-
-         while(source_root){
-            node_ptr y = cloner(source_root);
-            NodeTraits::set_left(new_parent, y);
-            NodeTraits::set_parent(y, new_parent);
-
-            if(NodeTraits::get_right(source_root)){
-               NodeTraits::set_right(y, deep_clone_node(NodeTraits::get_right(source_root), y
-                                                    ,cloner, disposer));
-            }
-            new_parent = y;
-            source_root = NodeTraits::get_left(source_root);
-         }
-      #ifndef BOOST_INTRUSIVE_DISABLE_EXCEPTION_HANDLING
-      }
-      BOOST_CATCH(...){
-         deep_dispose_node(top, disposer);
-         BOOST_RETHROW;
-      }
-      BOOST_CATCH_END
-      #endif
-      return top;
-   }
-
-   template<class Disposer>
-   static void deep_dispose_node(node_ptr x, Disposer disposer)
-   {
-      // erase without rebalancing
-      while(x){
-         deep_dispose_node(NodeTraits::get_right(x), disposer);
-         node_ptr y = NodeTraits::get_left(x);
-         disposer(x);
-         x = y;
-      }
-   }
    /// @endcond
 };
 
Modified: trunk/boost/intrusive/set.hpp
==============================================================================
--- trunk/boost/intrusive/set.hpp	(original)
+++ trunk/boost/intrusive/set.hpp	2007-09-26 11:26:35 EDT (Wed, 26 Sep 2007)
@@ -24,63 +24,59 @@
 //! The class template set is an intrusive container, that mimics most of 
 //! the interface of std::set as described in the C++ standard.
 //! 
-//! The template parameter ValueTraits is called "value traits". It stores
-//! information and operations about the type to be stored in the container.
+//! The template parameter \c T is the type to be managed by the container.
+//! The user can specify additional options and if no options are provided
+//! default options are used.
 //!
-//! The template parameter Compare, provides a function object that can compare two 
-//!   element values as sort keys to determine their relative order in the set. 
-//!
-//! If the user specifies ConstantTimeSize as "true", a member of type SizeType
-//! will be embedded in the class, that will keep track of the number of stored objects.
-//! This will allow constant-time O(1) size() member, instead of default O(N) size.
-template < class ValueTraits
-         , class Compare         //= std::less<typename ValueTraits::value_type>
-         , bool ConstantTimeSize //= true
-         , class SizeType        //= std::size_t
-         >
-class set
+//! The container supports the following options:
+//! \c base_hook<>/member_hook<>/value_traits<>,
+//! \c constant_time_size<>, \c size_type<> and
+//! \c compare<>.
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+template<class T, class ...Options>
+#else
+template<class Config>
+#endif
+class set_impl
 {
    /// @cond
-   typedef rbtree<ValueTraits, Compare, ConstantTimeSize, SizeType> tree_type;
-
+   typedef rbtree_impl<Config> tree_type;
    //! This class is
    //! non-copyable
-   set (const set&);
+   set_impl (const set_impl&);
 
    //! This class is
    //! non-assignable
-   set &operator =(const set&);
+   set_impl &operator =(const set_impl&);
 
    typedef tree_type implementation_defined;
    /// @endcond
 
    public:
-   typedef ValueTraits                                               value_traits;
-   typedef typename ValueTraits::value_type                          value_type;
-   typedef typename ValueTraits::pointer                             pointer;
-   typedef typename ValueTraits::const_pointer                       const_pointer;
-   typedef typename std::iterator_traits<pointer>::reference         reference;
-   typedef typename std::iterator_traits<const_pointer>::reference   const_reference;
-   typedef typename std::iterator_traits<pointer>::difference_type   difference_type;
-   typedef SizeType                                                  size_type;
-   typedef value_type                                                key_type;
-   typedef Compare                                                   value_compare;
-   typedef value_compare                                             key_compare;
+   typedef typename implementation_defined::value_type               value_type;
+   typedef typename implementation_defined::value_traits             value_traits;
+   typedef typename implementation_defined::pointer                  pointer;
+   typedef typename implementation_defined::const_pointer            const_pointer;
+   typedef typename implementation_defined::reference                reference;
+   typedef typename implementation_defined::const_reference          const_reference;
+   typedef typename implementation_defined::difference_type          difference_type;
+   typedef typename implementation_defined::size_type                size_type;
+   typedef typename implementation_defined::value_compare            value_compare;
+   typedef typename implementation_defined::key_compare              key_compare;
    typedef typename implementation_defined::iterator                 iterator;
    typedef typename implementation_defined::const_iterator           const_iterator;
    typedef typename implementation_defined::reverse_iterator         reverse_iterator;
    typedef typename implementation_defined::const_reverse_iterator   const_reverse_iterator;
    typedef typename implementation_defined::insert_commit_data       insert_commit_data;
+   typedef typename implementation_defined::node_traits              node_traits;
+   typedef typename implementation_defined::node                     node;
+   typedef typename implementation_defined::node_ptr                 node_ptr;
+   typedef typename implementation_defined::const_node_ptr           const_node_ptr;
+   typedef typename implementation_defined::node_algorithms          node_algorithms;
 
    /// @cond
    private:
    tree_type tree_;
-
-   template <class V1, class P1, bool C1, class S1>
-   friend bool operator==(const set<V1, P1, C1, S1>& x, const set<V1, P1, C1, S1>& y);
-
-   template <class V1, class P1, bool C1, class S1>
-   friend bool operator<(const set<V1, P1, C1, S1>& x, const set<V1, P1, C1, S1>& y);
    /// @endcond
 
    public:
@@ -90,9 +86,10 @@
    //! 
    //! <b>Throws</b>: If value_traits::node_traits::node
    //!   constructor throws (this does not happen with predefined Boost.Intrusive hooks)
-   //!   or the copy constructor of the Compare object throws. 
-   set(const Compare &cmp = Compare()) 
-      :  tree_(cmp)
+   //!   or the copy constructor of the value_compare object throws. 
+   set_impl( const value_compare &cmp = value_compare()
+           , const value_traits &v_traits = value_traits()) 
+      :  tree_(cmp, v_traits)
    {}
 
    //! <b>Requires</b>: Dereferencing iterator must yield an lvalue of type value_type. 
@@ -106,10 +103,12 @@
    //! 
    //! <b>Throws</b>: If value_traits::node_traits::node
    //!   constructor throws (this does not happen with predefined Boost.Intrusive hooks)
-   //!   or the copy constructor/operator() of the Compare object throws. 
+   //!   or the copy constructor/operator() of the value_compare object throws. 
    template<class Iterator>
-   set(Iterator b, Iterator e, const Compare &cmp = Compare())
-      : tree_(true, b, e, cmp)
+   set_impl( Iterator b, Iterator e
+           , const value_compare &cmp = value_compare()
+           , const value_traits &v_traits = value_traits())
+      : tree_(true, b, e, cmp, v_traits)
    {  insert(b, e);  }
 
    //! <b>Effects</b>: Detaches all elements from this. The objects in the set 
@@ -119,7 +118,7 @@
    //!   value. Otherwise constant.
    //! 
    //! <b>Throws</b>: Nothing.
-   ~set() 
+   ~set_impl() 
    {}
 
    //! <b>Effects</b>: Returns an iterator pointing to the beginning of the set.
@@ -232,11 +231,11 @@
    //! <b>Throws</b>: Nothing.
    //! 
    //! <b>Complexity</b>: Constant.
-   static set &container_from_end_iterator(iterator end_iterator)
+   static set_impl &container_from_end_iterator(iterator end_iterator)
    {
-      return *detail::parent_from_member<set, tree_type>
+      return *detail::parent_from_member<set_impl, tree_type>
          ( &tree_type::container_from_end_iterator(end_iterator)
-         , &set::tree_);
+         , &set_impl::tree_);
    }
 
    //! <b>Precondition</b>: end_iterator must be a valid end const_iterator
@@ -247,11 +246,11 @@
    //! <b>Throws</b>: Nothing.
    //! 
    //! <b>Complexity</b>: Constant.
-   static const set &container_from_end_iterator(const_iterator end_iterator)
+   static const set_impl &container_from_end_iterator(const_iterator end_iterator)
    {
-      return *detail::parent_from_member<set, tree_type>
+      return *detail::parent_from_member<set_impl, tree_type>
          ( &tree_type::container_from_end_iterator(end_iterator)
-         , &set::tree_);
+         , &set_impl::tree_);
    }
 
    //! <b>Effects</b>: Returns the key_compare object used by the set.
@@ -281,7 +280,7 @@
    //! <b>Effects</b>: Returns the number of elements stored in the set.
    //! 
    //! <b>Complexity</b>: Linear to elements contained in *this if,
-   //!   ConstantTimeSize is false. Constant-time otherwise.
+   //!   constant-time size option is enabled. Constant-time otherwise.
    //! 
    //! <b>Throws</b>: Nothing.
    size_type size() const
@@ -293,7 +292,7 @@
    //! 
    //! <b>Throws</b>: If the swap() call for the comparison functor
    //!   found using ADL throws. Strong guarantee.
-   void swap(set& other)
+   void swap(set_impl& other)
    { tree_.swap(other.tree_); }
 
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
@@ -310,7 +309,7 @@
    //! 
    //! <b>Throws</b>: If cloner throws.
    template <class Cloner, class Disposer>
-   void clone_from(const set &src, Cloner cloner, Disposer disposer)
+   void clone_from(const set_impl &src, Cloner cloner, Disposer disposer)
    {  tree_.clone_from(src.tree_, cloner, disposer);  }
 
    //! <b>Requires</b>: value must be an lvalue
@@ -326,7 +325,7 @@
    //! <b>Complexity</b>: Average complexity for insert element is at
    //!   most logarithmic.
    //! 
-   //! <b>Throws</b>: If the internal Compare ordering function throws. Strong guarantee.
+   //! <b>Throws</b>: If the internal value_compare ordering function throws. Strong guarantee.
    //! 
    //! <b>Note</b>: Does not affect the validity of iterators and references.
    //!   No copy-constructors are called.
@@ -344,7 +343,7 @@
    //! <b>Complexity</b>: Logarithmic in general, but it's amortized
    //!   constant time if t is inserted immediately before hint.
    //! 
-   //! <b>Throws</b>: If the internal Compare ordering function throws. Strong guarantee.
+   //! <b>Throws</b>: If the internal value_compare ordering function throws. Strong guarantee.
    //! 
    //! <b>Note</b>: Does not affect the validity of iterators and references.
    //!   No copy-constructors are called.
@@ -449,11 +448,11 @@
    //! 
    //! <b>Effects</b>: Inserts a range into the set.
    //! 
-   //! <b>Complexity</b>: Insert range is in general O(N * log(N)), where N is the 
-   //!   size of the range. However, it is linear in N if the range is already sorted 
+   //! <b>Complexity</b>: Insert range is in general O(N * log(N)), where N is the
+   //!   size of the range. However, it is linear in N if the range is already sorted
    //!   by value_comp().
    //! 
-   //! <b>Throws</b>: If the internal Compare ordering function throws. Basic guarantee.
+   //! <b>Throws</b>: If the internal value_compare ordering function throws. Basic guarantee.
    //! 
    //! <b>Note</b>: Does not affect the validity of iterators and references.
    //!   No copy-constructors are called.
@@ -494,7 +493,7 @@
    //! 
    //! <b>Complexity</b>: O(log(size()) + this->count(value)).
    //! 
-   //! <b>Throws</b>: If the internal Compare ordering function throws. Basic guarantee.
+   //! <b>Throws</b>: If the internal value_compare ordering function throws. Basic guarantee.
    //! 
    //! <b>Note</b>: Invalidates the iterators (but not the references)
    //!    to the erased elements. No destructors are called.
@@ -556,7 +555,7 @@
    //! <b>Effects</b>: Erases all the elements with the given value.
    //!   Disposer::operator()(pointer) is called for the removed elements.
    //! 
-   //! <b>Throws</b>: If the internal Compare ordering function throws.
+   //! <b>Throws</b>: If the internal value_compare ordering function throws.
    //! 
    //! <b>Complexity</b>: O(log(size() + this->count(value)). Basic guarantee.
    //! 
@@ -618,7 +617,7 @@
    //! <b>Complexity</b>: Logarithmic to the number of elements contained plus lineal
    //!   to number of objects with the given key.
    //! 
-   //! <b>Throws</b>: If the internal Compare ordering function throws.
+   //! <b>Throws</b>: If the internal value_compare ordering function throws.
    size_type count(const_reference value) const
    {  return tree_.find(value) != end();  }
 
@@ -638,7 +637,7 @@
    //! 
    //! <b>Complexity</b>: Logarithmic.
    //! 
-   //! <b>Throws</b>: If the internal Compare ordering function throws.
+   //! <b>Throws</b>: If the internal value_compare ordering function throws.
    iterator lower_bound(const_reference value)
    {  return tree_.lower_bound(value);  }
 
@@ -666,7 +665,7 @@
    //! 
    //! <b>Complexity</b>: Logarithmic.
    //! 
-   //! <b>Throws</b>: If the internal Compare ordering function throws.
+   //! <b>Throws</b>: If the internal value_compare ordering function throws.
    const_iterator lower_bound(const_reference value) const
    {  return tree_.lower_bound(value);  }
 
@@ -694,7 +693,7 @@
    //! 
    //! <b>Complexity</b>: Logarithmic.
    //! 
-   //! <b>Throws</b>: If the internal Compare ordering function throws.
+   //! <b>Throws</b>: If the internal value_compare ordering function throws.
    iterator upper_bound(const_reference value)
    {  return tree_.upper_bound(value);  }
 
@@ -722,7 +721,7 @@
    //! 
    //! <b>Complexity</b>: Logarithmic.
    //! 
-   //! <b>Throws</b>: If the internal Compare ordering function throws.
+   //! <b>Throws</b>: If the internal value_compare ordering function throws.
    const_iterator upper_bound(const_reference value) const
    {  return tree_.upper_bound(value);  }
 
@@ -750,7 +749,7 @@
    //!
    //! <b>Complexity</b>: Logarithmic.
    //! 
-   //! <b>Throws</b>: If the internal Compare ordering function throws.
+   //! <b>Throws</b>: If the internal value_compare ordering function throws.
    iterator find(const_reference value)
    {  return tree_.find(value);  }
 
@@ -778,7 +777,7 @@
    //! 
    //! <b>Complexity</b>: Logarithmic.
    //! 
-   //! <b>Throws</b>: If the internal Compare ordering function throws.
+   //! <b>Throws</b>: If the internal value_compare ordering function throws.
    const_iterator find(const_reference value) const
    {  return tree_.find(value);  }
 
@@ -807,7 +806,7 @@
    //! 
    //! <b>Complexity</b>: Logarithmic.
    //! 
-   //! <b>Throws</b>: If the internal Compare ordering function throws.
+   //! <b>Throws</b>: If the internal value_compare ordering function throws.
    std::pair<iterator,iterator> equal_range(const_reference value)
    {  return tree_.equal_range(value);  }
 
@@ -837,7 +836,7 @@
    //! 
    //! <b>Complexity</b>: Logarithmic.
    //! 
-   //! <b>Throws</b>: If the internal Compare ordering function throws.
+   //! <b>Throws</b>: If the internal value_compare ordering function throws.
    std::pair<const_iterator, const_iterator>
       equal_range(const_reference value) const
    {  return tree_.equal_range(value);  }
@@ -872,8 +871,11 @@
    //! <b>Complexity</b>: Constant.
    //! 
    //! <b>Throws</b>: Nothing.
-   static iterator iterator_to(reference value)
-   {  return tree_type::iterator_to(value);  }
+   //! 
+   //! <b>Note</b>: This static function is available only if the <i>value traits</i>
+   //!   is stateless.
+   static iterator s_iterator_to(reference value)
+   {  return tree_type::s_iterator_to(value);  }
 
    //! <b>Requires</b>: value must be an lvalue and shall be in a set of
    //!   appropriate type. Otherwise the behavior is undefined.
@@ -884,91 +886,245 @@
    //! <b>Complexity</b>: Constant.
    //! 
    //! <b>Throws</b>: Nothing.
-   static const_iterator iterator_to(const_reference value)
-   {  return tree_type::iterator_to(value);  }
+   //! 
+   //! <b>Note</b>: This static function is available only if the <i>value traits</i>
+   //!   is stateless.
+   static const_iterator s_iterator_to(const_reference value)
+   {  return tree_type::s_iterator_to(value);  }
+
+   //! <b>Requires</b>: value must be an lvalue and shall be in a set of
+   //!   appropriate type. Otherwise the behavior is undefined.
+   //! 
+   //! <b>Effects</b>: Returns: a valid iterator i belonging to the set
+   //!   that points to the value
+   //! 
+   //! <b>Complexity</b>: Constant.
+   //! 
+   //! <b>Throws</b>: Nothing.
+   iterator iterator_to(reference value)
+   {  return tree_.iterator_to(value);  }
+
+   //! <b>Requires</b>: value must be an lvalue and shall be in a set of
+   //!   appropriate type. Otherwise the behavior is undefined.
+   //! 
+   //! <b>Effects</b>: Returns: a valid const_iterator i belonging to the
+   //!   set that points to the value
+   //! 
+   //! <b>Complexity</b>: Constant.
+   //! 
+   //! <b>Throws</b>: Nothing.
+   const_iterator iterator_to(const_reference value) const
+   {  return tree_.iterator_to(value);  }
+
+   //! <b>Requires</b>: value shall not be in a set/multiset.
+   //! 
+   //! <b>Effects</b>: init_node puts the hook of a value in a well-known default
+   //!   state.
+   //! 
+   //! <b>Throws</b>: Nothing.
+   //! 
+   //! <b>Complexity</b>: Constant time.
+   //! 
+   //! <b>Note</b>: This function puts the hook in the well-known default state
+   //!   used by auto_unlink and safe hooks.
+   static void init_node(reference value)
+   { tree_type::init_node(value);   }
+
+   //! <b>Requires</b>: replace_this must be a valid iterator of *this
+   //!   and with_this must not be inserted in any tree.
+   //! 
+   //! <b>Effects</b>: Replaces replace_this in its position in the
+   //!   tree with with_this. The tree does not need to be rebalanced.
+   //! 
+   //! <b>Complexity</b>: Constant. 
+   //! 
+   //! <b>Throws</b>: Nothing.
+   //! 
+   //! <b>Note</b>: This function will break container ordering invariants if
+   //!   with_this is not equivalent to *replace_this according to the
+   //!   ordering rules. This function is faster than erasing and inserting
+   //!   the node, since no rebalancing or comparison is needed.
+   void replace_node(iterator replace_this, reference with_this)
+   {  tree_.replace_node(replace_this, with_this);   }
 
    /// @cond
-   friend bool operator==(const set &x, const set &y)
+   friend bool operator==(const set_impl &x, const set_impl &y)
    {  return x.tree_ == y.tree_;  }
 
-   friend bool operator<(const set &x, const set &y)
+   friend bool operator<(const set_impl &x, const set_impl &y)
    {  return x.tree_ < y.tree_;  }
    /// @endcond
 };
 
-template <class V, class P, bool C, class S>
-inline bool operator!=(const set<V, P, C, S>& x, const set<V, P, C, S>& y) 
-{  return !(x==y); }
-
-template <class V, class P, bool C, class S>
-inline bool operator>(const set<V, P, C, S>& x, const set<V, P, C, S>& y) 
-{  return y < x; }
-
-template <class V, class P, bool C, class S>
-inline bool operator<=(const set<V, P, C, S>& x, const set<V, P, C, S>& y) 
-{  return !(y > x); }
-
-template <class V, class P, bool C, class S>
-inline bool operator>=(const set<V, P, C, S>& x, const set<V, P, C, S>& y) 
-{  return !(x < y); }
-
-template <class V, class P, bool C, class S>
-inline void swap(set<V, P, C, S>& x, set<V, P, C, S>& y)
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+template<class T, class ...Options>
+#else
+template<class Config>
+#endif
+inline bool operator!=
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+(const set_impl<T, Options...> &x, const set_impl<T, Options...> &y)
+#else
+(const set_impl<Config> &x, const set_impl<Config> &y)
+#endif
+{  return !(x == y); }
+
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+template<class T, class ...Options>
+#else
+template<class Config>
+#endif
+inline bool operator>
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+(const set_impl<T, Options...> &x, const set_impl<T, Options...> &y)
+#else
+(const set_impl<Config> &x, const set_impl<Config> &y)
+#endif
+{  return y < x;  }
+
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+template<class T, class ...Options>
+#else
+template<class Config>
+#endif
+inline bool operator<=
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+(const set_impl<T, Options...> &x, const set_impl<T, Options...> &y)
+#else
+(const set_impl<Config> &x, const set_impl<Config> &y)
+#endif
+{  return !(y < x);  }
+
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+template<class T, class ...Options>
+#else
+template<class Config>
+#endif
+inline bool operator>=
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+(const set_impl<T, Options...> &x, const set_impl<T, Options...> &y)
+#else
+(const set_impl<Config> &x, const set_impl<Config> &y)
+#endif
+{  return !(x < y);  }
+
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+template<class T, class ...Options>
+#else
+template<class Config>
+#endif
+inline void swap
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+(set_impl<T, Options...> &x, set_impl<T, Options...> &y)
+#else
+(set_impl<Config> &x, set_impl<Config> &y)
+#endif
 {  x.swap(y);  }
 
+//! Helper metafunction to define a \c set that yields to the same type when the
+//! same options (either explicitly or implicitly) are used.
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+template<class T, class ...Options>
+#else
+template<class T, class O1 = none, class O2 = none
+                , class O3 = none, class O4 = none>
+#endif
+struct make_set
+{
+   /// @cond
+   typedef set_impl
+      < typename make_rbtree_opt<T, O1, O2, O3, O4>::type
+      > implementation_defined;
+   /// @endcond
+   typedef implementation_defined type;
+};
+
+#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+template<class T, class O1, class O2, class O3, class O4>
+class set
+   :  public make_set<T, O1, O2, O3, O4>::type
+{
+   typedef typename make_set
+      <T, O1, O2, O3, O4>::type   Base;
+
+   public:
+   typedef typename Base::value_compare      value_compare;
+   typedef typename Base::value_traits       value_traits;
+   typedef typename Base::iterator           iterator;
+   typedef typename Base::const_iterator     const_iterator;
+
+   //Assert if passed value traits are compatible with the type
+   BOOST_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value));
+
+   set( const value_compare &cmp = value_compare()
+         , const value_traits &v_traits = value_traits())
+      :  Base(cmp, v_traits)
+   {}
+
+   template<class Iterator>
+   set( Iterator b, Iterator e
+      , const value_compare &cmp = value_compare()
+      , const value_traits &v_traits = value_traits())
+      :  Base(b, e, cmp, v_traits)
+   {}
+
+   static set &container_from_end_iterator(iterator end_iterator)
+   {  return static_cast<set &>(Base::container_from_end_iterator(end_iterator));   }
+
+   static const set &container_from_end_iterator(const_iterator end_iterator)
+   {  return static_cast<const set &>(Base::container_from_end_iterator(end_iterator));   }
+};
+
+#endif
+
 //! The class template multiset is an intrusive container, that mimics most of 
 //! the interface of std::multiset as described in the C++ standard.
 //! 
-//! The template parameter ValueTraits is called "value traits". It stores
-//! information and operations about the type to be stored
-//! in list and what type of hook has been chosen to include it in the list.
-//! The value_traits class is supplied by the appropriate hook as a template subtype 
-//! called "value_traits".
+//! The template parameter \c T is the type to be managed by the container.
+//! The user can specify additional options and if no options are provided
+//! default options are used.
 //!
-//! The template parameter Compare, provides a function object that can compare two 
-//!   element values as sort keys to determine their relative order in the set. 
-//!
-//! If the user specifies ConstantTimeSize as "true", a member of type SizeType
-//! will be embedded in the class, that will keep track of the number of stored objects.
-//! This will allow constant-time O(1) size() member, instead of default O(N) size.
-template < class ValueTraits
-         , class Compare         //= std::less<typename ValueTraits::value_type>
-         , bool ConstantTimeSize //= true
-         , class SizeType        //= std::size_t
-         >
-class multiset
+//! The container supports the following options:
+//! \c base_hook<>/member_hook<>/value_traits<>,
+//! \c constant_time_size<>, \c size_type<> and
+//! \c compare<>.
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+template<class T, class ...Options>
+#else
+template<class Config>
+#endif
+class multiset_impl
 {
    /// @cond
-   typedef rbtree<ValueTraits, Compare, ConstantTimeSize, SizeType> tree_type;
-
-   //! This class is
-   //! non-copyable
-   multiset (const multiset&);
-
-   //! This class is
-   //! non-asignable
-   multiset &operator =(const multiset&);
+   typedef rbtree_impl<Config> tree_type;
 
+   //Non-copyable and non-assignable
+   multiset_impl (const multiset_impl&);
+   multiset_impl &operator =(const multiset_impl&);
    typedef tree_type implementation_defined;
    /// @endcond
 
    public:
-   typedef ValueTraits                                               value_traits;
-   typedef typename ValueTraits::value_type                          value_type;
-   typedef typename ValueTraits::pointer                             pointer;
-   typedef typename ValueTraits::const_pointer                       const_pointer;
-   typedef typename std::iterator_traits<pointer>::reference         reference;
-   typedef typename std::iterator_traits<const_pointer>::reference   const_reference;
-   typedef typename std::iterator_traits<pointer>::difference_type   difference_type;
-   typedef SizeType                                                  size_type;
-   typedef value_type                                                key_type;
-   typedef Compare                                                   value_compare;
-   typedef value_compare                                             key_compare;
+   typedef typename implementation_defined::value_type               value_type;
+   typedef typename implementation_defined::value_traits             value_traits;
+   typedef typename implementation_defined::pointer                  pointer;
+   typedef typename implementation_defined::const_pointer            const_pointer;
+   typedef typename implementation_defined::reference                reference;
+   typedef typename implementation_defined::const_reference          const_reference;
+   typedef typename implementation_defined::difference_type          difference_type;
+   typedef typename implementation_defined::size_type                size_type;
+   typedef typename implementation_defined::value_compare            value_compare;
+   typedef typename implementation_defined::key_compare              key_compare;
    typedef typename implementation_defined::iterator                 iterator;
    typedef typename implementation_defined::const_iterator           const_iterator;
    typedef typename implementation_defined::reverse_iterator         reverse_iterator;
    typedef typename implementation_defined::const_reverse_iterator   const_reverse_iterator;
    typedef typename implementation_defined::insert_commit_data       insert_commit_data;
+   typedef typename implementation_defined::node_traits              node_traits;
+   typedef typename implementation_defined::node                     node;
+   typedef typename implementation_defined::node_ptr                 node_ptr;
+   typedef typename implementation_defined::const_node_ptr           const_node_ptr;
+   typedef typename implementation_defined::node_algorithms          node_algorithms;
 
    /// @cond
    private:
@@ -982,9 +1138,10 @@
    //! 
    //! <b>Throws</b>: If value_traits::node_traits::node
    //!   constructor throws (this does not happen with predefined Boost.Intrusive hooks)
-   //!   or the copy constructor/operator() of the Compare object throws. 
-   multiset(const Compare &cmp = Compare()) 
-      :  tree_(cmp)
+   //!   or the copy constructor/operator() of the value_compare object throws. 
+   multiset_impl( const value_compare &cmp = value_compare()
+                , const value_traits &v_traits = value_traits()) 
+      :  tree_(cmp, v_traits)
    {}
 
    //! <b>Requires</b>: Dereferencing iterator must yield an lvalue of type value_type. 
@@ -993,15 +1150,17 @@
    //! <b>Effects</b>: Constructs an empty multiset and inserts elements from 
    //!   [b, e).
    //! 
-   //! <b>Complexity</b>: Linear in N if [b, e) is already sorted using 
+   //! <b>Complexity</b>: Linear in N if [b, e) is already sorted using
    //!   comp and otherwise N * log N, where N is last  first.
    //! 
    //! <b>Throws</b>: If value_traits::node_traits::node
    //!   constructor throws (this does not happen with predefined Boost.Intrusive hooks)
-   //!   or the copy constructor/operator() of the Compare object throws. 
+   //!   or the copy constructor/operator() of the value_compare object throws. 
    template<class Iterator>
-   multiset(Iterator b, Iterator e, const Compare &cmp = Compare())
-      : tree_(false, b, e, cmp)
+   multiset_impl( Iterator b, Iterator e
+                , const value_compare &cmp = value_compare()
+                , const value_traits &v_traits = value_traits())
+      : tree_(false, b, e, cmp, v_traits)
    {}
 
    //! <b>Effects</b>: Detaches all elements from this. The objects in the set 
@@ -1011,7 +1170,7 @@
    //!   auto-unlink value. Otherwise constant.
    //! 
    //! <b>Throws</b>: Nothing.
-   ~multiset() 
+   ~multiset_impl() 
    {}
 
    //! <b>Effects</b>: Returns an iterator pointing to the beginning of the multiset.
@@ -1124,11 +1283,11 @@
    //! <b>Throws</b>: Nothing.
    //! 
    //! <b>Complexity</b>: Constant.
-   static multiset &container_from_end_iterator(iterator end_iterator)
+   static multiset_impl &container_from_end_iterator(iterator end_iterator)
    {
-      return *detail::parent_from_member<multiset, tree_type>
+      return *detail::parent_from_member<multiset_impl, tree_type>
          ( &tree_type::container_from_end_iterator(end_iterator)
-         , &multiset::tree_);
+         , &multiset_impl::tree_);
    }
 
    //! <b>Precondition</b>: end_iterator must be a valid end const_iterator
@@ -1139,11 +1298,11 @@
    //! <b>Throws</b>: Nothing.
    //! 
    //! <b>Complexity</b>: Constant.
-   static const multiset &container_from_end_iterator(const_iterator end_iterator)
+   static const multiset_impl &container_from_end_iterator(const_iterator end_iterator)
    {
-      return *detail::parent_from_member<multiset, tree_type>
+      return *detail::parent_from_member<multiset_impl, tree_type>
          ( &tree_type::container_from_end_iterator(end_iterator)
-         , &multiset::tree_);
+         , &multiset_impl::tree_);
    }
 
    //! <b>Effects</b>: Returns the key_compare object used by the multiset.
@@ -1173,7 +1332,7 @@
    //! <b>Effects</b>: Returns the number of elements stored in the multiset.
    //! 
    //! <b>Complexity</b>: Linear to elements contained in *this if,
-   //!   ConstantTimeSize is false. Constant-time otherwise.
+   //!   constant-time size option is enabled. Constant-time otherwise.
    //! 
    //! <b>Throws</b>: Nothing.
    size_type size() const
@@ -1185,7 +1344,7 @@
    //! 
    //! <b>Throws</b>: If the swap() call for the comparison functor
    //!   found using ADL throws. Strong guarantee.
-   void swap(multiset& other)
+   void swap(multiset_impl& other)
    { tree_.swap(other.tree_); }
 
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
@@ -1202,7 +1361,7 @@
    //! 
    //! <b>Throws</b>: If cloner throws. Basic guarantee.
    template <class Cloner, class Disposer>
-   void clone_from(const multiset &src, Cloner cloner, Disposer disposer)
+   void clone_from(const multiset_impl &src, Cloner cloner, Disposer disposer)
    {  tree_.clone_from(src.tree_, cloner, disposer);  }
 
    //! <b>Requires</b>: value must be an lvalue
@@ -1215,7 +1374,7 @@
    //! <b>Complexity</b>: Average complexity for insert element is at
    //!   most logarithmic.
    //! 
-   //! <b>Throws</b>: If the internal Compare ordering function throws. Strong guarantee.
+   //! <b>Throws</b>: If the internal value_compare ordering function throws. Strong guarantee.
    //! 
    //! <b>Note</b>: Does not affect the validity of iterators and references.
    //!   No copy-constructors are called.
@@ -1233,7 +1392,7 @@
    //! <b>Complexity</b>: Logarithmic in general, but it is amortized
    //!   constant time if t is inserted immediately before hint.
    //! 
-   //! <b>Throws</b>: If the internal Compare ordering function throws. Strong guarantee.
+   //! <b>Throws</b>: If the internal value_compare ordering function throws. Strong guarantee.
    //! 
    //! <b>Note</b>: Does not affect the validity of iterators and references.
    //!   No copy-constructors are called.
@@ -1248,11 +1407,11 @@
    //! <b>Returns</b>: An iterator that points to the position where the new
    //!   element was inserted.
    //! 
-   //! <b>Complexity</b>: Insert range is in general O(N * log(N)), where N is the 
-   //!   size of the range. However, it is linear in N if the range is already sorted 
+   //! <b>Complexity</b>: Insert range is in general O(N * log(N)), where N is the
+   //!   size of the range. However, it is linear in N if the range is already sorted
    //!   by value_comp().
    //! 
-   //! <b>Throws</b>: If the internal Compare ordering function throws. Basic guarantee.
+   //! <b>Throws</b>: If the internal value_compare ordering function throws. Basic guarantee.
    //! 
    //! <b>Note</b>: Does not affect the validity of iterators and references.
    //!   No copy-constructors are called.
@@ -1293,7 +1452,7 @@
    //! 
    //! <b>Complexity</b>: O(log(size() + this->count(value)).
    //! 
-   //! <b>Throws</b>: If the internal Compare ordering function throws. Basic guarantee.
+   //! <b>Throws</b>: If the internal value_compare ordering function throws. Basic guarantee.
    //! 
    //! <b>Note</b>: Invalidates the iterators (but not the references)
    //!    to the erased elements. No destructors are called.
@@ -1359,7 +1518,7 @@
    //! 
    //! <b>Complexity</b>: O(log(size() + this->count(value)).
    //! 
-   //! <b>Throws</b>: If the internal Compare ordering function throws. Basic guarantee.
+   //! <b>Throws</b>: If the internal value_compare ordering function throws. Basic guarantee.
    //! 
    //! <b>Note</b>: Invalidates the iterators (but not the references)
    //!    to the erased elements. No destructors are called.
@@ -1417,7 +1576,7 @@
    //! <b>Complexity</b>: Logarithmic to the number of elements contained plus lineal
    //!   to number of objects with the given key.
    //! 
-   //! <b>Throws</b>: If the internal Compare ordering function throws.
+   //! <b>Throws</b>: If the internal value_compare ordering function throws.
    size_type count(const_reference value) const
    {  return tree_.count(value);  }
 
@@ -1437,7 +1596,7 @@
    //! 
    //! <b>Complexity</b>: Logarithmic.
    //! 
-   //! <b>Throws</b>: If the internal Compare ordering function throws.
+   //! <b>Throws</b>: If the internal value_compare ordering function throws.
    iterator lower_bound(const_reference value)
    {  return tree_.lower_bound(value);  }
 
@@ -1465,7 +1624,7 @@
    //! 
    //! <b>Complexity</b>: Logarithmic.
    //! 
-   //! <b>Throws</b>: If the internal Compare ordering function throws.
+   //! <b>Throws</b>: If the internal value_compare ordering function throws.
    const_iterator lower_bound(const_reference value) const
    {  return tree_.lower_bound(value);  }
 
@@ -1493,7 +1652,7 @@
    //! 
    //! <b>Complexity</b>: Logarithmic.
    //! 
-   //! <b>Throws</b>: If the internal Compare ordering function throws.
+   //! <b>Throws</b>: If the internal value_compare ordering function throws.
    iterator upper_bound(const_reference value)
    {  return tree_.upper_bound(value);  }
 
@@ -1521,7 +1680,7 @@
    //! 
    //! <b>Complexity</b>: Logarithmic.
    //! 
-   //! <b>Throws</b>: If the internal Compare ordering function throws.
+   //! <b>Throws</b>: If the internal value_compare ordering function throws.
    const_iterator upper_bound(const_reference value) const
    {  return tree_.upper_bound(value);  }
 
@@ -1549,7 +1708,7 @@
    //!
    //! <b>Complexity</b>: Logarithmic.
    //! 
-   //! <b>Throws</b>: If the internal Compare ordering function throws.
+   //! <b>Throws</b>: If the internal value_compare ordering function throws.
    iterator find(const_reference value)
    {  return tree_.find(value);  }
 
@@ -1577,7 +1736,7 @@
    //! 
    //! <b>Complexity</b>: Logarithmic.
    //! 
-   //! <b>Throws</b>: If the internal Compare ordering function throws.
+   //! <b>Throws</b>: If the internal value_compare ordering function throws.
    const_iterator find(const_reference value) const
    {  return tree_.find(value);  }
 
@@ -1606,7 +1765,7 @@
    //! 
    //! <b>Complexity</b>: Logarithmic.
    //! 
-   //! <b>Throws</b>: If the internal Compare ordering function throws.
+   //! <b>Throws</b>: If the internal value_compare ordering function throws.
    std::pair<iterator,iterator> equal_range(const_reference value)
    {  return tree_.equal_range(value);  }
 
@@ -1636,7 +1795,7 @@
    //! 
    //! <b>Complexity</b>: Logarithmic.
    //! 
-   //! <b>Throws</b>: If the internal Compare ordering function throws.
+   //! <b>Throws</b>: If the internal value_compare ordering function throws.
    std::pair<const_iterator, const_iterator>
       equal_range(const_reference value) const
    {  return tree_.equal_range(value);  }
@@ -1671,8 +1830,11 @@
    //! <b>Complexity</b>: Constant.
    //! 
    //! <b>Throws</b>: Nothing.
-   static iterator iterator_to(reference value)
-   {  return tree_type::iterator_to(value);  }
+   //! 
+   //! <b>Note</b>: This static function is available only if the <i>value traits</i>
+   //!   is stateless.
+   static iterator s_iterator_to(reference value)
+   {  return tree_type::s_iterator_to(value);  }
 
    //! <b>Requires</b>: value must be an lvalue and shall be in a set of
    //!   appropriate type. Otherwise the behavior is undefined.
@@ -1683,38 +1845,197 @@
    //! <b>Complexity</b>: Constant.
    //! 
    //! <b>Throws</b>: Nothing.
-   static const_iterator iterator_to(const_reference value)
-   {  return tree_type::iterator_to(value);  }
+   //! 
+   //! <b>Note</b>: This static function is available only if the <i>value traits</i>
+   //!   is stateless.
+   static const_iterator s_iterator_to(const_reference value)
+   {  return tree_type::s_iterator_to(value);  }
+
+   //! <b>Requires</b>: value must be an lvalue and shall be in a set of
+   //!   appropriate type. Otherwise the behavior is undefined.
+   //! 
+   //! <b>Effects</b>: Returns: a valid iterator i belonging to the set
+   //!   that points to the value
+   //! 
+   //! <b>Complexity</b>: Constant.
+   //! 
+   //! <b>Throws</b>: Nothing.
+   iterator iterator_to(reference value)
+   {  return tree_.iterator_to(value);  }
+
+   //! <b>Requires</b>: value must be an lvalue and shall be in a set of
+   //!   appropriate type. Otherwise the behavior is undefined.
+   //! 
+   //! <b>Effects</b>: Returns: a valid const_iterator i belonging to the
+   //!   set that points to the value
+   //! 
+   //! <b>Complexity</b>: Constant.
+   //! 
+   //! <b>Throws</b>: Nothing.
+   const_iterator iterator_to(const_reference value) const
+   {  return tree_.iterator_to(value);  }
+
+   //! <b>Requires</b>: value shall not be in a set/multiset.
+   //! 
+   //! <b>Effects</b>: init_node puts the hook of a value in a well-known default
+   //!   state.
+   //! 
+   //! <b>Throws</b>: Nothing.
+   //! 
+   //! <b>Complexity</b>: Constant time.
+   //! 
+   //! <b>Note</b>: This function puts the hook in the well-known default state
+   //!   used by auto_unlink and safe hooks.
+   static void init_node(reference value)
+   { tree_type::init_node(value);   }
+
+   //! <b>Requires</b>: replace_this must be a valid iterator of *this
+   //!   and with_this must not be inserted in any tree.
+   //! 
+   //! <b>Effects</b>: Replaces replace_this in its position in the
+   //!   tree with with_this. The tree does not need to be rebalanced.
+   //! 
+   //! <b>Complexity</b>: Constant. 
+   //! 
+   //! <b>Throws</b>: Nothing.
+   //! 
+   //! <b>Note</b>: This function will break container ordering invariants if
+   //!   with_this is not equivalent to *replace_this according to the
+   //!   ordering rules. This function is faster than erasing and inserting
+   //!   the node, since no rebalancing or comparison is needed.
+   void replace_node(iterator replace_this, reference with_this)
+   {  tree_.replace_node(replace_this, with_this);   }
 
    /// @cond
-   friend bool operator==(const multiset &x, const multiset &y)
+   friend bool operator==(const multiset_impl &x, const multiset_impl &y)
    {  return x.tree_ == y.tree_;  }
 
-   friend bool operator<(const multiset &x, const multiset &y)
+   friend bool operator<(const multiset_impl &x, const multiset_impl &y)
    {  return x.tree_ < y.tree_;  }
    /// @endcond
 };
 
-template <class V, class P, bool C, class S>
-inline bool operator!=(const multiset<V, P, C, S>& x, const multiset<V, P, C, S>& y) 
-{  return !(x==y); }
-
-template <class V, class P, bool C, class S>
-inline bool operator>(const multiset<V, P, C, S>& x, const multiset<V, P, C, S>& y) 
-{  return y < x; }
-
-template <class V, class P, bool C, class S>
-inline bool operator<=(const multiset<V, P, C, S>& x, const multiset<V, P, C, S>& y) 
-{  return !(y > x); }
-
-template <class V, class P, bool C, class S>
-inline bool operator>=(const multiset<V, P, C, S>& x, const multiset<V, P, C, S>& y) 
-{  return !(x < y); }
-
-template <class V, class P, bool C, class S>
-inline void swap(multiset<V, P, C, S>& x, multiset<V, P, C, S>& y)
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+template<class T, class ...Options>
+#else
+template<class Config>
+#endif
+inline bool operator!=
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+(const multiset_impl<T, Options...> &x, const multiset_impl<T, Options...> &y)
+#else
+(const multiset_impl<Config> &x, const multiset_impl<Config> &y)
+#endif
+{  return !(x == y); }
+
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+template<class T, class ...Options>
+#else
+template<class Config>
+#endif
+inline bool operator>
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+(const multiset_impl<T, Options...> &x, const multiset_impl<T, Options...> &y)
+#else
+(const multiset_impl<Config> &x, const multiset_impl<Config> &y)
+#endif
+{  return y < x;  }
+
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+template<class T, class ...Options>
+#else
+template<class Config>
+#endif
+inline bool operator<=
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+(const multiset_impl<T, Options...> &x, const multiset_impl<T, Options...> &y)
+#else
+(const multiset_impl<Config> &x, const multiset_impl<Config> &y)
+#endif
+{  return !(y < x);  }
+
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+template<class T, class ...Options>
+#else
+template<class Config>
+#endif
+inline bool operator>=
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+(const multiset_impl<T, Options...> &x, const multiset_impl<T, Options...> &y)
+#else
+(const multiset_impl<Config> &x, const multiset_impl<Config> &y)
+#endif
+{  return !(x < y);  }
+
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+template<class T, class ...Options>
+#else
+template<class Config>
+#endif
+inline void swap
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+(multiset_impl<T, Options...> &x, multiset_impl<T, Options...> &y)
+#else
+(multiset_impl<Config> &x, multiset_impl<Config> &y)
+#endif
 {  x.swap(y);  }
 
+//! Helper metafunction to define a \c multiset that yields to the same type when the
+//! same options (either explicitly or implicitly) are used.
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+template<class T, class ...Options>
+#else
+template<class T, class O1 = none, class O2 = none
+                , class O3 = none, class O4 = none>
+#endif
+struct make_multiset
+{
+   /// @cond
+   typedef multiset_impl
+      < typename make_rbtree_opt<T, O1, O2, O3, O4>::type
+      > implementation_defined;
+   /// @endcond
+   typedef implementation_defined type;
+};
+
+#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+template<class T, class O1, class O2, class O3, class O4>
+class multiset
+   :  public make_multiset<T, O1, O2, O3, O4>::type
+{
+   typedef typename make_multiset
+      <T, O1, O2, O3, O4>::type   Base;
+
+   public:
+   typedef typename Base::value_compare      value_compare;
+   typedef typename Base::value_traits       value_traits;
+   typedef typename Base::iterator           iterator;
+   typedef typename Base::const_iterator     const_iterator;
+
+   //Assert if passed value traits are compatible with the type
+   BOOST_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value));
+
+   multiset( const value_compare &cmp = value_compare()
+           , const value_traits &v_traits = value_traits())
+      :  Base(cmp, v_traits)
+   {}
+
+   template<class Iterator>
+   multiset( Iterator b, Iterator e
+           , const value_compare &cmp = value_compare()
+           , const value_traits &v_traits = value_traits())
+      :  Base(b, e, cmp, v_traits)
+   {}
+
+   static multiset &container_from_end_iterator(iterator end_iterator)
+   {  return static_cast<multiset &>(Base::container_from_end_iterator(end_iterator));   }
+
+   static const multiset &container_from_end_iterator(const_iterator end_iterator)
+   {  return static_cast<const multiset &>(Base::container_from_end_iterator(end_iterator));   }
+};
+
+#endif
+
 } //namespace intrusive 
 } //namespace boost 
 
Modified: trunk/boost/intrusive/set_hook.hpp
==============================================================================
--- trunk/boost/intrusive/set_hook.hpp	(original)
+++ trunk/boost/intrusive/set_hook.hpp	2007-09-26 11:26:35 EDT (Wed, 26 Sep 2007)
@@ -17,16 +17,45 @@
 #include <boost/intrusive/detail/config_begin.hpp>
 #include <boost/intrusive/intrusive_fwd.hpp>
 #include <boost/intrusive/detail/utilities.hpp>
-#include <boost/intrusive/detail/pointer_to_other.hpp>
 #include <boost/intrusive/detail/rbtree_node.hpp>
 #include <boost/intrusive/rbtree_algorithms.hpp>
-#include <boost/intrusive/linking_policy.hpp>
-#include <boost/intrusive/tag.hpp>
-#include <boost/static_assert.hpp>
+#include <boost/intrusive/options.hpp>
+#include <boost/intrusive/detail/generic_hook.hpp>
 
 namespace boost {
 namespace intrusive {
 
+/// @cond
+template<class VoidPointer>
+struct get_set_node_algo
+{
+   typedef rbtree_algorithms<rbtree_node_traits<VoidPointer> > type;
+};
+/// @endcond
+
+//! Helper metafunction to define a \c set_base_hook that yields to the same
+//! type when the same options (either explicitly or implicitly) are used.
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+template<class ...Options>
+#else
+template<class O1 = none, class O2 = none, class O3 = none>
+#endif
+struct make_set_base_hook
+{
+   /// @cond
+   typedef typename pack_options
+      < hook_defaults, O1, O2, O3>::type packed_options;
+
+   typedef detail::generic_hook
+   < get_set_node_algo<typename packed_options::void_pointer>
+   , typename packed_options::tag
+   , packed_options::link_mode
+   , detail::SetBaseHook
+   > implementation_defined;
+   /// @endcond
+   typedef implementation_defined type;
+};
+
 //! Derive a class from set_base_hook in order to store objects in 
 //! in an set/multiset. set_base_hook holds the data necessary to maintain 
 //! the set/multiset and provides an appropriate value_traits class for set/multiset.
@@ -40,160 +69,102 @@
 //!
 //! The third argument is the pointer type that will be used internally in the hook
 //! and the set/multiset configured from this hook.
-template< class Tag              //= tag
-        , linking_policy Policy  //= safe_link
-        , class VoidPointer      //= void *
-        >
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+template<class ...Options>
+#else
+template<class O1, class O2, class O3>
+#endif
 class set_base_hook
-   :  private detail::rbtree_node_traits<VoidPointer>::node
+   :  public make_set_base_hook<O1, O2, O3>::type
 {
-   public:
-   typedef detail::rbtree_node_traits<VoidPointer>    node_traits;
-   enum { linking_policy = Policy };
-
-   /// @cond
-   private:
-   typedef rbtree_algorithms<node_traits>             node_algorithms;
-   /// @endcond
-
-   public:
-   typedef typename node_traits::node                 node;
-   typedef typename boost::pointer_to_other
-      <VoidPointer, node>::type                       node_ptr;
-   typedef typename boost::pointer_to_other
-      <VoidPointer, const node>::type                 const_node_ptr;
-   typedef set_base_hook
-      <Tag, Policy, VoidPointer>                      this_type;
-
-   typedef typename boost::pointer_to_other
-      <VoidPointer, this_type>::type                  this_type_ptr;
-
-   typedef typename boost::pointer_to_other
-      <VoidPointer, const this_type>::type            const_this_type_ptr;
-
-   /// @cond
-   private:
-
-   node_ptr this_as_node()
-   {  return node_ptr(static_cast<node *const>(this)); }
-
-   const_node_ptr this_as_node() const
-   {  return const_node_ptr(static_cast<const node *const>(this)); }
-   /// @endcond
-
-   public:
-   //! <b>Effects</b>: If Policy is auto_unlink or safe_mode_linnk
+   #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+   //! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
    //!   initializes the node to an unlinked state.
    //! 
-   //! <b>Throws</b>: Nothing.
-   set_base_hook()
-      :  node()
-   {
-      if(Policy == safe_link || Policy == auto_unlink){
-         node_algorithms::init(this_as_node());
-      }
-   }
+   //! <b>Throws</b>: Nothing. 
+   set_base_hook();
 
-   //! <b>Effects</b>: If Policy is auto_unlink or safe_mode_linnk
+   //! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
    //!   initializes the node to an unlinked state. The argument is ignored.
    //! 
    //! <b>Throws</b>: Nothing. 
    //! 
    //! <b>Rationale</b>: Providing a copy-constructor
-   //!   makes classes using set_base_hook STL-compliant without forcing the 
-   //!   user to do some additional work. "swap" can be used to emulate
+   //!   makes classes using the hook STL-compliant without forcing the 
+   //!   user to do some additional work. \c swap can be used to emulate
    //!   move-semantics.
-   set_base_hook(const set_base_hook& )
-      :  node()
-   {
-      if(Policy == safe_link || Policy == auto_unlink){
-         node_algorithms::init(this_as_node());
-      }
-   }
+   set_base_hook(const set_base_hook& );
 
    //! <b>Effects</b>: Empty function. The argument is ignored.
    //! 
    //! <b>Throws</b>: Nothing. 
    //! 
    //! <b>Rationale</b>: Providing an assignment operator 
-   //!   makes classes using set_base_hook STL-compliant without forcing the 
-   //!   user to do some additional work. "swap" can be used to emulate
+   //!   makes classes using the hook STL-compliant without forcing the 
+   //!   user to do some additional work. \c swap can be used to emulate
    //!   move-semantics.
-   set_base_hook& operator=(const set_base_hook& ) 
-   {  return *this;  }
+   set_base_hook& operator=(const set_base_hook& );
 
-   //! <b>Effects</b>: If Policy is normal_link, the destructor does
-   //!   nothing (ie. no code is generated). If Policy is safe_link and the
-   //!   object is stored in an list an assertion is raised. If Policy is
-   //!   auto_unlink and "is_linked()" is true, the node is unlinked.
-   //! 
+   //! <b>Effects</b>: If link_mode is \c normal_link, the destructor does
+   //!   nothing (ie. no code is generated). If link_mode is \c safe_link and the
+   //!   object is stored in an set an assertion is raised. If link_mode is
+   //!   \c auto_unlink and \c is_linked() is true, the node is unlinked.
+   //! 
+   //! <b>Throws</b>: Nothing. 
+   ~set_base_hook();
+
+   //! <b>Effects</b>: Swapping two nodes swaps the position of the elements 
+   //!   related to those nodes in one or two containers. That is, if the node 
+   //!   this is part of the element e1, the node x is part of the element e2 
+   //!   and both elements are included in the containers s1 and s2, then after 
+   //!   the swap-operation e1 is in s2 at the position of e2 and e2 is in s1 
+   //!   at the position of e1. If one element is not in a container, then 
+   //!   after the swap-operation the other element is not in a container. 
+   //!   Iterators to e1 and e2 related to those nodes are invalidated. 
+   //!
+   //! <b>Complexity</b>: Constant 
+   //!
    //! <b>Throws</b>: Nothing. 
-   ~set_base_hook() 
-   {  detail::destructor_impl(*this, detail::dispatcher<Policy>());  }
+   void swap_nodes(set_base_hook &other);
 
-   //! <b>Precondition</b>: Policy must be safe_link or auto_unlink.
+   //! <b>Precondition</b>: link_mode must be \c safe_link or \c auto_unlink.
    //!
    //! <b>Returns</b>: true, if the node belongs to a container, false
-   //!   otherwise. This function can be used to test whether set::iterator_to 
+   //!   otherwise. This function can be used to test whether \c set::iterator_to 
    //!   will return a valid iterator. 
    //!
    //! <b>Complexity</b>: Constant 
-   bool is_linked() const 
-   {
-      //is_linked() can be only used in safe-mode or auto-unlink
-      BOOST_STATIC_ASSERT((Policy == safe_link || Policy == auto_unlink));
-      return !node_algorithms::unique(this_as_node()); 
-   }
+   bool is_linked() const;
 
    //! <b>Effects</b>: Removes the node if it's inserted in a container.
-   //!   This function is only allowed if Policy is auto_unlink.
+   //!   This function is only allowed if link_mode is \c auto_unlink.
    //! 
    //! <b>Throws</b>: Nothing. 
-   void unlink()
-   {
-      BOOST_STATIC_ASSERT((Policy == auto_unlink));
-      node_algorithms::unlink_and_rebalance(this_as_node());
-      node_algorithms::init(this_as_node());
-   }
-
-   //! The value_traits class is used as the first template argument for multiset. 
-   //! The template argument T defines the class type stored in multiset. Objects 
-   //! of type T and of types derived from T can be stored. T don't need to be 
-   //! copy-constructible or assignable.
-   template<class T>
-   struct value_traits
-      :  detail::derivation_hook_value_traits<T, this_type, Tag>
-   {};
-
-   //! <b>Effects</b>: Converts a pointer to a node into
-   //!   a pointer to the hook that holds that node.
-   //! 
-   //! <b>Throws</b>: Nothing. 
-   static this_type_ptr to_hook_ptr(node_ptr p)
-   {
-      return this_type_ptr(static_cast<set_base_hook*> (detail::get_pointer(p))); 
-   }
-
-   //! <b>Effects</b>: Converts a const pointer to a node stored in a container into
-   //!   a const pointer to the hook that holds that node.
-   //! 
-   //! <b>Throws</b>: Nothing. 
-   static const_this_type_ptr to_hook_ptr(const_node_ptr p)
-   {
-      return const_this_type_ptr(static_cast<const set_base_hook*> (detail::get_pointer(p))); 
-   }
+   void unlink();
+   #endif
+};
 
-   //! <b>Effects</b>: Returns a pointer to the node that this hook holds.
-   //! 
-   //! <b>Throws</b>: Nothing. 
-   node_ptr to_node_ptr()
-   { return this_as_node(); }
+//! Helper metafunction to define a \c set_member_hook that yields to the same
+//! type when the same options (either explicitly or implicitly) are used.
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+template<class ...Options>
+#else
+template<class O1 = none, class O2 = none, class O3 = none>
+#endif
+struct make_set_member_hook
+{
+   /// @cond
+   typedef typename pack_options
+      < hook_defaults, O1, O2, O3>::type packed_options;
 
-   //! <b>Effects</b>: Returns a const pointer to the node that this hook holds.
-   //! 
-   //! <b>Throws</b>: Nothing. 
-   const_node_ptr to_node_ptr() const
-   { return this_as_node(); }
+   typedef detail::generic_hook
+   < get_set_node_algo<typename packed_options::void_pointer>
+   , member_tag
+   , packed_options::link_mode
+   , detail::NoBaseHook
+   > implementation_defined;
+   /// @endcond
+   typedef implementation_defined type;
 };
 
 //! Put a public data member set_member_hook in order to store objects of this class in
@@ -204,152 +175,79 @@
 //!
 //! The second argument is the pointer type that will be used internally in the hook
 //! and the set/multiset configured from this hook.
-template< linking_policy Policy  //= safe_link
-        , class VoidPointer      //= void *
-        >
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+template<class ...Options>
+#else
+template<class O1, class O2, class O3>
+#endif
 class set_member_hook
-   :  private detail::rbtree_node_traits<VoidPointer>::node
+   :  public make_set_member_hook<O1, O2, O3>::type
 {
-   public:
-   typedef detail::rbtree_node_traits<VoidPointer>    node_traits;
-   enum { linking_policy = Policy };
-
-   /// @cond
-   private:
-   typedef rbtree_algorithms<node_traits>             node_algorithms;
-   /// @endcond
-
-   public:
-   typedef typename node_traits::node                 node;
-   typedef typename boost::pointer_to_other
-      <VoidPointer, node>::type                       node_ptr;
-   typedef typename boost::pointer_to_other
-      <VoidPointer, const node>::type                 const_node_ptr;
-   typedef set_member_hook
-      <Policy, VoidPointer>                           this_type;
-
-   typedef typename boost::pointer_to_other
-      <VoidPointer, this_type >::type                 this_type_ptr;
-
-   typedef typename boost::pointer_to_other
-      <VoidPointer, const this_type >::type           const_this_type_ptr;
-
-   /// @cond
-   private:
-   node_ptr this_as_node()
-   {  return node_ptr(static_cast<node *const>(this)); }
-
-   const_node_ptr this_as_node() const
-   {  return const_node_ptr(static_cast<const node *const>(this)); }
-   /// @endcond
-
-   public:
-   //! <b>Effects</b>: If Policy is auto_unlink or safe_mode_linnk
+   #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+   //! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
    //!   initializes the node to an unlinked state.
    //! 
    //! <b>Throws</b>: Nothing. 
-   set_member_hook()
-      :  node()
-   {
-      if(Policy == safe_link || Policy == auto_unlink){
-         node_algorithms::init(this_as_node());
-      }
-   }
+   set_member_hook();
 
-   //! <b>Effects</b>: If Policy is auto_unlink or safe_mode_linnk
+   //! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
    //!   initializes the node to an unlinked state. The argument is ignored.
    //! 
    //! <b>Throws</b>: Nothing. 
    //! 
    //! <b>Rationale</b>: Providing a copy-constructor
-   //!   makes classes using set_member_hook STL-compliant without forcing the 
-   //!   user to do some additional work.
-   set_member_hook(const set_member_hook& )
-      :  node()
-   {
-      if(Policy == safe_link || Policy == auto_unlink){
-         node_algorithms::init(this_as_node());
-      }
-   }
+   //!   makes classes using the hook STL-compliant without forcing the 
+   //!   user to do some additional work. \c swap can be used to emulate
+   //!   move-semantics.
+   set_member_hook(const set_member_hook& );
 
    //! <b>Effects</b>: Empty function. The argument is ignored.
    //! 
    //! <b>Throws</b>: Nothing. 
    //! 
    //! <b>Rationale</b>: Providing an assignment operator 
-   //!   makes classes using set_member_hook STL-compliant without forcing the 
-   //!   user to do some additional work.
-   set_member_hook& operator=(const set_member_hook& ) 
-   {  return *this;  }
+   //!   makes classes using the hook STL-compliant without forcing the 
+   //!   user to do some additional work. \c swap can be used to emulate
+   //!   move-semantics.
+   set_member_hook& operator=(const set_member_hook& );
 
-   //! <b>Effects</b>: If Policy is normal_link, the destructor does
-   //!   nothing (ie. no code is generated). If Policy is safe_link and the
-   //!   object is stored in an list an assertion is raised. If Policy is
-   //!   auto_unlink and "is_linked()" is true, the node is unlinked.
-   //! 
+   //! <b>Effects</b>: If link_mode is \c normal_link, the destructor does
+   //!   nothing (ie. no code is generated). If link_mode is \c safe_link and the
+   //!   object is stored in an set an assertion is raised. If link_mode is
+   //!   \c auto_unlink and \c is_linked() is true, the node is unlinked.
+   //! 
+   //! <b>Throws</b>: Nothing. 
+   ~set_member_hook();
+
+   //! <b>Effects</b>: Swapping two nodes swaps the position of the elements 
+   //!   related to those nodes in one or two containers. That is, if the node 
+   //!   this is part of the element e1, the node x is part of the element e2 
+   //!   and both elements are included in the containers s1 and s2, then after 
+   //!   the swap-operation e1 is in s2 at the position of e2 and e2 is in s1 
+   //!   at the position of e1. If one element is not in a container, then 
+   //!   after the swap-operation the other element is not in a container. 
+   //!   Iterators to e1 and e2 related to those nodes are invalidated. 
+   //!
+   //! <b>Complexity</b>: Constant 
+   //!
    //! <b>Throws</b>: Nothing. 
-   ~set_member_hook() 
-   {  detail::destructor_impl(*this, detail::dispatcher<Policy>());  }
+   void swap_nodes(set_member_hook &other);
 
-   //! <b>Precondition</b>: Policy must be safe_link or auto_unlink.
+   //! <b>Precondition</b>: link_mode must be \c safe_link or \c auto_unlink.
    //!
-   //! <b>Complexity</b>: Constant
-   bool is_linked() const 
-   {
-      //is_linked() can be only used in safe-mode or auto-unlink
-      BOOST_STATIC_ASSERT((Policy == safe_link || Policy == auto_unlink));
-      return !node_algorithms::unique(this_as_node()); 
-   }
+   //! <b>Returns</b>: true, if the node belongs to a container, false
+   //!   otherwise. This function can be used to test whether \c set::iterator_to 
+   //!   will return a valid iterator. 
+   //!
+   //! <b>Complexity</b>: Constant 
+   bool is_linked() const;
 
    //! <b>Effects</b>: Removes the node if it's inserted in a container.
-   //!   This function is only allowed if Policy is auto_unlink.
-   //! 
-   //! <b>Throws</b>: Nothing. 
-   void unlink()
-   {
-      BOOST_STATIC_ASSERT((Policy == auto_unlink));
-      node_algorithms::unlink_and_rebalance(this_as_node());
-      node_algorithms::init(this_as_node());
-   }
-
-   //! The value_traits class is used as the first template argument for multiset. 
-   //! The template argument is a pointer to member pointing to the node in 
-   //! the class. Objects of type T and of types derived from T can be stored. 
-   //! T don't need to be copy-constructible or assignable.
-   template<class T, this_type T::* P>
-   struct value_traits
-      :  detail::member_hook_value_traits<T, this_type, P>
-   {};
-
-   //! <b>Effects</b>: Converts a pointer to a node into
-   //!   a pointer to the hook that holds that node.
-   //! 
-   //! <b>Throws</b>: Nothing. 
-   static this_type_ptr to_hook_ptr(node_ptr p)
-   {
-      return this_type_ptr(static_cast<this_type*> (detail::get_pointer(p))); 
-   }
-
-   //! <b>Effects</b>: Converts a const pointer to a node stored in a container into
-   //!   a const pointer to the hook that holds that node.
-   //! 
-   //! <b>Throws</b>: Nothing. 
-   static const_this_type_ptr to_hook_ptr(const_node_ptr p)
-   {
-      return const_this_type_ptr(static_cast<const this_type*> (detail::get_pointer(p))); 
-   }
-
-   //! <b>Effects</b>: Returns a pointer to the node that this hook holds.
-   //! 
-   //! <b>Throws</b>: Nothing. 
-   node_ptr to_node_ptr()
-   { return this_as_node(); }
-
-   //! <b>Effects</b>: Returns a const pointer to the node that this hook holds.
+   //!   This function is only allowed if link_mode is \c auto_unlink.
    //! 
    //! <b>Throws</b>: Nothing. 
-   const_node_ptr to_node_ptr() const
-   { return this_as_node(); }
+   void unlink();
+   #endif
 };
 
 } //namespace intrusive 
Modified: trunk/boost/intrusive/slist.hpp
==============================================================================
--- trunk/boost/intrusive/slist.hpp	(original)
+++ trunk/boost/intrusive/slist.hpp	2007-09-26 11:26:35 EDT (Wed, 26 Sep 2007)
@@ -16,21 +16,60 @@
 
 #include <boost/intrusive/detail/config_begin.hpp>
 #include <boost/static_assert.hpp>
-#ifndef BOOST_INTRUSIVE_DISABLE_EXCEPTION_HANDLING
-#include <boost/detail/no_exceptions_support.hpp>
-#endif
+#include <boost/intrusive/detail/no_exceptions_support.hpp>
 #include <boost/intrusive/detail/assert.hpp>
 #include <boost/intrusive/intrusive_fwd.hpp>
 #include <boost/intrusive/slist_hook.hpp>
 #include <boost/intrusive/circular_slist_algorithms.hpp>
 #include <boost/intrusive/detail/pointer_to_other.hpp>
-#include <boost/intrusive/linking_policy.hpp>
+#include <boost/intrusive/link_mode.hpp>
+#include <boost/intrusive/options.hpp>
 #include <functional>
 #include <cstddef>
 
 namespace boost {
 namespace intrusive {
 
+/// @cond
+
+template <class T>
+struct internal_default_slist_hook
+{
+   template <class U> static detail::one test(...);
+   template <class U> static detail::two test(typename U::default_slist_hook* = 0);
+   static const bool value = sizeof(test<T>(0)) == sizeof(detail::two);
+};
+
+template <class T>
+struct get_default_slist_hook
+{  typedef typename T::default_slist_hook type; };
+
+template <class ValueTraits, class SizeType, bool ConstantTimeSize>
+struct slistopt
+{
+   typedef ValueTraits  value_traits;
+   typedef SizeType     size_type;
+   static const bool constant_time_size = ConstantTimeSize;
+};
+
+template <class T>
+struct slist_defaults
+   :  pack_options
+      < none
+      , base_hook
+         <  typename detail::eval_if_c
+               < internal_default_slist_hook<T>::value
+               , get_default_slist_hook<T>
+               , detail::identity<none>
+               >::type
+         >
+      , constant_time_size<true>
+      , size_type<std::size_t>
+      >::type
+{};
+
+/// @endcond
+
 //! The class template slist is an intrusive container, that encapsulates 
 //! a singly-linked list. You can use such a list to squeeze the last bit 
 //! of performance from your application. Unfortunately, the little gains 
@@ -39,12 +78,13 @@
 //! this limitation some other member functions with rather unusual semantics 
 //! have to be introduced.
 //!
-//! The template parameter ValueTraits is called "value traits". It stores
-//! information and operations about the type to be stored in the container.
+//! The template parameter \c T is the type to be managed by the container.
+//! The user can specify additional options and if no options are provided
+//! default options are used.
 //!
-//! If the user specifies ConstantTimeSize as "true", a member of type SizeType
-//! will be embedded in the class, that will keep track of the number of stored objects.
-//! This will allow constant-time O(1) size() member, instead of default O(N) size.
+//! The container supports the following options:
+//! \c base_hook<>/member_hook<>/value_traits<>,
+//! \c constant_time_size<> and \c size_type<>.
 //! 
 //! The iterators of slist are forward iterators. slist provides a static 
 //! function called "previous" to compute the previous iterator of a given iterator. 
@@ -53,92 +93,131 @@
 //! are defined. In addition, whenever you have an end iterator, 'after this 
 //! iterator' means 'at the beginning of the list'. To improve the self-documentation
 //! a "before_begin()" function is defined, returning the end() iterator.
-template < class ValueTraits
-         , bool ConstantTimeSize //= true
-         , class SizeType        //= std::size_t
-         >
-class slist
-   :  private detail::size_holder<ConstantTimeSize, SizeType>
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+template<class T, class ...Options>
+#else
+template<class Config>
+#endif
+class slist_impl
 {
+   //Public typedefs
+   public:
+   typedef typename Config::value_traits                             value_traits;
    /// @cond
-   private:
-   typename ValueTraits::node_traits::node root_;
+   static const bool external_value_traits =
+      detail::external_value_traits_is_true<value_traits>::value;
+   typedef typename detail::eval_if_c
+      < external_value_traits
+      , detail::eval_value_traits<value_traits>
+      , detail::identity<value_traits>
+      >::type                                                        real_value_traits;
+   /// @endcond
+   typedef typename real_value_traits::pointer                       pointer;
+   typedef typename real_value_traits::const_pointer                 const_pointer;
+   typedef typename std::iterator_traits<pointer>::value_type        value_type;
+   typedef typename std::iterator_traits<pointer>::reference         reference;
+   typedef typename std::iterator_traits<const_pointer>::reference   const_reference;
+   typedef typename std::iterator_traits<pointer>::difference_type   difference_type;
+   typedef typename Config::size_type                                size_type;
+   typedef slist_iterator<slist_impl, false>                         iterator;
+   typedef slist_iterator<slist_impl, true>                          const_iterator;
+   typedef typename real_value_traits::node_traits                   node_traits;
+   typedef typename node_traits::node                                node;
+   typedef typename boost::pointer_to_other
+      <pointer, node>::type                                          node_ptr;
+   typedef typename boost::pointer_to_other
+      <pointer, const node>::type                                    const_node_ptr;
+   typedef circular_slist_algorithms<node_traits>                    node_algorithms;
 
-   typedef slist<ValueTraits, ConstantTimeSize, SizeType>   this_type; 
-   typedef typename ValueTraits::node_traits                node_traits;
-   typedef detail::size_holder<ConstantTimeSize, SizeType>  size_traits;
+   static const bool constant_time_size = Config::constant_time_size;
+   static const bool stateful_value_traits = detail::store_cont_ptr_on_it<slist_impl>::value;
+
+   /// @cond
+   private:
+   typedef detail::size_holder<constant_time_size, size_type>        size_traits;
 
    //! This class is
    //! non-copyable
-   slist (const slist&);
+   slist_impl (const slist_impl&);
 
    //! This class is
    //! non-asignable
-   slist &operator =(const slist&);
-   /// @endcond
+   slist_impl &operator =(const slist_impl&);
 
-   //Public typedefs
-   public:
-   typedef ValueTraits                                               value_traits;
-   typedef typename ValueTraits::value_type                          value_type;
-   typedef typename ValueTraits::pointer                             pointer;
-   typedef typename ValueTraits::const_pointer                       const_pointer;
-   typedef typename std::iterator_traits<pointer>::reference         reference;
-   typedef typename std::iterator_traits<const_pointer>::reference   const_reference;
-   typedef typename std::iterator_traits<pointer>::difference_type   difference_type;
-   typedef SizeType                                                  size_type;
-   typedef detail::slist_iterator<value_type, ValueTraits>           iterator;
-   typedef detail::slist_iterator<const value_type, ValueTraits>     const_iterator;
-
-   /// @cond
-   private:
-   typedef typename node_traits::node              node;
-   typedef typename boost::pointer_to_other
-      <pointer, node>::type                        node_ptr;
-   typedef typename boost::pointer_to_other
-      <pointer, const node>::type                  const_node_ptr;
-   typedef circular_slist_algorithms<node_traits>  node_algorithms;
    enum { safemode_or_autounlink  = 
-            (int)ValueTraits::linking_policy == (int)auto_unlink   ||
-            (int)ValueTraits::linking_policy == (int)safe_link     };
+            (int)real_value_traits::link_mode == (int)auto_unlink   ||
+            (int)real_value_traits::link_mode == (int)safe_link     };
 
    //Constant-time size is incompatible with auto-unlink hooks!
-   BOOST_STATIC_ASSERT(!(ConstantTimeSize && ((int)ValueTraits::linking_policy == (int)auto_unlink)));
+   BOOST_STATIC_ASSERT(!(constant_time_size && ((int)real_value_traits::link_mode == (int)auto_unlink)));
 
    node_ptr get_root_node()
-   {  return node_ptr(&root_);  }
+   {  return node_ptr(&data_.root_plus_size_.root_);  }
 
    const_node_ptr get_root_node() const
-   {  return const_node_ptr(&root_);  }
+   {  return const_node_ptr(&data_.root_plus_size_.root_);  }
 
    static node_ptr uncast(const_node_ptr ptr)
    {
       return node_ptr(const_cast<node*>(detail::get_pointer(ptr)));
    }
 
-   static iterator previous_node(iterator beg, iterator i)
+   struct root_plus_size
+      :  public size_traits
    {
-      return iterator
-         (node_algorithms::get_previous_node(beg.pointed_node(), i.pointed_node()));
-   }
+      node root_;
+   };
 
-   static const_iterator previous_node(const_iterator beg, const_iterator i)
+   struct data_t
+      :  public slist_impl::value_traits
    {
-      return const_iterator
-         (node_algorithms::get_previous_node(beg.pointed_node(), i.pointed_node()));
-   }
+      typedef typename slist_impl::value_traits value_traits;
+      data_t(const value_traits &val_traits)
+         :  value_traits(val_traits)
+      {}
+
+      root_plus_size root_plus_size_;
+   } data_;
+
+   size_traits &priv_size_traits()
+   {  return data_.root_plus_size_;  }
+
+   const size_traits &priv_size_traits() const
+   {  return data_.root_plus_size_;  }
+
+   const real_value_traits &get_real_value_traits(detail::bool_<false>) const
+   {  return data_;  }
+
+   const real_value_traits &get_real_value_traits(detail::bool_<true>) const
+   {  return data_.get_value_traits(*this);  }
+
+   real_value_traits &get_real_value_traits(detail::bool_<false>)
+   {  return data_;  }
+
+   real_value_traits &get_real_value_traits(detail::bool_<true>)
+   {  return data_.get_value_traits(*this);  }
+
    /// @endcond
 
    public:
+
+   const real_value_traits &get_real_value_traits() const
+   {  return this->get_real_value_traits(detail::bool_<external_value_traits>());  }
+
+   real_value_traits &get_real_value_traits()
+   {  return this->get_real_value_traits(detail::bool_<external_value_traits>());  }
+
+   public:
    //! <b>Effects</b>: constructs an empty list. 
    //! 
    //! <b>Complexity</b>: Constant 
    //! 
    //! <b>Throws</b>: If value_traits::node_traits::node
    //!   constructor throws (this does not happen with predefined Boost.Intrusive hooks).
-   slist()
+   slist_impl(const value_traits &v_traits = value_traits())
+      :  data_(v_traits)
    {
-      size_traits::set_size(size_type(0));
+      this->priv_size_traits().set_size(size_type(0));
       node_algorithms::init(this->get_root_node()); 
    }
 
@@ -151,9 +230,10 @@
    //! <b>Throws</b>: If value_traits::node_traits::node
    //!   constructor throws (this does not happen with predefined Boost.Intrusive hooks).
    template<class Iterator>
-   slist(Iterator b, Iterator e)
+   slist_impl(Iterator b, Iterator e, const value_traits &v_traits = value_traits())
+      :  data_(v_traits)
    {
-      size_traits::set_size(size_type(0));
+      this->priv_size_traits().set_size(size_type(0));
       node_algorithms::init(this->get_root_node());
       insert_after(before_begin(), b, e);
    }
@@ -162,12 +242,12 @@
    //!   or auto-unlink value, the destructor does nothing
    //!   (ie. no code is generated). Otherwise it detaches all elements from this. 
    //!   In this case the objects in the list are not deleted (i.e. no destructors 
-   //!   are called), but the hooks according to the ValueTraits template parameter
+   //!   are called), but the hooks according to the value_traits template parameter
    //!   are set to their default value.
    //! 
    //! <b>Complexity</b>: Linear to the number of elements in the list, if 
    //!   it's a safe-mode or auto-unlink value. Otherwise constant.
-   ~slist()
+   ~slist_impl()
    {  this->clear(); }
 
    //! <b>Effects</b>: Erases all the elements of the container.
@@ -185,7 +265,7 @@
       }
       else{
          node_algorithms::init(this->get_root_node());
-         size_traits::set_size(size_type(0));
+         this->priv_size_traits().set_size(size_type(0));
       }
    }
 
@@ -215,11 +295,11 @@
    //! <b>Note</b>: Does not affect the validity of iterators and references.
    void push_front(reference value) 
    {
-      node_ptr to_insert = ValueTraits::to_node_ptr(value);
+      node_ptr to_insert = get_real_value_traits().to_node_ptr(value);
       if(safemode_or_autounlink)
          BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
       node_algorithms::link_after(this->get_root_node(), to_insert); 
-      size_traits::increment();
+      this->priv_size_traits().increment();
    }
 
    //! <b>Effects</b>: Erases the first element of the list.
@@ -234,7 +314,7 @@
    {
       node_ptr to_erase = node_traits::get_next(this->get_root_node());
       node_algorithms::unlink_after(this->get_root_node());
-      size_traits::decrement();
+      this->priv_size_traits().decrement();
       if(safemode_or_autounlink)
          node_algorithms::init(to_erase);
    }
@@ -254,7 +334,7 @@
    {
       node_ptr to_erase = node_traits::get_next(this->get_root_node());
       this->pop_front();
-      disposer(ValueTraits::to_value_ptr(to_erase));
+      disposer(get_real_value_traits().to_value_ptr(to_erase));
    }
 
    //! <b>Effects</b>: Returns a reference to the first element of the list.
@@ -263,7 +343,7 @@
    //! 
    //! <b>Complexity</b>: Constant.
    reference front()
-   { return *ValueTraits::to_value_ptr(node_traits::get_next(this->get_root_node())); }
+   { return *get_real_value_traits().to_value_ptr(node_traits::get_next(this->get_root_node())); }
 
    //! <b>Effects</b>: Returns a const_reference to the first element of the list.
    //! 
@@ -271,7 +351,7 @@
    //! 
    //! <b>Complexity</b>: Constant.
    const_reference front() const
-   { return *ValueTraits::to_value_ptr(uncast(node_traits::get_next(this->get_root_node()))); }
+   { return *get_real_value_traits().to_value_ptr(uncast(node_traits::get_next(this->get_root_node()))); }
 
    //! <b>Effects</b>: Returns an iterator to the first element contained in the list.
    //! 
@@ -279,7 +359,7 @@
    //! 
    //! <b>Complexity</b>: Constant.
    iterator begin() 
-   { return iterator (node_traits::get_next(this->get_root_node())); }
+   { return iterator (node_traits::get_next(this->get_root_node()), this); }
 
    //! <b>Effects</b>: Returns a const_iterator to the first element contained in the list.
    //! 
@@ -287,7 +367,7 @@
    //! 
    //! <b>Complexity</b>: Constant.
    const_iterator begin() const 
-   { return const_iterator (node_traits::get_next(this->get_root_node())); }
+   { return const_iterator (node_traits::get_next(this->get_root_node()), this); }
 
    //! <b>Effects</b>: Returns a const_iterator to the first element contained in the list.
    //! 
@@ -295,7 +375,7 @@
    //! 
    //! <b>Complexity</b>: Constant.
    const_iterator cbegin() const 
-   { return const_iterator (node_traits::get_next(this->get_root_node())); }
+   { return const_iterator (node_traits::get_next(this->get_root_node()), this); }
 
    //! <b>Effects</b>: Returns an iterator to the end of the list.
    //! 
@@ -303,7 +383,7 @@
    //! 
    //! <b>Complexity</b>: Constant.
    iterator end() 
-   { return iterator (this->get_root_node()); }
+   { return iterator (this->get_root_node(), this); }
 
    //! <b>Effects</b>: Returns a const_iterator to the end of the list.
    //! 
@@ -311,7 +391,7 @@
    //! 
    //! <b>Complexity</b>: Constant.
    const_iterator end() const 
-   { return const_iterator (uncast(this->get_root_node())); }
+   { return const_iterator (uncast(this->get_root_node()), this); }
 
    //! <b>Effects</b>: Returns a const_iterator to the end of the list.
    //! 
@@ -319,7 +399,7 @@
    //! 
    //! <b>Complexity</b>: Constant.
    const_iterator cend() const 
-   { return const_iterator (uncast(this->get_root_node())); }
+   { return const_iterator (uncast(this->get_root_node()), this); }
 
    //! <b>Effects</b>: Returns an iterator that points to a position
    //!   before the first element. Equivalent to "end()"
@@ -356,11 +436,8 @@
    //! <b>Throws</b>: Nothing.
    //! 
    //! <b>Complexity</b>: Constant.
-   static slist &container_from_end_iterator(iterator end_iterator)
-   {
-      return *detail::parent_from_member<slist, node>
-         ( detail::get_pointer(end_iterator.pointed_node()), &slist::root_);
-   }
+   static slist_impl &container_from_end_iterator(iterator end_iterator)
+   {  return priv_container_from_end_iterator(end_iterator);   }
 
    //! <b>Precondition</b>: end_iterator must be a valid end const_iterator
    //!   of slist.
@@ -370,24 +447,21 @@
    //! <b>Throws</b>: Nothing.
    //! 
    //! <b>Complexity</b>: Constant.
-   static const slist &container_from_end_iterator(const_iterator end_iterator)
-   {
-      return *detail::parent_from_member<slist, node>
-         ( detail::get_pointer(end_iterator.pointed_node()), &slist::root_);
-   }
+   static const slist_impl &container_from_end_iterator(const_iterator end_iterator)
+   {  return priv_container_from_end_iterator(end_iterator);   }
 
    //! <b>Effects</b>: Returns the number of the elements contained in the list.
    //! 
    //! <b>Throws</b>: Nothing.
    //! 
    //! <b>Complexity</b>: Linear to the number of elements contained in the list.
-   //!   if ConstantTimeSize is false. Constant time otherwise.
+   //!   if constant_time_size is false. Constant time otherwise.
    //! 
    //! <b>Note</b>: Does not affect the validity of iterators and references.
    size_type size() const
    {
-      if(ConstantTimeSize)
-         return size_traits::get_size();
+      if(constant_time_size)
+         return this->priv_size_traits().get_size();
       else
          return node_algorithms::count(this->get_root_node()) - 1; 
    }
@@ -409,13 +483,13 @@
    //! <b>Complexity</b>: Linear to the number of elements of both lists.
    //! 
    //! <b>Note</b>: Does not affect the validity of iterators and references.
-   void swap(slist& other)
+   void swap(slist_impl& other)
    {
       node_algorithms::swap_nodes(this->get_root_node(), other.get_root_node());
-      if(ConstantTimeSize){
-         size_type backup = size_traits::get_size();
-         size_traits::set_size(other.get_size());
-         other.set_size(backup);
+      if(constant_time_size){
+         size_type backup = this->priv_size_traits().get_size();
+         this->priv_size_traits().set_size(other.priv_size_traits().get_size());
+         other.priv_size_traits().set_size(backup);
       }
    }
 
@@ -533,25 +607,21 @@
    //! 
    //! <b>Throws</b>: If cloner throws.
    template <class Cloner, class Disposer>
-   void clone_from(const slist &src, Cloner cloner, Disposer disposer)
+   void clone_from(const slist_impl &src, Cloner cloner, Disposer disposer)
    {  
       this->clear_and_dispose(disposer);
-      #ifndef BOOST_INTRUSIVE_DISABLE_EXCEPTION_HANDLING
-      BOOST_TRY{
-      #endif
+      BOOST_INTRUSIVE_TRY{
          iterator prev = this->before_begin();
          const_iterator b(src.begin()), e(src.end());
          for(; b != e; ++b, ++prev){
             this->insert_after(prev, *cloner(*b));
          }
-      #ifndef BOOST_INTRUSIVE_DISABLE_EXCEPTION_HANDLING
       }
-      BOOST_CATCH(...){
+      BOOST_INTRUSIVE_CATCH(...){
          this->clear_and_dispose(disposer);
          BOOST_RETHROW;
       }
-      BOOST_CATCH_END
-      #endif
+      BOOST_INTRUSIVE_CATCH_END
    }
 
    //! <b>Requires</b>: value must be an lvalue and prev_p must point to an element
@@ -569,12 +639,12 @@
    //! <b>Note</b>: Does not affect the validity of iterators and references.
    iterator insert_after(iterator prev_p, reference value)
    {
-      node_ptr n = ValueTraits::to_node_ptr(value);
+      node_ptr n = get_real_value_traits().to_node_ptr(value);
       if(safemode_or_autounlink)
          BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(n));
       node_algorithms::link_after(prev_p.pointed_node(), n);
-      size_traits::increment();
-      return iterator (n);
+      this->priv_size_traits().increment();
+      return iterator (n, this);
    }
 
    //! <b>Requires</b>: Dereferencing iterator must yield 
@@ -644,7 +714,7 @@
       iterator it(prev); ++it;
       node_ptr to_erase(it.pointed_node());
       node_algorithms::unlink_after(prev.pointed_node());
-      size_traits::decrement();
+      this->priv_size_traits().decrement();
       iterator ret(++prev);
       if(safemode_or_autounlink)
          node_algorithms::init(to_erase);
@@ -725,7 +795,7 @@
       iterator it(prev); ++it;
       node_ptr to_erase(it.pointed_node());
       iterator ret(this->erase_after(prev));
-      disposer(ValueTraits::to_value_ptr(to_erase));
+      disposer(get_real_value_traits().to_value_ptr(to_erase));
       return ret;
    }
 
@@ -853,7 +923,7 @@
    //! 
    //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
    //! list. Iterators of this list and all the references are not invalidated.
-   iterator splice_after(iterator prev, slist &x)
+   iterator splice_after(iterator prev, slist_impl &x)
    {
       if (!x.empty()){
          iterator last_x(x.previous(x.end()));
@@ -861,8 +931,8 @@
             ( prev.pointed_node()
             , x.end().pointed_node()
             , last_x.pointed_node());
-         size_traits::set_size(size_traits::get_size() + x.get_size());
-         x.set_size(size_type(0));
+         this->priv_size_traits().set_size(this->priv_size_traits().get_size() + x.priv_size_traits().get_size());
+         x.priv_size_traits().set_size(size_type(0));
          return last_x;
       }
       else{
@@ -883,15 +953,15 @@
    //! 
    //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
    //! list. Iterators of this list and all the references are not invalidated.
-   void splice_after(iterator prev, slist &x, iterator prev_ele)
+   void splice_after(iterator prev, slist_impl &x, iterator prev_ele)
    {
       iterator nxt = prev_ele;
       ++nxt;
       if (nxt != prev && prev_ele != prev){
          node_algorithms::transfer_after
             (prev.pointed_node(), prev_ele.pointed_node(), nxt.pointed_node());
-         size_traits::increment();
-         x.decrement();
+         this->priv_size_traits().increment();
+         x.priv_size_traits().decrement();
       }
    }
 
@@ -906,19 +976,19 @@
    //! <b>Throws</b>: Nothing.
    //! 
    //! <b>Complexity</b>: Linear to the number of elements transferred
-   //!   if ConstantTimeSize is true. Constant-time otherwise.
+   //!   if constant_time_size is true. Constant-time otherwise.
    //! 
    //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
    //!   list. Iterators of this list and all the references are not invalidated.
-   void splice_after(iterator prev_pos, slist &x, iterator before_first, iterator before_last)
+   void splice_after(iterator prev_pos, slist_impl &x, iterator before_first, iterator before_last)
    {
       if (before_first != before_last){
-         if(ConstantTimeSize){
+         if(constant_time_size){
             size_type increment = std::distance(before_first, before_last);
             node_algorithms::transfer_after
                (prev_pos.pointed_node(), before_first.pointed_node(), before_last.pointed_node());
-            size_traits::set_size(size_traits::get_size() + increment);
-            x.set_size(x.get_size() - increment);
+            this->priv_size_traits().set_size(this->priv_size_traits().get_size() + increment);
+            x.priv_size_traits().set_size(x.priv_size_traits().get_size() - increment);
          }
          else{
             node_algorithms::transfer_after
@@ -941,15 +1011,15 @@
    //! 
    //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
    //!   list. Iterators of this list and all the references are not invalidated.
-   void splice_after(iterator prev_pos, slist &x, iterator before_first, iterator before_last, difference_type n)
+   void splice_after(iterator prev_pos, slist_impl &x, iterator before_first, iterator before_last, difference_type n)
    {
       if(n){
-         if(ConstantTimeSize){
+         if(constant_time_size){
             BOOST_INTRUSIVE_INVARIANT_ASSERT(std::distance(before_first, before_last) == n);
             node_algorithms::transfer_after
                (prev_pos.pointed_node(), before_first.pointed_node(), before_last.pointed_node());
-            size_traits::set_size(size_traits::get_size() + n);
-            x.set_size(x.get_size() - n);
+            this->priv_size_traits().set_size(this->priv_size_traits().get_size() + n);
+            x.priv_size_traits().set_size(x.priv_size_traits().get_size() - n);
          }
          else{
             node_algorithms::transfer_after
@@ -975,7 +1045,7 @@
    //! 
    //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
    //! list. Iterators of this list and all the references are not invalidated.
-   iterator splice(iterator it, slist &x)
+   iterator splice(iterator it, slist_impl &x)
    {  return splice_after(this->previous(it), x);   }
 
    //! <b>Requires</b>: it p must be a valid iterator of *this.
@@ -991,7 +1061,7 @@
    //! 
    //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
    //! list. Iterators of this list and all the references are not invalidated.
-   void splice(iterator pos, slist &x, iterator elem)
+   void splice(iterator pos, slist_impl &x, iterator elem)
    {  return splice_after(this->previous(pos), x, this->previous(elem));  }
 
    //! <b>Requires</b>: pos must be a dereferenceable iterator in *this
@@ -1004,11 +1074,11 @@
    //! <b>Throws</b>: Nothing.
    //! 
    //! <b>Complexity</b>: Linear to the sum of elements before pos, first, and last.
-   //!   Plus linear to the number of elements transferred if ConstantTimeSize is true.
+   //!   Plus linear to the number of elements transferred if constant_time_size is true.
    //! 
    //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
    //!   list. Iterators of this list and all the references are not invalidated.
-   void splice(iterator pos, slist &x, iterator first, iterator last)
+   void splice(iterator pos, slist_impl &x, iterator first, iterator last)
    {  return splice_after(this->previous(pos), x, this->previous(first), this->previous(last));  }
 
    //! <b>Requires</b>: pos must be a dereferenceable iterator in *this
@@ -1025,7 +1095,7 @@
    //! 
    //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
    //!   list. Iterators of this list and all the references are not invalidated.
-   void splice(iterator pos, slist &x, iterator first, iterator last, difference_type n)
+   void splice(iterator pos, slist_impl &x, iterator first, iterator last, difference_type n)
    {  return splice_after(this->previous(pos), x, this->previous(first), this->previous(last), n);  }
 
    //! <b>Effects</b>: This function sorts the list *this according to std::less<value_type>. 
@@ -1044,8 +1114,8 @@
    {
       if (node_traits::get_next(node_traits::get_next(this->get_root_node()))
                != this->get_root_node()) {
-         slist carry;
-         slist counter[64];
+         slist_impl carry;
+         slist_impl counter[64];
          int fill = 0;
          iterator last_inserted;
          while(!this->empty()){
@@ -1057,8 +1127,10 @@
             }
             BOOST_INTRUSIVE_INVARIANT_ASSERT(counter[i].empty());
 
-            iterator last_element(previous_node(last_inserted, carry.end()));
-            if(ConstantTimeSize){
+            node_ptr p = node_algorithms::get_previous_node
+               (last_inserted.pointed_node(), carry.end().pointed_node());
+            iterator last_element(p, this);
+            if(constant_time_size){
                counter[i].splice_after( counter[i].end(), carry
                                       , carry.before_begin(), last_element
                                       , carry.size());
@@ -1067,19 +1139,18 @@
                counter[i].splice_after( counter[i].end(), carry
                                       , carry.before_begin(), last_element);
             }
-            //counter[i].splice_after(counter[i].end(), carry, carry.end(), previous_node(last_inserted, carry.end()));
-            //carry.swap(counter[i]);
             if(i == fill)
                ++fill;
          }
 
          for (int i = 1; i < fill; ++i)
             last_inserted = counter[i].merge(counter[i-1], p);
-         //this->swap(counter[fill-1]);
          BOOST_INTRUSIVE_INVARIANT_ASSERT(this->empty());
 
-         iterator last_element(previous_node(last_inserted, counter[--fill].end()));
-         if(ConstantTimeSize){
+         node_ptr p = node_algorithms::get_previous_node
+            (last_inserted.pointed_node(), counter[--fill].end().pointed_node());
+         iterator last_element(p, this);
+         if(constant_time_size){
             this->splice_after( end(), counter[fill], counter[fill].before_begin()
                               , last_element, counter[fill].size());
          }
@@ -1126,7 +1197,7 @@
    //! 
    //! <b>Note</b>: Iterators and references are not invalidated.
    template<class Predicate>
-   iterator merge(slist& x, Predicate p) 
+   iterator merge(slist_impl& x, Predicate p) 
    {
       iterator a(before_begin()), e(end()), ax(x.before_begin());
       iterator last_inserted(e);
@@ -1161,7 +1232,7 @@
    //!   size() + x.size() - 1 comparisons.
    //! 
    //! <b>Note</b>: Iterators and references are not invalidated
-   void merge(slist& x)
+   void merge(slist_impl& x)
    { this->merge(x, std::less<value_type>()); }
 
    //! <b>Effects</b>: Reverses the order of elements in the list. 
@@ -1328,10 +1399,46 @@
    //! <b>Complexity</b>: Constant time.
    //! 
    //! <b>Note</b>: Iterators and references are not invalidated.
-   static iterator iterator_to(reference value) 
+   //!   This static function is available only if the <i>value traits</i>
+   //!   is stateless.
+   static iterator s_iterator_to(reference value) 
+   {
+      BOOST_STATIC_ASSERT((!stateful_value_traits));
+      BOOST_INTRUSIVE_INVARIANT_ASSERT (!node_algorithms::unique(value_traits::to_node_ptr(value)));
+      return iterator (value_traits::to_node_ptr(value), 0);
+   }
+
+   //! <b>Requires</b>: value must be a const reference to a value inserted in a list.
+   //! 
+   //! <b>Effects</b>: This function returns an iterator pointing to the element.
+   //! 
+   //! <b>Throws</b>: Nothing.
+   //! 
+   //! <b>Complexity</b>: Constant time.
+   //! 
+   //! <b>Note</b>: Iterators and references are not invalidated.
+   //!   This static function is available only if the <i>value traits</i>
+   //!   is stateless.
+   static const_iterator s_iterator_to(const_reference value) 
+   {
+      BOOST_STATIC_ASSERT((!stateful_value_traits));
+      BOOST_INTRUSIVE_INVARIANT_ASSERT (!node_algorithms::unique(value_traits::to_node_ptr(const_cast<reference> (value))));
+      return const_iterator (value_traits::to_node_ptr(const_cast<reference> (value)), 0);
+   }
+
+   //! <b>Requires</b>: value must be a reference to a value inserted in a list.
+   //! 
+   //! <b>Effects</b>: This function returns a const_iterator pointing to the element
+   //! 
+   //! <b>Throws</b>: Nothing.
+   //! 
+   //! <b>Complexity</b>: Constant time.
+   //! 
+   //! <b>Note</b>: Iterators and references are not invalidated.
+   iterator iterator_to(reference value) 
    { 
-      BOOST_INTRUSIVE_INVARIANT_ASSERT (!node_algorithms::unique(ValueTraits::to_node_ptr(value)));
-      return iterator (ValueTraits::to_node_ptr(value)); 
+      BOOST_INTRUSIVE_INVARIANT_ASSERT (!node_algorithms::unique(value_traits::to_node_ptr(value)));
+      return iterator (value_traits::to_node_ptr(value), this);
    }
 
    //! <b>Requires</b>: value must be a const reference to a value inserted in a list.
@@ -1343,10 +1450,10 @@
    //! <b>Complexity</b>: Constant time.
    //! 
    //! <b>Note</b>: Iterators and references are not invalidated.
-   static const_iterator iterator_to(const_reference value) 
+   const_iterator iterator_to(const_reference value) const
    { 
-      BOOST_INTRUSIVE_INVARIANT_ASSERT (!node_algorithms::unique(ValueTraits::to_node_ptr(const_cast<reference> (value))));
-      return const_iterator (ValueTraits::to_node_ptr(const_cast<reference> (value))); 
+      BOOST_INTRUSIVE_INVARIANT_ASSERT (!node_algorithms::unique(value_traits::to_node_ptr(const_cast<reference> (value))));
+      return const_iterator (value_traits::to_node_ptr(const_cast<reference> (value)), this);
    }
 
    //! <b>Returns</b>: The iterator to the element before i in the list. 
@@ -1360,7 +1467,7 @@
    {
       return iterator
          (node_algorithms::get_previous_node
-            (before_begin().pointed_node(), i.pointed_node()));
+            (before_begin().pointed_node(), i.pointed_node()), 0);
    }
 
    //! <b>Returns</b>: The const_iterator to the element before i in the list. 
@@ -1374,17 +1481,52 @@
    {
       return const_iterator
          (node_algorithms::get_previous_node
-            (before_begin().pointed_node(), i.pointed_node()));
+            (before_begin().pointed_node(), i.pointed_node()), 0);
+   }
+
+   private:
+   static slist_impl &priv_container_from_end_iterator(const const_iterator &end_iterator)
+   {
+      root_plus_size *r = detail::parent_from_member<root_plus_size, node>
+         ( detail::get_pointer(end_iterator.pointed_node()), &root_plus_size::root_);
+      data_t *d = detail::parent_from_member<data_t, root_plus_size>
+         ( r, &data_t::root_plus_size_);
+      slist_impl *s  = detail::parent_from_member<slist_impl, data_t>(d, &slist_impl::data_);
+      return *s;
    }
 };
 
-template <class V, bool C, class S>
-inline bool operator==(const slist<V, C, S>& x, const slist<V, C, S>& y)
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+template<class T, class ...Options>
+#else
+template<class Config>
+#endif
+inline bool operator<
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+(const slist_impl<T, Options...> &x, const slist_impl<T, Options...> &y)
+#else
+(const slist_impl<Config> &x, const slist_impl<Config> &y)
+#endif
+{  return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());  }
+
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+template<class T, class ...Options>
+#else
+template<class Config>
+#endif
+bool operator==
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+(const slist_impl<T, Options...> &x, const slist_impl<T, Options...> &y)
+#else
+(const slist_impl<Config> &x, const slist_impl<Config> &y)
+#endif
 {
+   typedef slist_impl<Config> slist_type;
+   typedef typename slist_type::const_iterator const_iterator;
+   const bool C = slist_type::constant_time_size;
    if(C && x.size() != y.size()){
       return false;
    }
-   typedef typename slist<V, C, S>::const_iterator const_iterator;
    const_iterator end1 = x.end();
 
    const_iterator i1 = x.begin();
@@ -1406,31 +1548,131 @@
    }
 }
 
-template <class V, bool C, class S>
-inline bool operator<(const slist<V, C, S>& x,
-                      const slist<V, C, S>& y)
-{  return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());  }
-
-template <class V, bool C, class S>
-inline bool operator!=(const slist<V, C, S>& x, const slist<V, C, S>& y) 
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+template<class T, class ...Options>
+#else
+template<class Config>
+#endif
+inline bool operator!=
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+(const slist_impl<T, Options...> &x, const slist_impl<T, Options...> &y)
+#else
+(const slist_impl<Config> &x, const slist_impl<Config> &y)
+#endif
 {  return !(x == y); }
 
-template <class V, bool C, class S>
-inline bool operator>(const slist<V, C, S>& x, const slist<V, C, S>& y) 
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+template<class T, class ...Options>
+#else
+template<class Config>
+#endif
+inline bool operator>
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+(const slist_impl<T, Options...> &x, const slist_impl<T, Options...> &y)
+#else
+(const slist_impl<Config> &x, const slist_impl<Config> &y)
+#endif
 {  return y < x;  }
 
-template <class V, bool C, class S>
-inline bool operator<=(const slist<V, C, S>& x, const slist<V, C, S>& y) 
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+template<class T, class ...Options>
+#else
+template<class Config>
+#endif
+inline bool operator<=
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+(const slist_impl<T, Options...> &x, const slist_impl<T, Options...> &y)
+#else
+(const slist_impl<Config> &x, const slist_impl<Config> &y)
+#endif
 {  return !(y < x);  }
 
-template <class V, bool C, class S>
-inline bool operator>=(const slist<V, C, S>& x, const slist<V, C, S>& y) 
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+template<class T, class ...Options>
+#else
+template<class Config>
+#endif
+inline bool operator>=
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+(const slist_impl<T, Options...> &x, const slist_impl<T, Options...> &y)
+#else
+(const slist_impl<Config> &x, const slist_impl<Config> &y)
+#endif
 {  return !(x < y);  }
 
-template <class V, bool C, class S>
-inline void swap(slist<V, C, S>& x, slist<V, C, S>& y)
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+template<class T, class ...Options>
+#else
+template<class Config>
+#endif
+inline void swap
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+(slist_impl<T, Options...> &x, slist_impl<T, Options...> &y)
+#else
+(slist_impl<Config> &x, slist_impl<Config> &y)
+#endif
 {  x.swap(y);  }
 
+//! Helper metafunction to define a \c slist that yields to the same type when the
+//! same options (either explicitly or implicitly) are used.
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+template<class T, class ...Options>
+#else
+template<class T, class O1 = none, class O2 = none, class O3 = none>
+#endif
+struct make_slist
+{
+   /// @cond
+   typedef typename pack_options
+      < slist_defaults<T>, O1, O2, O3>::type packed_options;
+   typedef typename detail::get_value_traits
+      <T, typename packed_options::value_traits>::type value_traits;
+   typedef slist_impl
+      <
+         slistopt
+         < value_traits
+         , typename packed_options::size_type
+         , packed_options::constant_time_size
+         >
+      > implementation_defined;
+   /// @endcond
+   typedef implementation_defined type;
+};
+
+
+#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+template<class T, class O1, class O2, class O3>
+class slist
+   :  public make_slist<T, O1, O2, O3>::type
+{
+   typedef typename make_slist
+      <T, O1, O2, O3>::type   Base;
+   typedef typename Base::real_value_traits  real_value_traits;
+   //Assert if passed value traits are compatible with the type
+   BOOST_STATIC_ASSERT((detail::is_same<typename real_value_traits::value_type, T>::value));
+   public:
+   typedef typename Base::value_traits       value_traits;
+   typedef typename Base::iterator           iterator;
+   typedef typename Base::const_iterator     const_iterator;
+
+   slist(const value_traits &v_traits = value_traits())
+      :  Base(v_traits)
+   {}
+
+   template<class Iterator>
+   slist(Iterator b, Iterator e, const value_traits &v_traits = value_traits())
+      :  Base(b, e, v_traits)
+   {}
+
+   static slist &container_from_end_iterator(iterator end_iterator)
+   {  return static_cast<slist &>(Base::container_from_end_iterator(end_iterator));   }
+
+   static const slist &container_from_end_iterator(const_iterator end_iterator)
+   {  return static_cast<const slist &>(Base::container_from_end_iterator(end_iterator));   }
+};
+
+#endif
+
 } //namespace intrusive 
 } //namespace boost 
 
Modified: trunk/boost/intrusive/slist_hook.hpp
==============================================================================
--- trunk/boost/intrusive/slist_hook.hpp	(original)
+++ trunk/boost/intrusive/slist_hook.hpp	2007-09-26 11:26:35 EDT (Wed, 26 Sep 2007)
@@ -17,19 +17,48 @@
 #include <boost/intrusive/detail/config_begin.hpp>
 #include <boost/intrusive/intrusive_fwd.hpp>
 #include <boost/intrusive/detail/utilities.hpp>
-#include <boost/intrusive/detail/pointer_to_other.hpp>
 #include <boost/intrusive/detail/slist_node.hpp>
 #include <boost/intrusive/circular_slist_algorithms.hpp>
-#include <boost/intrusive/linking_policy.hpp>
-#include <boost/intrusive/tag.hpp>
-#include <boost/static_assert.hpp>
+#include <boost/intrusive/options.hpp>
+#include <boost/intrusive/detail/generic_hook.hpp>
 
 namespace boost {
 namespace intrusive {
 
+/// @cond
+template<class VoidPointer>
+struct get_slist_node_algo
+{
+   typedef circular_slist_algorithms<slist_node_traits<VoidPointer> > type;
+};
+/// @endcond
+
+//! Helper metafunction to define a \c slist_base_hook that yields to the same
+//! type when the same options (either explicitly or implicitly) are used.
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+template<class ...Options>
+#else
+template<class O1 = none, class O2 = none, class O3 = none>
+#endif
+struct make_slist_base_hook
+{
+   /// @cond
+   typedef typename pack_options
+      < hook_defaults, O1, O2, O3>::type packed_options;
+
+   typedef detail::generic_hook
+   < get_slist_node_algo<typename packed_options::void_pointer>
+   , typename packed_options::tag
+   , packed_options::link_mode
+   , detail::SlistBaseHook
+   > implementation_defined;
+   /// @endcond
+   typedef implementation_defined type;
+};
+
 //! Derive a class from slist_base_hook in order to store objects in 
-//! in an slist. slist_base_hook holds the data necessary to maintain the 
-//! list and provides an appropriate value_traits class for slist.
+//! in an list. slist_base_hook holds the data necessary to maintain the 
+//! list and provides an appropriate value_traits class for list.
 //! 
 //! The first integer template argument defines a tag to identify the node. 
 //! The same tag value can be used in different classes, but if a class is 
@@ -39,97 +68,50 @@
 //! The second boolean template parameter will specify the linking mode of the hook.
 //!
 //! The third argument is the pointer type that will be used internally in the hook
-//! and the slist configured from this hook.
-template< class Tag              //= tag
-        , linking_policy Policy  //= safe_link
-        , class VoidPointer      //= void *
-        >
+//! and the list configured from this hook.
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+template<class ...Options>
+#else
+template<class O1, class O2, class O3>
+#endif
 class slist_base_hook
-   :  private detail::slist_node_traits<VoidPointer>::node
+   :  public make_slist_base_hook<O1, O2, O3>::type
 {
-   public:
-   typedef detail::slist_node_traits<VoidPointer>     node_traits;
-   enum {   linking_policy = Policy   };
-
-   /// @cond
-   private:
-   typedef circular_slist_algorithms<node_traits>              node_algorithms;
-   /// @endcond
-
-   public:
-   typedef typename node_traits::node                 node;
-   typedef typename boost::pointer_to_other
-      <VoidPointer, node>::type                       node_ptr;
-   typedef typename boost::pointer_to_other
-      <VoidPointer, const node>::type                 const_node_ptr;
-   typedef slist_base_hook
-      <Tag, Policy, VoidPointer>                      this_type;
-
-   typedef typename boost::pointer_to_other
-      <VoidPointer, this_type>::type                  this_type_ptr;
-
-   typedef typename boost::pointer_to_other
-      <VoidPointer, const this_type>::type            const_this_type_ptr;
-
-   /// @cond
-   private:
-   node_ptr this_as_node()
-   {  return node_ptr(static_cast<node *const>(this)); }
-
-   const_node_ptr this_as_node() const
-   {  return const_node_ptr(static_cast<const node *const>(this)); }
-   /// @endcond
-
-   public:
-
-   //! <b>Effects</b>: If Policy is auto_unlink or safe_mode_linnk
+   #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+   //! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
    //!   initializes the node to an unlinked state.
    //! 
    //! <b>Throws</b>: Nothing. 
-   slist_base_hook()
-      :  node()
-   {
-      if(Policy == safe_link || Policy == auto_unlink){
-         node_algorithms::init(this_as_node());
-      }
-   }
+   slist_base_hook();
 
-   //! <b>Effects</b>: If Policy is auto_unlink or safe_mode_linnk
+   //! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
    //!   initializes the node to an unlinked state. The argument is ignored.
    //! 
    //! <b>Throws</b>: Nothing. 
    //! 
    //! <b>Rationale</b>: Providing a copy-constructor
-   //!   makes classes using slist_base_hook STL-compliant without forcing the 
-   //!   user to do some additional work. "swap" can be used to emulate
+   //!   makes classes using the hook STL-compliant without forcing the 
+   //!   user to do some additional work. \c swap can be used to emulate
    //!   move-semantics.
-   slist_base_hook(const slist_base_hook& ) 
-      :  node()
-   {
-      if(Policy == safe_link || Policy == auto_unlink){
-         node_algorithms::init(this_as_node());
-      }
-   }
+   slist_base_hook(const slist_base_hook& );
 
    //! <b>Effects</b>: Empty function. The argument is ignored.
    //! 
    //! <b>Throws</b>: Nothing. 
    //! 
    //! <b>Rationale</b>: Providing an assignment operator 
-   //!   makes classes using slist_base_hook STL-compliant without forcing the 
-   //!   user to do some additional work. "swap" can be used to emulate
+   //!   makes classes using the hook STL-compliant without forcing the 
+   //!   user to do some additional work. \c swap can be used to emulate
    //!   move-semantics.
-   slist_base_hook& operator=(const slist_base_hook& ) 
-   {  return *this;  }
+   slist_base_hook& operator=(const slist_base_hook& );
 
-   //! <b>Effects</b>: If Policy is normal_link, the destructor does
-   //!   nothing (ie. no code is generated). If Policy is safe_link and the
-   //!   object is stored in an list an assertion is raised. If Policy is
-   //!   auto_unlink and "is_linked()" is true, the node is unlinked.
+   //! <b>Effects</b>: If link_mode is \c normal_link, the destructor does
+   //!   nothing (ie. no code is generated). If link_mode is \c safe_link and the
+   //!   object is stored in an slist an assertion is raised. If link_mode is
+   //!   \c auto_unlink and \c is_linked() is true, the node is unlinked.
    //! 
    //! <b>Throws</b>: Nothing. 
-   ~slist_base_hook()
-   {  detail::destructor_impl(*this, detail::dispatcher<Policy>());  }
+   ~slist_base_hook();
 
    //! <b>Effects</b>: Swapping two nodes swaps the position of the elements 
    //!   related to those nodes in one or two containers. That is, if the node 
@@ -143,174 +125,99 @@
    //! <b>Complexity</b>: Constant 
    //!
    //! <b>Throws</b>: Nothing. 
-   void swap_nodes(slist_base_hook &other) 
-   { node_algorithms::swap_nodes(this_as_node(), other.this_as_node()); }
+   void swap_nodes(slist_base_hook &other);
 
-   //! <b>Precondition</b>: Policy must be safe_link or auto_unlink.
+   //! <b>Precondition</b>: link_mode must be \c safe_link or \c auto_unlink.
    //!
    //! <b>Returns</b>: true, if the node belongs to a container, false
-   //!   otherwise. This function can be used to test whether list::iterator_to 
+   //!   otherwise. This function can be used to test whether \c slist::iterator_to 
    //!   will return a valid iterator. 
    //!
    //! <b>Complexity</b>: Constant 
-   bool is_linked() const 
-   {
-      //is_linked() can be only used in safe-mode or auto-unlink
-      BOOST_STATIC_ASSERT((Policy == safe_link || Policy == auto_unlink));
-      return !node_algorithms::unique(this_as_node()); 
-   }
+   bool is_linked() const;
 
    //! <b>Effects</b>: Removes the node if it's inserted in a container.
-   //!   This function is only allowed if Policy is auto_unlink.
-   //! 
-   //! <b>Throws</b>: Nothing. 
-   void unlink()
-   {
-      BOOST_STATIC_ASSERT((Policy == auto_unlink));
-      node_algorithms::unlink(this_as_node());
-      node_algorithms::init(this_as_node());
-   }
-
-   //! The value_traits class is used as the first template argument for list. 
-   //! The template argument T defines the class type stored in list. Objects 
-   //! of type T and of types derived from T can be stored. T doesn't need to be 
-   //! copy-constructible or assignable.
-   template<class T>
-   struct value_traits
-      : detail::derivation_hook_value_traits<T, this_type, Tag>
-   {};
-
-   //! <b>Effects</b>: Converts a pointer to a node into
-   //!   a pointer to the hook that holds that node.
+   //!   This function is only allowed if link_mode is \c auto_unlink.
    //! 
    //! <b>Throws</b>: Nothing. 
-   static this_type_ptr to_hook_ptr(node_ptr p)
-   {
-      return this_type_ptr(static_cast<slist_base_hook*> (detail::get_pointer(p))); 
-   }
-
-   //! <b>Effects</b>: Converts a const pointer to a node stored in a container into
-   //!   a const pointer to the hook that holds that node.
-   //! 
-   //! <b>Throws</b>: Nothing. 
-   static const_this_type_ptr to_hook_ptr(const_node_ptr p)
-   {
-      return const_this_type_ptr(static_cast<const slist_base_hook*> (detail::get_pointer(p))); 
-   }
+   void unlink();
+   #endif
+};
 
-   //! <b>Effects</b>: Returns a pointer to the node that this hook holds.
-   //! 
-   //! <b>Throws</b>: Nothing. 
-   node_ptr to_node_ptr()
-   { return this_as_node(); }
+//! Helper metafunction to define a \c slist_member_hook that yields to the same
+//! type when the same options (either explicitly or implicitly) are used.
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+template<class ...Options>
+#else
+template<class O1 = none, class O2 = none, class O3 = none>
+#endif
+struct make_slist_member_hook
+{
+   /// @cond
+   typedef typename pack_options
+      < hook_defaults, O1, O2, O3>::type packed_options;
 
-   //! <b>Effects</b>: Returns a const pointer to the node that this hook holds.
-   //! 
-   //! <b>Throws</b>: Nothing. 
-   const_node_ptr to_node_ptr() const
-   { return this_as_node(); }
+   typedef detail::generic_hook
+   < get_slist_node_algo<typename packed_options::void_pointer>
+   , member_tag
+   , packed_options::link_mode
+   , detail::NoBaseHook
+   > implementation_defined;
+   /// @endcond
+   typedef implementation_defined type;
 };
 
 //! Put a public data member slist_member_hook in order to store objects of this class in
-//! an slist. slist_member_hook holds the data necessary for maintaining the list and 
-//! provides an appropriate value_traits class for slist.
-//! 
-//! The template argument T defines the class type stored in slist. Objects of type 
-//! T and of types derived from T can be stored. T doesn't need to be 
-//! copy-constructible or assignable.
+//! an list. slist_member_hook holds the data necessary for maintaining the list and 
+//! provides an appropriate value_traits class for list.
 //! 
-//! The second boolean template parameter will specify the linking mode of the hook.
+//! The first boolean template parameter will specify the linking mode of the hook.
 //!
-//! The third argument is the pointer type that will be used internally in the hook
-//! and the slist configured from this hook.
-template< linking_policy Policy  //= safe_link
-        , class VoidPointer      //= void *
-        >
-class slist_member_hook 
-   :  private detail::slist_node_traits<VoidPointer>::node
+//! The second argument is the pointer type that will be used internally in the hook
+//! and the list configured from this hook.
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+template<class ...Options>
+#else
+template<class O1, class O2, class O3>
+#endif
+class slist_member_hook
+   :  public make_slist_member_hook<O1, O2, O3>::type
 {
-   public:
-   typedef detail::slist_node_traits<VoidPointer>     node_traits;
-   enum { linking_policy = Policy };
-
-   /// @cond
-   private:
-   typedef circular_slist_algorithms<node_traits>              node_algorithms;
-   /// @endcond
-
-   public:
-   typedef typename node_traits::node                 node;
-   typedef typename boost::pointer_to_other
-      <VoidPointer, node>::type                       node_ptr;
-   typedef typename boost::pointer_to_other
-      <VoidPointer, const node>::type                 const_node_ptr;
-   typedef slist_member_hook
-      <Policy, VoidPointer>                           this_type;
-
-   typedef typename boost::pointer_to_other
-      <VoidPointer, this_type >::type                 this_type_ptr;
-
-   typedef typename boost::pointer_to_other
-      <VoidPointer, const this_type >::type           const_this_type_ptr;
-
-   /// @cond
-   private:
-   node_ptr this_as_node()
-   {  return node_ptr(static_cast<node *const>(this)); }
-
-   const_node_ptr this_as_node() const
-   {  return const_node_ptr(static_cast<const node *const>(this)); }
-   /// @endcond
-
-   public:
-   //! <b>Effects</b>: If Policy is auto_unlink or safe_mode_linnk
+   #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+   //! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
    //!   initializes the node to an unlinked state.
    //! 
    //! <b>Throws</b>: Nothing. 
-   slist_member_hook()
-      :  node()
-   {
-      if(Policy == safe_link || Policy == auto_unlink){
-         node_algorithms::init(this_as_node());
-      }
-   }
+   slist_member_hook();
 
-   //! <b>Effects</b>: If Policy is auto_unlink or safe_mode_linnk
+   //! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
    //!   initializes the node to an unlinked state. The argument is ignored.
    //! 
    //! <b>Throws</b>: Nothing. 
    //! 
    //! <b>Rationale</b>: Providing a copy-constructor
-   //!   makes classes using slist_member_hook STL-compliant without forcing the 
-   //!   user to do some additional work. "swap" can be used to emulate
+   //!   makes classes using the hook STL-compliant without forcing the 
+   //!   user to do some additional work. \c swap can be used to emulate
    //!   move-semantics.
-   slist_member_hook(const slist_member_hook& ) 
-      :  node()
-   {
-      if(Policy == safe_link || Policy == auto_unlink){
-         node_algorithms::init(this_as_node());
-      }
-   }
+   slist_member_hook(const slist_member_hook& );
 
    //! <b>Effects</b>: Empty function. The argument is ignored.
    //! 
    //! <b>Throws</b>: Nothing. 
    //! 
    //! <b>Rationale</b>: Providing an assignment operator 
-   //!   makes classes using slist_member_hook STL-compliant without forcing the 
-   //!   user to do some additional work. "swap" can be used to emulate
+   //!   makes classes using the hook STL-compliant without forcing the 
+   //!   user to do some additional work. \c swap can be used to emulate
    //!   move-semantics.
-   slist_member_hook& operator=(const slist_member_hook& )
-   {  return *this;  }
+   slist_member_hook& operator=(const slist_member_hook& );
 
-   //! <b>Effects</b>: If Policy is normal_link, the destructor does
-   //!   nothing (ie. no code is generated). If Policy is safe_link and the
-   //!   object is stored in an list an assertion is raised. If Policy is
-   //!   auto_unlink and "is_linked()" is true, the node is unlinked.
+   //! <b>Effects</b>: If link_mode is \c normal_link, the destructor does
+   //!   nothing (ie. no code is generated). If link_mode is \c safe_link and the
+   //!   object is stored in an slist an assertion is raised. If link_mode is
+   //!   \c auto_unlink and \c is_linked() is true, the node is unlinked.
    //! 
    //! <b>Throws</b>: Nothing. 
-   ~slist_member_hook()
-   {  detail::destructor_impl(*this, detail::dispatcher<Policy>());  }
+   ~slist_member_hook();
 
    //! <b>Effects</b>: Swapping two nodes swaps the position of the elements 
    //!   related to those nodes in one or two containers. That is, if the node 
@@ -323,78 +230,29 @@
    //!
    //! <b>Complexity</b>: Constant 
    //!
-   //! <b>Throws</b>: Nothing.
-   void swap_nodes(slist_member_hook& other) 
-   { node_algorithms::swap_nodes(this_as_node(), other.this_as_node()); }
+   //! <b>Throws</b>: Nothing. 
+   void swap_nodes(slist_member_hook &other);
 
-   //! <b>Precondition</b>: Policy must be safe_link or auto_unlink.
+   //! <b>Precondition</b>: link_mode must be \c safe_link or \c auto_unlink.
    //!
    //! <b>Returns</b>: true, if the node belongs to a container, false
-   //!   otherwise. This function can be used to test whether list::iterator_to 
+   //!   otherwise. This function can be used to test whether \c slist::iterator_to 
    //!   will return a valid iterator. 
    //!
-   //! <b>Complexity</b>: Constant
-   bool is_linked() const 
-   {
-      //is_linked() can be only used in safe-mode or auto-unlink
-      BOOST_STATIC_ASSERT((Policy == safe_link || Policy == auto_unlink));
-      return !node_algorithms::unique(this_as_node()); 
-   }
+   //! <b>Complexity</b>: Constant 
+   bool is_linked() const;
 
    //! <b>Effects</b>: Removes the node if it's inserted in a container.
-   //!   This function is only allowed if Policy is auto_unlink.
-   //! 
-   //! <b>Throws</b>: Nothing. 
-   void unlink()
-   {
-      BOOST_STATIC_ASSERT((Policy == auto_unlink));
-      node_algorithms::unlink(this_as_node());
-      node_algorithms::init(this_as_node());
-   }
-
-   //! The value_traits class is used as the first template argument for list. 
-   //! The template argument is a pointer to member pointing to the node in 
-   //! the class. Objects of type T and of types derived from T can be stored. 
-   //! T doesn't need to be copy-constructible or assignable.
-   template<class T, this_type T::* M>
-   struct value_traits
-      : detail::member_hook_value_traits<T, this_type, M>
-   {};
-
-   //! <b>Effects</b>: Converts a pointer to a node into
-   //!   a pointer to the hook that holds that node.
-   //! 
-   //! <b>Throws</b>: Nothing. 
-   static this_type_ptr to_hook_ptr(node_ptr p)
-   {
-      return this_type_ptr(static_cast<this_type*> (detail::get_pointer(p))); 
-   }
-
-   //! <b>Effects</b>: Converts a const pointer to a node stored in a container into
-   //!   a const pointer to the hook that holds that node.
-   //! 
-   //! <b>Throws</b>: Nothing. 
-   static const_this_type_ptr to_hook_ptr(const_node_ptr p)
-   {
-      return const_this_type_ptr(static_cast<const this_type*> (detail::get_pointer(p))); 
-   }
-
-   //! <b>Effects</b>: Returns a pointer to the node that this hook holds.
-   //! 
-   //! <b>Throws</b>: Nothing. 
-   node_ptr to_node_ptr()
-   { return this_as_node(); }
-
-   //! <b>Effects</b>: Returns a const pointer to the node that this hook holds.
+   //!   This function is only allowed if link_mode is \c auto_unlink.
    //! 
    //! <b>Throws</b>: Nothing. 
-   const_node_ptr to_node_ptr() const
-   { return this_as_node(); }
+   void unlink();
+   #endif
 };
 
 } //namespace intrusive 
 } //namespace boost 
 
-#include<boost/intrusive/detail/config_end.hpp>
+#include <boost/intrusive/detail/config_end.hpp>
 
 #endif //BOOST_INTRUSIVE_SLIST_HOOK_HPP
Deleted: trunk/boost/intrusive/tag.hpp
==============================================================================
--- trunk/boost/intrusive/tag.hpp	2007-09-26 11:26:35 EDT (Wed, 26 Sep 2007)
+++ (empty file)
@@ -1,26 +0,0 @@
-/////////////////////////////////////////////////////////////////////////////
-//
-// (C) Copyright Ion Gaztanaga  2006-2007
-//
-// Distributed under the Boost Software License, Version 1.0.
-//    (See accompanying file LICENSE_1_0.txt or copy at
-//          http://www.boost.org/LICENSE_1_0.txt)
-//
-// See http://www.boost.org/libs/intrusive for documentation.
-//
-/////////////////////////////////////////////////////////////////////////////
-
-#ifndef BOOST_INTRUSIVE_DEFAULT_TAG_HPP
-#define BOOST_INTRUSIVE_DEFAULT_TAG_HPP
-
-namespace boost {
-namespace intrusive {
-
-//!This is the declaration of the default
-//!hook used by base hooks
-class tag;
-
-} //namespace intrusive 
-} //namespace boost 
-
-#endif //BOOST_INTRUSIVE_DEFAULT_TAG_HPP
Modified: trunk/boost/intrusive/trivial_value_traits.hpp
==============================================================================
--- trunk/boost/intrusive/trivial_value_traits.hpp	(original)
+++ trunk/boost/intrusive/trivial_value_traits.hpp	2007-09-26 11:26:35 EDT (Wed, 26 Sep 2007)
@@ -13,7 +13,7 @@
 #ifndef BOOST_INTRUSIVE_TRIVIAL_VALUE_TRAITS_HPP
 #define BOOST_INTRUSIVE_TRIVIAL_VALUE_TRAITS_HPP
 
-#include <boost/intrusive/linking_policy.hpp>
+#include <boost/intrusive/link_mode.hpp>
 
 namespace boost {
 namespace intrusive {
@@ -21,7 +21,7 @@
 //!This value traits template is used to create value traits
 //!from user defined node traits where value_traits::value_type and
 //!node_traits::node should be equal
-template<class NodeTraits, linking_policy LinkingPolicy = safe_link>
+template<class NodeTraits, link_mode_type LinkMode = normal_link>
 struct trivial_value_traits
 {
    typedef NodeTraits                                          node_traits;
@@ -30,11 +30,11 @@
    typedef typename node_traits::node                          value_type;
    typedef node_ptr                                            pointer;
    typedef const_node_ptr                                      const_pointer;
-   enum {   linking_policy =  LinkingPolicy  };
-   static node_ptr to_node_ptr (value_type &value)             {  return node_ptr(&value); }
+   static const link_mode_type link_mode = LinkMode;
+   static node_ptr       to_node_ptr (value_type &value)       {  return node_ptr(&value); }
    static const_node_ptr to_node_ptr (const value_type &value) {  return const_node_ptr(&value); }
-   static pointer to_value_ptr(node_ptr n)                     {  return pointer(n); }
-   static const_pointer to_value_ptr(const_node_ptr n)         {  return const_pointer(n); }
+   static pointer        to_value_ptr(node_ptr n)              {  return pointer(n); }
+   static const_pointer  to_value_ptr(const_node_ptr n)        {  return const_pointer(n); }
 };
 
 } //namespace intrusive 
Modified: trunk/boost/intrusive/unordered_set.hpp
==============================================================================
--- trunk/boost/intrusive/unordered_set.hpp	(original)
+++ trunk/boost/intrusive/unordered_set.hpp	2007-09-26 11:26:35 EDT (Wed, 26 Sep 2007)
@@ -10,8 +10,8 @@
 // See http://www.boost.org/libs/intrusive for documentation.
 //
 /////////////////////////////////////////////////////////////////////////////
-#ifndef BOOST_INTRUSIVE_HASHSET_HPP
-#define BOOST_INTRUSIVE_HASHSET_HPP
+#ifndef BOOST_INTRUSIVE_UNORDERED_SET_HPP
+#define BOOST_INTRUSIVE_UNORDERED_SET_HPP
 
 #include <boost/intrusive/detail/config_begin.hpp>
 #include <boost/intrusive/intrusive_fwd.hpp>
@@ -32,27 +32,22 @@
 //! unordered_set more complicated than purely intrusive containers.
 //! `bucket_type` is default-constructible, copyable and assignable
 //!
-//! The template parameter ValueTraits is called "value traits". It stores
-//! information and operations about the type to be stored in the container.
+//! The template parameter \c T is the type to be managed by the container.
+//! The user can specify additional options and if no options are provided
+//! default options are used.
 //!
-//! The template parameter Hash is a unary function object that take an argument
-//!   of type ValueTraits::value_type and returns a value of type std::size_t.
-//!
-//! The template parameter Equal is a binary predicate that takes two arguments of
-//!   type ValueTraits::value_type. Equal is an equivalence relation.
-//!
-//! If the user specifies ConstantTimeSize as "true", a member of type SizeType
-//! will be embedded in the class, that will keep track of the number of stored objects.
-//! This will allow constant-time O(1) size() member, instead of default O(N) size.
+//! The container supports the following options:
+//! \c base_hook<>/member_hook<>/value_traits<>,
+//! \c constant_time_size<>, \c size_type<>, \c hash<> and \c equal<> .
 //!
 //! unordered_set only provides forward iterators but it provides 4 iterator types:
 //! iterator and const_iterator to navigate through the whole container and
 //! local_iterator and const_local_iterator to navigate through the values
 //! stored in a single bucket. Local iterators are faster and smaller.
 //!
-//! It's not recommended to use non ConstantTimeSize unordered_sets because several
+//! It's not recommended to use non constant-time size unordered_sets because several
 //! key functions, like "empty()", become non-constant time functions. Non
-//! ConstantTimeSize unordered_sets are mainly provided to support auto-unlink hooks.
+//! constant-time size unordered_sets are mainly provided to support auto-unlink hooks.
 //!
 //! unordered_set, unlike std::unordered_set, does not make automatic rehashings nor
 //! offers functions related to a load factor. Rehashing can be explicitly requested
@@ -60,48 +55,53 @@
 //!
 //! Since no automatic rehashing is done, iterators are never invalidated when
 //! inserting or erasing elements. Iterators are only invalidated when rehasing.
-template< class ValueTraits
-        , class Hash             //= boost::hash<typename ValueTraits::value_type>
-        , class Equal            //= std::equal_to<typename ValueTraits::value_type>
-        , bool  ConstantTimeSize //= true
-        , class SizeType         //= std::size_t
-        >
-class unordered_set
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+template<class T, class ...Options>
+#else
+template<class Config>
+#endif
+class unordered_set_impl
 {
    /// @cond
    private:
-   typedef hashtable<ValueTraits, Hash, Equal, ConstantTimeSize, SizeType> table_type;
+   typedef hashtable_impl<Config> table_type;
 
    //! This class is
    //! non-copyable
-   unordered_set (const unordered_set&);
+   unordered_set_impl (const unordered_set_impl&);
 
    //! This class is
    //! non-assignable
-   unordered_set &operator =(const unordered_set&);
+   unordered_set_impl &operator =(const unordered_set_impl&);
 
    typedef table_type implementation_defined;
    /// @endcond
 
    public:
-   typedef ValueTraits                                                  value_traits;
-   typedef typename ValueTraits::value_type                             value_type;
-   typedef typename ValueTraits::pointer                                pointer;
-   typedef typename ValueTraits::const_pointer                          const_pointer;
-   typedef typename std::iterator_traits<pointer>::reference            reference;
-   typedef typename std::iterator_traits<const_pointer>::reference      const_reference;
-   typedef typename std::iterator_traits<pointer>::difference_type      difference_type;
-   typedef SizeType                                                     size_type;
-   typedef value_type                                                   key_type;
-   typedef Equal                                                        key_equal;
-   typedef Hash                                                         hasher;
+   typedef typename implementation_defined::value_type                  value_type;
+   typedef typename implementation_defined::value_traits                value_traits;
+   typedef typename implementation_defined::bucket_traits               bucket_traits;
+   typedef typename implementation_defined::pointer                     pointer;
+   typedef typename implementation_defined::const_pointer               const_pointer;
+   typedef typename implementation_defined::reference                   reference;
+   typedef typename implementation_defined::const_reference             const_reference;
+   typedef typename implementation_defined::difference_type             difference_type;
+   typedef typename implementation_defined::size_type                   size_type;
+   typedef typename implementation_defined::key_type                    key_type;
+   typedef typename implementation_defined::key_equal                   key_equal;
+   typedef typename implementation_defined::hasher                      hasher;
    typedef typename implementation_defined::bucket_type                 bucket_type;
-   typedef typename boost::pointer_to_other<pointer, bucket_type>::type bucket_ptr;
+   typedef typename implementation_defined::bucket_ptr                  bucket_ptr;
    typedef typename implementation_defined::iterator                    iterator;
    typedef typename implementation_defined::const_iterator              const_iterator;
    typedef typename implementation_defined::insert_commit_data          insert_commit_data;
    typedef typename implementation_defined::local_iterator              local_iterator;
    typedef typename implementation_defined::const_local_iterator        const_local_iterator;
+   typedef typename implementation_defined::node_traits                 node_traits;
+   typedef typename implementation_defined::node                        node;
+   typedef typename implementation_defined::node_ptr                    node_ptr;
+   typedef typename implementation_defined::const_node_ptr              const_node_ptr;
+   typedef typename implementation_defined::node_algorithms             node_algorithms;
 
    /// @cond
    private:
@@ -112,7 +112,7 @@
 
    //! <b>Requires</b>: buckets must not be being used by any other resource.
    //!
-   //! <b>Effects</b>: Constructs an empty unordered_set, storing a reference
+   //! <b>Effects</b>: Constructs an empty unordered_set_impl, storing a reference
    //!   to the bucket array and copies of the hasher and equal functors.
    //!   
    //! <b>Complexity</b>: Constant. 
@@ -123,11 +123,11 @@
    //!
    //! <b>Notes</b>: buckets array must be disposed only after
    //!   *this is disposed. 
-   unordered_set( bucket_ptr buckets
-           , size_type buckets_len
-           , const Hash & hasher = Hash()
-           , const Equal &equal = Equal()) 
-      :  table_(buckets, buckets_len, hasher, equal)
+   unordered_set_impl( const bucket_traits &b_traits
+                     , const hasher & hash_func = hasher()
+                     , const key_equal &equal_func = key_equal()
+                     , const value_traits &v_traits = value_traits()) 
+      :  table_(b_traits, hash_func, equal_func, v_traits)
    {}
 
    //! <b>Requires</b>: buckets must not be being used by any other resource
@@ -141,18 +141,18 @@
    //! 
    //! <b>Throws</b>: If value_traits::node_traits::node
    //!   constructor throws (this does not happen with predefined Boost.Intrusive hooks)
-   //!   or the copy constructor or invocation of Hash or Equal throws. 
+   //!   or the copy constructor or invocation of hasher or key_equal throws. 
    //!
    //! <b>Notes</b>: buckets array must be disposed only after
    //!   *this is disposed. 
    template<class Iterator>
-   unordered_set( bucket_ptr buckets
-           , size_type buckets_len
-           , Iterator b
-           , Iterator e
-           , const Hash & hasher = Hash()
-           , const Equal &equal = Equal()) 
-      :  table_(buckets, buckets_len, hasher, equal)
+   unordered_set_impl( Iterator b
+                     , Iterator e
+                     , const bucket_traits &b_traits
+                     , const hasher & hash_func = hasher()
+                     , const key_equal &equal_func = key_equal()
+                     , const value_traits &v_traits = value_traits()) 
+      :  table_(b_traits, hash_func, equal_func, v_traits)
    {  table_.insert_unique(b, e);  }
 
    //! <b>Effects</b>: Detaches all elements from this. The objects in the unordered_set 
@@ -162,7 +162,7 @@
    //!   it's a safe-mode or auto-unlink value. Otherwise constant.
    //! 
    //! <b>Throws</b>: Nothing.
-   ~unordered_set() 
+   ~unordered_set_impl() 
    {}
 
    //! <b>Effects</b>: Returns an iterator pointing to the beginning of the unordered_set.
@@ -236,7 +236,7 @@
 
    //! <b>Effects</b>: Returns true is the container is empty.
    //! 
-   //! <b>Complexity</b>: if ConstantTimeSize is false, average constant time
+   //! <b>Complexity</b>: if constant-time size option is disabled, average constant time
    //!   (worst case, with empty() == true): O(this->bucket_count()).
    //!   Otherwise constant.
    //! 
@@ -247,7 +247,7 @@
    //! <b>Effects</b>: Returns the number of elements stored in the unordered_set.
    //! 
    //! <b>Complexity</b>: Linear to elements contained in *this if
-   //!   ConstantTimeSize is false. Constant-time otherwise.
+   //!   constant-time size option is enabled. Constant-time otherwise.
    //! 
    //! <b>Throws</b>: Nothing.
    size_type size() const
@@ -263,7 +263,7 @@
    //!
    //! <b>Throws</b>: If the swap() call for the comparison or hash functors
    //!   found using ADL throw. Basic guarantee.
-   void swap(unordered_set& other)
+   void swap(unordered_set_impl& other)
    { table_.swap(other.table_); }
 
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
@@ -280,7 +280,7 @@
    //! 
    //! <b>Throws</b>: If cloner throws. Basic guarantee.
    template <class Cloner, class Disposer>
-   void clone_from(const unordered_set &src, Cloner cloner, Disposer disposer)
+   void clone_from(const unordered_set_impl &src, Cloner cloner, Disposer disposer)
    {  table_.clone_from(src.table_, cloner, disposer);  }
 
    //! <b>Requires</b>: value must be an lvalue
@@ -433,13 +433,13 @@
    //! <b>Complexity</b>: Average case O(this->count(value)).
    //!   Worst case O(this->size()).
    //! 
-   //! <b>Throws</b>: If hasher or equal throw. Basic guarantee.
+   //! <b>Throws</b>: If hash_func or equal_func throw. Basic guarantee.
    //! 
    //! <b>Note</b>: Invalidates the iterators (but not the references)
    //!    to the erased elements. No destructors are called.
    template<class KeyType, class KeyHasher, class KeyValueEqual>
-   size_type erase(const KeyType& key, KeyHasher hasher, KeyValueEqual equal)
-   {  return table_.erase(key, hasher, equal);  }
+   size_type erase(const KeyType& key, KeyHasher hash_func, KeyValueEqual equal_func)
+   {  return table_.erase(key, hash_func, equal_func);  }
 
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
    //!
@@ -493,7 +493,7 @@
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
    //!
    //! <b>Effects</b>: Erases all the elements with the given key.
-   //!   according to the comparison functor "equal".
+   //!   according to the comparison functor "equal_func".
    //!   Disposer::operator()(pointer) is called for the removed elements.
    //!
    //! <b>Returns</b>: The number of erased elements.
@@ -501,13 +501,13 @@
    //! <b>Complexity</b>: Average case O(this->count(value)).
    //!   Worst case O(this->size()).
    //! 
-   //! <b>Throws</b>: If hasher or key_value_equal throw. Basic guarantee.
+   //! <b>Throws</b>: If hash_func or equal_func throw. Basic guarantee.
    //! 
    //! <b>Note</b>: Invalidates the iterators
    //!    to the erased elements.
    template<class KeyType, class KeyHasher, class KeyValueEqual, class Disposer>
-   size_type erase_and_dispose(const KeyType& key, KeyHasher hasher, KeyValueEqual equal, Disposer disposer)
-   {  return table_.erase_and_dispose(key, hasher, equal, disposer);  }
+   size_type erase_and_dispose(const KeyType& key, KeyHasher hash_func, KeyValueEqual equal_func, Disposer disposer)
+   {  return table_.erase_and_dispose(key, hash_func, equal_func, disposer);  }
 
    //! <b>Effects</b>: Erases all of the elements. 
    //! 
@@ -544,22 +544,22 @@
    size_type count(const_reference value) const
    {  return table_.find(value) != end();  }
 
-   //! <b>Requires</b>: "hasher" must be a hash function that induces 
+   //! <b>Requires</b>: "hash_func" must be a hash function that induces 
    //!   the same hash values as the stored hasher. The difference is that
-   //!   "hasher" hashes the given key instead of the value_type.
+   //!   "hash_func" hashes the given key instead of the value_type.
    //!
-   //!   "key_value_equal" must be a equality function that induces 
+   //!   "equal_func" must be a equality function that induces 
    //!   the same equality as key_equal. The difference is that
-   //!   "key_value_equal" compares an arbitrary key with the contained values.
+   //!   "equal_func" compares an arbitrary key with the contained values.
    //!
    //! <b>Effects</b>: Returns the number of contained elements with the given key
    //!
    //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
    //! 
-   //! <b>Throws</b>: If hasher or equal throw.
+   //! <b>Throws</b>: If hash_func or equal_func throw.
    template<class KeyType, class KeyHasher, class KeyValueEqual, class Disposer>
-   size_type count(const KeyType& key, KeyHasher hasher, KeyValueEqual equal) const
-   {  return table_.find(key, hasher, equal) != end();  }
+   size_type count(const KeyType& key, KeyHasher hash_func, KeyValueEqual equal_func) const
+   {  return table_.find(key, hash_func, equal_func) != end();  }
 
    //! <b>Effects</b>: Finds an iterator to the first element is equal to
    //!   "value" or end() if that element does not exist.
@@ -570,13 +570,13 @@
    iterator find(const_reference value)
    {  return table_.find(value);  }
 
-   //! <b>Requires</b>: "hasher" must be a hash function that induces 
+   //! <b>Requires</b>: "hash_func" must be a hash function that induces 
    //!   the same hash values as the stored hasher. The difference is that
-   //!   "hasher" hashes the given key instead of the value_type.
+   //!   "hash_func" hashes the given key instead of the value_type.
    //!
-   //!   "key_value_equal" must be a equality function that induces 
+   //!   "equal_func" must be a equality function that induces 
    //!   the same equality as key_equal. The difference is that
-   //!   "key_value_equal" compares an arbitrary key with the contained values.
+   //!   "equal_func" compares an arbitrary key with the contained values.
    //!
    //! <b>Effects</b>: Finds an iterator to the first element whose key is 
    //!   "key" according to the given hasher and equality functor or end() if
@@ -584,14 +584,14 @@
    //!
    //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
    //! 
-   //! <b>Throws</b>: If hasher or equal throw.
+   //! <b>Throws</b>: If hash_func or equal_func throw.
    //!
    //! <b>Note</b>: This function is used when constructing a value_type
    //!   is expensive and the value_type can be compared with a cheaper
    //!   key type. Usually this key is part of the value_type.
    template<class KeyType, class KeyHasher, class KeyValueEqual>
-   iterator find(const KeyType& key, KeyHasher hasher, KeyValueEqual equal)
-   {  return table_.find(key, hasher, equal);  }
+   iterator find(const KeyType& key, KeyHasher hash_func, KeyValueEqual equal_func)
+   {  return table_.find(key, hash_func, equal_func);  }
 
    //! <b>Effects</b>: Finds a const_iterator to the first element whose key is 
    //!   "key" or end() if that element does not exist.
@@ -602,13 +602,13 @@
    const_iterator find(const_reference value) const
    {  return table_.find(value);  }
 
-   //! <b>Requires</b>: "hasher" must be a hash function that induces 
+   //! <b>Requires</b>: "hash_func" must be a hash function that induces 
    //!   the same hash values as the stored hasher. The difference is that
-   //!   "hasher" hashes the given key instead of the value_type.
+   //!   "hash_func" hashes the given key instead of the value_type.
    //!
-   //!   "key_value_equal" must be a equality function that induces 
+   //!   "equal_func" must be a equality function that induces 
    //!   the same equality as key_equal. The difference is that
-   //!   "key_value_equal" compares an arbitrary key with the contained values.
+   //!   "equal_func" compares an arbitrary key with the contained values.
    //!
    //! <b>Effects</b>: Finds an iterator to the first element whose key is 
    //!   "key" according to the given hasher and equality functor or end() if
@@ -616,14 +616,14 @@
    //! 
    //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
    //! 
-   //! <b>Throws</b>: If hasher or equal throw.
+   //! <b>Throws</b>: If hash_func or equal_func throw.
    //!
    //! <b>Note</b>: This function is used when constructing a value_type
    //!   is expensive and the value_type can be compared with a cheaper
    //!   key type. Usually this key is part of the value_type.
    template<class KeyType, class KeyHasher, class KeyValueEqual>
-   const_iterator find(const KeyType& key, KeyHasher hasher, KeyValueEqual equal) const
-   {  return table_.find(key, equal);  }
+   const_iterator find(const KeyType& key, KeyHasher hash_func, KeyValueEqual equal_func) const
+   {  return table_.find(key, hash_func, equal_func);  }
 
    //! <b>Effects</b>: Returns a range containing all elements with values equivalent
    //!   to value. Returns std::make_pair(this->end(), this->end()) if no such 
@@ -635,28 +635,29 @@
    std::pair<iterator,iterator> equal_range(const_reference value)
    {  return table_.equal_range(value);  }
 
-   //! <b>Requires</b>: "hasher" must be a hash function that induces 
+   //! <b>Requires</b>: "hash_func" must be a hash function that induces 
    //!   the same hash values as the stored hasher. The difference is that
-   //!   "hasher" hashes the given key instead of the value_type.
+   //!   "hash_func" hashes the given key instead of the value_type.
    //!
-   //!   "key_value_equal" must be a equality function that induces 
+   //!   "equal_func" must be a equality function that induces 
    //!   the same equality as key_equal. The difference is that
-   //!   "key_value_equal" compares an arbitrary key with the contained values.
+   //!   "equal_func" compares an arbitrary key with the contained values.
    //!
    //! <b>Effects</b>: Returns a range containing all elements with equivalent
    //!   keys. Returns std::make_pair(this->end(), this->end()) if no such 
    //!   elements exist.
    //! 
-   //! <b>Complexity</b>: Average case O(this->count(key, hasher, equal)). Worst case O(this->size()).
+   //! <b>Complexity</b>: Average case O(this->count(key, hash_func, hash_func)).
+   //!   Worst case O(this->size()).
    //! 
-   //! <b>Throws</b>: If hasher or the equal throw.
+   //! <b>Throws</b>: If hash_func or the equal_func throw.
    //!
    //! <b>Note</b>: This function is used when constructing a value_type
    //!   is expensive and the value_type can be compared with a cheaper
    //!   key type. Usually this key is part of the value_type.
    template<class KeyType, class KeyHasher, class KeyValueEqual>
-   std::pair<iterator,iterator> equal_range(const KeyType& key, KeyHasher hasher, KeyValueEqual equal)
-   {  return table_.equal_range(key, hasher, equal);  }
+   std::pair<iterator,iterator> equal_range(const KeyType& key, KeyHasher hash_func, KeyValueEqual equal_func)
+   {  return table_.equal_range(key, hash_func, equal_func);  }
 
    //! <b>Effects</b>: Returns a range containing all elements with values equivalent
    //!   to value. Returns std::make_pair(this->end(), this->end()) if no such 
@@ -669,29 +670,30 @@
       equal_range(const_reference value) const
    {  return table_.equal_range(value);  }
 
-   //! <b>Requires</b>: "hasher" must be a hash function that induces 
+   //! <b>Requires</b>: "hash_func" must be a hash function that induces 
    //!   the same hash values as the stored hasher. The difference is that
-   //!   "hasher" hashes the given key instead of the value_type.
+   //!   "hash_func" hashes the given key instead of the value_type.
    //!
-   //!   "key_value_equal" must be a equality function that induces 
+   //!   "equal_func" must be a equality function that induces 
    //!   the same equality as key_equal. The difference is that
-   //!   "key_value_equal" compares an arbitrary key with the contained values.
+   //!   "equal_func" compares an arbitrary key with the contained values.
    //!
    //! <b>Effects</b>: Returns a range containing all elements with equivalent
    //!   keys. Returns std::make_pair(this->end(), this->end()) if no such 
    //!   elements exist.
    //! 
-   //! <b>Complexity</b>: Average case O(this->count(key, hasher, equal)). Worst case O(this->size()).
+   //! <b>Complexity</b>: Average case O(this->count(key, hash_func, equal_func)).
+   //!   Worst case O(this->size()).
    //! 
-   //! <b>Throws</b>: If the hasher or equal throw.
+   //! <b>Throws</b>: If the hash_func or equal_func throw.
    //!
    //! <b>Note</b>: This function is used when constructing a value_type
    //!   is expensive and the value_type can be compared with a cheaper
    //!   key type. Usually this key is part of the value_type.
    template<class KeyType, class KeyHasher, class KeyValueEqual>
    std::pair<const_iterator, const_iterator>
-      equal_range(const KeyType& key, KeyHasher hasher, KeyValueEqual equal) const
-   {  return table_.equal_range(key, equal);  }
+      equal_range(const KeyType& key, KeyHasher hash_func, KeyValueEqual equal_func) const
+   {  return table_.equal_range(key, hash_func, equal_func);  }
 
    //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of
    //!   appropriate type. Otherwise the behavior is undefined.
@@ -726,8 +728,11 @@
    //! <b>Complexity</b>: Constant.
    //! 
    //! <b>Throws</b>: Nothing.
-   static local_iterator local_iterator_to(reference value)
-   {  return table_type::local_iterator_to(value);  }
+   //! 
+   //! <b>Note</b>: This static function is available only if the <i>value traits</i>
+   //!   is stateless.
+   static local_iterator s_local_iterator_to(reference value)
+   {  return table_type::s_local_iterator_to(value);  }
 
    //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of
    //!   appropriate type. Otherwise the behavior is undefined.
@@ -738,8 +743,35 @@
    //! <b>Complexity</b>: Constant.
    //! 
    //! <b>Throws</b>: Nothing.
-   static const_local_iterator local_iterator_to(const_reference value)
-   {  return table_type::local_iterator_to(value);  }
+   //! 
+   //! <b>Note</b>: This static function is available only if the <i>value traits</i>
+   //!   is stateless.
+   static const_local_iterator s_local_iterator_to(const_reference value)
+   {  return table_type::s_local_iterator_to(value);  }
+
+   //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of
+   //!   appropriate type. Otherwise the behavior is undefined.
+   //! 
+   //! <b>Effects</b>: Returns: a valid local_iterator belonging to the unordered_set
+   //!   that points to the value
+   //! 
+   //! <b>Complexity</b>: Constant.
+   //! 
+   //! <b>Throws</b>: Nothing.
+   local_iterator local_iterator_to(reference value)
+   {  return table_.local_iterator_to(value);  }
+
+   //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of
+   //!   appropriate type. Otherwise the behavior is undefined.
+   //! 
+   //! <b>Effects</b>: Returns: a valid const_local_iterator belonging to
+   //!   the unordered_set that points to the value
+   //! 
+   //! <b>Complexity</b>: Constant.
+   //! 
+   //! <b>Throws</b>: Nothing.
+   const_local_iterator local_iterator_to(const_reference value) const
+   {  return table_.local_iterator_to(value);  }
 
    //! <b>Effects</b>: Returns the number of buckets passed in the constructor
    //!   or the last rehash function.
@@ -771,21 +803,21 @@
    size_type bucket(const value_type& k) const
    {  return table_.bucket(k);   }
 
-   //! <b>Requires</b>: "hasher" must be a hash function that induces 
+   //! <b>Requires</b>: "hash_func" must be a hash function that induces 
    //!   the same hash values as the stored hasher. The difference is that
-   //!   "hasher" hashes the given key instead of the value_type.
+   //!   "hash_func" hashes the given key instead of the value_type.
    //!
    //! <b>Effects</b>: Returns the index of the bucket in which elements
    //!   with keys equivalent to k would be found, if any such element existed.
    //! 
    //! <b>Complexity</b>: Constant.
    //! 
-   //! <b>Throws</b>: If hasher throws.
+   //! <b>Throws</b>: If hash_func throws.
    //!
    //! <b>Note</b>: the return value is in the range [0, this->bucket_count()).
    template<class KeyType, class KeyHasher>
-   size_type bucket(const KeyType& k,  KeyHasher hasher) const
-   {  return table_.bucket(k, hasher);   }
+   size_type bucket(const KeyType& k,  KeyHasher hash_func) const
+   {  return table_.bucket(k, hash_func);   }
 
    //! <b>Effects</b>: Returns the bucket array pointer passed in the constructor
    //!   or the last rehash function.
@@ -891,8 +923,8 @@
    //! <b>Complexity</b>: Average case linear in this->size(), worst case quadratic.
    //! 
    //! <b>Throws</b>: If the hasher functor throws. Basic guarantee.
-   void rehash(bucket_ptr new_buckets, size_type new_size)
-   {  table_.rehash(new_buckets, new_size); }
+   void rehash(const bucket_traits &new_bucket_traits)
+   {  table_.rehash(new_bucket_traits); }
 
    //! <b>Effects</b>: Returns the nearest new bucket count optimized for
    //!   the container that is bigger than n. This suggestion can be used
@@ -919,6 +951,70 @@
    {  return table_type::suggested_lower_bucket_count(n);  }
 };
 
+//! Helper metafunction to define an \c unordered_set that yields to the same type when the
+//! same options (either explicitly or implicitly) are used.
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+template<class T, class ...Options>
+#else
+template<class T, class O1 = none, class O2 = none
+                , class O3 = none, class O4 = none
+                , class O5 = none, class O6 = none
+                , class O7 = none
+                >
+#endif
+struct make_unordered_set
+{
+   /// @cond
+   typedef unordered_set_impl
+      <  typename make_hashtable_opt
+            <T, O1, O2, O3, O4, O5, O6, O7>::type
+      > implementation_defined;
+   /// @endcond
+   typedef implementation_defined type;
+};
+
+#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+template<class T, class O1, class O2, class O3, class O4, class O5, class O6, class O7>
+class unordered_set
+   :  public make_unordered_set<T, O1, O2, O3, O4, O5, O6, O7>::type
+{
+   typedef typename make_unordered_set
+      <T, O1, O2, O3, O4, O5, O6, O7>::type   Base;
+
+   //Assert if passed value traits are compatible with the type
+   BOOST_STATIC_ASSERT((detail::is_same<typename Base::value_traits::value_type, T>::value));
+
+   public:
+   typedef typename Base::value_traits       value_traits;
+   typedef typename Base::bucket_traits      bucket_traits;
+   typedef typename Base::iterator           iterator;
+   typedef typename Base::const_iterator     const_iterator;
+   typedef typename Base::bucket_ptr         bucket_ptr;
+   typedef typename Base::size_type          size_type;
+   typedef typename Base::hasher             hasher;
+   typedef typename Base::key_equal          key_equal;
+
+   unordered_set  ( const bucket_traits &b_traits
+                  , const hasher & hash_func = hasher()
+                  , const key_equal &equal_func = key_equal()
+                  , const value_traits &v_traits = value_traits()) 
+      :  Base(b_traits, hash_func, equal_func, v_traits)
+   {}
+
+   template<class Iterator>
+   unordered_set  ( Iterator b
+                  , Iterator e
+                  , const bucket_traits &b_traits
+                  , const hasher & hash_func = hasher()
+                  , const key_equal &equal_func = key_equal()
+                  , const value_traits &v_traits = value_traits()) 
+      :  Base(b, e, b_traits, hash_func, equal_func, v_traits)
+   {}
+};
+
+#endif
+
+
 //! The class template unordered_multiset is an intrusive container, that mimics most of 
 //! the interface of std::tr1::unordered_multiset as described in the C++ TR1.
 //!
@@ -930,27 +1026,22 @@
 //! unordered_multiset more complicated than purely intrusive containers.
 //! `bucket_type` is default-constructible, copyable and assignable
 //!
-//! The template parameter ValueTraits is called "value traits". It stores
-//! information and operations about the type to be stored in the container.
-//!
-//! The template parameter Hash is a unary function object that take an argument
-//!   of type ValueTraits::value_type and returns a value of type std::size_t.
+//! The template parameter \c T is the type to be managed by the container.
+//! The user can specify additional options and if no options are provided
+//! default options are used.
 //!
-//! The template parameter Equal is a binary predicate that takes two arguments of
-//!   type ValueTraits::value_type. Equal is an equivalence relation.
-//!
-//! If the user specifies ConstantTimeSize as "true", a member of type SizeType
-//! will be embedded in the class, that will keep track of the number of stored objects.
-//! This will allow constant-time O(1) size() member, instead of default O(N) size.
+//! The container supports the following options:
+//! \c base_hook<>/member_hook<>/value_traits<>,
+//! \c constant_time_size<>, \c size_type<>, \c hash<> and \c equal<> .
 //!
 //! unordered_multiset only provides forward iterators but it provides 4 iterator types:
 //! iterator and const_iterator to navigate through the whole container and
 //! local_iterator and const_local_iterator to navigate through the values
 //! stored in a single bucket. Local iterators are faster and smaller.
 //!
-//! It's not recommended to use non ConstantTimeSize unordered_multisets because several
+//! It's not recommended to use non constant-time size unordered_multisets because several
 //! key functions, like "empty()", become non-constant time functions. Non
-//! ConstantTimeSize unordered_multisets are mainly provided to support auto-unlink hooks.
+//! constant-time size unordered_multisets are mainly provided to support auto-unlink hooks.
 //!
 //! unordered_multiset, unlike std::unordered_set, does not make automatic rehashings nor
 //! offers functions related to a load factor. Rehashing can be explicitly requested
@@ -958,48 +1049,53 @@
 //!
 //! Since no automatic rehashing is done, iterators are never invalidated when
 //! inserting or erasing elements. Iterators are only invalidated when rehasing.
-template< class ValueTraits
-        , class Hash             //= boost::hash<typename ValueTraits::value_type>
-        , class Equal            //= std::equal_to<typename ValueTraits::value_type>
-        , bool  ConstantTimeSize //= true
-        , class SizeType         //= std::size_t
-        >
-class unordered_multiset
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+template<class T, class ...Options>
+#else
+template<class Config>
+#endif
+class unordered_multiset_impl
 {
    /// @cond
    private:
-   typedef hashtable<ValueTraits, Hash, Equal, ConstantTimeSize, SizeType> table_type;
+   typedef hashtable_impl<Config> table_type;
    /// @endcond
 
    //! This class is
    //! non-copyable
-   unordered_multiset (const unordered_multiset&);
+   unordered_multiset_impl (const unordered_multiset_impl&);
 
    //! This class is
    //! non-assignable
-   unordered_multiset &operator =(const unordered_multiset&);
+   unordered_multiset_impl &operator =(const unordered_multiset_impl&);
 
    typedef table_type implementation_defined;
 
    public:
-   typedef ValueTraits                                                  value_traits;
-   typedef typename ValueTraits::value_type                             value_type;
-   typedef typename ValueTraits::pointer                                pointer;
-   typedef typename ValueTraits::const_pointer                          const_pointer;
-   typedef typename std::iterator_traits<pointer>::reference            reference;
-   typedef typename std::iterator_traits<const_pointer>::reference      const_reference;
-   typedef typename std::iterator_traits<pointer>::difference_type      difference_type;
-   typedef SizeType                                                     size_type;
-   typedef value_type                                                   key_type;
-   typedef Equal                                                        key_equal;
-   typedef Hash                                                         hasher;
+   typedef typename implementation_defined::value_type                  value_type;
+   typedef typename implementation_defined::value_traits                value_traits;
+   typedef typename implementation_defined::bucket_traits               bucket_traits;
+   typedef typename implementation_defined::pointer                     pointer;
+   typedef typename implementation_defined::const_pointer               const_pointer;
+   typedef typename implementation_defined::reference                   reference;
+   typedef typename implementation_defined::const_reference             const_reference;
+   typedef typename implementation_defined::difference_type             difference_type;
+   typedef typename implementation_defined::size_type                   size_type;
+   typedef typename implementation_defined::key_type                    key_type;
+   typedef typename implementation_defined::key_equal                   key_equal;
+   typedef typename implementation_defined::hasher                      hasher;
    typedef typename implementation_defined::bucket_type                 bucket_type;
-   typedef typename boost::pointer_to_other<pointer, bucket_type>::type bucket_ptr;
+   typedef typename implementation_defined::bucket_ptr                  bucket_ptr;
    typedef typename implementation_defined::iterator                    iterator;
    typedef typename implementation_defined::const_iterator              const_iterator;
    typedef typename implementation_defined::insert_commit_data          insert_commit_data;
    typedef typename implementation_defined::local_iterator              local_iterator;
    typedef typename implementation_defined::const_local_iterator        const_local_iterator;
+   typedef typename implementation_defined::node_traits                 node_traits;
+   typedef typename implementation_defined::node                        node;
+   typedef typename implementation_defined::node_ptr                    node_ptr;
+   typedef typename implementation_defined::const_node_ptr              const_node_ptr;
+   typedef typename implementation_defined::node_algorithms             node_algorithms;
 
    /// @cond
    private:
@@ -1021,11 +1117,11 @@
    //!
    //! <b>Notes</b>: buckets array must be disposed only after
    //!   *this is disposed. 
-   unordered_multiset  ( bucket_ptr buckets
-                  , size_type buckets_len
-                  , const Hash & hasher = Hash()
-                  , const Equal &equal = Equal()) 
-      :  table_(buckets, buckets_len, hasher, equal)
+   unordered_multiset_impl ( const bucket_traits &b_traits
+                           , const hasher & hash_func = hasher()
+                           , const key_equal &equal_func = key_equal()
+                           , const value_traits &v_traits = value_traits()) 
+      :  table_(b_traits, hash_func, equal_func, v_traits)
    {}
 
    //! <b>Requires</b>: buckets must not be being used by any other resource
@@ -1039,18 +1135,18 @@
    //! 
    //! <b>Throws</b>: If value_traits::node_traits::node
    //!   constructor throws (this does not happen with predefined Boost.Intrusive hooks)
-   //!   or the copy constructor or invocation of Hash or Equal throws. 
+   //!   or the copy constructor or invocation of hasher or key_equal throws. 
    //!
    //! <b>Notes</b>: buckets array must be disposed only after
    //!   *this is disposed.
    template<class Iterator>
-   unordered_multiset  ( bucket_ptr buckets
-                  , size_type buckets_len
-                  , Iterator b
-                  , Iterator e
-                  , const Hash & hasher = Hash()
-                  , const Equal &equal = Equal()) 
-      :  table_(buckets, buckets_len, hasher, equal)
+   unordered_multiset_impl ( Iterator b
+                           , Iterator e
+                           , const bucket_traits &b_traits
+                           , const hasher & hash_func = hasher()
+                           , const key_equal &equal_func = key_equal()
+                           , const value_traits &v_traits = value_traits()) 
+      :  table_(b_traits, hash_func, equal_func, v_traits)
    {  table_.insert_equal(b, e);  }
 
    //! <b>Effects</b>: Detaches all elements from this. The objects in the unordered_multiset 
@@ -1060,7 +1156,7 @@
    //!   it's a safe-mode or auto-unlink value. Otherwise constant.
    //! 
    //! <b>Throws</b>: Nothing.
-   ~unordered_multiset() 
+   ~unordered_multiset_impl() 
    {}
 
    //! <b>Effects</b>: Returns an iterator pointing to the beginning of the unordered_multiset.
@@ -1134,7 +1230,7 @@
 
    //! <b>Effects</b>: Returns true is the container is empty.
    //! 
-   //! <b>Complexity</b>: if ConstantTimeSize is false, average constant time
+   //! <b>Complexity</b>: if constant-time size option is disabled, average constant time
    //!   (worst case, with empty() == true): O(this->bucket_count()).
    //!   Otherwise constant.
    //! 
@@ -1145,7 +1241,7 @@
    //! <b>Effects</b>: Returns the number of elements stored in the unordered_multiset.
    //! 
    //! <b>Complexity</b>: Linear to elements contained in *this if
-   //!   ConstantTimeSize is false. Constant-time otherwise.
+   //!   constant-time size option is enabled. Constant-time otherwise.
    //! 
    //! <b>Throws</b>: Nothing.
    size_type size() const
@@ -1162,7 +1258,7 @@
    //!
    //! <b>Throws</b>: If the swap() call for the comparison or hash functors
    //!   found using ADL throw. Basic guarantee.
-   void swap(unordered_multiset& other)
+   void swap(unordered_multiset_impl& other)
    { table_.swap(other.table_); }
 
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
@@ -1179,7 +1275,7 @@
    //! 
    //! <b>Throws</b>: If cloner throws.
    template <class Cloner, class Disposer>
-   void clone_from(const unordered_multiset &src, Cloner cloner, Disposer disposer)
+   void clone_from(const unordered_multiset_impl &src, Cloner cloner, Disposer disposer)
    {  table_.clone_from(src.table_, cloner, disposer);  }
 
    //! <b>Requires</b>: value must be an lvalue
@@ -1202,8 +1298,8 @@
    //! 
    //! <b>Effects</b>: Equivalent to this->insert(t) for each element in [b, e).
    //! 
-   //! <b>Complexity</b>: Insert range is in general O(N * log(N)), where N is the 
-   //!   size of the range. However, it is linear in N if the range is already sorted 
+   //! <b>Complexity</b>: Insert range is in general O(N * log(N)), where N is the
+   //!   size of the range. However, it is linear in N if the range is already sorted
    //!   by value_comp().
    //! 
    //! <b>Throws</b>: If the internal hasher or the equality functor throws. Basic guarantee.
@@ -1251,9 +1347,9 @@
    size_type erase(const_reference value)
    {  return table_.erase(value);  }
 
-   //! <b>Requires</b>: "hasher" must be a hash function that induces 
+   //! <b>Requires</b>: "hash_func" must be a hash function that induces 
    //!   the same hash values as the stored hasher. The difference is that
-   //!   "hasher" hashes the given key instead of the value_type.
+   //!   "hash_func" hashes the given key instead of the value_type.
    //!
    //!   "key_value_equal" must be a equality function that induces 
    //!   the same equality as key_equal. The difference is that
@@ -1267,13 +1363,14 @@
    //! <b>Complexity</b>: Average case O(this->count(value)).
    //!   Worst case O(this->size()).
    //! 
-   //! <b>Throws</b>: If the hasher or the equal functors throws. Basic guarantee.
+   //! <b>Throws</b>: If the hash_func or the equal_func functors throws.
+   //!   Basic guarantee.
    //! 
    //! <b>Note</b>: Invalidates the iterators (but not the references)
    //!    to the erased elements. No destructors are called.
    template<class KeyType, class KeyHasher, class KeyValueEqual>
-   size_type erase(const KeyType& key, KeyHasher hasher, KeyValueEqual equal)
-   {  return table_.erase(key, hasher, equal);  }
+   size_type erase(const KeyType& key, KeyHasher hash_func, KeyValueEqual equal_func)
+   {  return table_.erase(key, hash_func, equal_func);  }
 
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
    //!
@@ -1327,7 +1424,7 @@
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
    //!
    //! <b>Effects</b>: Erases all the elements with the given key.
-   //!   according to the comparison functor "equal".
+   //!   according to the comparison functor "equal_func".
    //!   Disposer::operator()(pointer) is called for the removed elements.
    //!
    //! <b>Returns</b>: The number of erased elements.
@@ -1335,13 +1432,13 @@
    //! <b>Complexity</b>: Average case O(this->count(value)).
    //!   Worst case O(this->size()).
    //! 
-   //! <b>Throws</b>: If hasher or equal throw. Basic guarantee.
+   //! <b>Throws</b>: If hash_func or equal_func throw. Basic guarantee.
    //! 
    //! <b>Note</b>: Invalidates the iterators
    //!    to the erased elements.
    template<class KeyType, class KeyHasher, class KeyValueEqual, class Disposer>
-   size_type erase_and_dispose(const KeyType& key, KeyHasher hasher, KeyValueEqual equal, Disposer disposer)
-   {  return table_.erase_and_dispose(key, hasher, equal, disposer);  }
+   size_type erase_and_dispose(const KeyType& key, KeyHasher hash_func, KeyValueEqual equal_func, Disposer disposer)
+   {  return table_.erase_and_dispose(key, hash_func, equal_func, disposer);  }
 
    //! <b>Effects</b>: Erases all the elements of the container.
    //! 
@@ -1378,9 +1475,9 @@
    size_type count(const_reference value) const
    {  return table_.count(value);  }
 
-   //! <b>Requires</b>: "hasher" must be a hash function that induces 
+   //! <b>Requires</b>: "hash_func" must be a hash function that induces 
    //!   the same hash values as the stored hasher. The difference is that
-   //!   "hasher" hashes the given key instead of the value_type.
+   //!   "hash_func" hashes the given key instead of the value_type.
    //!
    //!   "key_value_equal" must be a equality function that induces 
    //!   the same equality as key_equal. The difference is that
@@ -1392,8 +1489,8 @@
    //! 
    //! <b>Throws</b>: If the internal hasher or the equality functor throws.
    template<class KeyType, class KeyHasher, class KeyValueEqual, class Disposer>
-   size_type count(const KeyType& key, KeyHasher hasher, KeyValueEqual equal) const
-   {  return table_.count(key, hasher, equal);  }
+   size_type count(const KeyType& key, KeyHasher hash_func, KeyValueEqual equal_func) const
+   {  return table_.count(key, hash_func, equal_func);  }
 
    //! <b>Effects</b>: Finds an iterator to the first element whose value is 
    //!   "value" or end() if that element does not exist.
@@ -1404,9 +1501,9 @@
    iterator find(const_reference value)
    {  return table_.find(value);  }
 
-   //! <b>Requires</b>: "hasher" must be a hash function that induces 
+   //! <b>Requires</b>: "hash_func" must be a hash function that induces 
    //!   the same hash values as the stored hasher. The difference is that
-   //!   "hasher" hashes the given key instead of the value_type.
+   //!   "hash_func" hashes the given key instead of the value_type.
    //!
    //!   "key_value_equal" must be a equality function that induces 
    //!   the same equality as key_equal. The difference is that
@@ -1424,8 +1521,8 @@
    //!   is expensive and the value_type can be compared with a cheaper
    //!   key type. Usually this key is part of the value_type.
    template<class KeyType, class KeyHasher, class KeyValueEqual>
-   iterator find(const KeyType& key, KeyHasher hasher, KeyValueEqual equal)
-   {  return table_.find(key, hasher, equal);  }
+   iterator find(const KeyType& key, KeyHasher hash_func, KeyValueEqual equal_func)
+   {  return table_.find(key, hash_func, equal_func);  }
 
    //! <b>Effects</b>: Finds a const_iterator to the first element whose key is 
    //!   "key" or end() if that element does not exist.
@@ -1436,9 +1533,9 @@
    const_iterator find(const_reference value) const
    {  return table_.find(value);  }
 
-   //! <b>Requires</b>: "hasher" must be a hash function that induces 
+   //! <b>Requires</b>: "hash_func" must be a hash function that induces 
    //!   the same hash values as the stored hasher. The difference is that
-   //!   "hasher" hashes the given key instead of the value_type.
+   //!   "hash_func" hashes the given key instead of the value_type.
    //!
    //!   "key_value_equal" must be a equality function that induces 
    //!   the same equality as key_equal. The difference is that
@@ -1456,8 +1553,8 @@
    //!   is expensive and the value_type can be compared with a cheaper
    //!   key type. Usually this key is part of the value_type.
    template<class KeyType, class KeyHasher, class KeyValueEqual>
-   const_iterator find(const KeyType& key, KeyHasher hasher, KeyValueEqual equal) const
-   {  return table_.find(key, equal);  }
+   const_iterator find(const KeyType& key, KeyHasher hash_func, KeyValueEqual equal_func) const
+   {  return table_.find(key, hash_func, equal_func);  }
 
    //! <b>Effects</b>: Returns a range containing all elements with values equivalent
    //!   to value. Returns std::make_pair(this->end(), this->end()) if no such 
@@ -1469,9 +1566,9 @@
    std::pair<iterator,iterator> equal_range(const_reference value)
    {  return table_.equal_range(value);  }
 
-   //! <b>Requires</b>: "hasher" must be a hash function that induces 
+   //! <b>Requires</b>: "hash_func" must be a hash function that induces 
    //!   the same hash values as the stored hasher. The difference is that
-   //!   "hasher" hashes the given key instead of the value_type.
+   //!   "hash_func" hashes the given key instead of the value_type.
    //!
    //!   "key_value_equal" must be a equality function that induces 
    //!   the same equality as key_equal. The difference is that
@@ -1481,7 +1578,8 @@
    //!   keys. Returns std::make_pair(this->end(), this->end()) if no such 
    //!   elements exist.
    //! 
-   //! <b>Complexity</b>: Average case O(this->count(key, hasher, equal)). Worst case O(this->size()).
+   //! <b>Complexity</b>: Average case O(this->count(key, hash_func, equal_func)).
+   //!   Worst case O(this->size()).
    //! 
    //! <b>Throws</b>: If the internal hasher or the equality functor throws.
    //!
@@ -1489,8 +1587,9 @@
    //!   is expensive and the value_type can be compared with a cheaper
    //!   key type. Usually this key is part of the value_type.
    template<class KeyType, class KeyHasher, class KeyValueEqual>
-   std::pair<iterator,iterator> equal_range(const KeyType& key, KeyHasher hasher, KeyValueEqual equal)
-   {  return table_.equal_range(key, hasher, equal);  }
+   std::pair<iterator,iterator> equal_range
+      (const KeyType& key, KeyHasher hash_func, KeyValueEqual equal_func)
+   {  return table_.equal_range(key, hash_func, equal_func);  }
 
    //! <b>Effects</b>: Returns a range containing all elements with values equivalent
    //!   to value. Returns std::make_pair(this->end(), this->end()) if no such 
@@ -1503,9 +1602,9 @@
       equal_range(const_reference value) const
    {  return table_.equal_range(value);  }
 
-   //! <b>Requires</b>: "hasher" must be a hash function that induces 
+   //! <b>Requires</b>: "hash_func" must be a hash function that induces 
    //!   the same hash values as the stored hasher. The difference is that
-   //!   "hasher" hashes the given key instead of the value_type.
+   //!   "hash_func" hashes the given key instead of the value_type.
    //!
    //!   "key_value_equal" must be a equality function that induces 
    //!   the same equality as key_equal. The difference is that
@@ -1515,7 +1614,8 @@
    //!   keys. Returns std::make_pair(this->end(), this->end()) if no such 
    //!   elements exist.
    //! 
-   //! <b>Complexity</b>: Average case O(this->count(key, hasher, equal)). Worst case O(this->size()).
+   //! <b>Complexity</b>: Average case O(this->count(key, hash_func, equal_func)).
+   //!   Worst case O(this->size()).
    //! 
    //! <b>Throws</b>: If the internal hasher or the equality functor throws.
    //!
@@ -1524,8 +1624,8 @@
    //!   key type. Usually this key is part of the value_type.
    template<class KeyType, class KeyHasher, class KeyValueEqual>
    std::pair<const_iterator, const_iterator>
-      equal_range(const KeyType& key, KeyHasher hasher, KeyValueEqual equal) const
-   {  return table_.equal_range(key, equal);  }
+      equal_range(const KeyType& key, KeyHasher hash_func, KeyValueEqual equal_func) const
+   {  return table_.equal_range(key, hash_func, equal_func);  }
 
    //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_multiset of
    //!   appropriate type. Otherwise the behavior is undefined.
@@ -1551,29 +1651,59 @@
    const_iterator iterator_to(const_reference value) const
    {  return table_.iterator_to(value);  }
 
-   //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_multiset of
+   //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of
    //!   appropriate type. Otherwise the behavior is undefined.
    //! 
-   //! <b>Effects</b>: Returns: a valid local_iterator belonging to the unordered_multiset
+   //! <b>Effects</b>: Returns: a valid local_iterator belonging to the unordered_set
    //!   that points to the value
    //! 
    //! <b>Complexity</b>: Constant.
    //! 
    //! <b>Throws</b>: Nothing.
-   static local_iterator local_iterator_to(reference value)
-   {  return table_type::local_iterator_to(value);  }
+   //! 
+   //! <b>Note</b>: This static function is available only if the <i>value traits</i>
+   //!   is stateless.
+   static local_iterator s_local_iterator_to(reference value)
+   {  return table_type::s_local_iterator_to(value);  }
 
-   //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_multiset of
+   //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of
    //!   appropriate type. Otherwise the behavior is undefined.
    //! 
    //! <b>Effects</b>: Returns: a valid const_local_iterator belonging to
-   //!   the unordered_multiset that points to the value
+   //!   the unordered_set that points to the value
    //! 
    //! <b>Complexity</b>: Constant.
    //! 
    //! <b>Throws</b>: Nothing.
-   static const_local_iterator local_iterator_to(const_reference value)
-   {  return table_type::local_iterator_to(value);  }
+   //! 
+   //! <b>Note</b>: This static function is available only if the <i>value traits</i>
+   //!   is stateless.
+   static const_local_iterator s_local_iterator_to(const_reference value)
+   {  return table_type::s_local_iterator_to(value);  }
+
+   //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of
+   //!   appropriate type. Otherwise the behavior is undefined.
+   //! 
+   //! <b>Effects</b>: Returns: a valid local_iterator belonging to the unordered_set
+   //!   that points to the value
+   //! 
+   //! <b>Complexity</b>: Constant.
+   //! 
+   //! <b>Throws</b>: Nothing.
+   local_iterator local_iterator_to(reference value)
+   {  return table_.local_iterator_to(value);  }
+
+   //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of
+   //!   appropriate type. Otherwise the behavior is undefined.
+   //! 
+   //! <b>Effects</b>: Returns: a valid const_local_iterator belonging to
+   //!   the unordered_set that points to the value
+   //! 
+   //! <b>Complexity</b>: Constant.
+   //! 
+   //! <b>Throws</b>: Nothing.
+   const_local_iterator local_iterator_to(const_reference value) const
+   {  return table_.local_iterator_to(value);  }
 
    //! <b>Effects</b>: Returns the number of buckets passed in the constructor
    //!   or the last rehash function.
@@ -1605,9 +1735,9 @@
    size_type bucket(const value_type& k) const
    {  return table_.bucket(k);   }
 
-   //! <b>Requires</b>: "hasher" must be a hash function that induces 
+   //! <b>Requires</b>: "hash_func" must be a hash function that induces 
    //!   the same hash values as the stored hasher. The difference is that
-   //!   "hasher" hashes the given key instead of the value_type.
+   //!   "hash_func" hashes the given key instead of the value_type.
    //!
    //! <b>Effects</b>: Returns the index of the bucket in which elements
    //!   with keys equivalent to k would be found, if any such element existed.
@@ -1618,8 +1748,8 @@
    //!
    //! <b>Note</b>: the return value is in the range [0, this->bucket_count()).
    template<class KeyType, class KeyHasher>
-   size_type bucket(const KeyType& k, const KeyHasher &hasher) const
-   {  return table_.bucket(k, hasher);   }
+   size_type bucket(const KeyType& k, const KeyHasher &hash_func) const
+   {  return table_.bucket(k, hash_func);   }
 
    //! <b>Effects</b>: Returns the bucket array pointer passed in the constructor
    //!   or the last rehash function.
@@ -1725,8 +1855,8 @@
    //! <b>Complexity</b>: Average case linear in this->size(), worst case quadratic.
    //! 
    //! <b>Throws</b>: If the hasher functor throws.
-   void rehash(bucket_ptr new_buckets, size_type new_size)
-   {  table_.rehash(new_buckets, new_size); }
+   void rehash(const bucket_traits &new_bucket_traits)
+   {  table_.rehash(new_bucket_traits); }
 
    //! <b>Effects</b>: Returns the nearest new bucket count optimized for
    //!   the container that is bigger than n. This suggestion can be used
@@ -1753,9 +1883,71 @@
    {  return table_type::suggested_lower_bucket_count(n);  }
 };
 
+//! Helper metafunction to define an \c unordered_multiset that yields to the same type when the
+//! same options (either explicitly or implicitly) are used.
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+template<class T, class ...Options>
+#else
+template<class T, class O1 = none, class O2 = none
+                , class O3 = none, class O4 = none
+                , class O5 = none, class O6 = none
+                , class O7 = none
+                >
+#endif
+struct make_unordered_multiset
+{
+   /// @cond
+   typedef unordered_multiset_impl
+      <  typename make_hashtable_opt
+            <T, O1, O2, O3, O4, O5, O6, O7>::type
+      > implementation_defined;
+   /// @endcond
+   typedef implementation_defined type;
+};
+
+#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+template<class T, class O1, class O2, class O3, class O4, class O5, class O6, class O7>
+class unordered_multiset
+   :  public make_unordered_multiset<T, O1, O2, O3, O4, O5, O6, O7>::type
+{
+   typedef typename make_unordered_multiset
+      <T, O1, O2, O3, O4, O5, O6, O7>::type   Base;
+   //Assert if passed value traits are compatible with the type
+   BOOST_STATIC_ASSERT((detail::is_same<typename Base::value_traits::value_type, T>::value));
+
+   public:
+   typedef typename Base::value_traits       value_traits;
+   typedef typename Base::bucket_traits      bucket_traits;
+   typedef typename Base::iterator           iterator;
+   typedef typename Base::const_iterator     const_iterator;
+   typedef typename Base::bucket_ptr         bucket_ptr;
+   typedef typename Base::size_type          size_type;
+   typedef typename Base::hasher             hasher;
+   typedef typename Base::key_equal          key_equal;
+
+   unordered_multiset( const bucket_traits &b_traits
+                     , const hasher & hash_func = hasher()
+                     , const key_equal &equal_func = key_equal()
+                     , const value_traits &v_traits = value_traits()) 
+      :  Base(b_traits, hash_func, equal_func, v_traits)
+   {}
+
+   template<class Iterator>
+   unordered_multiset( Iterator b
+                     , Iterator e
+                     , const bucket_traits &b_traits
+                     , const hasher & hash_func = hasher()
+                     , const key_equal &equal_func = key_equal()
+                     , const value_traits &v_traits = value_traits()) 
+      :  Base(b, e, b_traits, hash_func, equal_func, v_traits)
+   {}
+};
+
+#endif
+
 } //namespace intrusive 
 } //namespace boost 
 
 #include <boost/intrusive/detail/config_end.hpp>
 
-#endif //BOOST_INTRUSIVE_HASHSET_HPP
+#endif //BOOST_INTRUSIVE_UNORDERED_SET_HPP
Modified: trunk/boost/intrusive/unordered_set_hook.hpp
==============================================================================
--- trunk/boost/intrusive/unordered_set_hook.hpp	(original)
+++ trunk/boost/intrusive/unordered_set_hook.hpp	2007-09-26 11:26:35 EDT (Wed, 26 Sep 2007)
@@ -11,19 +11,50 @@
 //
 /////////////////////////////////////////////////////////////////////////////
 
-#ifndef BOOST_INTRUSIVE_HASHSET_HOOK_HPP
-#define BOOST_INTRUSIVE_HASHSET_HOOK_HPP
+#ifndef BOOST_INTRUSIVE_UNORDERED_SET_HOOK_HPP
+#define BOOST_INTRUSIVE_UNORDERED_SET_HOOK_HPP
 
 #include <boost/intrusive/detail/config_begin.hpp>
 #include <boost/intrusive/intrusive_fwd.hpp>
 #include <boost/intrusive/detail/utilities.hpp>
-#include <boost/intrusive/detail/pointer_to_other.hpp>
 #include <boost/intrusive/slist_hook.hpp>
-#include <boost/intrusive/linking_policy.hpp>
+#include <boost/intrusive/options.hpp>
+#include <boost/intrusive/detail/generic_hook.hpp>
 
 namespace boost {
 namespace intrusive {
 
+/// @cond
+template<class VoidPointer>
+struct get_uset_node_algo
+{
+   typedef circular_slist_algorithms<slist_node_traits<VoidPointer> > type;
+};
+/// @endcond
+
+//! Helper metafunction to define a \c unordered_set_base_hook that yields to the same
+//! type when the same options (either explicitly or implicitly) are used.
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+template<class ...Options>
+#else
+template<class O1 = none, class O2 = none, class O3 = none>
+#endif
+struct make_unordered_set_base_hook
+{
+   /// @cond
+   typedef typename pack_options
+      < hook_defaults, O1, O2, O3>::type packed_options;
+
+   typedef detail::generic_hook
+   < get_slist_node_algo<typename packed_options::void_pointer>
+   , typename packed_options::tag
+   , packed_options::link_mode
+   , detail::UsetBaseHook
+   > implementation_defined;
+   /// @endcond
+   typedef implementation_defined type;
+};
+
 //! Derive a class from unordered_set_base_hook in order to store objects in 
 //! in an unordered_set/unordered_multi_set. unordered_set_base_hook holds the data necessary to maintain 
 //! the unordered_set/unordered_multi_set and provides an appropriate value_traits class for unordered_set/unordered_multi_set.
@@ -37,122 +68,103 @@
 //!
 //! The third argument is the pointer type that will be used internally in the hook
 //! and the unordered_set/unordered_multi_set configured from this hook.
-template< class Tag              //= tag
-        , linking_policy Policy  //= safe_link
-        , class VoidPointer      //= void *
-        >
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+template<class ...Options>
+#else
+template<class O1, class O2, class O3>
+#endif
 class unordered_set_base_hook
+   :  public make_unordered_set_base_hook<O1, O2, O3>::type
 {
-   /// @cond
-   typedef slist_base_hook<Tag, Policy, VoidPointer> IsListHook;
-   IsListHook m_slisthook;
-   typedef IsListHook                                 implementation_defined;
-   /// @endcond
-
-   public:
-   enum { linking_policy = Policy };
-   typedef typename implementation_defined::node_traits  node_traits;
-   typedef typename node_traits::node                    node;
-   typedef typename boost::pointer_to_other
-      <VoidPointer, node>::type                          node_ptr;
-   typedef typename boost::pointer_to_other
-      <VoidPointer, const node>::type                    const_node_ptr;
-   typedef unordered_set_base_hook
-      <Tag, Policy, VoidPointer>                         this_type;
-   typedef typename boost::pointer_to_other
-      <VoidPointer, this_type>::type                     this_type_ptr;
-   typedef typename boost::pointer_to_other
-      <VoidPointer, const this_type>::type               const_this_type_ptr;
-
-   //! <b>Effects</b>: If Policy is auto_unlink or safe_mode_linnk
+   #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+   //! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
    //!   initializes the node to an unlinked state.
    //! 
-   //! <b>Throws</b>: Nothing.
-   unordered_set_base_hook()
-      :  m_slisthook()
-   {}
+   //! <b>Throws</b>: Nothing. 
+   unordered_set_base_hook();
 
-   //! <b>Effects</b>: If Policy is auto_unlink or safe_mode_linnk
+   //! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
    //!   initializes the node to an unlinked state. The argument is ignored.
    //! 
-   //! <b>Throws</b>: Nothing.
+   //! <b>Throws</b>: Nothing. 
    //! 
    //! <b>Rationale</b>: Providing a copy-constructor
-   //!   makes classes using unordered_set_base_hook STL-compliant without forcing the 
-   //!   user to do some additional work. "swap" can be used to emulate
+   //!   makes classes using the hook STL-compliant without forcing the 
+   //!   user to do some additional work. \c swap can be used to emulate
    //!   move-semantics.
-   unordered_set_base_hook(const unordered_set_base_hook &other)
-      :  m_slisthook(other.m_slisthook)
-   {}
+   unordered_set_base_hook(const unordered_set_base_hook& );
 
    //! <b>Effects</b>: Empty function. The argument is ignored.
    //! 
-   //! <b>Throws</b>: Nothing.
+   //! <b>Throws</b>: Nothing. 
    //! 
    //! <b>Rationale</b>: Providing an assignment operator 
-   //!   makes classes using unordered_set_base_hook STL-compliant without forcing the 
-   //!   user to do some additional work. "swap" can be used to emulate
+   //!   makes classes using the hook STL-compliant without forcing the 
+   //!   user to do some additional work. \c swap can be used to emulate
    //!   move-semantics.
-   unordered_set_base_hook& operator=(const unordered_set_base_hook &other)
-   {  return *this;  }
+   unordered_set_base_hook& operator=(const unordered_set_base_hook& );
 
-   //! <b>Effects</b>: If Policy is normal_link, the destructor does
-   //!   nothing (ie. no code is generated). If Policy is safe_link and the
-   //!   object is stored in an list an assertion is raised. If Policy is
-   //!   auto_unlink and "is_linked()" is true, the node is unlinked.
-   //! 
-   //! <b>Throws</b>: Nothing.
-   ~unordered_set_base_hook() 
-   {} //m_slisthook's destructor does the job
+   //! <b>Effects</b>: If link_mode is \c normal_link, the destructor does
+   //!   nothing (ie. no code is generated). If link_mode is \c safe_link and the
+   //!   object is stored in an unordered_set an assertion is raised. If link_mode is
+   //!   \c auto_unlink and \c is_linked() is true, the node is unlinked.
+   //! 
+   //! <b>Throws</b>: Nothing. 
+   ~unordered_set_base_hook();
+
+   //! <b>Effects</b>: Swapping two nodes swaps the position of the elements 
+   //!   related to those nodes in one or two containers. That is, if the node 
+   //!   this is part of the element e1, the node x is part of the element e2 
+   //!   and both elements are included in the containers s1 and s2, then after 
+   //!   the swap-operation e1 is in s2 at the position of e2 and e2 is in s1 
+   //!   at the position of e1. If one element is not in a container, then 
+   //!   after the swap-operation the other element is not in a container. 
+   //!   Iterators to e1 and e2 related to those nodes are invalidated. 
+   //!
+   //! <b>Complexity</b>: Constant 
+   //!
+   //! <b>Throws</b>: Nothing. 
+   void swap_nodes(unordered_set_base_hook &other);
 
-   //! <b>Precondition</b>: Policy must be safe_link or auto_unlink.
+   //! <b>Precondition</b>: link_mode must be \c safe_link or \c auto_unlink.
    //!
    //! <b>Returns</b>: true, if the node belongs to a container, false
-   //!   otherwise. This function can be used to test whether unordered_set/unordered_multiset::iterator_to 
+   //!   otherwise. This function can be used to test whether \c unordered_set::iterator_to 
    //!   will return a valid iterator. 
    //!
-   //! <b>Complexity</b>: Constant
-   bool is_linked() const 
-   {  return m_slisthook.is_linked(); }
-
-   //! The value_traits class is used as the first template argument for unordered_set/unordered_multiset. 
-   //! The template argument T defines the class type stored in unordered_set/unordered_multiset. Objects 
-   //! of type T and of types derived from T can be stored. T doesn't need to be 
-   //! copy-constructible or assignable.
-   template<class T>
-   struct value_traits
-      : detail::derivation_hook_value_traits<T, this_type, Tag>
-   {};
-
-   //! <b>Effects</b>: Converts a pointer to a node into
-   //!   a pointer to the hook that holds that node.
-   //! 
-   //! <b>Throws</b>: Nothing.
-   static this_type_ptr to_hook_ptr(node_ptr p)
-   {
-      return this_type_ptr((this_type*)detail::get_pointer(IsListHook::to_hook_ptr(p)));
-   }
-
-   //! <b>Effects</b>: Converts a const pointer to a node stored in a container into
-   //!   a const pointer to the hook that holds that node.
-   //! 
-   //! <b>Throws</b>: Nothing.
-   static const_this_type_ptr to_hook_ptr(const_node_ptr p)
-   {
-      return const_this_type_ptr((const this_type*)detail::get_pointer(IsListHook::to_hook_ptr(p)));
-   }
-
-   //! <b>Effects</b>: Returns a pointer to the node that this hook holds.
-   //! 
-   //! <b>Throws</b>: Nothing.
-   node_ptr to_node_ptr()
-   {  return m_slisthook.to_node_ptr();  }
-
-   //! <b>Effects</b>: Returns a const pointer to the node that this hook holds.
-   //! 
-   //! <b>Throws</b>: Nothing.
-   const_node_ptr to_node_ptr() const
-   {  return m_slisthook.to_node_ptr();  }
+   //! <b>Complexity</b>: Constant 
+   bool is_linked() const;
+
+   //! <b>Effects</b>: Removes the node if it's inserted in a container.
+   //!   This function is only allowed if link_mode is \c auto_unlink.
+   //! 
+   //! <b>Throws</b>: Nothing. 
+   void unlink();
+   #endif
+};
+
+
+//! Helper metafunction to define a \c unordered_set_member_hook that yields to the same
+//! type when the same options (either explicitly or implicitly) are used.
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+template<class ...Options>
+#else
+template<class O1 = none, class O2 = none, class O3 = none>
+#endif
+struct make_unordered_set_member_hook
+{
+   /// @cond
+   typedef typename pack_options
+      < hook_defaults, O1, O2, O3>::type packed_options;
+
+   typedef detail::generic_hook
+   < get_uset_node_algo<typename packed_options::void_pointer>
+   , member_tag
+   , packed_options::link_mode
+   , detail::NoBaseHook
+   > implementation_defined;
+   /// @endcond
+   typedef implementation_defined type;
 };
 
 //! Put a public data member unordered_set_member_hook in order to store objects of this class in
@@ -163,123 +175,79 @@
 //!
 //! The second argument is the pointer type that will be used internally in the hook
 //! and the unordered_set/unordered_multi_set configured from this hook.
-template< linking_policy Policy  //= safe_link
-        , class VoidPointer      //= void *
-        >
+#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+template<class ...Options>
+#else
+template<class O1, class O2, class O3>
+#endif
 class unordered_set_member_hook
+   :  public make_unordered_set_member_hook<O1, O2, O3>::type
 {
-   /// @cond
-   typedef slist_member_hook<Policy, VoidPointer>  IsListHook;
-   IsListHook m_slisthook;
-   typedef IsListHook                                 implementation_defined;
-   /// @endcond
-
-   public:
-   enum { linking_policy = Policy };
-   typedef typename implementation_defined::node_traits  node_traits;
-   typedef typename node_traits::node                    node;
-   typedef typename boost::pointer_to_other
-      <VoidPointer, node>::type                          node_ptr;
-   typedef typename boost::pointer_to_other
-      <VoidPointer, const node>::type                    const_node_ptr;
-   typedef unordered_set_member_hook
-      <Policy, VoidPointer>                              this_type;
-   typedef typename boost::pointer_to_other
-      <VoidPointer, this_type>::type                     this_type_ptr;
-   typedef typename boost::pointer_to_other
-      <VoidPointer, const this_type>::type               const_this_type_ptr;
-
-   public:
-   //! <b>Effects</b>: If Policy is auto_unlink or safe_mode_linnk
+   #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+   //! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
    //!   initializes the node to an unlinked state.
    //! 
    //! <b>Throws</b>: Nothing. 
-   unordered_set_member_hook()
-      :  m_slisthook()
-   {}
+   unordered_set_member_hook();
 
-   //! <b>Effects</b>: If Policy is auto_unlink or safe_mode_linnk
+   //! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
    //!   initializes the node to an unlinked state. The argument is ignored.
    //! 
    //! <b>Throws</b>: Nothing. 
    //! 
    //! <b>Rationale</b>: Providing a copy-constructor
-   //!   makes classes using unordered_set_member_hook STL-compliant without forcing the 
-   //!   user to do some additional work.
-   unordered_set_member_hook(const unordered_set_member_hook &other)
-      :  m_slisthook(other.m_slisthook)
-   {}
+   //!   makes classes using the hook STL-compliant without forcing the 
+   //!   user to do some additional work. \c swap can be used to emulate
+   //!   move-semantics.
+   unordered_set_member_hook(const unordered_set_member_hook& );
 
    //! <b>Effects</b>: Empty function. The argument is ignored.
    //! 
    //! <b>Throws</b>: Nothing. 
    //! 
    //! <b>Rationale</b>: Providing an assignment operator 
-   //!   makes classes using unordered_set_member_hook STL-compliant without forcing the 
-   //!   user to do some additional work.
-   unordered_set_member_hook& operator=(const unordered_set_member_hook &other) 
-   {  return *this;  }
+   //!   makes classes using the hook STL-compliant without forcing the 
+   //!   user to do some additional work. \c swap can be used to emulate
+   //!   move-semantics.
+   unordered_set_member_hook& operator=(const unordered_set_member_hook& );
 
-   //! <b>Effects</b>: If Policy is normal_link, the destructor does
-   //!   nothing (ie. no code is generated). If Policy is safe_link and the
-   //!   object is stored in an list an assertion is raised. If Policy is
-   //!   auto_unlink and "is_linked()" is true, the node is unlinked.
-   //! 
+   //! <b>Effects</b>: If link_mode is \c normal_link, the destructor does
+   //!   nothing (ie. no code is generated). If link_mode is \c safe_link and the
+   //!   object is stored in an unordered_set an assertion is raised. If link_mode is
+   //!   \c auto_unlink and \c is_linked() is true, the node is unlinked.
+   //! 
+   //! <b>Throws</b>: Nothing. 
+   ~unordered_set_member_hook();
+
+   //! <b>Effects</b>: Swapping two nodes swaps the position of the elements 
+   //!   related to those nodes in one or two containers. That is, if the node 
+   //!   this is part of the element e1, the node x is part of the element e2 
+   //!   and both elements are included in the containers s1 and s2, then after 
+   //!   the swap-operation e1 is in s2 at the position of e2 and e2 is in s1 
+   //!   at the position of e1. If one element is not in a container, then 
+   //!   after the swap-operation the other element is not in a container. 
+   //!   Iterators to e1 and e2 related to those nodes are invalidated. 
+   //!
+   //! <b>Complexity</b>: Constant 
+   //!
    //! <b>Throws</b>: Nothing. 
-   ~unordered_set_member_hook() 
-   {} //m_slisthook's destructor does the job
+   void swap_nodes(unordered_set_member_hook &other);
 
-   //! <b>Precondition</b>: Policy must be safe_link or auto_unlink.
+   //! <b>Precondition</b>: link_mode must be \c safe_link or \c auto_unlink.
+   //!
+   //! <b>Returns</b>: true, if the node belongs to a container, false
+   //!   otherwise. This function can be used to test whether \c unordered_set::iterator_to 
+   //!   will return a valid iterator. 
    //!
    //! <b>Complexity</b>: Constant 
-   bool is_linked() const 
-   {  return m_slisthook.is_linked();  }
-
-   //! The value_traits class is used as the first template argument for unordered_set/unordered_multiset. 
-   //! The template argument is a pointer to member pointing to the node in 
-   //! the class. Objects of type T and of types derived from T can be stored. 
-   //! T doesn't need to be copy-constructible or assignable.
-   template<class T, this_type T::* M>
-   struct value_traits
-      : detail::member_hook_value_traits<T, this_type, M>
-   {};
+   bool is_linked() const;
 
    //! <b>Effects</b>: Removes the node if it's inserted in a container.
-   //!   This function is only allowed if Policy is auto_unlink.
-   //! 
-   //! <b>Throws</b>: Nothing. 
-   void unlink()
-   {  m_slisthook.unlink();   }
-
-   //! <b>Effects</b>: Converts a pointer to a node into
-   //!   a pointer to the hook that holds that node.
-   //! 
-   //! <b>Throws</b>: Nothing. 
-   static this_type_ptr to_hook_ptr(node_ptr p)
-   {
-      return this_type_ptr((this_type*)detail::get_pointer(IsListHook::to_hook_ptr(p)));
-   }
-
-   //! <b>Effects</b>: Converts a const pointer to a node stored in a container into
-   //!   a const pointer to the hook that holds that node.
-   //! 
-   //! <b>Throws</b>: Nothing. 
-   static const_this_type_ptr to_hook_ptr(const_node_ptr p)
-   {
-      return const_this_type_ptr((const this_type*)detail::get_pointer(IsListHook::to_hook_ptr(p)));
-   }
-
-   //! <b>Effects</b>: Returns a pointer to the node that this hook holds.
-   //! 
-   //! <b>Throws</b>: Nothing. 
-   node_ptr to_node_ptr()
-   {  return m_slisthook.to_node_ptr();  }
-
-   //! <b>Effects</b>: Returns a const pointer to the node that this hook holds.
+   //!   This function is only allowed if link_mode is \c auto_unlink.
    //! 
    //! <b>Throws</b>: Nothing. 
-   const_node_ptr to_node_ptr() const
-   {  return m_slisthook.to_node_ptr();  }
+   void unlink();
+   #endif
 };
 
 } //namespace intrusive 
@@ -287,4 +255,4 @@
 
 #include <boost/intrusive/detail/config_end.hpp>
 
-#endif //BOOST_INTRUSIVE_HASHSET_HOOK_HPP
+#endif //BOOST_INTRUSIVE_UNORDERED_SET_HOOK_HPP