diff --git a/include/boost/unordered/detail/implementation.hpp b/include/boost/unordered/detail/implementation.hpp index 8661e408..e1cfc2e7 100644 --- a/include/boost/unordered/detail/implementation.hpp +++ b/include/boost/unordered/detail/implementation.hpp @@ -701,18 +701,23 @@ namespace boost { //////////////////////////////////////////////////////////////////////////// // Type checkers used for the transparent member functions added by C++20 and up - template - struct is_transparent : public false_type + template struct is_transparent : public false_type { }; - template - struct is_transparent + struct is_transparent::type> : public true_type { }; + template struct are_transparent + { + static bool const value = + is_transparent::value && is_transparent::value; + }; + //////////////////////////////////////////////////////////////////////////// // Explicitly call a destructor diff --git a/include/boost/unordered/unordered_map.hpp b/include/boost/unordered/unordered_map.hpp index a41e1d9c..c9fd46d2 100644 --- a/include/boost/unordered/unordered_map.hpp +++ b/include/boost/unordered/unordered_map.hpp @@ -432,8 +432,7 @@ namespace boost { template typename boost::enable_if_c< - detail::is_transparent::value && - detail::is_transparent::value && + detail::are_transparent::value && !boost::is_convertible::value && !boost::is_convertible::value, node_type>::type @@ -725,8 +724,7 @@ namespace boost { template typename boost::enable_if_c< - detail::is_transparent::value && - detail::is_transparent::value && + detail::are_transparent::value && !boost::is_convertible::value && !boost::is_convertible::value, size_type>::type @@ -774,8 +772,7 @@ namespace boost { const_iterator find(const key_type&) const; template - typename boost::enable_if_c::value && - detail::is_transparent::value, + typename boost::enable_if_c::value, iterator>::type find(const Key& key) { @@ -785,8 +782,7 @@ namespace boost { } template - typename boost::enable_if_c::value && - detail::is_transparent::value, + typename boost::enable_if_c::value, const_iterator>::type find(const Key& key) const { @@ -808,8 +804,7 @@ namespace boost { size_type count(const key_type&) const; template - typename boost::enable_if_c::value && - detail::is_transparent::value, + typename boost::enable_if_c::value, size_type>::type count(const Key& k) const { @@ -828,8 +823,7 @@ namespace boost { const key_type&) const; template - typename boost::enable_if_c::value && - detail::is_transparent::value, + typename boost::enable_if_c::value, std::pair >::type equal_range(const Key& key) { @@ -842,8 +836,7 @@ namespace boost { } template - typename boost::enable_if_c::value && - detail::is_transparent::value, + typename boost::enable_if_c::value, std::pair >::type equal_range(const Key& key) const { @@ -1448,6 +1441,26 @@ namespace boost { iterator find(const key_type&); const_iterator find(const key_type&) const; + template + typename boost::enable_if_c::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, + 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 b52f31d1..4c544092 100644 --- a/test/unordered/transparent_tests.cpp +++ b/test/unordered/transparent_tests.cpp @@ -164,11 +164,10 @@ template void test_transparent_find() int n = 5; for (int i = 0; i < n; ++i) { - map[key(i)] = i; + map.insert(std::make_pair(i, i)); } - int const expected_key_count = 2 * n; - BOOST_TEST(key::count_ == expected_key_count); + int const expected_key_count = key::count_; // explicitly test `find()` and `find() const` separately // @@ -183,14 +182,14 @@ template void test_transparent_find() pair const& p = *pos; int const v = p.second; - BOOST_TEST(v == i); + BOOST_TEST_EQ(v, i); } - BOOST_TEST(key::count_ == expected_key_count); + BOOST_TEST_EQ(key::count_, expected_key_count); map_iterator pos = m.find(1337); BOOST_TEST(pos == m.end()); - BOOST_TEST(key::count_ == expected_key_count); + BOOST_TEST_EQ(key::count_, expected_key_count); } { @@ -206,11 +205,11 @@ template void test_transparent_find() BOOST_TEST(v == i); } - BOOST_TEST(key::count_ == expected_key_count); + BOOST_TEST_EQ(key::count_, expected_key_count); map_iterator pos = m.find(1337); BOOST_TEST(pos == m.end()); - BOOST_TEST(key::count_ == expected_key_count); + BOOST_TEST_EQ(key::count_, expected_key_count); } } @@ -226,12 +225,10 @@ template void test_non_transparent_find() int n = 5; for (int i = 0; i < n; ++i) { - map[key(i)] = i; + map.insert(std::make_pair(i, i)); } - int key_count = 2 * n; - - BOOST_TEST(key::count_ == key_count); + int key_count = key::count_; // explicitly test `find()` and `find() const` separately // @@ -246,13 +243,13 @@ template void test_non_transparent_find() pair const& p = *pos; int const v = p.second; - BOOST_TEST(v == i); + BOOST_TEST_EQ(v, i); } - BOOST_TEST(key::count_ == n + key_count); + BOOST_TEST_EQ(key::count_, n + key_count); map_iterator pos = m.find(1337); BOOST_TEST(pos == m.end()); - BOOST_TEST(key::count_ == 1 + n + key_count); + BOOST_TEST_EQ(key::count_, 1 + n + key_count); key_count = key::count_; } @@ -267,13 +264,13 @@ template void test_non_transparent_find() pair const& p = *pos; int const v = p.second; - BOOST_TEST(v == i); + BOOST_TEST_EQ(v, i); } - BOOST_TEST(key::count_ == n + key_count); + BOOST_TEST_EQ(key::count_, n + key_count); map_iterator pos = m.find(1337); BOOST_TEST(pos == m.end()); - BOOST_TEST(key::count_ == 1 + n + key_count); + BOOST_TEST_EQ(key::count_, 1 + n + key_count); } } @@ -738,7 +735,8 @@ template void test_non_transparent_extract() BOOST_TEST_EQ(key::count_, key_count); } -UNORDERED_AUTO_TEST (unordered_map_transparent_count) { +void test_unordered_map() +{ { typedef boost::unordered_map @@ -790,4 +788,47 @@ UNORDERED_AUTO_TEST (unordered_map_transparent_count) { } } +void test_unordered_multimap() +{ + { + typedef boost::unordered_multimap + unordered_multimap; + + test_transparent_find(); + } + + { + // non-transparent Hash, non-transparent KeyEqual + // + typedef boost::unordered_multimap + unordered_multimap; + + test_non_transparent_find(); + } + + { + // transparent Hash, non-transparent KeyEqual + // + typedef boost::unordered_multimap + unordered_multimap; + + test_non_transparent_find(); + } + + { + // non-transparent Hash, transparent KeyEqual + // + typedef boost::unordered_multimap + unordered_multimap; + + test_non_transparent_find(); + } +} + +UNORDERED_AUTO_TEST (transparent_ops) { + test_unordered_map(); + test_unordered_multimap(); +} + RUN_TESTS()