$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r78319 - in branches/release: . boost boost/functional boost/functional/hash boost/functional/hash/detail boost/unordered boost/unordered/detail libs libs/functional libs/functional/hash/doc libs/functional/hash/test libs/unordered libs/unordered/doc libs/unordered/test/exception libs/unordered/test/helpers libs/unordered/test/unordered
From: dnljms_at_[hidden]
Date: 2012-05-03 18:05:26
Author: danieljames
Date: 2012-05-03 18:05:21 EDT (Thu, 03 May 2012)
New Revision: 78319
URL: http://svn.boost.org/trac/boost/changeset/78319
Log:
Unordered/Hash: Merge from trunk.
Added:
   branches/release/boost/functional/hash/detail/container_fwd_0x.hpp
      - copied unchanged from r78145, /trunk/boost/functional/hash/detail/container_fwd_0x.hpp
   branches/release/libs/functional/hash/test/hash_std_array_test.cpp
      - copied, changed from r78145, /trunk/libs/functional/hash/test/hash_std_array_test.cpp
   branches/release/libs/functional/hash/test/hash_std_tuple_test.cpp
      - copied, changed from r78145, /trunk/libs/functional/hash/test/hash_std_tuple_test.cpp
   branches/release/libs/unordered/test/helpers/postfix.hpp
      - copied unchanged from r77835, /trunk/libs/unordered/test/helpers/postfix.hpp
Properties modified: 
   branches/release/   (props changed)
   branches/release/boost/   (props changed)
   branches/release/boost/functional/   (props changed)
   branches/release/boost/unordered/   (props changed)
   branches/release/libs/   (props changed)
   branches/release/libs/functional/   (props changed)
   branches/release/libs/unordered/   (props changed)
Text files modified: 
   branches/release/boost/functional/hash/detail/hash_float.hpp                   |    16 +                                       
   branches/release/boost/functional/hash/extensions.hpp                          |    89 +++++++                                 
   branches/release/boost/unordered/detail/allocator_helpers.hpp                  |    41 +++                                     
   branches/release/boost/unordered/detail/buckets.hpp                            |   423 +++++++++++++++++++++++++++++++++++++-- 
   branches/release/boost/unordered/detail/emplace_args.hpp                       |    60 ++--                                    
   branches/release/boost/unordered/detail/equivalent.hpp                         |   223 +++++++++++---------                    
   branches/release/boost/unordered/detail/fwd.hpp                                |    30 --                                      
   branches/release/boost/unordered/detail/table.hpp                              |   299 ++-------------------------             
   branches/release/boost/unordered/detail/unique.hpp                             |   155 +++++++------                           
   branches/release/boost/unordered/unordered_map.hpp                             |    42 ++-                                     
   branches/release/boost/unordered/unordered_map_fwd.hpp                         |    18 +                                       
   branches/release/boost/unordered/unordered_set.hpp                             |    28 +-                                      
   branches/release/boost/unordered/unordered_set_fwd.hpp                         |    16 +                                       
   branches/release/libs/functional/hash/doc/changes.qbk                          |     7                                         
   branches/release/libs/functional/hash/doc/ref.xml                              |    30 ++                                      
   branches/release/libs/functional/hash/test/Jamfile.v2                          |     6                                         
   branches/release/libs/functional/hash/test/hash_complex_test.cpp               |     4                                         
   branches/release/libs/functional/hash/test/hash_float_test.hpp                 |     4                                         
   branches/release/libs/functional/hash/test/hash_map_test.cpp                   |     2                                         
   branches/release/libs/functional/hash/test/hash_number_test.cpp                |     4                                         
   branches/release/libs/functional/hash/test/hash_std_array_test.cpp             |    24 +-                                      
   branches/release/libs/functional/hash/test/hash_std_tuple_test.cpp             |    14                                         
   branches/release/libs/unordered/doc/changes.qbk                                |    17 +                                       
   branches/release/libs/unordered/test/exception/assign_exception_tests.cpp      |     2                                         
   branches/release/libs/unordered/test/exception/constructor_exception_tests.cpp |     2                                         
   branches/release/libs/unordered/test/exception/containers.hpp                  |     2                                         
   branches/release/libs/unordered/test/exception/copy_exception_tests.cpp        |     2                                         
   branches/release/libs/unordered/test/exception/erase_exception_tests.cpp       |     2                                         
   branches/release/libs/unordered/test/exception/insert_exception_tests.cpp      |     2                                         
   branches/release/libs/unordered/test/exception/rehash_exception_tests.cpp      |     2                                         
   branches/release/libs/unordered/test/exception/swap_exception_tests.cpp        |     2                                         
   branches/release/libs/unordered/test/unordered/Jamfile.v2                      |     4                                         
   branches/release/libs/unordered/test/unordered/allocator_traits.cpp            |     6                                         
   branches/release/libs/unordered/test/unordered/assign_tests.cpp                |     6                                         
   branches/release/libs/unordered/test/unordered/at_tests.cpp                    |     3                                         
   branches/release/libs/unordered/test/unordered/bucket_tests.cpp                |     3                                         
   branches/release/libs/unordered/test/unordered/compile_map.cpp                 |     2                                         
   branches/release/libs/unordered/test/unordered/compile_set.cpp                 |     2                                         
   branches/release/libs/unordered/test/unordered/constructor_tests.cpp           |     6                                         
   branches/release/libs/unordered/test/unordered/copy_tests.cpp                  |     3                                         
   branches/release/libs/unordered/test/unordered/equality_deprecated.cpp         |     3                                         
   branches/release/libs/unordered/test/unordered/equality_tests.cpp              |    12                                         
   branches/release/libs/unordered/test/unordered/equivalent_keys_tests.cpp       |     3                                         
   branches/release/libs/unordered/test/unordered/erase_equiv_tests.cpp           |     3                                         
   branches/release/libs/unordered/test/unordered/erase_tests.cpp                 |     3                                         
   branches/release/libs/unordered/test/unordered/find_tests.cpp                  |     3                                         
   branches/release/libs/unordered/test/unordered/fwd_map_test.cpp                |     2                                         
   branches/release/libs/unordered/test/unordered/fwd_set_test.cpp                |     2                                         
   branches/release/libs/unordered/test/unordered/incomplete_test.cpp             |     5                                         
   branches/release/libs/unordered/test/unordered/insert_stable_tests.cpp         |     3                                         
   branches/release/libs/unordered/test/unordered/insert_tests.cpp                |     6                                         
   branches/release/libs/unordered/test/unordered/link_test_1.cpp                 |     2                                         
   branches/release/libs/unordered/test/unordered/link_test_2.cpp                 |     2                                         
   branches/release/libs/unordered/test/unordered/load_factor_tests.cpp           |     3                                         
   branches/release/libs/unordered/test/unordered/minimal_allocator.cpp           |     2                                         
   branches/release/libs/unordered/test/unordered/move_tests.cpp                  |     3                                         
   branches/release/libs/unordered/test/unordered/rehash_tests.cpp                |     3                                         
   branches/release/libs/unordered/test/unordered/simple_tests.cpp                |     3                                         
   branches/release/libs/unordered/test/unordered/swap_tests.cpp                  |     5                                         
   branches/release/libs/unordered/test/unordered/unnecessary_copy_tests.cpp      |     6                                         
   60 files changed, 1018 insertions(+), 659 deletions(-)
Modified: branches/release/boost/functional/hash/detail/hash_float.hpp
==============================================================================
--- branches/release/boost/functional/hash/detail/hash_float.hpp	(original)
+++ branches/release/boost/functional/hash/detail/hash_float.hpp	2012-05-03 18:05:21 EDT (Thu, 03 May 2012)
@@ -87,9 +87,23 @@
     namespace hash_detail
     {
         template <class T>
+        inline bool is_zero(T v)
+        {
+#if !defined(__GNUC__)
+            return v == 0;
+#else
+            // GCC's '-Wfloat-equal' will complain about comparing
+            // v to 0, but because it disables warnings for system
+            // headers it won't complain if you use std::equal_to to
+            // compare with 0. Resulting in this silliness:
+            return std::equal_to<T>()(v, 0);
+#endif
+        }
+
+        template <class T>
         inline std::size_t float_hash_value(T v)
         {
-            return v == 0 ? 0 : float_hash_impl(v);
+            return boost::hash_detail::is_zero(v) ? 0 : float_hash_impl(v);
         }
     }
 }
Modified: branches/release/boost/functional/hash/extensions.hpp
==============================================================================
--- branches/release/boost/functional/hash/extensions.hpp	(original)
+++ branches/release/boost/functional/hash/extensions.hpp	2012-05-03 18:05:21 EDT (Thu, 03 May 2012)
@@ -14,7 +14,11 @@
 #define BOOST_FUNCTIONAL_HASH_EXTENSIONS_HPP
 
 #include <boost/functional/hash/hash.hpp>
-#include <boost/detail/container_fwd.hpp>
+#include <boost/functional/hash/detail/container_fwd_0x.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/preprocessor/repetition/repeat_from_to.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
 
 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
 # pragma once
@@ -54,51 +58,51 @@
     std::size_t hash_value(std::pair<A, B> const& v)
     {
         std::size_t seed = 0;
-        hash_combine(seed, v.first);
-        hash_combine(seed, v.second);
+        boost::hash_combine(seed, v.first);
+        boost::hash_combine(seed, v.second);
         return seed;
     }
 
     template <class T, class A>
     std::size_t hash_value(std::vector<T, A> const& v)
     {
-        return hash_range(v.begin(), v.end());
+        return boost::hash_range(v.begin(), v.end());
     }
 
     template <class T, class A>
     std::size_t hash_value(std::list<T, A> const& v)
     {
-        return hash_range(v.begin(), v.end());
+        return boost::hash_range(v.begin(), v.end());
     }
 
     template <class T, class A>
     std::size_t hash_value(std::deque<T, A> const& v)
     {
-        return hash_range(v.begin(), v.end());
+        return boost::hash_range(v.begin(), v.end());
     }
 
     template <class K, class C, class A>
     std::size_t hash_value(std::set<K, C, A> const& v)
     {
-        return hash_range(v.begin(), v.end());
+        return boost::hash_range(v.begin(), v.end());
     }
 
     template <class K, class C, class A>
     std::size_t hash_value(std::multiset<K, C, A> const& v)
     {
-        return hash_range(v.begin(), v.end());
+        return boost::hash_range(v.begin(), v.end());
     }
 
     template <class K, class T, class C, class A>
     std::size_t hash_value(std::map<K, T, C, A> const& v)
     {
-        return hash_range(v.begin(), v.end());
+        return boost::hash_range(v.begin(), v.end());
     }
 
     template <class K, class T, class C, class A>
     std::size_t hash_value(std::multimap<K, T, C, A> const& v)
     {
-        return hash_range(v.begin(), v.end());
+        return boost::hash_range(v.begin(), v.end());
     }
 
     template <class T>
@@ -110,6 +114,71 @@
         return seed;
     }
 
+#if !defined(BOOST_NO_0X_HDR_ARRAY)
+    template <class T, std::size_t N>
+    std::size_t hash_value(std::array<T, N> const& v)
+    {
+        return boost::hash_range(v.begin(), v.end());
+    }
+#endif
+
+#if !defined(BOOST_NO_0X_HDR_TUPLE)
+    namespace hash_detail {
+        template <std::size_t I, typename T>
+        inline typename boost::enable_if_c<(I == std::tuple_size<T>::value),
+                void>::type
+            hash_combine_tuple(std::size_t&, T const&)
+        {
+        }
+
+        template <std::size_t I, typename T>
+        inline typename boost::enable_if_c<(I < std::tuple_size<T>::value),
+                void>::type
+            hash_combine_tuple(std::size_t& seed, T const& v)
+        {
+            boost::hash_combine(seed, std::get<I>(v));
+            boost::hash_detail::hash_combine_tuple<I + 1>(seed, v);
+        }
+
+        template <typename T>
+        inline std::size_t hash_tuple(T const& v)
+        {
+            std::size_t seed = 0;
+            boost::hash_detail::hash_combine_tuple<0>(seed, v);
+            return seed;
+        }
+    }
+
+#if !defined(BOOST_NO_VARIADIC_TEMPLATES)
+    template <typename... T>
+    inline std::size_t hash_value(std::tuple<T...> const& v)
+    {
+        return boost::hash_detail::hash_tuple(v);
+    }
+#else
+
+    inline std::size_t hash_value(std::tuple<> const& v)
+    {
+        return boost::hash_detail::hash_tuple(v);
+    }
+
+#   define BOOST_HASH_TUPLE_F(z, n, _)                                      \
+    template<                                                               \
+        BOOST_PP_ENUM_PARAMS_Z(z, n, typename A)                            \
+    >                                                                       \
+    inline std::size_t hash_value(std::tuple<                               \
+        BOOST_PP_ENUM_PARAMS_Z(z, n, A)                                     \
+    > const& v)                                                             \
+    {                                                                       \
+        return boost::hash_detail::hash_tuple(v);                           \
+    }
+
+    BOOST_PP_REPEAT_FROM_TO(1, 11, BOOST_HASH_TUPLE_F, _)
+#   undef BOOST_HASH_TUPLE_F
+#endif
+
+#endif
+
     //
     // call_hash_impl
     //
Modified: branches/release/boost/unordered/detail/allocator_helpers.hpp
==============================================================================
--- branches/release/boost/unordered/detail/allocator_helpers.hpp	(original)
+++ branches/release/boost/unordered/detail/allocator_helpers.hpp	2012-05-03 18:05:21 EDT (Thu, 03 May 2012)
@@ -27,11 +27,34 @@
 #include <boost/utility/addressof.hpp>
 
 #if !defined(BOOST_UNORDERED_USE_ALLOCATOR_TRAITS)
-#define BOOST_UNORDERED_USE_ALLOCATOR_TRAITS 0
+// An allocator_traits test is currently failing for gcc 4.7 on mingw. I think
+// this is because it's an older development version. Temporarily disabling
+// std::allocator_traits in order ot get clean test results. Will reactivate
+// later.
+
+/*
+#   if defined(__GXX_EXPERIMENTAL_CXX0X__) && \
+            (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7))
+#       define BOOST_UNORDERED_USE_ALLOCATOR_TRAITS 1
+#   endif
+*/
+
+// Use container's allocator_traits for older versions of Visual C++ as I don't
+// test with them.
+#   if defined(BOOST_MSVC) && BOOST_MSVC < 1400
+#       define BOOST_UNORDERED_USE_ALLOCATOR_TRAITS 2
+#   endif
+
 #endif
 
-#if BOOST_UNORDERED_USE_ALLOCATOR_TRAITS
+#if !defined(BOOST_UNORDERED_USE_ALLOCATOR_TRAITS)
+#   define BOOST_UNORDERED_USE_ALLOCATOR_TRAITS 0
+#endif
+
+#if BOOST_UNORDERED_USE_ALLOCATOR_TRAITS == 1
 #  include <memory>
+#elif BOOST_UNORDERED_USE_ALLOCATOR_TRAITS == 2
+#  include <boost/container/allocator/allocator_traits.hpp>
 #endif
 
 #if !defined(BOOST_NO_0X_HDR_TYPE_TRAITS)
@@ -194,7 +217,7 @@
     // Uses the standard versions if available.
     // (although untested as I don't have access to a standard version yet)
 
-#if BOOST_UNORDERED_USE_ALLOCATOR_TRAITS
+#if BOOST_UNORDERED_USE_ALLOCATOR_TRAITS == 1
 
     template <typename Alloc>
     struct allocator_traits : std::allocator_traits<Alloc> {};
@@ -206,6 +229,18 @@
             template rebind_alloc<T> type;
     };
 
+#elif BOOST_UNORDERED_USE_ALLOCATOR_TRAITS == 2
+
+    template <typename Alloc>
+    struct allocator_traits :
+        boost::container::allocator_traits<Alloc> {};
+
+    template <typename Alloc, typename T>
+    struct rebind_wrap :
+        boost::container::allocator_traits<Alloc>::
+            template portable_rebind_alloc<T>
+    {};
+
 #else
 
     // TODO: Does this match std::allocator_traits<Alloc>::rebind_alloc<T>?
Modified: branches/release/boost/unordered/detail/buckets.hpp
==============================================================================
--- branches/release/boost/unordered/detail/buckets.hpp	(original)
+++ branches/release/boost/unordered/detail/buckets.hpp	2012-05-03 18:05:21 EDT (Thu, 03 May 2012)
@@ -18,6 +18,8 @@
 #include <boost/type_traits/alignment_of.hpp>
 #include <boost/swap.hpp>
 #include <boost/assert.hpp>
+#include <boost/limits.hpp>
+#include <boost/iterator.hpp>
 
 #if defined(BOOST_MSVC)
 #pragma warning(push)
@@ -29,7 +31,10 @@
     template <typename Types> struct table;
     template <typename NodePointer> struct bucket;
     struct ptr_bucket;
-    template <typename A, typename Bucket, typename Node> struct buckets;
+    template <typename A, typename Bucket, typename Node, typename Policy>
+    struct buckets;
+    template <typename Types> struct table_impl;
+    template <typename Types> struct grouped_table_impl;
 
     ///////////////////////////////////////////////////////////////////
     //
@@ -178,13 +183,364 @@
 
         enum { extra_node = false };
     };
+}}}
+
+namespace boost { namespace unordered { namespace iterator_detail {
+
+    ////////////////////////////////////////////////////////////////////////////
+    // Iterators
+    //
+    // all no throw
+
+    template <typename NodePointer, typename Value> struct iterator;
+    template <typename ConstNodePointer, typename NodePointer,
+        typename Value> struct c_iterator;
+    template <typename NodePointer, typename Value, typename Policy>
+        struct l_iterator;
+    template <typename ConstNodePointer, typename NodePointer,
+        typename Value, typename Policy> struct cl_iterator;
+
+    // Local Iterators
+    //
+    // all no throw
+
+    template <typename NodePointer, typename Value, typename Policy>
+    struct l_iterator
+        : public boost::iterator<
+            std::forward_iterator_tag, Value, std::ptrdiff_t,
+            NodePointer, Value&>
+    {
+#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
+        template <typename ConstNodePointer, typename NodePointer2,
+                typename Value2, typename Policy2>
+        friend struct boost::unordered::iterator_detail::cl_iterator;
+    private:
+#endif
+        typedef NodePointer node_pointer;
+        typedef boost::unordered::iterator_detail::iterator<NodePointer, Value>
+            iterator;
+        node_pointer ptr_;
+        std::size_t bucket_;
+        std::size_t bucket_count_;
+
+    public:
+
+        l_iterator() : ptr_() {}
+
+        l_iterator(iterator x, std::size_t b, std::size_t c)
+            : ptr_(x.node_), bucket_(b), bucket_count_(c) {}
+
+        Value& operator*() const {
+            return ptr_->value();
+        }
+
+        Value* operator->() const {
+            return ptr_->value_ptr();
+        }
+
+        l_iterator& operator++() {
+            ptr_ = static_cast<node_pointer>(ptr_->next_);
+            if (ptr_ && Policy::to_bucket(bucket_count_, ptr_->hash_)
+                    != bucket_)
+                ptr_ = node_pointer();
+            return *this;
+        }
+
+        l_iterator operator++(int) {
+            l_iterator tmp(*this);
+            ++(*this);
+            return tmp;
+        }
+
+        bool operator==(l_iterator x) const {
+            return ptr_ == x.ptr_;
+        }
+
+        bool operator!=(l_iterator x) const {
+            return ptr_ != x.ptr_;
+        }
+    };
+
+    template <typename ConstNodePointer, typename NodePointer, typename Value,
+             typename Policy>
+    struct cl_iterator
+        : public boost::iterator<
+            std::forward_iterator_tag, Value, std::ptrdiff_t,
+            ConstNodePointer, Value const&>
+    {
+        friend struct boost::unordered::iterator_detail::l_iterator
+            <NodePointer, Value, Policy>;
+    private:
+
+        typedef NodePointer node_pointer;
+        typedef boost::unordered::iterator_detail::iterator<NodePointer, Value>
+            iterator;
+        node_pointer ptr_;
+        std::size_t bucket_;
+        std::size_t bucket_count_;
+
+    public:
+
+        cl_iterator() : ptr_() {}
+
+        cl_iterator(iterator x, std::size_t b, std::size_t c) :
+            ptr_(x.node_), bucket_(b), bucket_count_(c) {}
+
+        cl_iterator(boost::unordered::iterator_detail::l_iterator<
+                NodePointer, Value, Policy> const& x) :
+            ptr_(x.ptr_), bucket_(x.bucket_), bucket_count_(x.bucket_count_)
+        {}
+
+        Value const&
+            operator*() const {
+            return ptr_->value();
+        }
+
+        Value const* operator->() const {
+            return ptr_->value_ptr();
+        }
+
+        cl_iterator& operator++() {
+            ptr_ = static_cast<node_pointer>(ptr_->next_);
+            if (ptr_ && Policy::to_bucket(bucket_count_, ptr_->hash_)
+                    != bucket_)
+                ptr_ = node_pointer();
+            return *this;
+        }
+
+        cl_iterator operator++(int) {
+            cl_iterator tmp(*this);
+            ++(*this);
+            return tmp;
+        }
+
+        friend bool operator==(cl_iterator const& x, cl_iterator const& y) {
+            return x.ptr_ == y.ptr_;
+        }
+
+        friend bool operator!=(cl_iterator const& x, cl_iterator const& y) {
+            return x.ptr_ != y.ptr_;
+        }
+    };
+
+    template <typename NodePointer, typename Value>
+    struct iterator
+        : public boost::iterator<
+            std::forward_iterator_tag, Value, std::ptrdiff_t,
+            NodePointer, Value&>
+    {
+#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
+        template <typename, typename, typename>
+        friend struct boost::unordered::iterator_detail::c_iterator;
+        template <typename, typename, typename>
+        friend struct boost::unordered::iterator_detail::l_iterator;
+        template <typename, typename, typename, typename>
+        friend struct boost::unordered::iterator_detail::cl_iterator;
+        template <typename>
+        friend struct boost::unordered::detail::table;
+        template <typename, typename, typename, typename>
+        friend struct boost::unordered::detail::buckets;
+        template <typename>
+        friend struct boost::unordered::detail::table_impl;
+        template <typename>
+        friend struct boost::unordered::detail::grouped_table_impl;
+    private:
+#endif
+        typedef NodePointer node_pointer;
+        node_pointer node_;
+
+    public:
+
+        iterator() : node_() {}
+
+        explicit iterator(node_pointer const& x) : node_(x) {}
+
+        Value& operator*() const {
+            return node_->value();
+        }
+
+        Value* operator->() const {
+            return &node_->value();
+        }
+
+        iterator& operator++() {
+            node_ = static_cast<node_pointer>(node_->next_);
+            return *this;
+        }
+
+        iterator operator++(int) {
+            iterator tmp(node_);
+            node_ = static_cast<node_pointer>(node_->next_);
+            return tmp;
+        }
+
+        bool operator==(iterator const& x) const {
+            return node_ == x.node_;
+        }
+
+        bool operator!=(iterator const& x) const {
+            return node_ != x.node_;
+        }
+    };
+
+    template <typename ConstNodePointer, typename NodePointer, typename Value>
+    struct c_iterator
+        : public boost::iterator<
+            std::forward_iterator_tag, Value, std::ptrdiff_t,
+            ConstNodePointer, Value const&>
+    {
+        friend struct boost::unordered::iterator_detail::iterator<
+                NodePointer, Value>;
+
+#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
+        template <typename>
+        friend struct boost::unordered::detail::table;
+        template <typename, typename, typename, typename>
+        friend struct boost::unordered::detail::buckets;
+        template <typename>
+        friend struct boost::unordered::detail::table_impl;
+        template <typename>
+        friend struct boost::unordered::detail::grouped_table_impl;
+
+    private:
+#endif
+
+        typedef NodePointer node_pointer;
+        typedef boost::unordered::iterator_detail::iterator<NodePointer, Value>
+            iterator;
+        node_pointer node_;
+
+    public:
+
+        c_iterator() : node_() {}
+
+        explicit c_iterator(node_pointer const& x) : node_(x) {}
+
+        c_iterator(boost::unordered::iterator_detail::iterator<
+                NodePointer, Value> const& x) : node_(x.node_) {}
+
+        Value const& operator*() const {
+            return node_->value();
+        }
+
+        Value const* operator->() const {
+            return &node_->value();
+        }
+
+        c_iterator& operator++() {
+            node_ = static_cast<node_pointer>(node_->next_);
+            return *this;
+        }
+
+        c_iterator operator++(int) {
+            c_iterator tmp(node_);
+            node_ = static_cast<node_pointer>(node_->next_);
+            return tmp;
+        }
+
+        friend bool operator==(c_iterator const& x, c_iterator const& y) {
+            return x.node_ == y.node_;
+        }
+
+        friend bool operator!=(c_iterator const& x, c_iterator const& y) {
+            return x.node_ != y.node_;
+        }
+    };
+}}}
+
+namespace boost { namespace unordered { namespace detail {
+
+    ///////////////////////////////////////////////////////////////////
+    //
+    // Hash Policy
+    //
+    // Don't really want buckets to derive from this, but will for now.
+
+    template <typename SizeT>
+    struct prime_policy
+    {
+        template <typename Hash, typename T>
+        static inline SizeT apply_hash(Hash const& hf, T const& x) {
+            return hf(x);
+        }
+
+        static inline SizeT to_bucket(SizeT bucket_count, SizeT hash) {
+            return hash % bucket_count;
+        }
+
+        static inline SizeT new_bucket_count(SizeT min) {
+            return boost::unordered::detail::next_prime(min);
+        }
+
+        static inline SizeT prev_bucket_count(SizeT max) {
+            return boost::unordered::detail::prev_prime(max);
+        }
+    };
+
+    template <typename SizeT>
+    struct mix64_policy
+    {
+        template <typename Hash, typename T>
+        static inline SizeT apply_hash(Hash const& hf, T const& x) {
+            SizeT key = hf(x);
+            key = (~key) + (key << 21); // key = (key << 21) - key - 1;
+            key = key ^ (key >> 24);
+            key = (key + (key << 3)) + (key << 8); // key * 265
+            key = key ^ (key >> 14);
+            key = (key + (key << 2)) + (key << 4); // key * 21
+            key = key ^ (key >> 28);
+            key = key + (key << 31);
+            return key;
+        }
+
+        static inline SizeT to_bucket(SizeT bucket_count, SizeT hash) {
+            return hash & (bucket_count - 1);
+        }
+
+        static inline SizeT new_bucket_count(SizeT min) {
+            if (min <= 4) return 4;
+            --min;
+            min |= min >> 1;
+            min |= min >> 2;
+            min |= min >> 4;
+            min |= min >> 8;
+            min |= min >> 16;
+            min |= min >> 32;
+            return min + 1;
+        }
+
+        static inline SizeT prev_bucket_count(SizeT max) {
+            max |= max >> 1;
+            max |= max >> 2;
+            max |= max >> 4;
+            max |= max >> 8;
+            max |= max >> 16;
+            max |= max >> 32;
+            return (max >> 1) + 1;
+        }
+    };
+
+    template <int digits, int radix>
+    struct pick_policy_impl {
+        typedef prime_policy<std::size_t> type;
+    };
+
+    template <>
+    struct pick_policy_impl<64, 2> {
+        typedef mix64_policy<std::size_t> type;
+    };
+
+    struct pick_policy :
+        pick_policy_impl<
+            std::numeric_limits<std::size_t>::digits,
+            std::numeric_limits<std::size_t>::radix> {};
 
     ///////////////////////////////////////////////////////////////////
     //
     // Buckets
 
-    template <typename A, typename Bucket, typename Node>
-    struct buckets
+    template <typename A, typename Bucket, typename Node, typename Policy>
+    struct buckets : Policy
     {
     private:
         buckets(buckets const&);
@@ -193,6 +549,7 @@
         typedef boost::unordered::detail::allocator_traits<A> traits;
         typedef typename traits::value_type value_type;
 
+        typedef Policy policy;
         typedef Node node;
         typedef Bucket bucket;
         typedef typename boost::unordered::detail::rebind_wrap<A, node>::type
@@ -214,6 +571,16 @@
         typedef boost::unordered::detail::node_constructor<node_allocator>
             node_constructor;
 
+        typedef boost::unordered::iterator_detail::
+            iterator<node_pointer, value_type> iterator;
+        typedef boost::unordered::iterator_detail::
+            c_iterator<const_node_pointer, node_pointer, value_type> c_iterator;
+        typedef boost::unordered::iterator_detail::
+            l_iterator<node_pointer, value_type, policy> l_iterator;
+        typedef boost::unordered::iterator_detail::
+            cl_iterator<const_node_pointer, node_pointer, value_type, policy>
+            cl_iterator;
+
         // Members
 
         bucket_pointer buckets_;
@@ -247,7 +614,7 @@
         std::size_t max_bucket_count() const
         {
             // -1 to account for the start bucket.
-            return boost::unordered::detail::prev_prime(
+            return policy::prev_bucket_count(
                 bucket_allocator_traits::max_size(bucket_alloc()) - 1);
         }
 
@@ -266,16 +633,17 @@
             return this->get_bucket(bucket_index)->next_;
         }
 
-        node_pointer get_start() const
+        iterator get_start() const
         {
-            return static_cast<node_pointer>(this->get_previous_start()->next_);
+            return iterator(static_cast<node_pointer>(
+                        this->get_previous_start()->next_));
         }
 
-        node_pointer get_start(std::size_t bucket_index) const
+        iterator get_start(std::size_t bucket_index) const
         {
             previous_pointer prev = this->get_previous_start(bucket_index);
-            return prev ? static_cast<node_pointer>(prev->next_) :
-                node_pointer();
+            return prev ? iterator(static_cast<node_pointer>(prev->next_)) :
+                iterator();
         }
 
         float load_factor() const
@@ -288,14 +656,15 @@
         std::size_t bucket_size(std::size_t index) const
         {
             if (!this->size_) return 0;
-            node_pointer ptr = this->get_start(index);
-            if (!ptr) return 0;
+            iterator it = this->get_start(index);
+            if (!it.node_) return 0;
 
             std::size_t count = 0;
-            while(ptr && ptr->hash_ % this->bucket_count_ == index)
+            while(it.node_ && policy::to_bucket(
+                        this->bucket_count_, it.node_->hash_) == index)
             {
                 ++count;
-                ptr = static_cast<node_pointer>(ptr->next_);
+                ++it;
             }
 
             return count;
@@ -391,21 +760,22 @@
         ////////////////////////////////////////////////////////////////////////
         // Delete/destruct
 
-        inline void delete_node(node_pointer n)
+        inline void delete_node(c_iterator n)
         {
-            boost::unordered::detail::destroy(n->value_ptr());
-            node_allocator_traits::destroy(node_alloc(), boost::addressof(*n));
-            node_allocator_traits::deallocate(node_alloc(), n, 1);
+            boost::unordered::detail::destroy(n.node_->value_ptr());
+            node_allocator_traits::destroy(node_alloc(),
+                    boost::addressof(*n.node_));
+            node_allocator_traits::deallocate(node_alloc(), n.node_, 1);
             --size_;
         }
 
-        std::size_t delete_nodes(node_pointer begin, node_pointer end)
+        std::size_t delete_nodes(c_iterator begin, c_iterator end)
         {
             std::size_t count = 0;
 
             while(begin != end) {
-                node_pointer n = begin;
-                begin = static_cast<node_pointer>(begin->next_);
+                c_iterator n = begin;
+                ++begin;
                 delete_node(n);
                 ++count;
             }
@@ -433,7 +803,7 @@
                 while(prev->next_) {
                     node_pointer n = static_cast<node_pointer>(prev->next_);
                     prev->next_ = n->next_;
-                    delete_node(n);
+                    delete_node(iterator(n));
                 }
 
                 delete_extra_node(prev);
@@ -463,7 +833,7 @@
             while(prev->next_) {
                 node_pointer n = static_cast<node_pointer>(prev->next_);
                 prev->next_ = n->next_;
-                delete_node(n);
+                delete_node(iterator(n));
             }
 
             bucket_pointer end = this->get_bucket(this->bucket_count_);
@@ -487,7 +857,7 @@
             else
             {
                 bucket_pointer next_bucket = this->get_bucket(
-                    next->hash_ % this->bucket_count_);
+                    policy::to_bucket(this->bucket_count_, next->hash_));
 
                 if (next_bucket != bucket)
                 {
@@ -513,7 +883,7 @@
                     if (n == end) return;
     
                     std::size_t new_bucket_index =
-                        n->hash_ % this->bucket_count_;
+                        policy::to_bucket(this->bucket_count_, n->hash_);
                     if (bucket_index != new_bucket_index) {
                         bucket_index = new_bucket_index;
                         break;
@@ -529,7 +899,7 @@
                 if (n == end) break;
     
                 std::size_t new_bucket_index =
-                    n->hash_ % this->bucket_count_;
+                    policy::to_bucket(this->bucket_count_, n->hash_);
                 if (bucket_index != new_bucket_index) {
                     bucket_index = new_bucket_index;
                     this->get_bucket(bucket_index)->next_ = previous_pointer();
@@ -538,7 +908,8 @@
     
             // Finally fix the bucket containing the trailing node.
             if (n) {
-                this->get_bucket(n->hash_ % this->bucket_count_)->next_
+                this->get_bucket(
+                    policy::to_bucket(this->bucket_count_, n->hash_))->next_
                     = prev;
             }
         }
Modified: branches/release/boost/unordered/detail/emplace_args.hpp
==============================================================================
--- branches/release/boost/unordered/detail/emplace_args.hpp	(original)
+++ branches/release/boost/unordered/detail/emplace_args.hpp	2012-05-03 18:05:21 EDT (Thu, 03 May 2012)
@@ -160,9 +160,9 @@
     //
     // Used for piecewise construction.
 
-#if !BOOST_WORKAROUND(__SUNPRO_CC, <= 0x590)
+#if !defined(__SUNPRO_CC)
 
-#define BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(n, namespace_)                 \
+#   define BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(n, namespace_)              \
     template<typename T>                                                    \
     void construct_from_tuple(T* ptr, namespace_::tuple<>)                  \
     {                                                                       \
@@ -172,7 +172,7 @@
     BOOST_PP_REPEAT_FROM_TO(1, n,                                           \
         BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE_IMPL, namespace_)
 
-#define BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE_IMPL(z, n, namespace_)         \
+#   define BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE_IMPL(z, n, namespace_)      \
     template<typename T, BOOST_PP_ENUM_PARAMS_Z(z, n, typename A)>          \
     void construct_from_tuple(T* ptr,                                       \
             namespace_::tuple<BOOST_PP_ENUM_PARAMS_Z(z, n, A)> const& x)    \
@@ -182,32 +182,26 @@
         );                                                                  \
     }
 
-#define BOOST_UNORDERED_GET_TUPLE_ARG(z, n, namespace_)                     \
+#   define BOOST_UNORDERED_GET_TUPLE_ARG(z, n, namespace_)                  \
     namespace_::get<n>(x)
 
-BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(10, boost)
-
-#if !defined(BOOST_NO_0X_HDR_TUPLE)
-BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(10, std)
-#endif
-
-#undef BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE
-#undef BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE_IMPL
-#undef BOOST_UNORDERED_GET_TUPLE_ARG
-
 #else
 
     template <int N> struct length {};
 
-    template<typename T>
-    void construct_from_tuple_impl(
-            boost::unordered::detail::length<0>, T* ptr,
-            boost::tuple<>)
-    {
-        new ((void*) ptr) T();
-    }
+#   define BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(n, namespace_)              \
+    template<typename T>                                                    \
+    void construct_from_tuple_impl(                                         \
+            boost::unordered::detail::length<0>, T* ptr,                    \
+            namespace_::tuple<>)                                            \
+    {                                                                       \
+        new ((void*) ptr) T();                                              \
+    }                                                                       \
+                                                                            \
+    BOOST_PP_REPEAT_FROM_TO(1, n,                                           \
+        BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE_IMPL, namespace_)
 
-#define BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE_IMPL(z, n, _)                  \
+#   define BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE_IMPL(z, n, namespace_)      \
     template<typename T, BOOST_PP_ENUM_PARAMS_Z(z, n, typename A)>          \
     void construct_from_tuple_impl(                                         \
             boost::unordered::detail::length<n>, T* ptr,                    \
@@ -218,11 +212,22 @@
         );                                                                  \
     }
 
-#define BOOST_UNORDERED_GET_TUPLE_ARG(z, n, _)                              \
-    boost::get<n>(x)
+#   define BOOST_UNORDERED_GET_TUPLE_ARG(z, n, namespace_)                  \
+    namespace_::get<n>(x)
+
+#endif
+
+BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(10, boost)
+
+#if !defined(__SUNPRO_CC) && !defined(BOOST_NO_0X_HDR_TUPLE)
+   BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(10, std)
+#endif
+
+#undef BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE
+#undef BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE_IMPL
+#undef BOOST_UNORDERED_GET_TUPLE_ARG
 
-    BOOST_PP_REPEAT_FROM_TO(1, 10,                                          \
-        BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE_IMPL, _)
+#if defined(__SUNPRO_CC)
 
     template <typename T, typename Tuple>
     void construct_from_tuple(T* ptr, Tuple const& x)
@@ -233,9 +238,6 @@
             ptr, x);
     }
 
-#undef BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE_IMPL
-#undef BOOST_UNORDERED_GET_TUPLE_ARG
-
 #endif
 
     ////////////////////////////////////////////////////////////////////////////
Modified: branches/release/boost/unordered/detail/equivalent.hpp
==============================================================================
--- branches/release/boost/unordered/detail/equivalent.hpp	(original)
+++ branches/release/boost/unordered/detail/equivalent.hpp	2012-05-03 18:05:21 EDT (Thu, 03 May 2012)
@@ -136,6 +136,8 @@
 
         typedef boost::unordered::detail::grouped_table_impl<types> table;
         typedef boost::unordered::detail::set_extractor<value_type> extractor;
+
+        typedef boost::unordered::detail::pick_policy::type policy;
     };
 
     template <typename A, typename K, typename M, typename H, typename P>
@@ -160,6 +162,8 @@
         typedef boost::unordered::detail::grouped_table_impl<types> table;
         typedef boost::unordered::detail::map_extractor<key_type, value_type>
             extractor;
+
+        typedef boost::unordered::detail::pick_policy::type policy;
     };
 
     template <typename Types>
@@ -169,6 +173,7 @@
         typedef typename table::value_type value_type;
         typedef typename table::bucket bucket;
         typedef typename table::buckets buckets;
+        typedef typename table::policy policy;
         typedef typename table::node_pointer node_pointer;
         typedef typename table::node_allocator node_allocator;
         typedef typename table::node_allocator_traits node_allocator_traits;
@@ -181,6 +186,7 @@
         typedef typename table::node_constructor node_constructor;
         typedef typename table::extractor extractor;
         typedef typename table::iterator iterator;
+        typedef typename table::c_iterator c_iterator;
 
         // Constructors
 
@@ -214,46 +220,48 @@
         // Accessors
 
         template <class Key, class Pred>
-        node_pointer find_node_impl(
+        iterator find_node_impl(
                 std::size_t hash,
                 Key const& k,
                 Pred const& eq) const
         {
-            std::size_t bucket_index = hash % this->bucket_count_;
-            node_pointer n = this->get_start(bucket_index);
+            std::size_t bucket_index =
+                policy::to_bucket(this->bucket_count_, hash);
+            iterator n = this->get_start(bucket_index);
 
             for (;;)
             {
-                if (!n) return n;
+                if (!n.node_) return n;
 
-                std::size_t node_hash = n->hash_;
+                std::size_t node_hash = n.node_->hash_;
                 if (hash == node_hash)
                 {
-                    if (eq(k, this->get_key(n->value())))
+                    if (eq(k, this->get_key(*n)))
                         return n;
                 }
                 else
                 {
-                    if (node_hash % this->bucket_count_ != bucket_index)
-                        return node_pointer();
+                    if (policy::to_bucket(this->bucket_count_, node_hash)
+                            != bucket_index)
+                        return iterator();
                 }
 
-                n = static_cast<node_pointer>(
-                    static_cast<node_pointer>(n->group_prev_)->next_);
+                n = iterator(static_cast<node_pointer>(
+                    static_cast<node_pointer>(n.node_->group_prev_)->next_));
             }
         }
 
         std::size_t count(key_type const& k) const
         {
-            node_pointer n = this->find_node(k);
-            if (!n) return 0;
+            iterator n = this->find_node(k);
+            if (!n.node_) return 0;
 
             std::size_t count = 0;
-            node_pointer it = n;
+            node_pointer it = n.node_;
             do {
                 it = static_cast<node_pointer>(it->group_prev_);
                 ++count;
-            } while(it != n);
+            } while(it != n.node_);
 
             return count;
         }
@@ -261,12 +269,12 @@
         std::pair<iterator, iterator>
             equal_range(key_type const& k) const
         {
-            node_pointer n = this->find_node(k);
+            iterator n = this->find_node(k);
             return std::make_pair(
-                iterator(n), iterator(n ?
+                n, n.node_ ? iterator(
                     static_cast<node_pointer>(
-                        static_cast<node_pointer>(n->group_prev_)->next_) :
-                    n));
+                        static_cast<node_pointer>(n.node_->group_prev_)->next_
+                    )) : n);
         }
 
         // Equality
@@ -276,14 +284,14 @@
             if(this->size_ != other.size_) return false;
             if(!this->size_) return true;
     
-            for(node_pointer n1 = this->get_start(); n1;)
+            for(iterator n1 = this->get_start(); n1.node_;)
             {
-                node_pointer n2 = other.find_matching_node(n1);
-                if (!n2) return false;
-                node_pointer end1 = static_cast<node_pointer>(
-                    static_cast<node_pointer>(n1->group_prev_)->next_);
-                node_pointer end2 = static_cast<node_pointer>(
-                    static_cast<node_pointer>(n2->group_prev_)->next_);
+                iterator n2 = other.find_matching_node(n1);
+                if (!n2.node_) return false;
+                iterator end1(static_cast<node_pointer>(
+                    static_cast<node_pointer>(n1.node_->group_prev_)->next_));
+                iterator end2(static_cast<node_pointer>(
+                    static_cast<node_pointer>(n2.node_->group_prev_)->next_));
                 if (!group_equals(n1, end1, n2, end2)) return false;
                 n1 = end1;    
             }
@@ -293,25 +301,24 @@
 
 #if !defined(BOOST_UNORDERED_DEPRECATED_EQUALITY)
 
-        static bool group_equals(node_pointer n1, node_pointer end1,
-                node_pointer n2, node_pointer end2)
+        static bool group_equals(iterator n1, iterator end1,
+                iterator n2, iterator end2)
         {
             for(;;)
             {
-                if (n1->value() != n2->value())
-                    break;
+                if (*n1 != *n2) break;
 
-                n1 = static_cast<node_pointer>(n1->next_);
-                n2 = static_cast<node_pointer>(n2->next_);
+                ++n1;
+                ++n2;
             
                 if (n1 == end1) return n2 == end2;
                 if (n2 == end2) return false;
             }
             
-            for(node_pointer n1a = n1, n2a = n2;;)
+            for(iterator n1a = n1, n2a = n2;;)
             {
-                n1a = static_cast<node_pointer>(n1a->next_);
-                n2a = static_cast<node_pointer>(n2a->next_);
+                ++n1a;
+                ++n2a;
 
                 if (n1a == end1)
                 {
@@ -322,50 +329,50 @@
                 if (n2a == end2) return false;
             }
 
-            node_pointer start = n1;
-            for(;n1 != end2; n1 = static_cast<node_pointer>(n1->next_))
+            iterator start = n1;
+            for(;n1 != end1; ++n1)
             {
-                value_type const& v = n1->value();
+                value_type const& v = *n1;
                 if (find(start, n1, v)) continue;
                 std::size_t matches = count_equal(n2, end2, v);
-                if (!matches || matches != 1 + count_equal(
-                        static_cast<node_pointer>(n1->next_), end1, v))
-                    return false;
+                if (!matches) return false;
+                iterator next = n1;
+                ++next;
+                if (matches != 1 + count_equal(next, end1, v)) return false;
             }
             
             return true;
         }
 
-        static bool find(node_pointer n, node_pointer end, value_type const& v)
+        static bool find(iterator n, iterator end, value_type const& v)
         {
-            for(;n != end; n = static_cast<node_pointer>(n->next_))
-                if (n->value() == v)
+            for(;n != end; ++n)
+                if (*n == v)
                     return true;
             return false;
         }
 
-        static std::size_t count_equal(node_pointer n, node_pointer end,
+        static std::size_t count_equal(iterator n, iterator end,
             value_type const& v)
         {
             std::size_t count = 0;
-            for(;n != end; n = static_cast<node_pointer>(n->next_))
-                if (n->value() == v) ++count;
+            for(;n != end; ++n)
+                if (*n == v) ++count;
             return count;
         }
 
 #else
 
-        static bool group_equals(node_pointer n1, node_pointer end1,
-                node_pointer n2, node_pointer end2)
+        static bool group_equals(iterator n1, iterator end1,
+                iterator n2, iterator end2)
         {
             for(;;)
             {
-                if(!extractor::compare_mapped(
-                    n1->value(), n2->value()))
+                if(!extractor::compare_mapped(*n1, *n2))
                     return false;
 
-                n1 = static_cast<node_pointer>(n1->next_);
-                n2 = static_cast<node_pointer>(n2->next_);
+                ++n1;
+                ++n2;
 
                 if (n1 == end1) return n2 == end2;
                 if (n2 == end2) return false;
@@ -387,35 +394,37 @@
             pos->group_prev_ = static_cast<link_pointer>(n);
         }
 
-        inline node_pointer add_node(
+        inline iterator add_node(
                 node_constructor& a,
                 std::size_t hash,
-                node_pointer pos)
+                iterator pos)
         {
             node_pointer n = a.release();
             n->hash_ = hash;
-            if(pos) {
-                this->add_after_node(n, pos);
+            if (pos.node_) {
+                this->add_after_node(n, pos.node_);
                 if (n->next_) {
-                    std::size_t next_bucket =
-                        static_cast<node_pointer>(n->next_)->hash_ %
-                        this->bucket_count_;
-                    if (next_bucket != hash % this->bucket_count_) {
+                    std::size_t next_bucket = policy::to_bucket(
+                        this->bucket_count_,
+                        static_cast<node_pointer>(n->next_)->hash_);
+                    if (next_bucket !=
+                            policy::to_bucket(this->bucket_count_, hash)) {
                         this->get_bucket(next_bucket)->next_ = n;
                     }
                 }
             }
             else {
-                bucket_pointer b = this->get_bucket(hash % this->bucket_count_);
+                bucket_pointer b = this->get_bucket(
+                    policy::to_bucket(this->bucket_count_, hash));
 
                 if (!b->next_)
                 {
                     previous_pointer start_node = this->get_previous_start();
                     
                     if (start_node->next_) {
-                        this->get_bucket(
+                        this->get_bucket(policy::to_bucket(this->bucket_count_,
                             static_cast<node_pointer>(start_node->next_)->hash_
-                                % this->bucket_count_)->next_ = n;
+                        ))->next_ = n;
                     }
     
                     b->next_ = start_node;
@@ -429,14 +438,14 @@
                 }
             }
             ++this->size_;
-            return n;
+            return iterator(n);
         }
 
-        node_pointer emplace_impl(node_constructor& a)
+        iterator emplace_impl(node_constructor& a)
         {
             key_type const& k = this->get_key(a.value());
-            std::size_t hash = this->hash_function()(k);
-            node_pointer position = this->find_node(hash, k);
+            std::size_t hash = this->hash(k);
+            iterator position = this->find_node(hash, k);
 
             // reserve has basic exception safety if the hash function
             // throws, strong otherwise.
@@ -447,9 +456,8 @@
         void emplace_impl_no_rehash(node_constructor& a)
         {
             key_type const& k = this->get_key(a.value());
-            std::size_t hash = this->hash_function()(k);
-            this->add_node(a, hash,
-                this->find_node(hash, k));
+            std::size_t hash = this->hash(k);
+            this->add_node(a, hash, this->find_node(hash, k));
         }
 
 #if defined(BOOST_NO_RVALUE_REFERENCES)
@@ -523,8 +531,9 @@
         {
             if(!this->size_) return 0;
 
-            std::size_t hash = this->hash_function()(k);
-            std::size_t bucket_index = hash % this->bucket_count_;
+            std::size_t hash = this->hash(k);
+            std::size_t bucket_index =
+                policy::to_bucket(this->bucket_count_, hash);
             bucket_pointer bucket = this->get_bucket(bucket_index);
 
             previous_pointer prev = bucket->next_;
@@ -535,7 +544,8 @@
                 if (!prev->next_) return 0;
                 std::size_t node_hash =
                     static_cast<node_pointer>(prev->next_)->hash_;
-                if (node_hash % this->bucket_count_ != bucket_index)
+                if (policy::to_bucket(this->bucket_count_, node_hash)
+                        != bucket_index)
                     return 0;
                 if (node_hash == hash &&
                     this->key_eq()(k, this->get_key(
@@ -551,36 +561,38 @@
             node_pointer end = static_cast<node_pointer>(end1);
             prev->next_ = end1;
             this->fix_buckets(bucket, prev, end);
-            return this->delete_nodes(pos, end);
+            return this->delete_nodes(c_iterator(pos), c_iterator(end));
         }
 
-        node_pointer erase(node_pointer r)
+        iterator erase(c_iterator r)
         {
-            BOOST_ASSERT(r);
-            node_pointer next = static_cast<node_pointer>(r->next_);
+            BOOST_ASSERT(r.node_);
+            iterator next(r.node_);
+            ++next;
 
             bucket_pointer bucket = this->get_bucket(
-                r->hash_ % this->bucket_count_);
-            previous_pointer prev = unlink_node(*bucket, r);
+                policy::to_bucket(this->bucket_count_, r.node_->hash_));
+            previous_pointer prev = unlink_node(*bucket, r.node_);
 
-            this->fix_buckets(bucket, prev, next);
+            this->fix_buckets(bucket, prev, next.node_);
 
             this->delete_node(r);
 
             return next;
         }
 
-        node_pointer erase_range(node_pointer r1, node_pointer r2)
+        iterator erase_range(c_iterator r1, c_iterator r2)
         {
-            if (r1 == r2) return r2;
+            if (r1 == r2) return iterator(r2.node_);
 
-            std::size_t bucket_index = r1->hash_ % this->bucket_count_;
+            std::size_t bucket_index =
+                policy::to_bucket(this->bucket_count_, r1.node_->hash_);
             previous_pointer prev = unlink_nodes(
-                *this->get_bucket(bucket_index), r1, r2);
-            this->fix_buckets_range(bucket_index, prev, r1, r2);
+                *this->get_bucket(bucket_index), r1.node_, r2.node_);
+            this->fix_buckets_range(bucket_index, prev, r1.node_, r2.node_);
             this->delete_nodes(r1, r2);
 
-            return r2;
+            return iterator(r2.node_);
         }
 
         static previous_pointer unlink_node(bucket& b, node_pointer n)
@@ -697,17 +709,18 @@
 
             node_constructor a(dst.node_alloc());
 
-            node_pointer n = src.get_start();
+            iterator n = src.get_start();
             previous_pointer prev = dst.get_previous_start();
 
-            while(n) {
-                std::size_t hash = n->hash_;
-                node_pointer group_end =
+            while (n.node_) {
+                std::size_t hash = n.node_->hash_;
+                iterator group_end(
                     static_cast<node_pointer>(
-                        static_cast<node_pointer>(n->group_prev_)->next_);
+                        static_cast<node_pointer>(n.node_->group_prev_)->next_
+                    ));
 
                 a.construct_node();
-                a.construct_value2(n->value());
+                a.construct_value2(*n);
 
                 node_pointer first_node = a.release();
                 node_pointer end = first_node;
@@ -715,11 +728,10 @@
                 prev->next_ = static_cast<link_pointer>(first_node);
                 ++dst.size_;
 
-                for(n = static_cast<node_pointer>(n->next_); n != group_end;
-                        n = static_cast<node_pointer>(n->next_))
+                for (++n; n != group_end; ++n)
                 {
                     a.construct_node();
-                    a.construct_value2(n->value());
+                    a.construct_value2(*n);
                     end = a.release();
                     end->hash_ = hash;
                     add_after_node(end, first_node);
@@ -744,17 +756,18 @@
 
             node_constructor a(dst.node_alloc());
 
-            node_pointer n = src.get_start();
+            iterator n = src.get_start();
             previous_pointer prev = dst.get_previous_start();
 
-            while(n) {
-                std::size_t hash = n->hash_;
-                node_pointer group_end =
+            while (n.node_) {
+                std::size_t hash = n.node_->hash_;
+                iterator group_end(
                     static_cast<node_pointer>(
-                        static_cast<node_pointer>(n->group_prev_)->next_);
+                        static_cast<node_pointer>(n.node_->group_prev_)->next_
+                    ));
 
                 a.construct_node();
-                a.construct_value2(boost::move(n->value()));
+                a.construct_value2(boost::move(*n));
 
                 node_pointer first_node = a.release();
                 node_pointer end = first_node;
@@ -762,11 +775,10 @@
                 prev->next_ = static_cast<link_pointer>(first_node);
                 ++dst.size_;
 
-                for(n = static_cast<node_pointer>(n->next_); n != group_end;
-                        n = static_cast<node_pointer>(n->next_))
+                for(++n; n != group_end; ++n)
                 {
                     a.construct_node();
-                    a.construct_value2(boost::move(n->value()));
+                    a.construct_value2(boost::move(*n));
                     end = a.release();
                     end->hash_ = hash;
                     add_after_node(end, first_node);
@@ -809,7 +821,8 @@
         static previous_pointer place_in_bucket(buckets& dst,
                 previous_pointer prev, node_pointer end)
         {
-            bucket_pointer b = dst.get_bucket(end->hash_ % dst.bucket_count_);
+            bucket_pointer b = dst.get_bucket(policy::to_bucket(
+                        dst.bucket_count_, end->hash_));
 
             if (!b->next_) {
                 b->next_ = static_cast<node_pointer>(prev);
Modified: branches/release/boost/unordered/detail/fwd.hpp
==============================================================================
--- branches/release/boost/unordered/detail/fwd.hpp	(original)
+++ branches/release/boost/unordered/detail/fwd.hpp	2012-05-03 18:05:21 EDT (Thu, 03 May 2012)
@@ -10,41 +10,11 @@
 # pragma once
 #endif
 
-#include <boost/config.hpp>
-#include <memory>
-#include <functional>
-#include <boost/functional/hash_fwd.hpp>
 
 namespace boost
 {
 namespace unordered
 {
-    template <class K,
-        class T,
-        class H = boost::hash<K>,
-        class P = std::equal_to<K>,
-        class A = std::allocator<std::pair<const K, T> > >
-    class unordered_map;
-
-    template <class K,
-        class T,
-        class H = boost::hash<K>,
-        class P = std::equal_to<K>,
-        class A = std::allocator<std::pair<const K, T> > >
-    class unordered_multimap;
-
-    template <class T,
-        class H = boost::hash<T>,
-        class P = std::equal_to<T>,
-        class A = std::allocator<T> >
-    class unordered_set;
-
-    template <class T,
-        class H = boost::hash<T>,
-        class P = std::equal_to<T>,
-        class A = std::allocator<T> >
-    class unordered_multiset;
-
     struct piecewise_construct_t {};
     const piecewise_construct_t piecewise_construct = piecewise_construct_t();
 }
Modified: branches/release/boost/unordered/detail/table.hpp
==============================================================================
--- branches/release/boost/unordered/detail/table.hpp	(original)
+++ branches/release/boost/unordered/detail/table.hpp	2012-05-03 18:05:21 EDT (Thu, 03 May 2012)
@@ -11,251 +11,8 @@
 #include <boost/unordered/detail/util.hpp>
 #include <boost/type_traits/aligned_storage.hpp>
 #include <boost/type_traits/alignment_of.hpp>
-#include <boost/iterator.hpp>
 #include <cmath>
 
-namespace boost { namespace unordered { namespace iterator_detail {
-
-    ////////////////////////////////////////////////////////////////////////////
-    // Iterators
-    //
-    // all no throw
-
-    template <typename NodePointer, typename Value> struct iterator;
-    template <typename ConstNodePointer, typename NodePointer,
-        typename Value> struct c_iterator;
-    template <typename NodePointer, typename Value> struct l_iterator;
-    template <typename ConstNodePointer, typename NodePointer,
-        typename Value> struct cl_iterator;
-
-    // Local Iterators
-    //
-    // all no throw
-
-    template <typename NodePointer, typename Value>
-    struct l_iterator
-        : public boost::iterator<
-            std::forward_iterator_tag, Value, std::ptrdiff_t,
-            NodePointer, Value&>
-    {
-#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
-        template <typename ConstNodePointer, typename NodePointer2,
-                typename Value2>
-        friend struct boost::unordered::iterator_detail::cl_iterator;
-    private:
-#endif
-        typedef NodePointer node_pointer;
-        node_pointer ptr_;
-        std::size_t bucket_;
-        std::size_t bucket_count_;
-
-    public:
-
-        l_iterator() : ptr_() {}
-
-        l_iterator(node_pointer x, std::size_t b, std::size_t c)
-            : ptr_(x), bucket_(b), bucket_count_(c) {}
-
-        Value& operator*() const {
-            return ptr_->value();
-        }
-
-        Value* operator->() const {
-            return ptr_->value_ptr();
-        }
-
-        l_iterator& operator++() {
-            ptr_ = static_cast<node_pointer>(ptr_->next_);
-            if (ptr_ && ptr_->hash_ % bucket_count_ != bucket_)
-                ptr_ = node_pointer();
-            return *this;
-        }
-
-        l_iterator operator++(int) {
-            l_iterator tmp(*this);
-            ++(*this);
-            return tmp;
-        }
-
-        bool operator==(l_iterator x) const {
-            return ptr_ == x.ptr_;
-        }
-
-        bool operator!=(l_iterator x) const {
-            return ptr_ != x.ptr_;
-        }
-    };
-
-    template <typename ConstNodePointer, typename NodePointer, typename Value>
-    struct cl_iterator
-        : public boost::iterator<
-            std::forward_iterator_tag, Value, std::ptrdiff_t,
-            ConstNodePointer, Value const&>
-    {
-        friend struct boost::unordered::iterator_detail::l_iterator
-            <NodePointer, Value>;
-    private:
-
-        typedef NodePointer node_pointer;
-        node_pointer ptr_;
-        std::size_t bucket_;
-        std::size_t bucket_count_;
-
-    public:
-
-        cl_iterator() : ptr_() {}
-
-        cl_iterator(node_pointer x, std::size_t b, std::size_t c) :
-            ptr_(x), bucket_(b), bucket_count_(c) {}
-
-        cl_iterator(boost::unordered::iterator_detail::l_iterator<
-                NodePointer, Value> const& x) :
-            ptr_(x.ptr_), bucket_(x.bucket_), bucket_count_(x.bucket_count_)
-        {}
-
-        Value const&
-            operator*() const {
-            return ptr_->value();
-        }
-
-        Value const* operator->() const {
-            return ptr_->value_ptr();
-        }
-
-        cl_iterator& operator++() {
-            ptr_ = static_cast<node_pointer>(ptr_->next_);
-            if (ptr_ && ptr_->hash_ % bucket_count_ != bucket_)
-                ptr_ = node_pointer();
-            return *this;
-        }
-
-        cl_iterator operator++(int) {
-            cl_iterator tmp(*this);
-            ++(*this);
-            return tmp;
-        }
-
-        friend bool operator==(cl_iterator const& x, cl_iterator const& y) {
-            return x.ptr_ == y.ptr_;
-        }
-
-        friend bool operator!=(cl_iterator const& x, cl_iterator const& y) {
-            return x.ptr_ != y.ptr_;
-        }
-    };
-
-    template <typename NodePointer, typename Value>
-    struct iterator
-        : public boost::iterator<
-            std::forward_iterator_tag, Value, std::ptrdiff_t,
-            NodePointer, Value&>
-    {
-#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
-        template <typename ConstNodePointer, typename NodePointer2,
-                typename Value2>
-        friend struct boost::unordered::iterator_detail::c_iterator;
-    private:
-#endif
-        typedef NodePointer node_pointer;
-        node_pointer node_;
-
-    public:
-
-        iterator() : node_() {}
-
-        explicit iterator(node_pointer const& x) : node_(x) {}
-
-        Value& operator*() const {
-            return node_->value();
-        }
-
-        Value* operator->() const {
-            return &node_->value();
-        }
-
-        iterator& operator++() {
-            node_ = static_cast<node_pointer>(node_->next_);
-            return *this;
-        }
-
-        iterator operator++(int) {
-            iterator tmp(node_);
-            node_ = static_cast<node_pointer>(node_->next_);
-            return tmp;
-        }
-
-        bool operator==(iterator const& x) const {
-            return node_ == x.node_;
-        }
-
-        bool operator!=(iterator const& x) const {
-            return node_ != x.node_;
-        }
-    };
-
-    template <typename ConstNodePointer, typename NodePointer, typename Value>
-    struct c_iterator
-        : public boost::iterator<
-            std::forward_iterator_tag, Value, std::ptrdiff_t,
-            ConstNodePointer, Value const&>
-    {
-        friend struct boost::unordered::iterator_detail::iterator<
-                NodePointer, Value>;
-
-#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
-        template <typename K, typename T, typename H, typename P, typename A>
-        friend class boost::unordered::unordered_map;
-        template <typename K, typename T, typename H, typename P, typename A>
-        friend class boost::unordered::unordered_multimap;
-        template <typename T, typename H, typename P, typename A>
-        friend class boost::unordered::unordered_set;
-        template <typename T, typename H, typename P, typename A>
-        friend class boost::unordered::unordered_multiset;
-
-    private:
-#endif
-
-        typedef NodePointer node_pointer;
-        node_pointer node_;
-
-    public:
-
-        c_iterator() : node_() {}
-
-        explicit c_iterator(node_pointer const& x) : node_(x) {}
-
-        c_iterator(boost::unordered::iterator_detail::iterator<
-                NodePointer, Value> const& x) : node_(x.node_) {}
-
-        Value const& operator*() const {
-            return node_->value();
-        }
-
-        Value const* operator->() const {
-            return &node_->value();
-        }
-
-        c_iterator& operator++() {
-            node_ = static_cast<node_pointer>(node_->next_);
-            return *this;
-        }
-
-        c_iterator operator++(int) {
-            c_iterator tmp(node_);
-            node_ = static_cast<node_pointer>(node_->next_);
-            return tmp;
-        }
-
-        friend bool operator==(c_iterator const& x, c_iterator const& y) {
-            return x.node_ == y.node_;
-        }
-
-        friend bool operator!=(c_iterator const& x, c_iterator const& y) {
-            return x.node_ != y.node_;
-        }
-    };
-}}}
-
 namespace boost { namespace unordered { namespace detail {
 
     ////////////////////////////////////////////////////////////////////////////
@@ -302,7 +59,8 @@
         boost::unordered::detail::buckets<
             typename Types::allocator,
             typename Types::bucket,
-            typename Types::node>,
+            typename Types::node,
+            typename Types::policy>,
         boost::unordered::detail::functions<
             typename Types::hasher,
             typename Types::key_equal>
@@ -318,6 +76,7 @@
         typedef typename Types::value_type value_type;
         typedef typename Types::table table_impl;
         typedef typename Types::link_pointer link_pointer;
+        typedef typename Types::policy policy;
 
         typedef boost::unordered::detail::functions<
             typename Types::hasher,
@@ -326,22 +85,15 @@
         typedef boost::unordered::detail::buckets<
             typename Types::allocator,
             typename Types::bucket,
-            typename Types::node> buckets;
+            typename Types::node,
+            typename Types::policy> buckets;
 
         typedef typename buckets::node_allocator node_allocator;
         typedef typename buckets::node_allocator_traits node_allocator_traits;
         typedef typename buckets::node_pointer node_pointer;
         typedef typename buckets::const_node_pointer const_node_pointer;
 
-        typedef boost::unordered::iterator_detail::
-            iterator<node_pointer, value_type> iterator;
-        typedef boost::unordered::iterator_detail::
-            c_iterator<const_node_pointer, node_pointer, value_type> c_iterator;
-        typedef boost::unordered::iterator_detail::
-            l_iterator<node_pointer, value_type> l_iterator;
-        typedef boost::unordered::iterator_detail::
-            cl_iterator<const_node_pointer, node_pointer, value_type>
-            cl_iterator;
+        typedef typename table::iterator iterator;
 
         // Members
 
@@ -384,7 +136,7 @@
 
         std::size_t min_buckets_for_size(std::size_t size) const
         {
-            BOOST_ASSERT(this->mlf_ != 0);
+            BOOST_ASSERT(this->mlf_ >= minimum_max_load_factor);
     
             using namespace std;
     
@@ -395,7 +147,7 @@
             // Or from rehash post-condition:
             // count > size / mlf_
 
-            return boost::unordered::detail::next_prime(
+            return policy::new_bucket_count(
                 boost::unordered::detail::double_to_size(floor(
                     static_cast<double>(size) /
                     static_cast<double>(mlf_))) + 1);
@@ -408,7 +160,7 @@
                 hasher const& hf,
                 key_equal const& eq,
                 node_allocator const& a) :
-            buckets(a, boost::unordered::detail::next_prime(num_buckets)),
+            buckets(a, policy::new_bucket_count(num_buckets)),
             functions(hf, eq),
             mlf_(1.0f),
             max_load_(0)
@@ -458,9 +210,9 @@
 
         // Iterators
 
-        node_pointer begin() const {
+        iterator begin() const {
             return !this->buckets_ ?
-                node_pointer() : this->get_start();
+                iterator() : this->get_start();
         }
 
         // Assignment
@@ -586,36 +338,41 @@
             return extractor::extract(x);
         }
 
+        std::size_t hash(key_type const& k) const
+        {
+            return policy::apply_hash(this->hash_function(), k);
+        }
+
         // Find Node
 
         template <typename Key, typename Hash, typename Pred>
-        node_pointer generic_find_node(
+        iterator generic_find_node(
                 Key const& k,
                 Hash const& hash_function,
                 Pred const& eq) const
         {
-            if (!this->size_) return node_pointer();
+            if (!this->size_) return iterator();
             return static_cast<table_impl const*>(this)->
-                find_node_impl(hash_function(k), k, eq);
+                find_node_impl(policy::apply_hash(hash_function, k), k, eq);
         }
 
-        node_pointer find_node(
+        iterator find_node(
                 std::size_t hash,
                 key_type const& k) const
         {
-            if (!this->size_) return node_pointer();
+            if (!this->size_) return iterator();
             return static_cast<table_impl const*>(this)->
                 find_node_impl(hash, k, this->key_eq());
         }
 
-        node_pointer find_node(key_type const& k) const
+        iterator find_node(key_type const& k) const
         {
-            if (!this->size_) return node_pointer();
+            if (!this->size_) return iterator();
             return static_cast<table_impl const*>(this)->
-                find_node_impl(this->hash_function()(k), k, this->key_eq());
+                find_node_impl(this->hash(k), k, this->key_eq());
         }
 
-        node_pointer find_matching_node(node_pointer n) const
+        iterator find_matching_node(iterator n) const
         {
             // TODO: Does this apply to C++11?
             //
@@ -623,7 +380,7 @@
             // when different hash functions are used. So I can't use the hash
             // value from the node here.
     
-            return find_node(get_key(n->value()));
+            return find_node(get_key(*n));
         }
 
         // Reserve and rehash
@@ -666,10 +423,10 @@
 
         if(!this->size_) {
             if(this->buckets_) this->delete_buckets();
-            this->bucket_count_ = next_prime(min_buckets);
+            this->bucket_count_ = policy::new_bucket_count(min_buckets);
         }
         else {
-            min_buckets = next_prime((std::max)(min_buckets,
+            min_buckets = policy::new_bucket_count((std::max)(min_buckets,
                 boost::unordered::detail::double_to_size(floor(
                     static_cast<double>(this->size_) /
                     static_cast<double>(mlf_))) + 1));
Modified: branches/release/boost/unordered/detail/unique.hpp
==============================================================================
--- branches/release/boost/unordered/detail/unique.hpp	(original)
+++ branches/release/boost/unordered/detail/unique.hpp	2012-05-03 18:05:21 EDT (Thu, 03 May 2012)
@@ -132,6 +132,8 @@
 
         typedef boost::unordered::detail::table_impl<types> table;
         typedef boost::unordered::detail::set_extractor<value_type> extractor;
+
+        typedef boost::unordered::detail::pick_policy::type policy;
     };
 
     template <typename A, typename K, typename M, typename H, typename P>
@@ -156,6 +158,8 @@
         typedef boost::unordered::detail::table_impl<types> table;
         typedef boost::unordered::detail::map_extractor<key_type, value_type>
             extractor;
+
+        typedef boost::unordered::detail::pick_policy::type policy;
     };
 
     template <typename Types>
@@ -165,6 +169,7 @@
         typedef typename table::value_type value_type;
         typedef typename table::bucket bucket;
         typedef typename table::buckets buckets;
+        typedef typename table::policy policy;
         typedef typename table::node_pointer node_pointer;
         typedef typename table::node_allocator node_allocator;
         typedef typename table::node_allocator_traits node_allocator_traits;
@@ -177,6 +182,7 @@
         typedef typename table::node_constructor node_constructor;
         typedef typename table::extractor extractor;
         typedef typename table::iterator iterator;
+        typedef typename table::c_iterator c_iterator;
 
         typedef std::pair<iterator, bool> emplace_return;
 
@@ -212,44 +218,46 @@
         // Accessors
 
         template <class Key, class Pred>
-        node_pointer find_node_impl(
+        iterator find_node_impl(
                 std::size_t hash,
                 Key const& k,
                 Pred const& eq) const
         {
-            std::size_t bucket_index = hash % this->bucket_count_;
-            node_pointer n = this->get_start(bucket_index);
+            std::size_t bucket_index =
+                policy::to_bucket(this->bucket_count_, hash);
+            iterator n = this->get_start(bucket_index);
 
             for (;;)
             {
-                if (!n) return n;
+                if (!n.node_) return n;
 
-                std::size_t node_hash = n->hash_;
+                std::size_t node_hash = n.node_->hash_;
                 if (hash == node_hash)
                 {
-                    if (eq(k, this->get_key(n->value())))
+                    if (eq(k, this->get_key(*n)))
                         return n;
                 }
                 else
                 {
-                    if (node_hash % this->bucket_count_ != bucket_index)
-                        return node_pointer();
+                    if (policy::to_bucket(this->bucket_count_, node_hash)
+                            != bucket_index)
+                        return iterator();
                 }
 
-                n = static_cast<node_pointer>(n->next_);
+                ++n;
             }
         }
 
         std::size_t count(key_type const& k) const
         {
-            return this->find_node(k) ? 1 : 0;
+            return this->find_node(k).node_ ? 1 : 0;
         }
 
         value_type& at(key_type const& k) const
         {
             if (this->size_) {
-                node_pointer it = this->find_node(k);
-                if (it) return it->value();
+                iterator it = this->find_node(k);
+                if (it.node_) return *it;
             }
 
             boost::throw_exception(
@@ -259,9 +267,10 @@
         std::pair<iterator, iterator>
             equal_range(key_type const& k) const
         {
-            node_pointer n = this->find_node(k);
-            return std::make_pair(iterator(n),
-                iterator(n ? static_cast<node_pointer>(n->next_) : n));
+            iterator n = this->find_node(k);
+            iterator n2 = n;
+            if (n2.node_) ++n2;
+            return std::make_pair(n, n2);
         }
 
         // equals
@@ -271,17 +280,15 @@
             if(this->size_ != other.size_) return false;
             if(!this->size_) return true;
     
-            for(node_pointer n1 = this->get_start(); n1;
-                n1 = static_cast<node_pointer>(n1->next_))
+            for(iterator n1 = this->get_start(); n1.node_; ++n1)
             {
-                node_pointer n2 = other.find_matching_node(n1);
+                iterator n2 = other.find_matching_node(n1);
 
 #if !defined(BOOST_UNORDERED_DEPRECATED_EQUALITY)
-                if(!n2 || n1->value() != n2->value())
+                if (!n2.node_ || *n1 != *n2)
                     return false;
 #else
-                if(!n2 || !extractor::compare_mapped(
-                        n1->value(), n2->value()))
+                if (!n2.node_ || !extractor::compare_mapped(*n1, *n2))
                     return false;
 #endif
             }
@@ -291,23 +298,24 @@
 
         // Emplace/Insert
 
-        inline node_pointer add_node(
+        inline iterator add_node(
                 node_constructor& a,
                 std::size_t hash)
         {
             node_pointer n = a.release();
             n->hash_ = hash;
     
-            bucket_pointer b = this->get_bucket(hash % this->bucket_count_);
+            bucket_pointer b = this->get_bucket(
+                policy::to_bucket(this->bucket_count_, hash));
 
             if (!b->next_)
             {
                 previous_pointer start_node = this->get_previous_start();
                 
                 if (start_node->next_) {
-                    this->get_bucket(
-                        static_cast<node_pointer>(start_node->next_)->hash_ %
-                            this->bucket_count_)->next_ = n;
+                    this->get_bucket(policy::to_bucket(this->bucket_count_,
+                        static_cast<node_pointer>(start_node->next_)->hash_)
+                    )->next_ = n;
                 }
 
                 b->next_ = start_node;
@@ -321,17 +329,17 @@
             }
 
             ++this->size_;
-            return n;
+            return iterator(n);
         }
 
         value_type& operator[](key_type const& k)
         {
             typedef typename value_type::second_type mapped_type;
     
-            std::size_t hash = this->hash_function()(k);
-            node_pointer pos = this->find_node(hash, k);
+            std::size_t hash = this->hash(k);
+            iterator pos = this->find_node(hash, k);
     
-            if (pos) return pos->value();
+            if (pos.node_) return *pos;
     
             // Create the node before rehashing in case it throws an
             // exception (need strong safety in such a case).
@@ -349,7 +357,7 @@
 #endif
     
             this->reserve_for_insert(this->size_ + 1);
-            return add_node(a, hash)->value();
+            return *add_node(a, hash);
         }
 
 #if defined(BOOST_NO_RVALUE_REFERENCES)
@@ -357,7 +365,7 @@
                 boost::unordered::detail::please_ignore_this_overload> const&)
         {
             BOOST_ASSERT(false);
-            return emplace_return(iterator(this->begin()), false);
+            return emplace_return(this->begin(), false);
         }
 #endif
 
@@ -389,10 +397,10 @@
         emplace_return emplace_impl(key_type const& k,
             BOOST_UNORDERED_EMPLACE_ARGS)
         {
-            std::size_t hash = this->hash_function()(k);
-            node_pointer pos = this->find_node(hash, k);
+            std::size_t hash = this->hash(k);
+            iterator pos = this->find_node(hash, k);
     
-            if (pos) return emplace_return(iterator(pos), false);
+            if (pos.node_) return emplace_return(pos, false);
     
             // Create the node before rehashing in case it throws an
             // exception (need strong safety in such a case).
@@ -403,21 +411,21 @@
             // reserve has basic exception safety if the hash function
             // throws, strong otherwise.
             this->reserve_for_insert(this->size_ + 1);
-            return emplace_return(iterator(this->add_node(a, hash)), true);
+            return emplace_return(this->add_node(a, hash), true);
         }
 
         emplace_return emplace_impl_with_node(node_constructor& a)
         {
             key_type const& k = this->get_key(a.value());
-            std::size_t hash = this->hash_function()(k);
-            node_pointer pos = this->find_node(hash, k);
+            std::size_t hash = this->hash(k);
+            iterator pos = this->find_node(hash, k);
 
-            if (pos) return emplace_return(iterator(pos), false);
+            if (pos.node_) return emplace_return(pos, false);
 
             // reserve has basic exception safety if the hash function
             // throws, strong otherwise.
             this->reserve_for_insert(this->size_ + 1);
-            return emplace_return(iterator(this->add_node(a, hash)), true);
+            return emplace_return(this->add_node(a, hash), true);
         }
 
         template <BOOST_UNORDERED_EMPLACE_TEMPLATE>
@@ -473,7 +481,7 @@
         void insert_range_empty(node_constructor& a, key_type const& k,
             InputIt i, InputIt j)
         {
-            std::size_t hash = this->hash_function()(k);
+            std::size_t hash = this->hash(k);
             a.construct_node();
             a.construct_value2(*i);
             this->reserve_for_insert(this->size_ +
@@ -486,10 +494,10 @@
             InputIt i, InputIt j)
         {
             // No side effects in this initial code
-            std::size_t hash = this->hash_function()(k);
-            node_pointer pos = this->find_node(hash, k);
+            std::size_t hash = this->hash(k);
+            iterator pos = this->find_node(hash, k);
     
-            if (!pos) {
+            if (!pos.node_) {
                 a.construct_node();
                 a.construct_value2(*i);
     
@@ -523,8 +531,9 @@
         {
             if(!this->size_) return 0;
 
-            std::size_t hash = this->hash_function()(k);
-            std::size_t bucket_index = hash % this->bucket_count_;
+            std::size_t hash = this->hash(k);
+            std::size_t bucket_index =
+                policy::to_bucket(this->bucket_count_, hash);
             bucket_pointer bucket = this->get_bucket(bucket_index);
 
             previous_pointer prev = bucket->next_;
@@ -535,7 +544,8 @@
                 if (!prev->next_) return 0;
                 std::size_t node_hash =
                     static_cast<node_pointer>(prev->next_)->hash_;
-                if (node_hash % this->bucket_count_ != bucket_index)
+                if (policy::to_bucket(this->bucket_count_, node_hash)
+                        != bucket_index)
                     return 0;
                 if (node_hash == hash &&
                         this->key_eq()(k, this->get_key(
@@ -548,36 +558,38 @@
             node_pointer end = static_cast<node_pointer>(pos->next_);
             prev->next_ = pos->next_;
             this->fix_buckets(bucket, prev, end);
-            return this->delete_nodes(pos, end);
+            return this->delete_nodes(c_iterator(pos), c_iterator(end));
         }
 
-        node_pointer erase(node_pointer r)
+        iterator erase(c_iterator r)
         {
-            BOOST_ASSERT(r);
-            node_pointer next = static_cast<node_pointer>(r->next_);
+            BOOST_ASSERT(r.node_);
+            iterator next(r.node_);
+            ++next;
 
             bucket_pointer bucket = this->get_bucket(
-                r->hash_ % this->bucket_count_);
-            previous_pointer prev = unlink_node(*bucket, r);
+                policy::to_bucket(this->bucket_count_, r.node_->hash_));
+            previous_pointer prev = unlink_node(*bucket, r.node_);
 
-            this->fix_buckets(bucket, prev, next);
+            this->fix_buckets(bucket, prev, next.node_);
 
             this->delete_node(r);
 
             return next;
         }
 
-        node_pointer erase_range(node_pointer r1, node_pointer r2)
+        iterator erase_range(c_iterator r1, c_iterator r2)
         {
-            if (r1 == r2) return r2;
+            if (r1 == r2) return iterator(r2.node_);
 
-            std::size_t bucket_index = r1->hash_ % this->bucket_count_;
+            std::size_t bucket_index =
+                policy::to_bucket(this->bucket_count_, r1.node_->hash_);
             previous_pointer prev = unlink_nodes(
-                *this->get_bucket(bucket_index), r1, r2);
-            this->fix_buckets_range(bucket_index, prev, r1, r2);
+                *this->get_bucket(bucket_index), r1.node_, r2.node_);
+            this->fix_buckets_range(bucket_index, prev, r1.node_, r2.node_);
             this->delete_nodes(r1, r2);
 
-            return r2;
+            return iterator(r2.node_);
         }
 
         static previous_pointer unlink_node(bucket& b, node_pointer n)
@@ -610,18 +622,18 @@
 
             node_constructor a(dst.node_alloc());
 
-            node_pointer n = src.get_start();
+            iterator n = src.get_start();
             previous_pointer prev = dst.get_previous_start();
 
-            while(n) {
+            while(n.node_) {
                 a.construct_node();
-                a.construct_value2(n->value());
+                a.construct_value2(*n);
 
                 node_pointer node = a.release();
-                node->hash_ = n->hash_;
+                node->hash_ = n.node_->hash_;
                 prev->next_ = static_cast<link_pointer>(node);
                 ++dst.size_;
-                n = static_cast<node_pointer>(n->next_);
+                ++n;
 
                 prev = place_in_bucket(dst, prev);
             }
@@ -641,18 +653,18 @@
 
             node_constructor a(dst.node_alloc());
 
-            node_pointer n = src.get_start();
+            iterator n = src.get_start();
             previous_pointer prev = dst.get_previous_start();
 
-            while(n) {
+            while (n.node_) {
                 a.construct_node();
-                a.construct_value2(boost::move(n->value()));
+                a.construct_value2(boost::move(*n));
 
                 node_pointer node = a.release();
-                node->hash_ = n->hash_;
+                node->hash_ = n.node_->hash_;
                 prev->next_ = static_cast<link_pointer>(node);
                 ++dst.size_;
-                n = static_cast<node_pointer>(n->next_);
+                ++n;
 
                 prev = place_in_bucket(dst, prev);
             }
@@ -689,7 +701,8 @@
                 previous_pointer prev)
         {
             node_pointer n = static_cast<node_pointer>(prev->next_);
-            bucket_pointer b = dst.get_bucket(n->hash_ % dst.bucket_count_);
+            bucket_pointer b = dst.get_bucket(
+                buckets::to_bucket(dst.bucket_count_, n->hash_));
 
             if (!b->next_) {
                 b->next_ = prev;
Modified: branches/release/boost/unordered/unordered_map.hpp
==============================================================================
--- branches/release/boost/unordered/unordered_map.hpp	(original)
+++ branches/release/boost/unordered/unordered_map.hpp	2012-05-03 18:05:21 EDT (Thu, 03 May 2012)
@@ -203,12 +203,12 @@
 
         iterator begin()
         {
-            return iterator(table_.begin());
+            return table_.begin();
         }
 
         const_iterator begin() const
         {
-            return const_iterator(table_.begin());
+            return table_.begin();
         }
 
         iterator end()
@@ -223,7 +223,7 @@
 
         const_iterator cbegin() const
         {
-            return const_iterator(table_.begin());
+            return table_.begin();
         }
 
         const_iterator cend() const
@@ -465,7 +465,8 @@
 
         size_type bucket(const key_type& k) const
         {
-            return table_.hash_function()(k) % table_.bucket_count_;
+            return table::to_bucket(table_.bucket_count_,
+                table_.hash(k));
         }
 
         local_iterator begin(size_type n)
@@ -688,12 +689,12 @@
 
         iterator begin()
         {
-            return iterator(table_.begin());
+            return table_.begin();
         }
 
         const_iterator begin() const
         {
-            return const_iterator(table_.begin());
+            return table_.begin();
         }
 
         iterator end()
@@ -708,7 +709,7 @@
 
         const_iterator cbegin() const
         {
-            return const_iterator(table_.begin());
+            return table_.begin();
         }
 
         const_iterator cend() const
@@ -946,7 +947,8 @@
 
         size_type bucket(const key_type& k) const
         {
-            return table_.hash_function()(k) % table_.bucket_count_;
+            return table::to_bucket(table_.bucket_count_,
+                table_.hash(k));
         }
 
         local_iterator begin(size_type n)
@@ -1139,7 +1141,7 @@
     typename unordered_map<K,T,H,P,A>::iterator
         unordered_map<K,T,H,P,A>::erase(const_iterator position)
     {
-        return iterator(table_.erase(position.node_));
+        return table_.erase(position);
     }
 
     template <class K, class T, class H, class P, class A>
@@ -1154,7 +1156,7 @@
         unordered_map<K,T,H,P,A>::erase(
             const_iterator first, const_iterator last)
     {
-        return iterator(table_.erase_range(first.node_, last.node_));
+        return table_.erase_range(first, last);
     }
 
     template <class K, class T, class H, class P, class A>
@@ -1212,14 +1214,14 @@
     typename unordered_map<K,T,H,P,A>::iterator
         unordered_map<K,T,H,P,A>::find(const key_type& k)
     {
-        return iterator(table_.find_node(k));
+        return table_.find_node(k);
     }
 
     template <class K, class T, class H, class P, class A>
     typename unordered_map<K,T,H,P,A>::const_iterator
         unordered_map<K,T,H,P,A>::find(const key_type& k) const
     {
-        return const_iterator(table_.find_node(k));
+        return table_.find_node(k);
     }
 
     template <class K, class T, class H, class P, class A>
@@ -1231,7 +1233,7 @@
             CompatibleHash const& hash,
             CompatiblePredicate const& eq)
     {
-        return iterator(table_.generic_find_node(k, hash, eq));
+        return table_.generic_find_node(k, hash, eq);
     }
 
     template <class K, class T, class H, class P, class A>
@@ -1243,7 +1245,7 @@
             CompatibleHash const& hash,
             CompatiblePredicate const& eq) const
     {
-        return const_iterator(table_.generic_find_node(k, hash, eq));
+        return table_.generic_find_node(k, hash, eq);
     }
 
     template <class K, class T, class H, class P, class A>
@@ -1466,7 +1468,7 @@
     typename unordered_multimap<K,T,H,P,A>::iterator
         unordered_multimap<K,T,H,P,A>::erase(const_iterator position)
     {
-        return iterator(table_.erase(position.node_));
+        return table_.erase(position);
     }
 
     template <class K, class T, class H, class P, class A>
@@ -1481,7 +1483,7 @@
         unordered_multimap<K,T,H,P,A>::erase(
             const_iterator first, const_iterator last)
     {
-        return iterator(table_.erase_range(first.node_, last.node_));
+        return table_.erase_range(first, last);
     }
 
     template <class K, class T, class H, class P, class A>
@@ -1518,14 +1520,14 @@
     typename unordered_multimap<K,T,H,P,A>::iterator
         unordered_multimap<K,T,H,P,A>::find(const key_type& k)
     {
-        return iterator(table_.find_node(k));
+        return table_.find_node(k);
     }
 
     template <class K, class T, class H, class P, class A>
     typename unordered_multimap<K,T,H,P,A>::const_iterator
         unordered_multimap<K,T,H,P,A>::find(const key_type& k) const
     {
-        return const_iterator(table_.find_node(k));
+        return table_.find_node(k);
     }
 
     template <class K, class T, class H, class P, class A>
@@ -1537,7 +1539,7 @@
             CompatibleHash const& hash,
             CompatiblePredicate const& eq)
     {
-        return iterator(table_.generic_find_node(k, hash, eq));
+        return table_.generic_find_node(k, hash, eq);
     }
 
     template <class K, class T, class H, class P, class A>
@@ -1549,7 +1551,7 @@
             CompatibleHash const& hash,
             CompatiblePredicate const& eq) const
     {
-        return const_iterator(table_.generic_find_node(k, hash, eq));
+        return table_.generic_find_node(k, hash, eq);
     }
 
     template <class K, class T, class H, class P, class A>
Modified: branches/release/boost/unordered/unordered_map_fwd.hpp
==============================================================================
--- branches/release/boost/unordered/unordered_map_fwd.hpp	(original)
+++ branches/release/boost/unordered/unordered_map_fwd.hpp	2012-05-03 18:05:21 EDT (Thu, 03 May 2012)
@@ -10,12 +10,23 @@
 # pragma once
 #endif
 
+#include <boost/config.hpp>
+#include <memory>
+#include <functional>
+#include <boost/functional/hash_fwd.hpp>
 #include <boost/unordered/detail/fwd.hpp>
 
 namespace boost
 {
     namespace unordered
     {
+        template <class K,
+            class T,
+            class H = boost::hash<K>,
+            class P = std::equal_to<K>,
+            class A = std::allocator<std::pair<const K, T> > >
+        class unordered_map;
+
         template <class K, class T, class H, class P, class A>
         inline bool operator==(unordered_map<K, T, H, P, A> const&,
             unordered_map<K, T, H, P, A> const&);
@@ -26,6 +37,13 @@
         inline void swap(unordered_map<K, T, H, P, A>&,
                 unordered_map<K, T, H, P, A>&);
 
+        template <class K,
+            class T,
+            class H = boost::hash<K>,
+            class P = std::equal_to<K>,
+            class A = std::allocator<std::pair<const K, T> > >
+        class unordered_multimap;
+
         template <class K, class T, class H, class P, class A>
         inline bool operator==(unordered_multimap<K, T, H, P, A> const&,
             unordered_multimap<K, T, H, P, A> const&);
Modified: branches/release/boost/unordered/unordered_set.hpp
==============================================================================
--- branches/release/boost/unordered/unordered_set.hpp	(original)
+++ branches/release/boost/unordered/unordered_set.hpp	2012-05-03 18:05:21 EDT (Thu, 03 May 2012)
@@ -201,12 +201,12 @@
 
         iterator begin()
         {
-            return iterator(table_.begin());
+            return table_.begin();
         }
 
         const_iterator begin() const
         {
-            return const_iterator(table_.begin());
+            return table_.begin();
         }
 
         iterator end()
@@ -221,7 +221,7 @@
 
         const_iterator cbegin() const
         {
-            return const_iterator(table_.begin());
+            return table_.begin();
         }
 
         const_iterator cend() const
@@ -450,7 +450,8 @@
 
         size_type bucket(const key_type& k) const
         {
-            return table_.hash_function()(k) % table_.bucket_count_;
+            return table::to_bucket(table_.bucket_count_,
+                table_.hash(k));
         }
 
         local_iterator begin(size_type n)
@@ -921,7 +922,8 @@
 
         size_type bucket(const key_type& k) const
         {
-            return table_.hash_function()(k) % table_.bucket_count_;
+            return table::to_bucket(table_.bucket_count_,
+                table_.hash(k));
         }
 
         local_iterator begin(size_type n)
@@ -1114,7 +1116,7 @@
     typename unordered_set<T,H,P,A>::iterator
         unordered_set<T,H,P,A>::erase(const_iterator position)
     {
-        return iterator(table_.erase(position.node_));
+        return table_.erase(position);
     }
 
     template <class T, class H, class P, class A>
@@ -1129,7 +1131,7 @@
         unordered_set<T,H,P,A>::erase(
             const_iterator first, const_iterator last)
     {
-        return iterator(table_.erase_range(first.node_, last.node_));
+        return table_.erase_range(first, last);
     }
 
     template <class T, class H, class P, class A>
@@ -1166,7 +1168,7 @@
     typename unordered_set<T,H,P,A>::const_iterator
         unordered_set<T,H,P,A>::find(const key_type& k) const
     {
-        return const_iterator(table_.find_node(k));
+        return table_.find_node(k);
     }
 
     template <class T, class H, class P, class A>
@@ -1178,7 +1180,7 @@
             CompatibleHash const& hash,
             CompatiblePredicate const& eq) const
     {
-        return const_iterator(table_.generic_find_node(k, hash, eq));
+        return table_.generic_find_node(k, hash, eq);
     }
 
     template <class T, class H, class P, class A>
@@ -1392,7 +1394,7 @@
     typename unordered_multiset<T,H,P,A>::iterator
         unordered_multiset<T,H,P,A>::erase(const_iterator position)
     {
-        return iterator(table_.erase(position.node_));
+        return table_.erase(position);
     }
 
     template <class T, class H, class P, class A>
@@ -1407,7 +1409,7 @@
         unordered_multiset<T,H,P,A>::erase(
                 const_iterator first, const_iterator last)
     {
-        return iterator(table_.erase_range(first.node_, last.node_));
+        return table_.erase_range(first, last);
     }
 
     template <class T, class H, class P, class A>
@@ -1444,7 +1446,7 @@
     typename unordered_multiset<T,H,P,A>::const_iterator
         unordered_multiset<T,H,P,A>::find(const key_type& k) const
     {
-        return const_iterator(table_.find_node(k));
+        return table_.find_node(k);
     }
 
     template <class T, class H, class P, class A>
@@ -1456,7 +1458,7 @@
             CompatibleHash const& hash,
             CompatiblePredicate const& eq) const
     {
-        return const_iterator(table_.generic_find_node(k, hash, eq));
+        return table_.generic_find_node(k, hash, eq);
     }
 
     template <class T, class H, class P, class A>
Modified: branches/release/boost/unordered/unordered_set_fwd.hpp
==============================================================================
--- branches/release/boost/unordered/unordered_set_fwd.hpp	(original)
+++ branches/release/boost/unordered/unordered_set_fwd.hpp	2012-05-03 18:05:21 EDT (Thu, 03 May 2012)
@@ -10,12 +10,22 @@
 # pragma once
 #endif
 
+#include <boost/config.hpp>
+#include <memory>
+#include <functional>
+#include <boost/functional/hash_fwd.hpp>
 #include <boost/unordered/detail/fwd.hpp>
 
 namespace boost
 {
     namespace unordered
     {
+        template <class T,
+            class H = boost::hash<T>,
+            class P = std::equal_to<T>,
+            class A = std::allocator<T> >
+        class unordered_set;
+
         template <class T, class H, class P, class A>
         inline bool operator==(unordered_set<T, H, P, A> const&,
             unordered_set<T, H, P, A> const&);
@@ -26,6 +36,12 @@
         inline void swap(unordered_set<T, H, P, A> &m1,
                 unordered_set<T, H, P, A> &m2);
 
+        template <class T,
+            class H = boost::hash<T>,
+            class P = std::equal_to<T>,
+            class A = std::allocator<T> >
+        class unordered_multiset;
+
         template <class T, class H, class P, class A>
         inline bool operator==(unordered_multiset<T, H, P, A> const&,
             unordered_multiset<T, H, P, A> const&);
Modified: branches/release/libs/functional/hash/doc/changes.qbk
==============================================================================
--- branches/release/libs/functional/hash/doc/changes.qbk	(original)
+++ branches/release/libs/functional/hash/doc/changes.qbk	2012-05-03 18:05:21 EDT (Thu, 03 May 2012)
@@ -123,4 +123,11 @@
 
 * Avoid warning due with gcc's `-Wconversion` flag.
 
+[h2 Boost 1.50.0]
+
+* [@http://svn.boost.org/trac/boost/ticket/6771 Ticket 6771]:
+  Avoid gcc's `-Wfloat-equal` warning.
+* [@http://svn.boost.org/trac/boost/ticket/6806 Ticket 6806]:
+  Support `std::array` and `std::tuple` when available.
+
 [endsect]
Modified: branches/release/libs/functional/hash/doc/ref.xml
==============================================================================
--- branches/release/libs/functional/hash/doc/ref.xml	(original)
+++ branches/release/libs/functional/hash/doc/ref.xml	2012-05-03 18:05:21 EDT (Thu, 03 May 2012)
@@ -744,6 +744,25 @@
           <parameter name="val"><paramtype>std::type_index</paramtype></parameter>
         </signature>
 
+        <signature>
+          <template>
+            <template-type-parameter name="T"/>
+            <template-nontype-parameter name="N">
+              <type>std::size_t</type>
+            </template-nontype-parameter>
+          </template>
+          <type>std::size_t</type>
+          <parameter name="val"><paramtype>std::array<T, N> const&</paramtype></parameter>
+        </signature>
+
+        <signature>
+          <template>
+            <template-type-parameter name="T" pack="1"/>
+          </template>
+          <type>std::size_t</type>
+          <parameter name="val"><paramtype>std::tuple<T...></paramtype></parameter>
+        </signature>
+
         <description><para>
           Generally shouldn't be called directly by users, instead they should use
           <classname>boost::hash</classname>, <functionname>boost::hash_range</functionname>
@@ -809,7 +828,8 @@
                     <code>std::set<K, C, A></code>,
                     <code>std::multiset<K, C, A></code>,
                     <code>std::map<K, T, C, A></code>,
-                    <code>std::multimap<K, T, C, A></code>
+                    <code>std::multimap<K, T, C, A></code>,
+                    <code>std::array<T, N></code>
                   </entry>
                   <entry><code>hash_range(val.begin(), val.end())</code></entry>
                 </row>
@@ -821,6 +841,14 @@
 return seed;</programlisting></entry>
                 </row>
                 <row>
+                  <entry><code>std::tuple<T...></code></entry>
+                  <entry><programlisting>size_t seed = 0;
+<functionname>hash_combine</functionname>(seed, get<0>(val));
+<functionname>hash_combine</functionname>(seed, get<1>(val));
+// ....
+return seed;</programlisting></entry>
+                </row>
+                <row>
                   <entry>
                     <code>std::complex<T></code>
                   </entry>
Modified: branches/release/libs/functional/hash/test/Jamfile.v2
==============================================================================
--- branches/release/libs/functional/hash/test/Jamfile.v2	(original)
+++ branches/release/libs/functional/hash/test/Jamfile.v2	2012-05-03 18:05:21 EDT (Thu, 03 May 2012)
@@ -10,8 +10,8 @@
         <warnings>all
         <toolset>intel:<warnings>on
         <toolset>intel:<cxxflags>-strict-ansi
-        <toolset>gcc:<cxxflags>"-pedantic -Wstrict-aliasing -fstrict-aliasing -Wextra -Wsign-promo -Wunused-parameter -Wconversion"
-        <toolset>darwin:<cxxflags>"-pedantic -Wstrict-aliasing -fstrict-aliasing -Wextra -Wsign-promo -Wunused-parameter -Wconversion"
+        <toolset>gcc:<cxxflags>"-pedantic -Wstrict-aliasing -fstrict-aliasing -Wextra -Wsign-promo -Wunused-parameter -Wconversion -Wfloat-equal"
+        <toolset>darwin:<cxxflags>"-pedantic -Wstrict-aliasing -fstrict-aliasing -Wextra -Wsign-promo -Wunused-parameter -Wconversion -Wfloat-equal"
         <toolset>msvc:<warnings-as-errors>on
         #<toolset>gcc:<warnings-as-errors>on
         #<toolset>darwin:<warnings-as-errors>on
@@ -40,6 +40,8 @@
         [ run hash_map_test.cpp : : : <define>BOOST_HASH_NO_IMPLICIT_CASTS ]
         [ run hash_complex_test.cpp : : : <define>BOOST_HASH_NO_IMPLICIT_CASTS ]
         [ run hash_type_index_test.cpp : : : <define>BOOST_HASH_NO_IMPLICIT_CASTS ]
+        [ run hash_std_array_test.cpp : : : <define>BOOST_HASH_NO_IMPLICIT_CASTS ]
+        [ run hash_std_tuple_test.cpp : : : <define>BOOST_HASH_NO_IMPLICIT_CASTS ]
         [ run link_test.cpp link_test_2.cpp : : : <define>BOOST_HASH_NO_IMPLICIT_CASTS ]
         [ run link_ext_test.cpp link_no_ext_test.cpp : : : <define>BOOST_HASH_NO_IMPLICIT_CASTS ]
         [ run extensions_hpp_test.cpp : : : <define>BOOST_HASH_NO_IMPLICIT_CASTS ]
Modified: branches/release/libs/functional/hash/test/hash_complex_test.cpp
==============================================================================
--- branches/release/libs/functional/hash/test/hash_complex_test.cpp	(original)
+++ branches/release/libs/functional/hash/test/hash_complex_test.cpp	2012-05-03 18:05:21 EDT (Thu, 03 May 2012)
@@ -35,6 +35,10 @@
 #endif
 #endif
 
+#if defined(__GNUC__)
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+
 #include <complex>
 #include <sstream>
 #include <boost/limits.hpp>
Modified: branches/release/libs/functional/hash/test/hash_float_test.hpp
==============================================================================
--- branches/release/libs/functional/hash/test/hash_float_test.hpp	(original)
+++ branches/release/libs/functional/hash/test/hash_float_test.hpp	2012-05-03 18:05:21 EDT (Thu, 03 May 2012)
@@ -30,6 +30,10 @@
 #endif
 #endif
 
+#if defined(__GNUC__)
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+
 char const* float_type(float*) { return "float"; }
 char const* float_type(double*) { return "double"; }
 char const* float_type(long double*) { return "long double"; }
Modified: branches/release/libs/functional/hash/test/hash_map_test.cpp
==============================================================================
--- branches/release/libs/functional/hash/test/hash_map_test.cpp	(original)
+++ branches/release/libs/functional/hash/test/hash_map_test.cpp	2012-05-03 18:05:21 EDT (Thu, 03 May 2012)
@@ -27,7 +27,7 @@
 #define CONTAINER_TYPE multimap
 #include "./hash_map_test.hpp"
 
-#endif // TEST_EXTENSTIONS
+#endif // TEST_EXTENSIONS
 
 int main()
 {
Modified: branches/release/libs/functional/hash/test/hash_number_test.cpp
==============================================================================
--- branches/release/libs/functional/hash/test/hash_number_test.cpp	(original)
+++ branches/release/libs/functional/hash/test/hash_number_test.cpp	2012-05-03 18:05:21 EDT (Thu, 03 May 2012)
@@ -28,6 +28,10 @@
 #pragma warning(disable:4310) // cast truncates constant value
 #endif
 
+#if defined(__GNUC__)
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+
 template <class T>
 void numeric_test(T*)
 {
Copied: branches/release/libs/functional/hash/test/hash_std_array_test.cpp (from r78145, /trunk/libs/functional/hash/test/hash_std_array_test.cpp)
==============================================================================
--- /trunk/libs/functional/hash/test/hash_std_array_test.cpp	(original)
+++ branches/release/libs/functional/hash/test/hash_std_array_test.cpp	2012-05-03 18:05:21 EDT (Thu, 03 May 2012)
@@ -50,11 +50,11 @@
     std::vector<std::array<int, 1> > arrays;
     std::array<int, 1> val;
     val[0] = 0;
-    arrays.emplace_back(val);
+    arrays.push_back(val);
     val[0] = 1;
-    arrays.emplace_back(val);
+    arrays.push_back(val);
     val[0] = 2;
-    arrays.emplace_back(val);
+    arrays.push_back(val);
     array_tests(arrays);
 }
 
@@ -62,11 +62,11 @@
 {
     std::vector<std::array<std::string, 1> > arrays;
     std::array<std::string, 1> val;
-    arrays.emplace_back(val);
+    arrays.push_back(val);
     val[0] = "one";
-    arrays.emplace_back(val);
+    arrays.push_back(val);
     val[0] = "two";
-    arrays.emplace_back(val);
+    arrays.push_back(val);
     array_tests(arrays);
 }
 
@@ -74,17 +74,17 @@
 {
     std::vector<std::array<std::string,3 > > arrays;
     std::array<std::string, 3> val;
-    arrays.emplace_back(val);
+    arrays.push_back(val);
     val[0] = "one";
-    arrays.emplace_back(val);
+    arrays.push_back(val);
     val[0] = ""; val[1] = "one"; val[2] = "";
-    arrays.emplace_back(val);
+    arrays.push_back(val);
     val[0] = ""; val[1] = ""; val[2] = "one";
-    arrays.emplace_back(val);
+    arrays.push_back(val);
     val[0] = "one"; val[1] = "one"; val[2] = "one";
-    arrays.emplace_back(val);
+    arrays.push_back(val);
     val[0] = "one"; val[1] = "two"; val[2] = "three";
-    arrays.emplace_back(val);
+    arrays.push_back(val);
     array_tests(arrays);
 }
 
Copied: branches/release/libs/functional/hash/test/hash_std_tuple_test.cpp (from r78145, /trunk/libs/functional/hash/test/hash_std_tuple_test.cpp)
==============================================================================
--- /trunk/libs/functional/hash/test/hash_std_tuple_test.cpp	(original)
+++ branches/release/libs/functional/hash/test/hash_std_tuple_test.cpp	2012-05-03 18:05:21 EDT (Thu, 03 May 2012)
@@ -53,13 +53,13 @@
 
 void int_string_tuple_test() {
     std::vector<std::tuple<int, std::string> > int_string_tuples;
-    int_string_tuples.push_back(std::make_tuple(0, "zero"));
-    int_string_tuples.push_back(std::make_tuple(1, "one"));
-    int_string_tuples.push_back(std::make_tuple(2, "two"));
-    int_string_tuples.push_back(std::make_tuple(0, "one"));
-    int_string_tuples.push_back(std::make_tuple(1, "zero"));
-    int_string_tuples.push_back(std::make_tuple(0, ""));
-    int_string_tuples.push_back(std::make_tuple(1, ""));
+    int_string_tuples.push_back(std::make_tuple(0, std::string("zero")));
+    int_string_tuples.push_back(std::make_tuple(1, std::string("one")));
+    int_string_tuples.push_back(std::make_tuple(2, std::string("two")));
+    int_string_tuples.push_back(std::make_tuple(0, std::string("one")));
+    int_string_tuples.push_back(std::make_tuple(1, std::string("zero")));
+    int_string_tuples.push_back(std::make_tuple(0, std::string("")));
+    int_string_tuples.push_back(std::make_tuple(1, std::string("")));
     tuple_tests(int_string_tuples);
 }
 
Modified: branches/release/libs/unordered/doc/changes.qbk
==============================================================================
--- branches/release/libs/unordered/doc/changes.qbk	(original)
+++ branches/release/libs/unordered/doc/changes.qbk	2012-05-03 18:05:21 EDT (Thu, 03 May 2012)
@@ -175,4 +175,21 @@
 * Fix warning due to accidental odd assignment.
 * Slightly better error messages.
 
+[h2 Boost 1.50.0]
+
+* Fix equality for `unordered_multiset` and `unordered_multimap`.
+* [@http://svn.boost.org/trac/boost/ticket/6771 Ticket 6771]:
+  Avoid gcc's `-Wfloat-equal` warning.
+* [@http://svn.boost.org/trac/boost/ticket/6784 Ticket 6784]:
+  Fix some Sun specific code.
+* Remove some of the smaller prime number of buckets, as they may make
+  collisions quite probable (e.g. multiples of 5 are very common because
+  we used base 10).
+* On old versions of Visual C++, use the container library's implementation
+  of `allocator_traits`, as it's more likely to work.
+* On machines with 64 bit std::size_t, use power of 2 buckets, with Thomas
+  Wang's hash function to pick which one to use. As modulus is very slow
+  for 64 bit values.
+* Some internal changes.
+
 [endsect]
Modified: branches/release/libs/unordered/test/exception/assign_exception_tests.cpp
==============================================================================
--- branches/release/libs/unordered/test/exception/assign_exception_tests.cpp	(original)
+++ branches/release/libs/unordered/test/exception/assign_exception_tests.cpp	2012-05-03 18:05:21 EDT (Thu, 03 May 2012)
@@ -3,8 +3,6 @@
 // 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)
 
-#include "../helpers/prefix.hpp"
-
 #include "./containers.hpp"
 #include "../helpers/random_values.hpp"
 #include "../helpers/invariants.hpp"
Modified: branches/release/libs/unordered/test/exception/constructor_exception_tests.cpp
==============================================================================
--- branches/release/libs/unordered/test/exception/constructor_exception_tests.cpp	(original)
+++ branches/release/libs/unordered/test/exception/constructor_exception_tests.cpp	2012-05-03 18:05:21 EDT (Thu, 03 May 2012)
@@ -3,8 +3,6 @@
 // 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)
 
-#include "../helpers/prefix.hpp"
-
 #include "./containers.hpp"
 #include "../helpers/random_values.hpp"
 #include "../helpers/input_iterator.hpp"
Modified: branches/release/libs/unordered/test/exception/containers.hpp
==============================================================================
--- branches/release/libs/unordered/test/exception/containers.hpp	(original)
+++ branches/release/libs/unordered/test/exception/containers.hpp	2012-05-03 18:05:21 EDT (Thu, 03 May 2012)
@@ -3,8 +3,10 @@
 // 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)
 
+#include "../helpers/prefix.hpp"
 #include <boost/unordered_map.hpp>
 #include <boost/unordered_set.hpp>
+#include "../helpers/postfix.hpp"
 #include "../objects/exception.hpp"
 
 typedef boost::unordered_set<
Modified: branches/release/libs/unordered/test/exception/copy_exception_tests.cpp
==============================================================================
--- branches/release/libs/unordered/test/exception/copy_exception_tests.cpp	(original)
+++ branches/release/libs/unordered/test/exception/copy_exception_tests.cpp	2012-05-03 18:05:21 EDT (Thu, 03 May 2012)
@@ -3,8 +3,6 @@
 // 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)
 
-#include "../helpers/prefix.hpp"
-
 #include "./containers.hpp"
 #include "../helpers/random_values.hpp"
 
Modified: branches/release/libs/unordered/test/exception/erase_exception_tests.cpp
==============================================================================
--- branches/release/libs/unordered/test/exception/erase_exception_tests.cpp	(original)
+++ branches/release/libs/unordered/test/exception/erase_exception_tests.cpp	2012-05-03 18:05:21 EDT (Thu, 03 May 2012)
@@ -3,8 +3,6 @@
 // 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)
 
-#include "../helpers/prefix.hpp"
-
 #include "./containers.hpp"
 #include "../helpers/random_values.hpp"
 #include "../helpers/invariants.hpp"
Modified: branches/release/libs/unordered/test/exception/insert_exception_tests.cpp
==============================================================================
--- branches/release/libs/unordered/test/exception/insert_exception_tests.cpp	(original)
+++ branches/release/libs/unordered/test/exception/insert_exception_tests.cpp	2012-05-03 18:05:21 EDT (Thu, 03 May 2012)
@@ -3,8 +3,6 @@
 // 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)
 
-#include "../helpers/prefix.hpp"
-
 #include "./containers.hpp"
 #include <string>
 #include "../helpers/random_values.hpp"
Modified: branches/release/libs/unordered/test/exception/rehash_exception_tests.cpp
==============================================================================
--- branches/release/libs/unordered/test/exception/rehash_exception_tests.cpp	(original)
+++ branches/release/libs/unordered/test/exception/rehash_exception_tests.cpp	2012-05-03 18:05:21 EDT (Thu, 03 May 2012)
@@ -3,8 +3,6 @@
 // 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)
 
-#include "../helpers/prefix.hpp"
-
 #include "./containers.hpp"
 #include <string>
 #include "../helpers/random_values.hpp"
Modified: branches/release/libs/unordered/test/exception/swap_exception_tests.cpp
==============================================================================
--- branches/release/libs/unordered/test/exception/swap_exception_tests.cpp	(original)
+++ branches/release/libs/unordered/test/exception/swap_exception_tests.cpp	2012-05-03 18:05:21 EDT (Thu, 03 May 2012)
@@ -3,8 +3,6 @@
 // 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)
 
-#include "../helpers/prefix.hpp"
-
 #include "./containers.hpp"
 #include "../helpers/random_values.hpp"
 #include "../helpers/invariants.hpp"
Modified: branches/release/libs/unordered/test/unordered/Jamfile.v2
==============================================================================
--- branches/release/libs/unordered/test/unordered/Jamfile.v2	(original)
+++ branches/release/libs/unordered/test/unordered/Jamfile.v2	2012-05-03 18:05:21 EDT (Thu, 03 May 2012)
@@ -11,8 +11,8 @@
         <toolset>intel:<warnings>on
         # Would be nice to define -Wundef, but I'm getting warnings from
         # Boost.Preprocessor on trunk.
-        <toolset>gcc:<cxxflags>"-pedantic -Wstrict-aliasing -fstrict-aliasing -Wextra -Wsign-promo -Wunused-parameter -Wconversion -Wno-long-long"
-        <toolset>darwin:<cxxflags>"-pedantic -Wstrict-aliasing -fstrict-aliasing -Wextra -Wsign-promo -Wunused-parameter -Wconversion"
+        <toolset>gcc:<cxxflags>"-pedantic -Wstrict-aliasing -fstrict-aliasing -Wextra -Wsign-promo -Wunused-parameter -Wconversion -Wno-long-long -Wfloat-equal"
+        <toolset>darwin:<cxxflags>"-pedantic -Wstrict-aliasing -fstrict-aliasing -Wextra -Wsign-promo -Wunused-parameter -Wconversion -Wfloat-equal"
         #<toolset>gcc:<define>_GLIBCXX_DEBUG
         #<toolset>darwin:<define>_GLIBCXX_DEBUG
         #<toolset>msvc:<warnings-as-errors>on
Modified: branches/release/libs/unordered/test/unordered/allocator_traits.cpp
==============================================================================
--- branches/release/libs/unordered/test/unordered/allocator_traits.cpp	(original)
+++ branches/release/libs/unordered/test/unordered/allocator_traits.cpp	2012-05-03 18:05:21 EDT (Thu, 03 May 2012)
@@ -90,7 +90,7 @@
 {
     typedef empty_allocator<int> allocator;
     typedef boost::unordered::detail::allocator_traits<allocator> traits;
-#if BOOST_UNORDERED_USE_ALLOCATOR_TRAITS
+#if BOOST_UNORDERED_USE_ALLOCATOR_TRAITS == 1
     BOOST_MPL_ASSERT((boost::is_same<traits::size_type,
         std::make_unsigned<std::ptrdiff_t>::type>));
 #else
@@ -128,8 +128,8 @@
 {
     typedef allocator1<int> allocator;
     typedef boost::unordered::detail::allocator_traits<allocator> traits;
-#if BOOST_UNORDERED_USE_ALLOCATOR_TRAITS
-    BOOST_MPL_ASSERT((boost::is_same<typename traits::size_type,
+#if BOOST_UNORDERED_USE_ALLOCATOR_TRAITS == 1
+    BOOST_MPL_ASSERT((boost::is_same<traits::size_type,
         std::make_unsigned<std::ptrdiff_t>::type>));
 #else
     BOOST_MPL_ASSERT((boost::is_same<traits::size_type, std::size_t>));
Modified: branches/release/libs/unordered/test/unordered/assign_tests.cpp
==============================================================================
--- branches/release/libs/unordered/test/unordered/assign_tests.cpp	(original)
+++ branches/release/libs/unordered/test/unordered/assign_tests.cpp	2012-05-03 18:05:21 EDT (Thu, 03 May 2012)
@@ -4,9 +4,9 @@
 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 
 #include "../helpers/prefix.hpp"
-
 #include <boost/unordered_set.hpp>
 #include <boost/unordered_map.hpp>
+#include "../helpers/postfix.hpp"
 #include "../helpers/test.hpp"
 #include "../objects/test.hpp"
 #include "../objects/cxx11_allocator.hpp"
@@ -208,9 +208,7 @@
 
 #endif
 
-#if !defined(BOOST_NO_0X_HDR_INITIALIZER_LIST) && \
-    !defined(BOOST_NO_INITIALIZER_LISTS)
-
+#if !defined(BOOST_NO_0X_HDR_INITIALIZER_LIST)
 UNORDERED_AUTO_TEST(assign_initializer_list)
 {
     std::cerr<<"Initializer List Tests\n";
Modified: branches/release/libs/unordered/test/unordered/at_tests.cpp
==============================================================================
--- branches/release/libs/unordered/test/unordered/at_tests.cpp	(original)
+++ branches/release/libs/unordered/test/unordered/at_tests.cpp	2012-05-03 18:05:21 EDT (Thu, 03 May 2012)
@@ -4,8 +4,9 @@
 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 
 #include "../helpers/prefix.hpp"
-
 #include <boost/unordered_map.hpp>
+#include "../helpers/postfix.hpp"
+
 #include "../helpers/test.hpp"
 #include <string>
 
Modified: branches/release/libs/unordered/test/unordered/bucket_tests.cpp
==============================================================================
--- branches/release/libs/unordered/test/unordered/bucket_tests.cpp	(original)
+++ branches/release/libs/unordered/test/unordered/bucket_tests.cpp	2012-05-03 18:05:21 EDT (Thu, 03 May 2012)
@@ -4,9 +4,10 @@
 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 
 #include "../helpers/prefix.hpp"
-
 #include <boost/unordered_set.hpp>
 #include <boost/unordered_map.hpp>
+#include "../helpers/postfix.hpp"
+
 #include "../helpers/test.hpp"
 #include <algorithm>
 #include "../objects/test.hpp"
Modified: branches/release/libs/unordered/test/unordered/compile_map.cpp
==============================================================================
--- branches/release/libs/unordered/test/unordered/compile_map.cpp	(original)
+++ branches/release/libs/unordered/test/unordered/compile_map.cpp	2012-05-03 18:05:21 EDT (Thu, 03 May 2012)
@@ -7,8 +7,8 @@
 // requirements. Makes sure everything compiles and is defined correctly.
 
 #include "../helpers/prefix.hpp"
-
 #include <boost/unordered_map.hpp>
+#include "../helpers/postfix.hpp"
 
 #include <iostream>
 #include "../helpers/test.hpp"
Modified: branches/release/libs/unordered/test/unordered/compile_set.cpp
==============================================================================
--- branches/release/libs/unordered/test/unordered/compile_set.cpp	(original)
+++ branches/release/libs/unordered/test/unordered/compile_set.cpp	2012-05-03 18:05:21 EDT (Thu, 03 May 2012)
@@ -7,8 +7,8 @@
 // requirements. Makes sure everything compiles and is defined correctly.
 
 #include "../helpers/prefix.hpp"
-
 #include <boost/unordered_set.hpp>
+#include "../helpers/postfix.hpp"
 
 #include <iostream>
 #include "../helpers/test.hpp"
Modified: branches/release/libs/unordered/test/unordered/constructor_tests.cpp
==============================================================================
--- branches/release/libs/unordered/test/unordered/constructor_tests.cpp	(original)
+++ branches/release/libs/unordered/test/unordered/constructor_tests.cpp	2012-05-03 18:05:21 EDT (Thu, 03 May 2012)
@@ -4,9 +4,10 @@
 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 
 #include "../helpers/prefix.hpp"
-
 #include <boost/unordered_set.hpp>
 #include <boost/unordered_map.hpp>
+#include "../helpers/postfix.hpp"
+
 #include "../helpers/test.hpp"
 #include "../objects/test.hpp"
 #include "../helpers/random_values.hpp"
@@ -442,8 +443,7 @@
 
 #endif
 
-#if !defined(BOOST_NO_0X_HDR_INITIALIZER_LIST) && \
-    !defined(BOOST_NO_INITIALIZER_LISTS)
+#if !defined(BOOST_NO_0X_HDR_INITIALIZER_LIST)
 
 UNORDERED_AUTO_TEST(test_initializer_list) {
     std::cerr<<"Initializer List Tests\n";
Modified: branches/release/libs/unordered/test/unordered/copy_tests.cpp
==============================================================================
--- branches/release/libs/unordered/test/unordered/copy_tests.cpp	(original)
+++ branches/release/libs/unordered/test/unordered/copy_tests.cpp	2012-05-03 18:05:21 EDT (Thu, 03 May 2012)
@@ -4,9 +4,10 @@
 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 
 #include "../helpers/prefix.hpp"
-
 #include <boost/unordered_set.hpp>
 #include <boost/unordered_map.hpp>
+#include "../helpers/postfix.hpp"
+
 #include "../helpers/test.hpp"
 #include "../objects/test.hpp"
 #include "../objects/cxx11_allocator.hpp"
Modified: branches/release/libs/unordered/test/unordered/equality_deprecated.cpp
==============================================================================
--- branches/release/libs/unordered/test/unordered/equality_deprecated.cpp	(original)
+++ branches/release/libs/unordered/test/unordered/equality_deprecated.cpp	2012-05-03 18:05:21 EDT (Thu, 03 May 2012)
@@ -6,9 +6,10 @@
 #define BOOST_UNORDERED_DEPRECATED_EQUALITY
 
 #include "../helpers/prefix.hpp"
-
 #include <boost/unordered_set.hpp>
 #include <boost/unordered_map.hpp>
+#include "../helpers/postfix.hpp"
+
 #include <boost/preprocessor/seq.hpp>
 #include <list>
 #include "../helpers/test.hpp"
Modified: branches/release/libs/unordered/test/unordered/equality_tests.cpp
==============================================================================
--- branches/release/libs/unordered/test/unordered/equality_tests.cpp	(original)
+++ branches/release/libs/unordered/test/unordered/equality_tests.cpp	2012-05-03 18:05:21 EDT (Thu, 03 May 2012)
@@ -4,9 +4,10 @@
 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 
 #include "../helpers/prefix.hpp"
-
 #include <boost/unordered_set.hpp>
 #include <boost/unordered_map.hpp>
+#include "../helpers/postfix.hpp"
+
 #include <boost/preprocessor/seq.hpp>
 #include <list>
 #include "../helpers/test.hpp"
@@ -149,6 +150,14 @@
             ((1)(2))((1001)(1)), !=, ((1001)(2))((1)(1)))
     }
 
+    UNORDERED_AUTO_TEST(equality_multiple_group_test)
+    {
+        UNORDERED_EQUALITY_MULTISET_TEST(
+            (1)(1)(1)(1001)(2001)(2001)(2)(1002)(3)(1003)(2003), ==,
+            (3)(1003)(2003)(1002)(2)(2001)(2001)(1)(1001)(1)(1)
+        );
+    }
+
     // Test that equality still works when the two containers have
     // different hash functions but the same equality predicate.
 
@@ -167,7 +176,6 @@
         set1.insert(20); set2.insert(10);
         BOOST_TEST(set1 == set2);
     }
-
 }
 
 RUN_TESTS()
Modified: branches/release/libs/unordered/test/unordered/equivalent_keys_tests.cpp
==============================================================================
--- branches/release/libs/unordered/test/unordered/equivalent_keys_tests.cpp	(original)
+++ branches/release/libs/unordered/test/unordered/equivalent_keys_tests.cpp	2012-05-03 18:05:21 EDT (Thu, 03 May 2012)
@@ -4,9 +4,10 @@
 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 
 #include "../helpers/prefix.hpp"
-
 #include <boost/unordered_set.hpp>
 #include <boost/unordered_map.hpp>
+#include "../helpers/postfix.hpp"
+
 #include "../helpers/test.hpp"
 #include <algorithm>
 #include <map>
Modified: branches/release/libs/unordered/test/unordered/erase_equiv_tests.cpp
==============================================================================
--- branches/release/libs/unordered/test/unordered/erase_equiv_tests.cpp	(original)
+++ branches/release/libs/unordered/test/unordered/erase_equiv_tests.cpp	2012-05-03 18:05:21 EDT (Thu, 03 May 2012)
@@ -7,8 +7,9 @@
 // hairy with several tricky edge cases - so explicitly test each one.
 
 #include "../helpers/prefix.hpp"
-
 #include <boost/unordered_map.hpp>
+#include "../helpers/postfix.hpp"
+
 #include "../helpers/test.hpp"
 #include "../helpers/list.hpp"
 #include <set>
Modified: branches/release/libs/unordered/test/unordered/erase_tests.cpp
==============================================================================
--- branches/release/libs/unordered/test/unordered/erase_tests.cpp	(original)
+++ branches/release/libs/unordered/test/unordered/erase_tests.cpp	2012-05-03 18:05:21 EDT (Thu, 03 May 2012)
@@ -4,9 +4,10 @@
 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 
 #include "../helpers/prefix.hpp"
-
 #include <boost/unordered_set.hpp>
 #include <boost/unordered_map.hpp>
+#include "../helpers/postfix.hpp"
+
 #include "../helpers/test.hpp"
 #include <boost/next_prior.hpp>
 #include "../objects/test.hpp"
Modified: branches/release/libs/unordered/test/unordered/find_tests.cpp
==============================================================================
--- branches/release/libs/unordered/test/unordered/find_tests.cpp	(original)
+++ branches/release/libs/unordered/test/unordered/find_tests.cpp	2012-05-03 18:05:21 EDT (Thu, 03 May 2012)
@@ -4,9 +4,10 @@
 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 
 #include "../helpers/prefix.hpp"
-
 #include <boost/unordered_set.hpp>
 #include <boost/unordered_map.hpp>
+#include "../helpers/postfix.hpp"
+
 #include "../helpers/test.hpp"
 #include "../objects/test.hpp"
 #include "../helpers/random_values.hpp"
Modified: branches/release/libs/unordered/test/unordered/fwd_map_test.cpp
==============================================================================
--- branches/release/libs/unordered/test/unordered/fwd_map_test.cpp	(original)
+++ branches/release/libs/unordered/test/unordered/fwd_map_test.cpp	2012-05-03 18:05:21 EDT (Thu, 03 May 2012)
@@ -4,8 +4,8 @@
 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 
 #include "../helpers/prefix.hpp"
-
 #include <boost/unordered/unordered_map_fwd.hpp>
+#include "../helpers/postfix.hpp"
 
 template <typename T>
 void call_swap(boost::unordered_map<T,T>& x,
Modified: branches/release/libs/unordered/test/unordered/fwd_set_test.cpp
==============================================================================
--- branches/release/libs/unordered/test/unordered/fwd_set_test.cpp	(original)
+++ branches/release/libs/unordered/test/unordered/fwd_set_test.cpp	2012-05-03 18:05:21 EDT (Thu, 03 May 2012)
@@ -4,8 +4,8 @@
 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 
 #include "../helpers/prefix.hpp"
-
 #include <boost/unordered/unordered_set_fwd.hpp>
+#include "../helpers/postfix.hpp"
 
 struct true_type { char x[100]; };
 struct false_type { char x; };
Modified: branches/release/libs/unordered/test/unordered/incomplete_test.cpp
==============================================================================
--- branches/release/libs/unordered/test/unordered/incomplete_test.cpp	(original)
+++ branches/release/libs/unordered/test/unordered/incomplete_test.cpp	2012-05-03 18:05:21 EDT (Thu, 03 May 2012)
@@ -4,10 +4,11 @@
 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 
 #include "../helpers/prefix.hpp"
-
-#include <utility>
 #include <boost/unordered_map.hpp>
 #include <boost/unordered_set.hpp>
+#include "../helpers/postfix.hpp"
+
+#include <utility>
 
 namespace x
 {
Modified: branches/release/libs/unordered/test/unordered/insert_stable_tests.cpp
==============================================================================
--- branches/release/libs/unordered/test/unordered/insert_stable_tests.cpp	(original)
+++ branches/release/libs/unordered/test/unordered/insert_stable_tests.cpp	2012-05-03 18:05:21 EDT (Thu, 03 May 2012)
@@ -4,9 +4,10 @@
 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 
 #include "../helpers/prefix.hpp"
-
 #include <boost/unordered_set.hpp>
 #include <boost/unordered_map.hpp>
+#include "../helpers/postfix.hpp"
+
 #include "../helpers/test.hpp"
 
 #include <iostream>
Modified: branches/release/libs/unordered/test/unordered/insert_tests.cpp
==============================================================================
--- branches/release/libs/unordered/test/unordered/insert_tests.cpp	(original)
+++ branches/release/libs/unordered/test/unordered/insert_tests.cpp	2012-05-03 18:05:21 EDT (Thu, 03 May 2012)
@@ -4,9 +4,10 @@
 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 
 #include "../helpers/prefix.hpp"
-
 #include <boost/unordered_set.hpp>
 #include <boost/unordered_map.hpp>
+#include "../helpers/postfix.hpp"
+
 #include "../helpers/test.hpp"
 #include <boost/next_prior.hpp>
 #include "../objects/test.hpp"
@@ -465,8 +466,7 @@
     ((default_generator)(generate_collisions))
 )
 
-#if !defined(BOOST_NO_0X_HDR_INITIALIZER_LIST) && \
-    !defined(BOOST_NO_INITIALIZER_LISTS)
+#if !defined(BOOST_NO_0X_HDR_INITIALIZER_LIST)
 
 UNORDERED_AUTO_TEST(insert_initializer_list_set)
 {
Modified: branches/release/libs/unordered/test/unordered/link_test_1.cpp
==============================================================================
--- branches/release/libs/unordered/test/unordered/link_test_1.cpp	(original)
+++ branches/release/libs/unordered/test/unordered/link_test_1.cpp	2012-05-03 18:05:21 EDT (Thu, 03 May 2012)
@@ -4,9 +4,9 @@
 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 
 #include "../helpers/prefix.hpp"
-
 #include <boost/unordered_set.hpp>
 #include <boost/unordered_map.hpp>
+#include "../helpers/postfix.hpp"
 
 void foo(boost::unordered_set<int>&,
         boost::unordered_map<int, int>&,
Modified: branches/release/libs/unordered/test/unordered/link_test_2.cpp
==============================================================================
--- branches/release/libs/unordered/test/unordered/link_test_2.cpp	(original)
+++ branches/release/libs/unordered/test/unordered/link_test_2.cpp	2012-05-03 18:05:21 EDT (Thu, 03 May 2012)
@@ -4,9 +4,9 @@
 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 
 #include "../helpers/prefix.hpp"
-
 #include <boost/unordered_set.hpp>
 #include <boost/unordered_map.hpp>
+#include "../helpers/postfix.hpp"
 
 void foo(boost::unordered_set<int>& x1,
         boost::unordered_map<int, int>& x2,
Modified: branches/release/libs/unordered/test/unordered/load_factor_tests.cpp
==============================================================================
--- branches/release/libs/unordered/test/unordered/load_factor_tests.cpp	(original)
+++ branches/release/libs/unordered/test/unordered/load_factor_tests.cpp	2012-05-03 18:05:21 EDT (Thu, 03 May 2012)
@@ -4,9 +4,10 @@
 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 
 #include "../helpers/prefix.hpp"
-
 #include <boost/unordered_set.hpp>
 #include <boost/unordered_map.hpp>
+#include "../helpers/postfix.hpp"
+
 #include "../helpers/test.hpp"
 #include <boost/limits.hpp>
 #include "../helpers/random_values.hpp"
Modified: branches/release/libs/unordered/test/unordered/minimal_allocator.cpp
==============================================================================
--- branches/release/libs/unordered/test/unordered/minimal_allocator.cpp	(original)
+++ branches/release/libs/unordered/test/unordered/minimal_allocator.cpp	2012-05-03 18:05:21 EDT (Thu, 03 May 2012)
@@ -52,7 +52,7 @@
 
     BOOST_MPL_ASSERT((boost::is_same<typename traits::difference_type, std::ptrdiff_t>));
 
-#if BOOST_UNORDERED_USE_ALLOCATOR_TRAITS
+#if BOOST_UNORDERED_USE_ALLOCATOR_TRAITS == 1
     BOOST_MPL_ASSERT((boost::is_same<typename traits::size_type,
         std::make_unsigned<std::ptrdiff_t>::type>));
 #else
Modified: branches/release/libs/unordered/test/unordered/move_tests.cpp
==============================================================================
--- branches/release/libs/unordered/test/unordered/move_tests.cpp	(original)
+++ branches/release/libs/unordered/test/unordered/move_tests.cpp	2012-05-03 18:05:21 EDT (Thu, 03 May 2012)
@@ -4,9 +4,10 @@
 // file LICENSE_1_0.txt or move at http://www.boost.org/LICENSE_1_0.txt)
 
 #include "../helpers/prefix.hpp"
-
 #include <boost/unordered_set.hpp>
 #include <boost/unordered_map.hpp>
+#include "../helpers/postfix.hpp"
+
 #include "../helpers/test.hpp"
 #include "../objects/test.hpp"
 #include "../objects/cxx11_allocator.hpp"
Modified: branches/release/libs/unordered/test/unordered/rehash_tests.cpp
==============================================================================
--- branches/release/libs/unordered/test/unordered/rehash_tests.cpp	(original)
+++ branches/release/libs/unordered/test/unordered/rehash_tests.cpp	2012-05-03 18:05:21 EDT (Thu, 03 May 2012)
@@ -4,9 +4,10 @@
 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 
 #include "../helpers/prefix.hpp"
-
 #include <boost/unordered_set.hpp>
 #include <boost/unordered_map.hpp>
+#include "../helpers/postfix.hpp"
+
 #include "../helpers/test.hpp"
 #include "../helpers/random_values.hpp"
 #include "../helpers/tracker.hpp"
Modified: branches/release/libs/unordered/test/unordered/simple_tests.cpp
==============================================================================
--- branches/release/libs/unordered/test/unordered/simple_tests.cpp	(original)
+++ branches/release/libs/unordered/test/unordered/simple_tests.cpp	2012-05-03 18:05:21 EDT (Thu, 03 May 2012)
@@ -6,9 +6,10 @@
 // This test checks the runtime requirements of containers.
 
 #include "../helpers/prefix.hpp"
-
 #include <boost/unordered_set.hpp>
 #include <boost/unordered_map.hpp>
+#include "../helpers/postfix.hpp"
+
 #include "../helpers/test.hpp"
 #include <cstdlib>
 #include <algorithm>
Modified: branches/release/libs/unordered/test/unordered/swap_tests.cpp
==============================================================================
--- branches/release/libs/unordered/test/unordered/swap_tests.cpp	(original)
+++ branches/release/libs/unordered/test/unordered/swap_tests.cpp	2012-05-03 18:05:21 EDT (Thu, 03 May 2012)
@@ -4,12 +4,13 @@
 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 
 #include "../helpers/prefix.hpp"
+#include <boost/unordered_set.hpp>
+#include <boost/unordered_map.hpp>
+#include "../helpers/postfix.hpp"
 
 #include <boost/config.hpp>
 #include <algorithm>
 #include <iterator>
-#include <boost/unordered_set.hpp>
-#include <boost/unordered_map.hpp>
 #include "../helpers/test.hpp"
 #include "../objects/test.hpp"
 #include "../objects/cxx11_allocator.hpp"
Modified: branches/release/libs/unordered/test/unordered/unnecessary_copy_tests.cpp
==============================================================================
--- branches/release/libs/unordered/test/unordered/unnecessary_copy_tests.cpp	(original)
+++ branches/release/libs/unordered/test/unordered/unnecessary_copy_tests.cpp	2012-05-03 18:05:21 EDT (Thu, 03 May 2012)
@@ -1,12 +1,14 @@
-#include <iostream>
+
 // Copyright 2006-2009 Daniel James.
 // 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)
 
 #include "../helpers/prefix.hpp"
-
 #include <boost/unordered_set.hpp>
 #include <boost/unordered_map.hpp>
+#include "../helpers/postfix.hpp"
+
+#include <iostream>
 #include "../helpers/test.hpp"
 
 #if defined(BOOST_UNORDERED_VARIADIC_MOVE)