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<