From 8f1fc75fdfcf4e6227f936b14fa4e6224df4d95b Mon Sep 17 00:00:00 2001 From: LeonineKing1199 Date: Mon, 29 Nov 2021 14:37:04 -0800 Subject: [PATCH] Implement heterogeneous `find()` --- include/boost/unordered/unordered_map.hpp | 22 +++ test/unordered/transparent_tests.cpp | 167 ++++++++++++++++++++-- 2 files changed, 175 insertions(+), 14 deletions(-) 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..959ca49f 100644 --- a/test/unordered/transparent_tests.cpp +++ b/test/unordered/transparent_tests.cpp @@ -147,24 +147,163 @@ 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); + + { + 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); + + { + 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()