diff --git a/doc/ref.xml b/doc/ref.xml
index 36142320..6f8d16cb 100644
--- a/doc/ref.xml
+++ b/doc/ref.xml
@@ -1641,6 +1641,22 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor.
+
+ T&
+ key_type const&
+ T const&
+ key_type const&
+
+ A reference to x.second
where x
is the (unique) element whose key is equivalent to k
.
+
+
+ An exception object of type out_of_range
if no such element is present.
+
+
+ This is not specified in the draft standard, but that is probably an oversight. The issue has been raised in
+ comp.std.c++.
+
+
diff --git a/include/boost/unordered/detail/hash_table.hpp b/include/boost/unordered/detail/hash_table.hpp
index ff1e9767..5d373d5c 100644
--- a/include/boost/unordered/detail/hash_table.hpp
+++ b/include/boost/unordered/detail/hash_table.hpp
@@ -17,6 +17,7 @@
#include
#include
#include
+#include
#include
#include
diff --git a/include/boost/unordered/detail/hash_table_impl.hpp b/include/boost/unordered/detail/hash_table_impl.hpp
index 55b4281d..fd7d08cd 100644
--- a/include/boost/unordered/detail/hash_table_impl.hpp
+++ b/include/boost/unordered/detail/hash_table_impl.hpp
@@ -1839,6 +1839,17 @@ namespace boost {
return this->end();
}
+ value_type& at(key_type const& k) const
+ {
+ bucket_ptr bucket = get_bucket(k);
+ local_iterator_base it = find_iterator(bucket, k);
+
+ if (it.not_finished())
+ return *it;
+ else
+ throw std::out_of_range("Unable to find key in unordered_map.");
+ }
+
// equal_range
//
// strong exception safety, no side effects
diff --git a/include/boost/unordered_map.hpp b/include/boost/unordered_map.hpp
index 7b9af025..1fd2749c 100644
--- a/include/boost/unordered_map.hpp
+++ b/include/boost/unordered_map.hpp
@@ -211,6 +211,16 @@ namespace boost
return base[k].second;
}
+ mapped_type& at(const key_type& k)
+ {
+ return base.at(k).second;
+ }
+
+ mapped_type const& at(const key_type& k) const
+ {
+ return base.at(k).second;
+ }
+
// lookup
iterator find(const key_type& k)
diff --git a/test/objects/minimal.hpp b/test/objects/minimal.hpp
index 63863318..a0312fc0 100644
--- a/test/objects/minimal.hpp
+++ b/test/objects/minimal.hpp
@@ -18,6 +18,7 @@ namespace test
namespace minimal
{
class copy_constructible;
+ class default_copy_constructible;
class assignable;
template class hash;
template class equal_to;
@@ -36,6 +37,17 @@ namespace minimal
copy_constructible() {}
};
+ class default_copy_constructible
+ {
+ public:
+ static default_copy_constructible create() { return default_copy_constructible(); }
+ default_copy_constructible() {}
+ default_copy_constructible(default_copy_constructible const&) {}
+ ~default_copy_constructible() {}
+ private:
+ default_copy_constructible& operator=(default_copy_constructible const&);
+ };
+
class assignable
{
public:
diff --git a/test/unordered/Jamfile.v2 b/test/unordered/Jamfile.v2
index c3dce0b3..83e684d5 100644
--- a/test/unordered/Jamfile.v2
+++ b/test/unordered/Jamfile.v2
@@ -25,6 +25,7 @@ test-suite unordered-tests
[ run erase_tests.cpp ]
[ run erase_equiv_tests.cpp ]
[ run find_tests.cpp ]
+ [ run at_tests.cpp ]
[ run bucket_tests.cpp ]
[ run load_factor_tests.cpp ]
[ run rehash_tests.cpp ]
diff --git a/test/unordered/compile_tests.cpp b/test/unordered/compile_tests.cpp
index 7a0ba38f..f6aabca8 100644
--- a/test/unordered/compile_tests.cpp
+++ b/test/unordered/compile_tests.cpp
@@ -58,6 +58,19 @@ void unordered_equivalent_test(X& r, T const& t)
test::check_return_type::equals(r.insert(t));
}
+template
+void unordered_map_functions(X&, Key const& k, T const& t)
+{
+ typedef typename X::mapped_type mapped_type;
+
+ X a;
+ test::check_return_type::equals_ref(a[k]);
+ test::check_return_type::equals_ref(a.at(k));
+
+ X const b = a;
+ test::check_return_type::equals_ref(b.at(k));
+}
+
template
void unordered_test(X&, Key& k, T& t, Hash& hf, Pred& eq)
{
@@ -217,6 +230,7 @@ void test1()
unordered_unique_test(map, map_value);
unordered_map_test(map, value, value);
unordered_test(map, value, map_value, hash, equal_to);
+ unordered_map_functions(map, value, value);
std::cout<<"Test unordered_multimap.\n";
@@ -279,6 +293,18 @@ void test2()
unordered_map_test(map, assignable, copy_constructible);
unordered_test(map, assignable, map_value, hash, equal_to);
+
+ boost::unordered_map<
+ test::minimal::assignable,
+ test::minimal::default_copy_constructible,
+ test::minimal::hash,
+ test::minimal::equal_to,
+ test::minimal::allocator > map2;
+
+ test::minimal::default_copy_constructible default_copy_constructible;
+
+ unordered_map_functions(map2, assignable, default_copy_constructible);
+
std::cout<<"Test unordered_multimap.\n";
boost::unordered_multimap<