Boost logo

Boost-Commit :

From: igaztanaga_at_[hidden]
Date: 2008-06-21 05:04:24


Author: igaztanaga
Date: 2008-06-21 05:04:21 EDT (Sat, 21 Jun 2008)
New Revision: 46571
URL: http://svn.boost.org/trac/boost/changeset/46571

Log:
gcc 4.3 fixes for normal and -std=c++0x modes
Added:
   trunk/boost/intrusive/any_hook.hpp (contents, props changed)
   trunk/boost/intrusive/detail/any_node_and_algorithms.hpp (contents, props changed)
Text files modified:
   trunk/boost/intrusive/avltree_algorithms.hpp | 3
   trunk/boost/intrusive/circular_list_algorithms.hpp | 1
   trunk/boost/intrusive/circular_slist_algorithms.hpp | 1
   trunk/boost/intrusive/detail/common_slist_algorithms.hpp | 3
   trunk/boost/intrusive/detail/generic_hook.hpp | 53 +++++-----
   trunk/boost/intrusive/detail/hashtable_node.hpp | 12 +-
   trunk/boost/intrusive/detail/list_node.hpp | 1
   trunk/boost/intrusive/detail/parent_from_member.hpp | 21 ++--
   trunk/boost/intrusive/detail/slist_node.hpp | 1
   trunk/boost/intrusive/detail/tree_algorithms.hpp | 7 -
   trunk/boost/intrusive/detail/utilities.hpp | 19 +++
   trunk/boost/intrusive/hashtable.hpp | 199 +++++++++++++++++++++++++--------------
   trunk/boost/intrusive/intrusive_fwd.hpp | 17 +++
   trunk/boost/intrusive/linear_slist_algorithms.hpp | 1
   trunk/boost/intrusive/options.hpp | 94 ++++++++++++++----
   trunk/boost/intrusive/rbtree_algorithms.hpp | 2
   trunk/boost/intrusive/sgtree_algorithms.hpp | 2
   trunk/boost/intrusive/splaytree_algorithms.hpp | 2
   trunk/boost/intrusive/unordered_set.hpp | 18 ++-
   trunk/boost/intrusive/unordered_set_hook.hpp | 29 +----
   20 files changed, 311 insertions(+), 175 deletions(-)

Added: trunk/boost/intrusive/any_hook.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/intrusive/any_hook.hpp 2008-06-21 05:04:21 EDT (Sat, 21 Jun 2008)
@@ -0,0 +1,320 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2006-2008
+//
+// 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_ANY_HOOK_HPP
+#define BOOST_INTRUSIVE_ANY_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/any_node_and_algorithms.hpp>
+#include <boost/intrusive/options.hpp>
+#include <boost/intrusive/detail/generic_hook.hpp>
+#include <boost/intrusive/detail/pointer_to_other.hpp>
+
+namespace boost {
+namespace intrusive {
+
+/// @cond
+template<class VoidPointer>
+struct get_any_node_algo
+{
+ typedef any_algorithms<VoidPointer> type;
+};
+/// @endcond
+
+//! Helper metafunction to define a \c \c any_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_any_base_hook
+{
+ /// @cond
+ typedef typename pack_options
+ < hook_defaults, O1, O2, O3>::type packed_options;
+
+ typedef detail::generic_hook
+ < get_any_node_algo<typename packed_options::void_pointer>
+ , typename packed_options::tag
+ , packed_options::link_mode
+ , detail::AnyBaseHook
+ > implementation_defined;
+ /// @endcond
+ typedef implementation_defined type;
+};
+
+//! Derive a class from this hook in order to store objects of that class
+//! in an intrusive container.
+//!
+//! 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 \c any_base_hook, then each \c any_base_hook needs its
+//! unique tag.
+//!
+//! \c link_mode<> will specify the linking mode of the hook (\c normal_link, \c safe_link).
+//!
+//! \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 any_base_hook
+ : public make_any_base_hook<O1, O2, O3>::type
+{
+ #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+ public:
+ //! <b>Effects</b>: If link_mode is or \c safe_link
+ //! initializes the node to an unlinked state.
+ //!
+ //! <b>Throws</b>: Nothing.
+ any_base_hook();
+
+ //! <b>Effects</b>: If link_mode is 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 the hook STL-compliant without forcing the
+ //! user to do some additional work. \c swap can be used to emulate
+ //! move-semantics.
+ any_base_hook(const any_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 the hook STL-compliant without forcing the
+ //! user to do some additional work. \c swap can be used to emulate
+ //! move-semantics.
+ any_base_hook& operator=(const any_base_hook& );
+
+ //! <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 a container an assertion is raised.
+ //!
+ //! <b>Throws</b>: Nothing.
+ ~any_base_hook();
+
+ //! <b>Precondition</b>: link_mode must be \c safe_link.
+ //!
+ //! <b>Returns</b>: true, if the node belongs to a container, false
+ //! otherwise. This function can be used to test whether \c container::iterator_to
+ //! will return a valid iterator.
+ //!
+ //! <b>Complexity</b>: Constant
+ bool is_linked() const;
+ #endif
+};
+
+//! Helper metafunction to define a \c \c any_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_any_member_hook
+{
+ /// @cond
+ typedef typename pack_options
+ < hook_defaults, O1, O2, O3>::type packed_options;
+
+ typedef detail::generic_hook
+ < get_any_node_algo<typename packed_options::void_pointer>
+ , member_tag
+ , packed_options::link_mode
+ , detail::NoBaseHook
+ > implementation_defined;
+ /// @endcond
+ typedef implementation_defined type;
+};
+
+//! Store this hook in a class to be inserted
+//! in an intrusive container.
+//!
+//! 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 or \c safe_link).
+//!
+//! \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 any_member_hook
+ : public make_any_member_hook<O1, O2, O3>::type
+{
+ #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+ public:
+ //! <b>Effects</b>: If link_mode is or \c safe_link
+ //! initializes the node to an unlinked state.
+ //!
+ //! <b>Throws</b>: Nothing.
+ any_member_hook();
+
+ //! <b>Effects</b>: If link_mode is 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 the hook STL-compliant without forcing the
+ //! user to do some additional work. \c swap can be used to emulate
+ //! move-semantics.
+ any_member_hook(const any_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 the hook STL-compliant without forcing the
+ //! user to do some additional work. \c swap can be used to emulate
+ //! move-semantics.
+ any_member_hook& operator=(const any_member_hook& );
+
+ //! <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 a container an assertion is raised.
+ //!
+ //! <b>Throws</b>: Nothing.
+ ~any_member_hook();
+
+ //! <b>Precondition</b>: link_mode must be \c safe_link.
+ //!
+ //! <b>Returns</b>: true, if the node belongs to a container, false
+ //! otherwise. This function can be used to test whether \c container::iterator_to
+ //! will return a valid iterator.
+ //!
+ //! <b>Complexity</b>: Constant
+ bool is_linked() const;
+ #endif
+};
+
+/// @cond
+
+namespace detail{
+
+template<class ValueTraits>
+struct any_to_get_base_pointer_type
+{
+ typedef typename pointer_to_other
+ <typename ValueTraits::boost_intrusive_tags::node_traits::node_ptr, void>::type type;
+};
+
+template<class ValueTraits>
+struct any_to_get_member_pointer_type
+{
+ typedef typename pointer_to_other
+ <typename ValueTraits::node_ptr, void>::type type;
+};
+
+//!This option setter specifies that the container
+//!must use the specified base hook
+template<class BaseHook, template <class> class NodeTraits>
+struct any_to_some_hook
+{
+ typedef typename BaseHook::template pack<none>::value_traits old_value_traits;
+ template<class Base>
+ struct pack : public Base
+ {
+ struct value_traits : public old_value_traits
+ {
+ static const bool is_any_hook = true;
+ typedef typename detail::eval_if_c
+ < detail::internal_base_hook_bool_is_true<old_value_traits>::value
+ , any_to_get_base_pointer_type<old_value_traits>
+ , any_to_get_member_pointer_type<old_value_traits>
+ >::type void_pointer;
+ typedef NodeTraits<void_pointer> node_traits;
+ };
+ };
+};
+
+} //namespace detail{
+
+/// @endcond
+
+//!This option setter specifies that
+//!any hook should behave as an slist hook
+template<class BaseHook>
+struct any_to_slist_hook
+/// @cond
+ : public detail::any_to_some_hook<BaseHook, any_slist_node_traits>
+/// @endcond
+{};
+
+//!This option setter specifies that
+//!any hook should behave as an list hook
+template<class BaseHook>
+struct any_to_list_hook
+/// @cond
+ : public detail::any_to_some_hook<BaseHook, any_list_node_traits>
+/// @endcond
+{};
+
+//!This option setter specifies that
+//!any hook should behave as a set hook
+template<class BaseHook>
+struct any_to_set_hook
+/// @cond
+ : public detail::any_to_some_hook<BaseHook, any_rbtree_node_traits>
+/// @endcond
+{};
+
+//!This option setter specifies that
+//!any hook should behave as a set hook
+template<class BaseHook>
+struct any_to_avl_set_hook
+/// @cond
+ : public detail::any_to_some_hook<BaseHook, any_avltree_node_traits>
+/// @endcond
+{};
+
+//!This option setter specifies that any
+//!hook should behave as a set hook
+template<class BaseHook>
+struct any_to_bs_set_hook
+/// @cond
+ : public detail::any_to_some_hook<BaseHook, any_tree_node_traits>
+/// @endcond
+{};
+
+//!This option setter specifies that any hook
+//!should behave as an unordered set hook
+template<class BaseHook>
+struct any_to_unordered_set_hook
+/// @cond
+ : public detail::any_to_some_hook<BaseHook, any_unordered_node_traits>
+/// @endcond
+{};
+
+
+} //namespace intrusive
+} //namespace boost
+
+#include <boost/intrusive/detail/config_end.hpp>
+
+#endif //BOOST_INTRUSIVE_ANY_HOOK_HPP

Modified: trunk/boost/intrusive/avltree_algorithms.hpp
==============================================================================
--- trunk/boost/intrusive/avltree_algorithms.hpp (original)
+++ trunk/boost/intrusive/avltree_algorithms.hpp 2008-06-21 05:04:21 EDT (Sat, 21 Jun 2008)
@@ -68,6 +68,7 @@
 class avltree_algorithms
 {
    public:
+ typedef typename NodeTraits::node node;
    typedef NodeTraits node_traits;
    typedef typename NodeTraits::node_ptr node_ptr;
    typedef typename NodeTraits::const_node_ptr const_node_ptr;
@@ -75,8 +76,6 @@
 
    /// @cond
    private:
-
- typedef typename NodeTraits::node node;
    typedef detail::tree_algorithms<NodeTraits> tree_algorithms;
 
    template<class F>

Modified: trunk/boost/intrusive/circular_list_algorithms.hpp
==============================================================================
--- trunk/boost/intrusive/circular_list_algorithms.hpp (original)
+++ trunk/boost/intrusive/circular_list_algorithms.hpp 2008-06-21 05:04:21 EDT (Sat, 21 Jun 2008)
@@ -50,6 +50,7 @@
 class circular_list_algorithms
 {
    public:
+ typedef typename NodeTraits::node node;
    typedef typename NodeTraits::node_ptr node_ptr;
    typedef typename NodeTraits::const_node_ptr const_node_ptr;
    typedef NodeTraits node_traits;

Modified: trunk/boost/intrusive/circular_slist_algorithms.hpp
==============================================================================
--- trunk/boost/intrusive/circular_slist_algorithms.hpp (original)
+++ trunk/boost/intrusive/circular_slist_algorithms.hpp 2008-06-21 05:04:21 EDT (Sat, 21 Jun 2008)
@@ -54,6 +54,7 @@
    typedef detail::common_slist_algorithms<NodeTraits> base_t;
    /// @endcond
    public:
+ typedef typename NodeTraits::node node;
    typedef typename NodeTraits::node_ptr node_ptr;
    typedef typename NodeTraits::const_node_ptr const_node_ptr;
    typedef NodeTraits node_traits;

Added: trunk/boost/intrusive/detail/any_node_and_algorithms.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/intrusive/detail/any_node_and_algorithms.hpp 2008-06-21 05:04:21 EDT (Sat, 21 Jun 2008)
@@ -0,0 +1,292 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2006-2008
+//
+// 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_ANY_NODE_HPP
+#define BOOST_INTRUSIVE_ANY_NODE_HPP
+
+#include <boost/intrusive/detail/config_begin.hpp>
+#include <iterator>
+#include <boost/intrusive/detail/assert.hpp>
+#include <boost/intrusive/detail/pointer_to_other.hpp>
+#include <cstddef>
+
+namespace boost {
+namespace intrusive {
+
+template<class VoidPointer>
+struct any_node
+{
+ typedef typename boost::pointer_to_other
+ <VoidPointer, any_node>::type node_ptr;
+ node_ptr node_ptr_1;
+ node_ptr node_ptr_2;
+ node_ptr node_ptr_3;
+ std::size_t size_t_1;
+};
+
+template<class VoidPointer>
+struct any_list_node_traits
+{
+ typedef any_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;
+
+ static node_ptr get_next(const_node_ptr n)
+ { return n->node_ptr_1; }
+
+ static void set_next(node_ptr n, node_ptr next)
+ { n->node_ptr_1 = next; }
+
+ static node_ptr get_previous(const_node_ptr n)
+ { return n->node_ptr_2; }
+
+ static void set_previous(node_ptr n, node_ptr prev)
+ { n->node_ptr_2 = prev; }
+};
+
+
+template<class VoidPointer>
+struct any_slist_node_traits
+{
+ typedef any_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;
+
+ static node_ptr get_next(const_node_ptr n)
+ { return n->node_ptr_1; }
+
+ static void set_next(node_ptr n, node_ptr next)
+ { n->node_ptr_1 = next; }
+};
+
+
+template<class VoidPointer>
+struct any_unordered_node_traits
+ : public any_slist_node_traits<VoidPointer>
+{
+ typedef any_slist_node_traits<VoidPointer> reduced_slist_node_traits;
+ typedef typename reduced_slist_node_traits::node node;
+ typedef typename reduced_slist_node_traits::node_ptr node_ptr;
+ typedef typename reduced_slist_node_traits::const_node_ptr const_node_ptr;
+
+ static const bool store_hash = true;
+ static const bool optimize_multikey = true;
+
+ static node_ptr get_next(const_node_ptr n)
+ { return node_ptr(&static_cast<node &>(*n->node_ptr_1)); }
+
+ static void set_next(node_ptr n, node_ptr next)
+ { n->node_ptr_1 = next; }
+
+ static node_ptr get_prev_in_group(const_node_ptr n)
+ { return n->node_ptr_2; }
+
+ static void set_prev_in_group(node_ptr n, node_ptr prev)
+ { n->node_ptr_2 = prev; }
+
+ static std::size_t get_hash(const_node_ptr n)
+ { return n->size_t_1; }
+
+ static void set_hash(node_ptr n, std::size_t h)
+ { n->size_t_1 = h; }
+};
+
+
+template<class VoidPointer>
+struct any_rbtree_node_traits
+{
+ typedef any_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;
+
+ typedef std::size_t color;
+
+ static node_ptr get_parent(const_node_ptr n)
+ { return n->node_ptr_1; }
+
+ static void set_parent(node_ptr n, node_ptr p)
+ { n->node_ptr_1 = p; }
+
+ static node_ptr get_left(const_node_ptr n)
+ { return n->node_ptr_2; }
+
+ static void set_left(node_ptr n, node_ptr l)
+ { n->node_ptr_2 = l; }
+
+ static node_ptr get_right(const_node_ptr n)
+ { return n->node_ptr_3; }
+
+ static void set_right(node_ptr n, node_ptr r)
+ { n->node_ptr_3 = r; }
+
+ static color get_color(const_node_ptr n)
+ { return n->size_t_1; }
+
+ static void set_color(node_ptr n, color c)
+ { n->size_t_1 = c; }
+
+ static color black()
+ { return 0u; }
+
+ static color red()
+ { return 1u; }
+};
+
+
+template<class VoidPointer>
+struct any_avltree_node_traits
+{
+ typedef any_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;
+ typedef std::size_t balance;
+
+ static node_ptr get_parent(const_node_ptr n)
+ { return n->node_ptr_1; }
+
+ static void set_parent(node_ptr n, node_ptr p)
+ { n->node_ptr_1 = p; }
+
+ static node_ptr get_left(const_node_ptr n)
+ { return n->node_ptr_2; }
+
+ static void set_left(node_ptr n, node_ptr l)
+ { n->node_ptr_2 = l; }
+
+ static node_ptr get_right(const_node_ptr n)
+ { return n->node_ptr_3; }
+
+ static void set_right(node_ptr n, node_ptr r)
+ { n->node_ptr_3 = r; }
+
+ static balance get_balance(const_node_ptr n)
+ { return n->size_t_1; }
+
+ static void set_balance(node_ptr n, balance b)
+ { n->size_t_1 = b; }
+
+ static balance negative()
+ { return 0u; }
+
+ static balance zero()
+ { return 1u; }
+
+ static balance positive()
+ { return 2u; }
+};
+
+
+template<class VoidPointer>
+struct any_tree_node_traits
+{
+ typedef any_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;
+
+ static node_ptr get_parent(const_node_ptr n)
+ { return n->node_ptr_1; }
+
+ static void set_parent(node_ptr n, node_ptr p)
+ { n->node_ptr_1 = p; }
+
+ static node_ptr get_left(const_node_ptr n)
+ { return n->node_ptr_2; }
+
+ static void set_left(node_ptr n, node_ptr l)
+ { n->node_ptr_2 = l; }
+
+ static node_ptr get_right(const_node_ptr n)
+ { return n->node_ptr_3; }
+
+ static void set_right(node_ptr n, node_ptr r)
+ { n->node_ptr_3 = r; }
+};
+
+template<class VoidPointer>
+class any_node_traits
+{
+ public:
+ typedef any_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;
+};
+
+template<class VoidPointer>
+class any_algorithms
+{
+ public:
+ typedef any_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;
+ typedef any_node_traits<VoidPointer> node_traits;
+
+ //! <b>Requires</b>: node must not be part of any tree.
+ //!
+ //! <b>Effects</b>: After the function unique(node) == true.
+ //!
+ //! <b>Complexity</b>: Constant.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Nodes</b>: If node is inserted in a tree, this function corrupts the tree.
+ static void init(node_ptr node)
+ { node->node_ptr_1 = 0; };
+
+ //! <b>Effects</b>: Returns true if node is in the same state as if called init(node)
+ //!
+ //! <b>Complexity</b>: Constant.
+ //!
+ //! <b>Throws</b>: Nothing.
+ static bool inited(const_node_ptr node)
+ { return !node->node_ptr_1; };
+
+ static bool unique(const_node_ptr node)
+ { return 0 == node->node_ptr_1; }
+
+ static void unlink(node_ptr)
+ {
+ //Auto-unlink hooks and unlink() call for safe hooks are not
+ //available for any hooks!!!
+ any_algorithms<VoidPointer>::unlink_not_available_for_any_hooks();
+ }
+
+ static void swap_nodes(node_ptr l, node_ptr r)
+ {
+ //Any nodes have no swap_nodes capability because they don't know
+ //what algorithm they must use from unlink them from the container
+ any_algorithms<VoidPointer>::swap_nodes_not_available_for_any_hooks();
+ }
+};
+
+} //namespace intrusive
+} //namespace boost
+
+#include <boost/intrusive/detail/config_end.hpp>
+
+#endif //BOOST_INTRUSIVE_ANY_NODE_HPP

Modified: trunk/boost/intrusive/detail/common_slist_algorithms.hpp
==============================================================================
--- trunk/boost/intrusive/detail/common_slist_algorithms.hpp (original)
+++ trunk/boost/intrusive/detail/common_slist_algorithms.hpp 2008-06-21 05:04:21 EDT (Sat, 21 Jun 2008)
@@ -26,6 +26,7 @@
 class common_slist_algorithms
 {
    public:
+ typedef typename NodeTraits::node node;
    typedef typename NodeTraits::node_ptr node_ptr;
    typedef typename NodeTraits::const_node_ptr const_node_ptr;
    typedef NodeTraits node_traits;
@@ -53,7 +54,7 @@
    {
       node_ptr next = NodeTraits::get_next(this_node);
       return !next || next == this_node;
- }
+ }
 
    static bool inited(const_node_ptr this_node)
    { return !NodeTraits::get_next(this_node); }

Modified: trunk/boost/intrusive/detail/generic_hook.hpp
==============================================================================
--- trunk/boost/intrusive/detail/generic_hook.hpp (original)
+++ trunk/boost/intrusive/detail/generic_hook.hpp 2008-06-21 05:04:21 EDT (Sat, 21 Jun 2008)
@@ -18,6 +18,7 @@
 #include <boost/intrusive/detail/pointer_to_other.hpp>
 #include <boost/intrusive/link_mode.hpp>
 #include <boost/intrusive/detail/utilities.hpp>
+#include <boost/intrusive/detail/mpl.hpp>
 #include <boost/static_assert.hpp>
 
 namespace boost {
@@ -35,6 +36,7 @@
 , SplaySetBaseHook
 , AvlSetBaseHook
 , BsSetBaseHook
+, AnyBaseHook
 };
 
 struct no_default_definer{};
@@ -70,6 +72,10 @@
 struct default_definer<Hook, BsSetBaseHook>
 { typedef Hook default_bs_set_hook; };
 
+template <class Hook>
+struct default_definer<Hook, AnyBaseHook>
+{ typedef Hook default_any_hook; };
+
 template <class Hook, unsigned int BaseHookType>
 struct make_default_definer
 {
@@ -90,11 +96,11 @@
    typedef typename detail::if_c
       <!detail::is_same<Tag, member_tag>::value
       , detail::node_holder
- < typename GetNodeAlgorithms::type::node_traits::node
+ < typename GetNodeAlgorithms::type::node
          , Tag
          , LinkMode
          , HookType>
- , typename GetNodeAlgorithms::type::node_traits::node
+ , typename GetNodeAlgorithms::type::node
>::type type;
 };
 
@@ -122,38 +128,38 @@
    , public make_node_holder<GetNodeAlgorithms, Tag, LinkMode, HookType>::type
    /// @endcond
 {
- public:
    /// @cond
+ typedef typename GetNodeAlgorithms::type node_algorithms;
+ typedef typename node_algorithms::node node;
+ typedef typename node_algorithms::node_ptr node_ptr;
+ typedef typename node_algorithms::const_node_ptr const_node_ptr;
+
+ public:
    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;
+ typedef Tag tag;
+ typedef typename GetNodeAlgorithms::type::node_traits node_traits;
       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 };
+ static const bool safemode_or_autounlink =
+ (int)link_mode == (int)auto_unlink || (int)link_mode == (int)safe_link;
    };
+
+ public:
    /// @endcond
 
    generic_hook()
    {
       if(boost_intrusive_tags::safemode_or_autounlink){
- boost_intrusive_tags::node_algorithms::init
- (static_cast<typename boost_intrusive_tags::node*>(this));
+ node_algorithms::init(static_cast<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));
+ node_algorithms::init(static_cast<node*>(this));
       }
    }
 
@@ -168,26 +174,23 @@
 
    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));
+ node_algorithms::swap_nodes
+ ( static_cast<node*>(this), static_cast<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));
+ return !node_algorithms::unique
+ (static_cast<const 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));
+ node_algorithms::unlink(static_cast<node*>(this));
+ node_algorithms::init(static_cast<node*>(this));
    }
 };
 

Modified: trunk/boost/intrusive/detail/hashtable_node.hpp
==============================================================================
--- trunk/boost/intrusive/detail/hashtable_node.hpp (original)
+++ trunk/boost/intrusive/detail/hashtable_node.hpp 2008-06-21 05:04:21 EDT (Sat, 21 Jun 2008)
@@ -104,13 +104,13 @@
             <typename Container::value_type, IsConst>::type
>
 {
- 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 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
- < typename Container::pointer, const Container>::type const_cont_ptr;
- typedef typename Container::size_type size_type;
+ < typename Container::pointer, const Container>::type const_cont_ptr;
+ typedef typename Container::size_type size_type;
 
    static typename Container::node_ptr downcast_bucket(typename bucket_type::node_ptr p)
    { return typename Container::node_ptr(&static_cast<typename Container::node&>(*p)); }

Modified: trunk/boost/intrusive/detail/list_node.hpp
==============================================================================
--- trunk/boost/intrusive/detail/list_node.hpp (original)
+++ trunk/boost/intrusive/detail/list_node.hpp 2008-06-21 05:04:21 EDT (Sat, 21 Jun 2008)
@@ -18,7 +18,6 @@
 #include <iterator>
 #include <boost/intrusive/detail/assert.hpp>
 #include <boost/intrusive/detail/pointer_to_other.hpp>
-#include <boost/intrusive/circular_list_algorithms.hpp>
 
 namespace boost {
 namespace intrusive {

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 2008-06-21 05:04:21 EDT (Sat, 21 Jun 2008)
@@ -13,12 +13,11 @@
 #define BOOST_INTRUSIVE_PARENT_FROM_MEMBER_HPP
 
 #include <boost/intrusive/detail/config_begin.hpp>
-#include <boost/static_assert.hpp>
 #include <cstddef>
 
 #if defined(BOOST_MSVC) || (defined (BOOST_WINDOWS) && defined(BOOST_INTEL))
-#define BOOST_INTRUSIVE_OFFSET_FROM_PTR2MEMBER_MSVC_COMPLIANT
-#include <boost/cstdint.hpp>
+#define BOOST_INTRUSIVE_MSVC_COMPLIANT_PTR_TO_MEMBER
+#include <boost/cstdint.hpp>
 #endif
 
 namespace boost {
@@ -26,16 +25,18 @@
 namespace detail {
 
 template<class Parent, class Member>
-inline std::size_t offset_from_pointer_to_member(const Member Parent::* ptr_to_member)
+inline std::ptrdiff_t offset_from_pointer_to_member(const Member Parent::* ptr_to_member)
 {
    //The implementation of a pointer to member is compiler dependent.
- #if defined(BOOST_INTRUSIVE_OFFSET_FROM_PTR2MEMBER_MSVC_COMPLIANT)
- //This works with gcc, msvc, ac++, ibmcpp
+ #if defined(BOOST_INTRUSIVE_MSVC_COMPLIANT_PTR_TO_MEMBER)
+ //msvc compliant compilers use their the first 32 bits as offset (even in 64 bit mode)
    return *(const boost::int32_t*)(void*)&ptr_to_member;
- #elif defined(__GNUC__) || defined(__HP_aCC) || defined(BOOST_INTEL) || defined (__IBMCPP__) || defined (__DECCXX)
+ //This works with gcc, msvc, ac++, ibmcpp
+ #elif defined(__GNUC__) || defined(__HP_aCC) || defined(BOOST_INTEL) || \
+ defined(__IBMCPP__) || defined(__DECCXX)
    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));
+ return std::ptrdiff_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;
@@ -60,8 +61,8 @@
 } //namespace intrusive {
 } //namespace boost {
 
-#ifdef BOOST_INTRUSIVE_OFFSET_FROM_PTR2MEMBER_MSVC_COMPLIANT
-#undef BOOST_INTRUSIVE_OFFSET_FROM_PTR2MEMBER_MSVC_COMPLIANT
+#ifdef BOOST_INTRUSIVE_MSVC_COMPLIANT_PTR_TO_MEMBER
+#undef BOOST_INTRUSIVE_MSVC_COMPLIANT_PTR_TO_MEMBER
 #endif
 
 #include <boost/intrusive/detail/config_end.hpp>

Modified: trunk/boost/intrusive/detail/slist_node.hpp
==============================================================================
--- trunk/boost/intrusive/detail/slist_node.hpp (original)
+++ trunk/boost/intrusive/detail/slist_node.hpp 2008-06-21 05:04:21 EDT (Sat, 21 Jun 2008)
@@ -18,7 +18,6 @@
 #include <iterator>
 #include <boost/intrusive/detail/assert.hpp>
 #include <boost/intrusive/detail/pointer_to_other.hpp>
-#include <boost/intrusive/circular_slist_algorithms.hpp>
 
 namespace boost {
 namespace intrusive {

Modified: trunk/boost/intrusive/detail/tree_algorithms.hpp
==============================================================================
--- trunk/boost/intrusive/detail/tree_algorithms.hpp (original)
+++ trunk/boost/intrusive/detail/tree_algorithms.hpp 2008-06-21 05:04:21 EDT (Sat, 21 Jun 2008)
@@ -94,13 +94,8 @@
 template<class NodeTraits>
 class tree_algorithms
 {
- /// @cond
- private:
-
- typedef typename NodeTraits::node node;
- /// @endcond
-
    public:
+ typedef typename NodeTraits::node node;
    typedef NodeTraits node_traits;
    typedef typename NodeTraits::node_ptr node_ptr;
    typedef typename NodeTraits::const_node_ptr const_node_ptr;

Modified: trunk/boost/intrusive/detail/utilities.hpp
==============================================================================
--- trunk/boost/intrusive/detail/utilities.hpp (original)
+++ trunk/boost/intrusive/detail/utilities.hpp 2008-06-21 05:04:21 EDT (Sat, 21 Jun 2008)
@@ -25,6 +25,7 @@
 #include <climits>
 #include <iterator>
 #include <boost/cstdint.hpp>
+#include <boost/static_assert.hpp>
 
 namespace boost {
 namespace intrusive {
@@ -56,6 +57,24 @@
 };
 
 template <class T>
+struct internal_any_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::is_any_hook>
+ test (detail::bool_<U::is_any_hook>* = 0);
+ static const std::size_t value = sizeof(test<T>(0));
+};
+
+template <class T>
+struct internal_any_hook_bool_is_true
+{
+ static const bool value = internal_any_hook_bool<T>::value > sizeof(one)*2;
+};
+
+
+template <class T>
 struct external_value_traits_bool
 {
    template<bool Add>

Modified: trunk/boost/intrusive/hashtable.hpp
==============================================================================
--- trunk/boost/intrusive/hashtable.hpp (original)
+++ trunk/boost/intrusive/hashtable.hpp 2008-06-21 05:04:21 EDT (Sat, 21 Jun 2008)
@@ -83,9 +83,8 @@
 };
 
 template<class SupposedValueTraits>
-struct unordered_bucket_impl
+struct real_from_supposed_value_traits
 {
- /// @cond
    typedef typename detail::eval_if_c
       < detail::external_value_traits_is_true
          <SupposedValueTraits>::value
@@ -93,15 +92,33 @@
          <SupposedValueTraits>
       , detail::identity
          <SupposedValueTraits>
- >::type real_value_traits;
+ >::type type;
+};
 
+template<class SupposedValueTraits>
+struct get_slist_impl_from_supposed_value_traits
+{
+ typedef typename
+ real_from_supposed_value_traits
+ < SupposedValueTraits>::type real_value_traits;
    typedef typename detail::get_node_traits
       <real_value_traits>::type node_traits;
    typedef typename get_slist_impl
       <typename reduced_slist_node_traits
          <node_traits>::type
- >::type slist_impl;
+ >::type type;
+};
+
+
+template<class SupposedValueTraits>
+struct unordered_bucket_impl
+{
+ /// @cond
+ typedef typename
+ get_slist_impl_from_supposed_value_traits
+ <SupposedValueTraits>::type slist_impl;
    typedef detail::bucket_impl<slist_impl> implementation_defined;
+ /// @endcond
    typedef implementation_defined type;
 };
 
@@ -109,15 +126,6 @@
 struct unordered_bucket_ptr_impl
 {
    /// @cond
-
- typedef typename detail::eval_if_c
- < detail::external_value_traits_is_true
- <SupposedValueTraits>::value
- , detail::eval_value_traits
- <SupposedValueTraits>
- , detail::identity
- <SupposedValueTraits>
- >::type real_value_traits;
    typedef typename detail::get_node_traits
       <SupposedValueTraits>::type::node_ptr node_ptr;
    typedef typename unordered_bucket_impl
@@ -128,36 +136,6 @@
    typedef implementation_defined type;
 };
 
-} //namespace detail {
-
-/// @endcond
-
-template<class ValueTraitsOrHookOption>
-struct unordered_bucket
-{
- /// @cond
- typedef typename ValueTraitsOrHookOption::
- template pack<none>::value_traits supposed_value_traits;
- /// @endcond
- typedef typename detail::unordered_bucket_impl
- <supposed_value_traits>::type type;
-};
-
-template<class ValueTraitsOrHookOption>
-struct unordered_bucket_ptr
-{
- /// @cond
- typedef typename ValueTraitsOrHookOption::
- template pack<none>::value_traits supposed_value_traits;
- /// @endcond
- typedef typename detail::unordered_bucket_ptr_impl
- <supposed_value_traits>::type type;
-};
-
-/// @cond
-
-namespace detail{
-
 template <class T>
 struct store_hash_bool
 {
@@ -275,8 +253,6 @@
    std::size_t hash;
 };
 
-} //namespace detail {
-
 template <class T>
 struct internal_default_uset_hook
 {
@@ -285,6 +261,49 @@
    static const bool value = sizeof(test<T>(0)) == sizeof(detail::two);
 };
 
+} //namespace detail {
+
+//!This metafunction will obtain the type of a bucket
+//!from the value_traits or hook option to be used with
+//!a hash container.
+template<class ValueTraitsOrHookOption>
+struct unordered_bucket
+ : public detail::unordered_bucket_impl
+ <typename ValueTraitsOrHookOption::
+ template pack<none>::value_traits
+ >
+{};
+
+//!This metafunction will obtain the type of a bucket pointer
+//!from the value_traits or hook option to be used with
+//!a hash container.
+template<class ValueTraitsOrHookOption>
+struct unordered_bucket_ptr
+ : public detail::unordered_bucket_ptr_impl
+ <typename ValueTraitsOrHookOption::
+ template pack<none>::value_traits
+ >
+{};
+
+//!This metafunction will obtain the type of the default bucket traits
+//!(when the user does not specify the bucket_traits<> option) from the
+//!value_traits or hook option to be used with
+//!a hash container.
+template<class ValueTraitsOrHookOption>
+struct unordered_default_bucket_traits
+{
+ /// @cond
+ typedef typename ValueTraitsOrHookOption::
+ template pack<none>::value_traits supposed_value_traits;
+ typedef typename detail::
+ get_slist_impl_from_supposed_value_traits
+ <supposed_value_traits>::type slist_impl;
+ typedef detail::bucket_traits_impl
+ <slist_impl> implementation_defined;
+ /// @endcond
+ typedef implementation_defined type;
+};
+
 template <class T>
 struct get_default_uset_hook
 {
@@ -300,6 +319,7 @@
          , class BucketTraits
          , bool Power2Buckets
          , bool CacheBegin
+ , bool CompareHash
>
 struct usetopt
 {
@@ -312,6 +332,7 @@
    static const bool power_2_buckets = Power2Buckets;
    static const bool unique_keys = UniqueKeys;
    static const bool cache_begin = CacheBegin;
+ static const bool compare_hash = CompareHash;
 };
 
 struct default_bucket_traits;
@@ -322,7 +343,7 @@
       < none
       , base_hook
          < typename detail::eval_if_c
- < internal_default_uset_hook<T>::value
+ < detail::internal_default_uset_hook<T>::value
                , get_default_uset_hook<T>
                , detail::identity<none>
>::type
@@ -334,6 +355,7 @@
       , bucket_traits<default_bucket_traits>
       , power_2_buckets<false>
       , cache_begin<false>
+ , compare_hash<false>
>::type
 {};
 
@@ -441,17 +463,21 @@
       = detail::optimize_multikey_is_true<node_traits>::value && !unique_keys;
    static const bool power_2_buckets = Config::power_2_buckets;
    static const bool cache_begin = Config::cache_begin;
+ static const bool compare_hash = Config::compare_hash;
 
    /// @cond
    private:
+ //Configuration error: compare_hash<> can't be specified without store_hash<>
+ //See documentation for more explanations
+ BOOST_STATIC_ASSERT((!compare_hash || store_hash));
+
    typedef typename slist_impl::node_ptr slist_node_ptr;
    typedef typename boost::pointer_to_other
          <slist_node_ptr, void>::type void_pointer;
    //We'll define group traits, but these won't be instantiated if
    //optimize_multikey is not true
- typedef unordered_group_node_traits<void_pointer, node> group_traits;
+ typedef unordered_group_adapter<node_traits> group_traits;
    typedef circular_slist_algorithms<group_traits> group_algorithms;
-
    typedef detail::bool_<store_hash> store_hash_t;
    typedef detail::bool_<optimize_multikey> optimize_multikey_t;
    typedef detail::bool_<cache_begin> cache_begin_t;
@@ -831,7 +857,11 @@
       if(!found_equal){
          it = b.before_begin();
       }
- this->priv_insert_in_group(found_equal ? dcast_bucket_ptr(it.pointed_node()) : node_ptr(0), n, optimize_multikey_t());
+ if(optimize_multikey){
+ node_ptr first_in_group = found_equal ?
+ dcast_bucket_ptr(it.pointed_node()) : node_ptr(0);
+ this->priv_insert_in_group(first_in_group, n, optimize_multikey_t());
+ }
       priv_insertion_update_cache(bucket_num);
       this->priv_size_traits().increment();
       return iterator(b.insert_after(it, *n), this);
@@ -1136,10 +1166,10 @@
                               ,KeyValueEqual equal_func, Disposer disposer)
    {
       size_type bucket_num;
- std::size_t hash;
+ std::size_t h;
       siterator prev;
       siterator it =
- this->priv_find(key, hash_func, equal_func, bucket_num, hash, prev);
+ this->priv_find(key, hash_func, equal_func, bucket_num, h, prev);
       bool success = it != priv_invalid_local_it();
       size_type count(0);
       if(!success){
@@ -1156,7 +1186,14 @@
          bucket_type &b = this->priv_buckets()[bucket_num];
          for(siterator end = b.end(); it != end; ++count, ++it){
             slist_node_ptr n(it.pointed_node());
- if(!equal_func(key, priv_value_from_slist_node(n))){
+ const value_type &v = priv_value_from_slist_node(n);
+ if(compare_hash){
+ std::size_t vh = this->priv_stored_hash(v, store_hash_t());
+ if(h != vh || !equal_func(key, v)){
+ break;
+ }
+ }
+ else if(!equal_func(key, v)){
                break;
             }
             this->priv_size_traits().decrement();
@@ -1657,7 +1694,7 @@
       BOOST_INTRUSIVE_INVARIANT_ASSERT
       (!power_2_buckets || (0 == (new_buckets_len & (new_buckets_len-1u))));
 
- size_type n = this->priv_get_cache() - this->priv_buckets();
+ size_type n = priv_get_cache_bucket_num();
       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.
@@ -1665,8 +1702,10 @@
          (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){
+ size_type new_first_bucket_num = new_buckets_len;
+ if(same_buffer && fast_shrink && (n < new_buckets_len)){
          n = new_buckets_len;
+ new_first_bucket_num = priv_get_cache_bucket_num();
       }
 
       //Anti-exception stuff: they destroy the elements if something goes wrong
@@ -1696,6 +1735,8 @@
                const value_type &v = priv_value_from_slist_node(i.pointed_node());
                const std::size_t hash_value = this->priv_stored_hash(v, store_hash_t());
                const size_type new_n = priv_hash_to_bucket(hash_value, new_buckets_len);
+ if(cache_begin && new_n < new_first_bucket_num)
+ new_first_bucket_num = new_n;
                siterator last = bucket_type::s_iterator_to
                   (*priv_get_last_in_group(dcast_bucket_ptr(i.pointed_node())));
                if(same_buffer && new_n == n){
@@ -1710,6 +1751,8 @@
          }
          else{
             const size_type new_n = priv_hash_to_bucket(n, new_buckets_len);
+ if(cache_begin && new_n < new_first_bucket_num)
+ new_first_bucket_num = new_n;
             bucket_type &new_b = new_buckets[new_n];
             if(!old_bucket.empty()){
                new_b.splice_after( new_b.before_begin()
@@ -1723,8 +1766,8 @@
       this->priv_size_traits().set_size(size_backup);
       this->priv_real_bucket_traits() = new_bucket_traits;
       priv_initialize_cache();
- priv_insertion_update_cache(size_type(0u));
- priv_erasure_update_cache();
+ priv_insertion_update_cache(new_first_bucket_num);
+ //priv_erasure_update_cache();
       rollback1.release();
       rollback2.release();
    }
@@ -1912,16 +1955,16 @@
    static node_ptr dcast_bucket_ptr(typename slist_impl::node_ptr p)
    { return node_ptr(&static_cast<node&>(*p)); }
 
- std::size_t priv_stored_hash(const value_type &v, detail::true_)
+ std::size_t priv_stored_hash(const value_type &v, detail::true_) const
    { return node_traits::get_hash(this->get_real_value_traits().to_node_ptr(v)); }
 
- std::size_t priv_stored_hash(const value_type &v, detail::false_)
+ std::size_t priv_stored_hash(const value_type &v, detail::false_) const
    { return priv_hasher()(v); }
 
- std::size_t priv_stored_hash(slist_node_ptr n, detail::true_)
+ std::size_t priv_stored_hash(slist_node_ptr n, detail::true_) const
    { return node_traits::get_hash(dcast_bucket_ptr(n)); }
 
- std::size_t priv_stored_hash(slist_node_ptr, detail::false_)
+ std::size_t priv_stored_hash(slist_node_ptr, detail::false_) const
    {
       //This code should never be reached!
       BOOST_INTRUSIVE_INVARIANT_ASSERT(0);
@@ -2414,7 +2457,13 @@
 
       while(it != b.end()){
          const value_type &v = priv_value_from_slist_node(it.pointed_node());
- if(equal_func(key, v)){
+ if(compare_hash){
+ std::size_t vh = this->priv_stored_hash(v, store_hash_t());
+ if(h == vh && equal_func(key, v)){
+ return it;
+ }
+ }
+ else if(equal_func(key, v)){
             return it;
          }
          if(optimize_multikey){
@@ -2470,7 +2519,15 @@
          ++it;
          while(it != b.end()){
             const value_type &v = priv_value_from_slist_node(it.pointed_node());
- if(!equal_func(key, v)){
+ if(compare_hash){
+ std::size_t hv = this->priv_stored_hash(v, store_hash_t());
+ if(hv != h || !equal_func(key, v)){
+ to_return.second = it;
+ bucket_number_second = bucket_number_first;
+ return to_return;
+ }
+ }
+ else if(!equal_func(key, v)){
                to_return.second = it;
                bucket_number_second = bucket_number_first;
                return to_return;
@@ -2505,11 +2562,12 @@
          , class O3 = none, class O4 = none
          , class O5 = none, class O6 = none
          , class O7 = none, class O8 = none
+ , class O9 = none
>
 struct make_hashtable_opt
 {
    typedef typename pack_options
- < uset_defaults<T>, O1, O2, O3, O4, O5, O6, O7, O8>::type packed_options;
+ < uset_defaults<T>, O1, O2, O3, O4, O5, O6, O7, O8, O9>::type packed_options;
 
    //Real value traits must be calculated from options
    typedef typename detail::get_value_traits
@@ -2529,10 +2587,7 @@
    typedef typename detail::get_slist_impl
       <typename detail::reduced_slist_node_traits
          <typename real_value_traits::node_traits>::type
- >::type slist_impl;
-
- typedef typename detail::reduced_slist_node_traits
- <typename real_value_traits::node_traits>::type node_traits;
+ >::type slist_impl;
 
    typedef typename
       detail::if_c< detail::is_same
@@ -2553,6 +2608,7 @@
       , real_bucket_traits
       , packed_options::power_2_buckets
       , packed_options::cache_begin
+ , packed_options::compare_hash
> type;
 };
 /// @endcond
@@ -2566,6 +2622,7 @@
                 , class O3 = none, class O4 = none
                 , class O5 = none, class O6 = none
                 , class O7 = none, class O8 = none
+ , class O9 = none
>
 #endif
 struct make_hashtable
@@ -2573,7 +2630,7 @@
    /// @cond
    typedef hashtable_impl
       < typename make_hashtable_opt
- <T, false, O1, O2, O3, O4, O5, O6, O7, O8>::type
+ <T, false, O1, O2, O3, O4, O5, O6, O7, O8, O9>::type
> implementation_defined;
 
    /// @endcond
@@ -2581,12 +2638,12 @@
 };
 
 #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
-template<class T, class O1, class O2, class O3, class O4, class O5, class O6, class O7, class O8>
+template<class T, class O1, class O2, class O3, class O4, class O5, class O6, class O7, class O8, class O9>
 class hashtable
- : public make_hashtable<T, O1, O2, O3, O4, O5, O6, O7, O8>::type
+ : public make_hashtable<T, O1, O2, O3, O4, O5, O6, O7, O8, O9>::type
 {
    typedef typename make_hashtable
- <T, O1, O2, O3, O4, O5, O6, O7, O8>::type Base;
+ <T, O1, O2, O3, O4, O5, O6, O7, O8, O9>::type Base;
 
    public:
    typedef typename Base::value_traits value_traits;

Modified: trunk/boost/intrusive/intrusive_fwd.hpp
==============================================================================
--- trunk/boost/intrusive/intrusive_fwd.hpp (original)
+++ trunk/boost/intrusive/intrusive_fwd.hpp 2008-06-21 05:04:21 EDT (Sat, 21 Jun 2008)
@@ -294,6 +294,7 @@
    , class O6 = none
    , class O7 = none
    , class O8 = none
+ , class O9 = none
>
 class hashtable;
 
@@ -307,6 +308,7 @@
    , class O6 = none
    , class O7 = none
    , class O8 = none
+ , class O9 = none
>
 class unordered_set;
 
@@ -320,6 +322,7 @@
    , class O6 = none
    , class O7 = none
    , class O8 = none
+ , class O9 = none
>
 class unordered_multiset;
 
@@ -339,6 +342,20 @@
>
 class unordered_set_member_hook;
 
+template
+ < class O1 = none
+ , class O2 = none
+ , class O3 = none
+ >
+class any_base_hook;
+
+template
+ < class O1 = none
+ , class O2 = none
+ , class O3 = none
+ >
+class any_member_hook;
+
 } //namespace intrusive {
 } //namespace boost {
 

Modified: trunk/boost/intrusive/linear_slist_algorithms.hpp
==============================================================================
--- trunk/boost/intrusive/linear_slist_algorithms.hpp (original)
+++ trunk/boost/intrusive/linear_slist_algorithms.hpp 2008-06-21 05:04:21 EDT (Sat, 21 Jun 2008)
@@ -53,6 +53,7 @@
    typedef detail::common_slist_algorithms<NodeTraits> base_t;
    /// @endcond
    public:
+ typedef typename NodeTraits::node node;
    typedef typename NodeTraits::node_ptr node_ptr;
    typedef typename NodeTraits::const_node_ptr const_node_ptr;
    typedef NodeTraits node_traits;

Modified: trunk/boost/intrusive/options.hpp
==============================================================================
--- trunk/boost/intrusive/options.hpp (original)
+++ trunk/boost/intrusive/options.hpp 2008-06-21 05:04:21 EDT (Sat, 21 Jun 2008)
@@ -49,15 +49,56 @@
    typedef typename BucketTraits::bucket_traits type;
 };
 
-template<class T, class BaseHook>
-struct get_base_value_traits
+template <class T, class BaseHook>
+struct concrete_hook_base_value_traits
+{
+ typedef typename BaseHook::boost_intrusive_tags tags;
+ typedef detail::base_hook_traits
+ < T
+ , typename tags::node_traits
+ , tags::link_mode
+ , typename tags::tag
+ , tags::hook_type> type;
+};
+
+template <class BaseHook>
+struct concrete_hook_base_node_traits
+{ typedef typename BaseHook::boost_intrusive_tags::node_traits type; };
+
+template <class T, class BaseHook>
+struct any_hook_base_value_traits
 {
+ typedef typename BaseHook::boost_intrusive_tags tags;
    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;
+ , typename BaseHook::node_traits
+ , tags::link_mode
+ , typename tags::tag
+ , tags::hook_type> type;
+};
+
+template <class BaseHook>
+struct any_hook_base_node_traits
+{ typedef typename BaseHook::node_traits type; };
+
+template<class T, class BaseHook>
+struct get_base_value_traits
+{
+ typedef typename detail::eval_if_c
+ < internal_any_hook_bool_is_true<BaseHook>::value
+ , any_hook_base_value_traits<T, BaseHook>
+ , concrete_hook_base_value_traits<T, BaseHook>
+ >::type type;
+};
+
+template<class BaseHook>
+struct get_base_node_traits
+{
+ typedef typename detail::eval_if_c
+ < internal_any_hook_bool_is_true<BaseHook>::value
+ , any_hook_base_node_traits<BaseHook>
+ , concrete_hook_base_node_traits<BaseHook>
+ >::type type;
 };
 
 template<class T, class MemberHook>
@@ -66,6 +107,12 @@
    typedef typename MemberHook::member_value_traits type;
 };
 
+template<class MemberHook>
+struct get_member_node_traits
+{
+ typedef typename MemberHook::member_value_traits::node_traits type;
+};
+
 template<class T, class SupposedValueTraits>
 struct get_value_traits
 {
@@ -86,25 +133,12 @@
>::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
 {
@@ -125,7 +159,6 @@
>::type type;
 };
 
-
 } //namespace detail{
 
 
@@ -258,7 +291,6 @@
 struct member_hook
 {
 /// @cond
- typedef char Parent::* GenericPtrToMember;
    typedef detail::member_hook_traits
       < Parent
       , MemberHook
@@ -272,6 +304,7 @@
 /// @endcond
 };
 
+
 //!This option setter specifies that the container
 //!must use the specified base hook
 template<typename BaseHook>
@@ -457,6 +490,25 @@
 /// @endcond
 };
 
+
+//!This option setter specifies if the container will compare the hash value
+//!before comparing objects. This option can't be specified if store_hash<>
+//!is not true.
+//!This is specially helpful when we have containers with a high load factor.
+//!and the comparison function is much more expensive that comparing already
+//!stored hash values.
+template<bool Enabled>
+struct compare_hash
+{
+/// @cond
+ template<class Base>
+ struct pack : Base
+ {
+ static const bool compare_hash = Enabled;
+ };
+/// @endcond
+};
+
 /// @cond
 
 template<class Prev, class Next>

Modified: trunk/boost/intrusive/rbtree_algorithms.hpp
==============================================================================
--- trunk/boost/intrusive/rbtree_algorithms.hpp (original)
+++ trunk/boost/intrusive/rbtree_algorithms.hpp 2008-06-21 05:04:21 EDT (Sat, 21 Jun 2008)
@@ -116,6 +116,7 @@
 {
    public:
    typedef NodeTraits node_traits;
+ typedef typename NodeTraits::node node;
    typedef typename NodeTraits::node_ptr node_ptr;
    typedef typename NodeTraits::const_node_ptr const_node_ptr;
    typedef typename NodeTraits::color color;
@@ -123,7 +124,6 @@
    /// @cond
    private:
 
- typedef typename NodeTraits::node node;
    typedef detail::tree_algorithms<NodeTraits> tree_algorithms;
 
    template<class F>

Modified: trunk/boost/intrusive/sgtree_algorithms.hpp
==============================================================================
--- trunk/boost/intrusive/sgtree_algorithms.hpp (original)
+++ trunk/boost/intrusive/sgtree_algorithms.hpp 2008-06-21 05:04:21 EDT (Sat, 21 Jun 2008)
@@ -58,6 +58,7 @@
 class sgtree_algorithms
 {
    public:
+ typedef typename NodeTraits::node node;
    typedef NodeTraits node_traits;
    typedef typename NodeTraits::node_ptr node_ptr;
    typedef typename NodeTraits::const_node_ptr const_node_ptr;
@@ -65,7 +66,6 @@
    /// @cond
    private:
 
- typedef typename NodeTraits::node node;
    typedef detail::tree_algorithms<NodeTraits> tree_algorithms;
 
    static node_ptr uncast(const_node_ptr ptr)

Modified: trunk/boost/intrusive/splaytree_algorithms.hpp
==============================================================================
--- trunk/boost/intrusive/splaytree_algorithms.hpp (original)
+++ trunk/boost/intrusive/splaytree_algorithms.hpp 2008-06-21 05:04:21 EDT (Sat, 21 Jun 2008)
@@ -130,11 +130,11 @@
 {
    /// @cond
    private:
- typedef typename NodeTraits::node node;
    typedef detail::tree_algorithms<NodeTraits> tree_algorithms;
    /// @endcond
 
    public:
+ typedef typename NodeTraits::node node;
    typedef NodeTraits node_traits;
    typedef typename NodeTraits::node_ptr node_ptr;
    typedef typename NodeTraits::const_node_ptr const_node_ptr;

Modified: trunk/boost/intrusive/unordered_set.hpp
==============================================================================
--- trunk/boost/intrusive/unordered_set.hpp (original)
+++ trunk/boost/intrusive/unordered_set.hpp 2008-06-21 05:04:21 EDT (Sat, 21 Jun 2008)
@@ -961,6 +961,7 @@
                 , class O3 = none, class O4 = none
                 , class O5 = none, class O6 = none
                 , class O7 = none, class O8 = none
+ , class O9 = none
>
 #endif
 struct make_unordered_set
@@ -968,19 +969,19 @@
    /// @cond
    typedef unordered_set_impl
       < typename make_hashtable_opt
- <T, true, O1, O2, O3, O4, O5, O6, O7, O8>::type
+ <T, true, O1, O2, O3, O4, O5, O6, O7, O8, O9>::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 O8>
+template<class T, class O1, class O2, class O3, class O4, class O5, class O6, class O7, class O8, class O9>
 class unordered_set
- : public make_unordered_set<T, O1, O2, O3, O4, O5, O6, O7, O8>::type
+ : public make_unordered_set<T, O1, O2, O3, O4, O5, O6, O7, O8, O9>::type
 {
    typedef typename make_unordered_set
- <T, O1, O2, O3, O4, O5, O6, O7, O8>::type Base;
+ <T, O1, O2, O3, O4, O5, O6, O7, O8, O9>::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));
@@ -1894,6 +1895,7 @@
                 , class O3 = none, class O4 = none
                 , class O5 = none, class O6 = none
                 , class O7 = none, class O8 = none
+ , class O9 = none
>
 #endif
 struct make_unordered_multiset
@@ -1901,19 +1903,19 @@
    /// @cond
    typedef unordered_multiset_impl
       < typename make_hashtable_opt
- <T, false, O1, O2, O3, O4, O5, O6, O7, O8>::type
+ <T, false, O1, O2, O3, O4, O5, O6, O7, O8, O9>::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 O8>
+template<class T, class O1, class O2, class O3, class O4, class O5, class O6, class O7, class O8, class O9>
 class unordered_multiset
- : public make_unordered_multiset<T, O1, O2, O3, O4, O5, O6, O7, O8>::type
+ : public make_unordered_multiset<T, O1, O2, O3, O4, O5, O6, O7, O8, O9>::type
 {
    typedef typename make_unordered_multiset
- <T, O1, O2, O3, O4, O5, O6, O7, O8>::type Base;
+ <T, O1, O2, O3, O4, O5, O6, O7, O8, O9>::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));
 

Modified: trunk/boost/intrusive/unordered_set_hook.hpp
==============================================================================
--- trunk/boost/intrusive/unordered_set_hook.hpp (original)
+++ trunk/boost/intrusive/unordered_set_hook.hpp 2008-06-21 05:04:21 EDT (Sat, 21 Jun 2008)
@@ -35,7 +35,6 @@
       < VoidPointer
       , unordered_node<VoidPointer, StoreHash, OptimizeMultiKey>
>::type node_ptr;
-// node_ptr next_;
    node_ptr prev_in_group_;
    std::size_t hash_;
 };
@@ -48,7 +47,6 @@
       < VoidPointer
       , unordered_node<VoidPointer, false, true>
>::type node_ptr;
-// node_ptr next_;
    node_ptr prev_in_group_;
 };
 
@@ -60,7 +58,6 @@
       < VoidPointer
       , unordered_node<VoidPointer, true, false>
>::type node_ptr;
-// node_ptr next_;
    std::size_t hash_;
 };
 
@@ -97,34 +94,26 @@
    { n->hash_ = h; }
 };
 
-template<class VoidPointer, class Node>
-struct unordered_group_node_traits
+template<class NodeTraits>
+struct unordered_group_adapter
 {
- typedef 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 typename NodeTraits::node node;
+ typedef typename NodeTraits::node_ptr node_ptr;
+ typedef typename NodeTraits::const_node_ptr const_node_ptr;
 
    static node_ptr get_next(const_node_ptr n)
- { return n->prev_in_group_; }
+ { return NodeTraits::get_prev_in_group(n); }
 
    static void set_next(node_ptr n, node_ptr next)
- { n->prev_in_group_ = next; }
+ { NodeTraits::set_prev_in_group(n, next); }
 };
 
 template<class NodeTraits>
 struct unordered_algorithms
    : public circular_slist_algorithms<NodeTraits>
 {
- typedef circular_slist_algorithms<NodeTraits> base_type;
- typedef unordered_group_node_traits
- < typename boost::pointer_to_other
- < typename NodeTraits::node_ptr
- , void
- >::type
- , typename NodeTraits::node
- > group_traits;
+ typedef circular_slist_algorithms<NodeTraits> base_type;
+ typedef unordered_group_adapter<NodeTraits> group_traits;
    typedef circular_slist_algorithms<group_traits> group_algorithms;
 
    static void init(typename base_type::node_ptr n)


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk