diff --git a/include/boost/unordered/unordered_map.hpp b/include/boost/unordered/unordered_map.hpp index 3535fc7e..a566dee9 100644 --- a/include/boost/unordered/unordered_map.hpp +++ b/include/boost/unordered/unordered_map.hpp @@ -745,6 +745,28 @@ namespace boost { iterator find(const key_type&); const_iterator find(const key_type&) const; + template + typename boost::enable_if_c::value && + detail::is_transparent::value, + iterator>::type + find(const Key& key) + { + return iterator(table_.find_node_impl( + table::policy::apply_hash(this->hash_function(), key), key, + this->key_eq())); + } + + template + typename boost::enable_if_c::value && + detail::is_transparent::value, + const_iterator>::type + find(const Key& key) const + { + return const_iterator(table_.find_node_impl( + table::policy::apply_hash(this->hash_function(), key), key, + this->key_eq())); + } + template iterator find(CompatibleKey const&, CompatibleHash const&, diff --git a/test/unordered/transparent_tests.cpp b/test/unordered/transparent_tests.cpp index a0289c94..f4173d84 100644 --- a/test/unordered/transparent_tests.cpp +++ b/test/unordered/transparent_tests.cpp @@ -147,24 +147,169 @@ template void test_non_transparent_count() BOOST_TEST(key::count_ == 5); } +template void test_transparent_find() +{ + count_reset(); + + typedef typename UnorderedMap::const_iterator map_iterator; + typedef typename UnorderedMap::value_type pair; + + UnorderedMap map; + + int n = 5; + + for (int i = 0; i < n; ++i) { + map[key(i)] = i; + } + + int const expected_key_count = 2 * n; + BOOST_TEST(key::count_ == expected_key_count); + + // explicitly test `find()` and `find() const` separately + // + + { + UnorderedMap& m = map; + + for (int i = 0; i < n; ++i) { + map_iterator pos = m.find(i); + BOOST_TEST(pos != m.end()); + + pair const& p = *pos; + int const v = p.second; + + BOOST_TEST(v == i); + } + + BOOST_TEST(key::count_ == expected_key_count); + + map_iterator pos = m.find(1337); + BOOST_TEST(pos == m.end()); + BOOST_TEST(key::count_ == expected_key_count); + } + + { + UnorderedMap const& m = map; + + for (int i = 0; i < n; ++i) { + map_iterator pos = m.find(i); + BOOST_TEST(pos != m.end()); + + pair const& p = *pos; + int const v = p.second; + + BOOST_TEST(v == i); + } + + BOOST_TEST(key::count_ == expected_key_count); + + map_iterator pos = m.find(1337); + BOOST_TEST(pos == m.end()); + BOOST_TEST(key::count_ == expected_key_count); + } +} + +template void test_non_transparent_find() +{ + count_reset(); + + typedef typename UnorderedMap::const_iterator map_iterator; + typedef typename UnorderedMap::value_type pair; + + UnorderedMap map; + + int n = 5; + + for (int i = 0; i < n; ++i) { + map[key(i)] = i; + } + + int key_count = 2 * n; + + BOOST_TEST(key::count_ == key_count); + + // explicitly test `find()` and `find() const` separately + // + + { + UnorderedMap& m = map; + + for (int i = 0; i < n; ++i) { + map_iterator pos = m.find(i); + BOOST_TEST(pos != m.end()); + + pair const& p = *pos; + int const v = p.second; + + BOOST_TEST(v == i); + } + BOOST_TEST(key::count_ == n + key_count); + + map_iterator pos = m.find(1337); + BOOST_TEST(pos == m.end()); + BOOST_TEST(key::count_ == 1 + n + key_count); + + key_count = key::count_; + } + + { + UnorderedMap const& m = map; + + for (int i = 0; i < n; ++i) { + map_iterator pos = m.find(i); + BOOST_TEST(pos != m.end()); + + pair const& p = *pos; + int const v = p.second; + + BOOST_TEST(v == i); + } + BOOST_TEST(key::count_ == n + key_count); + + map_iterator pos = m.find(1337); + BOOST_TEST(pos == m.end()); + BOOST_TEST(key::count_ == 1 + n + key_count); + } +} + UNORDERED_AUTO_TEST (unordered_map_transparent_count) { - test_transparent_count >(); + { + typedef boost::unordered_map + unordered_map; - // non-transparent Hash, non-transparent KeyEqual - // - test_non_transparent_count< - boost::unordered_map >(); + test_transparent_count(); + test_transparent_find(); + } - // transparent Hash, non-transparent KeyEqual - // - test_non_transparent_count< - boost::unordered_map >(); + { + // non-transparent Hash, non-transparent KeyEqual + // + typedef boost::unordered_map unordered_map; - // non-transparent Hash, transparent KeyEqual - // - test_non_transparent_count< - boost::unordered_map >(); + test_non_transparent_count(); + test_non_transparent_find(); + } + + { + // transparent Hash, non-transparent KeyEqual + // + typedef boost::unordered_map + unordered_map; + + test_non_transparent_count(); + test_non_transparent_find(); + } + + { + // non-transparent Hash, transparent KeyEqual + // + typedef boost::unordered_map + unordered_map; + + test_non_transparent_count(); + test_non_transparent_find(); + } } RUN_TESTS()