diff --git a/doc/ref.xml b/doc/ref.xml
index c0e4bc30..58e14a95 100644
--- a/doc/ref.xml
+++ b/doc/ref.xml
@@ -636,6 +636,25 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
This is a boost extension.
+
+
+
+
+
+
+
+
+
+
+
+
+ unordered_set<Value, Hash, Pred, Alloc> const&
+
+ std::size_t
+
+ This is a boost extension.
+
+
@@ -1293,6 +1312,25 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
This is a boost extension.
+
+
+
+
+
+
+
+
+
+
+
+
+ unordered_multiset<Value, Hash, Pred, Alloc> const&
+
+ std::size_t
+
+ This is a boost extension.
+
+
@@ -2005,6 +2043,27 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
This is a boost extension.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ unordered_map<Key, Mapped, Hash, Pred, Alloc> const&
+
+ std::size_t
+
+ This is a boost extension.
+
+
@@ -2676,6 +2735,27 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
This is a boost extension.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ unordered_multimap<Key, Mapped, Hash, Pred, Alloc> const&
+
+ std::size_t
+
+ This is a boost extension.
+
+
diff --git a/include/boost/unordered/detail/hash_table_impl.hpp b/include/boost/unordered/detail/hash_table_impl.hpp
index 30e662a6..98aac7db 100644
--- a/include/boost/unordered/detail/hash_table_impl.hpp
+++ b/include/boost/unordered/detail/hash_table_impl.hpp
@@ -1926,6 +1926,41 @@ public:
return true;
}
+ inline bool group_hash(local_iterator_base it, type_wrapper*) const
+ {
+ std::size_t seed = group_count(it);
+ boost::hash_combine(seed, hash_function()(*it));
+ return seed;
+ }
+
+ inline bool group_hash(local_iterator_base it, void*) const
+ {
+ std::size_t seed = hash_function()(it->first);
+
+ local_iterator_base end = it;
+ end.next_group();
+
+ do {
+ boost::hash_combine(seed, it->second);
+ } while(it != end);
+
+ return seed;
+ }
+
+ std::size_t hash_value() const
+ {
+ std::size_t seed = 0;
+
+ for(bucket_ptr i = this->cached_begin_bucket_,
+ j = this->buckets_ + this->bucket_count_; i != j; ++i)
+ {
+ for(local_iterator_base it(i->next_); it.not_finished(); it.next_group())
+ seed ^= group_hash(it, (type_wrapper*)0);
+ }
+
+ return seed;
+ }
+
private:
// strong exception safety, no side effects
diff --git a/include/boost/unordered_map.hpp b/include/boost/unordered_map.hpp
index 6fe05b69..7dd7b185 100644
--- a/include/boost/unordered_map.hpp
+++ b/include/boost/unordered_map.hpp
@@ -16,8 +16,8 @@
#include
#include
-#include
#include
+#include
namespace boost
{
@@ -335,6 +335,11 @@ namespace boost
{
return !m1.base.equals(m2.base);
}
+
+ friend std::size_t hash_value(unordered_map const& m)
+ {
+ return m.base.hash_value();
+ }
}; // class template unordered_map
template
@@ -642,6 +647,11 @@ namespace boost
{
return !m1.base.equals(m2.base);
}
+
+ friend std::size_t hash_value(unordered_multimap const& m)
+ {
+ return m.base.hash_value();
+ }
}; // class template unordered_multimap
template
diff --git a/include/boost/unordered_set.hpp b/include/boost/unordered_set.hpp
index 9f713587..f20aef0c 100644
--- a/include/boost/unordered_set.hpp
+++ b/include/boost/unordered_set.hpp
@@ -16,8 +16,8 @@
#include
#include
-#include
#include
+#include
namespace boost
{
@@ -305,6 +305,11 @@ namespace boost
{
return !m1.base.equals(m2.base);
}
+
+ friend std::size_t hash_value(unordered_set const& m)
+ {
+ return m.base.hash_value();
+ }
}; // class template unordered_set
template
@@ -597,6 +602,11 @@ namespace boost
{
return !m1.base.equals(m2.base);
}
+
+ friend std::size_t hash_value(unordered_multiset const& m)
+ {
+ return m.base.hash_value();
+ }
}; // class template unordered_multiset
template
diff --git a/test/container/compile_tests.hpp b/test/container/compile_tests.hpp
index 19455aba..c8a22ae7 100644
--- a/test/container/compile_tests.hpp
+++ b/test/container/compile_tests.hpp
@@ -129,4 +129,9 @@ void equality_test(X& r, T&)
test::check_return_type::equals(a == b);
test::check_return_type::equals(a != b);
+#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
+ test::check_return_type::equals(boost::hash_value(a));
+#else
+ test::check_return_type::equals(hash_value(a));
+#endif
}
diff --git a/test/objects/minimal.hpp b/test/objects/minimal.hpp
index a1450437..f8f84445 100644
--- a/test/objects/minimal.hpp
+++ b/test/objects/minimal.hpp
@@ -57,6 +57,10 @@ namespace minimal
return false;
}
+ std::size_t hash_value(copy_constructible_equality_comparable) {
+ return 1;
+ }
+
class default_copy_constructible
{
public: