From 4e37a14bf870a37c2d6362028020692f3ebe17fe Mon Sep 17 00:00:00 2001 From: Christian Mazakas Date: Mon, 20 Dec 2021 08:41:06 -0800 Subject: [PATCH 1/3] Update transparent `equal_range()` tests to use `BOOST_TEST_EQ` where applicable --- test/unordered/transparent_tests.cpp | 56 ++++++++++++++-------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/test/unordered/transparent_tests.cpp b/test/unordered/transparent_tests.cpp index 4c544092..81bdbcdd 100644 --- a/test/unordered/transparent_tests.cpp +++ b/test/unordered/transparent_tests.cpp @@ -298,7 +298,7 @@ template void test_transparent_equal_range() BOOST_TEST(begin == end); BOOST_TEST(begin == map.end()); - BOOST_TEST(std::distance(begin, end) == 0); + BOOST_TEST_EQ(std::distance(begin, end), 0); } { @@ -315,10 +315,10 @@ template void test_transparent_equal_range() BOOST_TEST(begin == end); BOOST_TEST(begin == map.end()); - BOOST_TEST(std::distance(begin, end) == 0); + BOOST_TEST_EQ(std::distance(begin, end), 0); } - BOOST_TEST(key::count_ == 0); + BOOST_TEST_EQ(key::count_, 0); unordered_map[key(0)] = 1337; unordered_map[key(1)] = 1338; @@ -326,7 +326,7 @@ template void test_transparent_equal_range() int const expected_key_count = 6; - BOOST_TEST(key::count_ == expected_key_count); + BOOST_TEST_EQ(key::count_, expected_key_count); typedef typename UnorderedMap::value_type value_type; @@ -345,11 +345,11 @@ template void test_transparent_equal_range() BOOST_TEST(begin != end); BOOST_TEST(begin != map.end()); - BOOST_TEST(std::distance(begin, end) == 1); + BOOST_TEST_EQ(std::distance(begin, end), 1); value_type const& val = *begin; - BOOST_TEST(val.first.x_ == 0); - BOOST_TEST(val.second == 1337); + BOOST_TEST_EQ(val.first.x_, 0); + BOOST_TEST_EQ(val.second, 1337); iters = map.equal_range(1337); @@ -358,9 +358,9 @@ template void test_transparent_equal_range() BOOST_TEST(begin == end); BOOST_TEST(begin == map.end()); - BOOST_TEST(std::distance(begin, end) == 0); + BOOST_TEST_EQ(std::distance(begin, end), 0); - BOOST_TEST(key::count_ == expected_key_count); + BOOST_TEST_EQ(key::count_, expected_key_count); } { @@ -376,11 +376,11 @@ template void test_transparent_equal_range() BOOST_TEST(begin != end); BOOST_TEST(begin != map.end()); - BOOST_TEST(std::distance(begin, end) == 1); + BOOST_TEST_EQ(std::distance(begin, end), 1); value_type const& val = *begin; - BOOST_TEST(val.first.x_ == 0); - BOOST_TEST(val.second == 1337); + BOOST_TEST_EQ(val.first.x_, 0); + BOOST_TEST_EQ(val.second, 1337); iters = map.equal_range(1337); @@ -389,9 +389,9 @@ template void test_transparent_equal_range() BOOST_TEST(begin == end); BOOST_TEST(begin == map.end()); - BOOST_TEST(std::distance(begin, end) == 0); + BOOST_TEST_EQ(std::distance(begin, end), 0); - BOOST_TEST(key::count_ == expected_key_count); + BOOST_TEST_EQ(key::count_, expected_key_count); } } @@ -419,7 +419,7 @@ template void test_non_transparent_equal_range() BOOST_TEST(begin == end); BOOST_TEST(begin == map.end()); - BOOST_TEST(std::distance(begin, end) == 0); + BOOST_TEST_EQ(std::distance(begin, end), 0); } { @@ -436,10 +436,10 @@ template void test_non_transparent_equal_range() BOOST_TEST(begin == end); BOOST_TEST(begin == map.end()); - BOOST_TEST(std::distance(begin, end) == 0); + BOOST_TEST_EQ(std::distance(begin, end), 0); } - BOOST_TEST(key::count_ == 2); + BOOST_TEST_EQ(key::count_, 2); unordered_map[key(0)] = 1337; unordered_map[key(1)] = 1338; @@ -447,7 +447,7 @@ template void test_non_transparent_equal_range() int key_count = 8; - BOOST_TEST(key::count_ == key_count); + BOOST_TEST_EQ(key::count_, key_count); typedef typename UnorderedMap::value_type value_type; @@ -466,11 +466,11 @@ template void test_non_transparent_equal_range() BOOST_TEST(begin != end); BOOST_TEST(begin != map.end()); - BOOST_TEST(std::distance(begin, end) == 1); + BOOST_TEST_EQ(std::distance(begin, end), 1); value_type const& val = *begin; - BOOST_TEST(val.first.x_ == 0); - BOOST_TEST(val.second == 1337); + BOOST_TEST_EQ(val.first.x_, 0); + BOOST_TEST_EQ(val.second, 1337); iters = map.equal_range(1337); @@ -479,9 +479,9 @@ template void test_non_transparent_equal_range() BOOST_TEST(begin == end); BOOST_TEST(begin == map.end()); - BOOST_TEST(std::distance(begin, end) == 0); + BOOST_TEST_EQ(std::distance(begin, end), 0); - BOOST_TEST(key::count_ == 2 + key_count); + BOOST_TEST_EQ(key::count_, 2 + key_count); key_count += 2; } @@ -498,11 +498,11 @@ template void test_non_transparent_equal_range() BOOST_TEST(begin != end); BOOST_TEST(begin != map.end()); - BOOST_TEST(std::distance(begin, end) == 1); + BOOST_TEST_EQ(std::distance(begin, end), 1); value_type const& val = *begin; - BOOST_TEST(val.first.x_ == 0); - BOOST_TEST(val.second == 1337); + BOOST_TEST_EQ(val.first.x_, 0); + BOOST_TEST_EQ(val.second, 1337); iters = map.equal_range(1337); @@ -511,9 +511,9 @@ template void test_non_transparent_equal_range() BOOST_TEST(begin == end); BOOST_TEST(begin == map.end()); - BOOST_TEST(std::distance(begin, end) == 0); + BOOST_TEST_EQ(std::distance(begin, end), 0); - BOOST_TEST(key::count_ == 2 + key_count); + BOOST_TEST_EQ(key::count_, 2 + key_count); } } From 3d5a2d26d1b35a2c4de590980c974001fcacaf90 Mon Sep 17 00:00:00 2001 From: Christian Mazakas Date: Mon, 20 Dec 2021 08:50:30 -0800 Subject: [PATCH 2/3] Add test support for multimap's `equal_range()` --- test/unordered/transparent_tests.cpp | 70 +++++++++++++++++----------- 1 file changed, 44 insertions(+), 26 deletions(-) diff --git a/test/unordered/transparent_tests.cpp b/test/unordered/transparent_tests.cpp index 81bdbcdd..9cf3eda6 100644 --- a/test/unordered/transparent_tests.cpp +++ b/test/unordered/transparent_tests.cpp @@ -320,13 +320,18 @@ template void test_transparent_equal_range() BOOST_TEST_EQ(key::count_, 0); - unordered_map[key(0)] = 1337; - unordered_map[key(1)] = 1338; - unordered_map[key(2)] = 1339; + unordered_map.insert(std::make_pair(0, 1337)); + unordered_map.insert(std::make_pair(1, 1338)); + unordered_map.insert(std::make_pair(2, 1339)); + unordered_map.insert(std::make_pair(0, 1340)); + unordered_map.insert(std::make_pair(0, 1341)); + unordered_map.insert(std::make_pair(0, 1342)); - int const expected_key_count = 6; + int const expected_key_count = key::count_; - BOOST_TEST_EQ(key::count_, expected_key_count); + // do this so that multimap tests actually test a range with len > 1 + // + int const expected_range_len = static_cast(unordered_map.size() - 2); typedef typename UnorderedMap::value_type value_type; @@ -345,11 +350,12 @@ template void test_transparent_equal_range() BOOST_TEST(begin != end); BOOST_TEST(begin != map.end()); - BOOST_TEST_EQ(std::distance(begin, end), 1); + BOOST_TEST_EQ(std::distance(begin, end), expected_range_len); - value_type const& val = *begin; - BOOST_TEST_EQ(val.first.x_, 0); - BOOST_TEST_EQ(val.second, 1337); + for (iterator pos = begin; pos != end; ++pos) { + value_type const& val = *pos; + BOOST_TEST_EQ(val.first.x_, 0); + } iters = map.equal_range(1337); @@ -376,11 +382,12 @@ template void test_transparent_equal_range() BOOST_TEST(begin != end); BOOST_TEST(begin != map.end()); - BOOST_TEST_EQ(std::distance(begin, end), 1); + BOOST_TEST_EQ(std::distance(begin, end), expected_range_len); - value_type const& val = *begin; - BOOST_TEST_EQ(val.first.x_, 0); - BOOST_TEST_EQ(val.second, 1337); + for (iterator pos = begin; pos != end; ++pos) { + value_type const& val = *begin; + BOOST_TEST_EQ(val.first.x_, 0); + } iters = map.equal_range(1337); @@ -441,13 +448,18 @@ template void test_non_transparent_equal_range() BOOST_TEST_EQ(key::count_, 2); - unordered_map[key(0)] = 1337; - unordered_map[key(1)] = 1338; - unordered_map[key(2)] = 1339; + unordered_map.insert(std::make_pair(0, 1337)); + unordered_map.insert(std::make_pair(1, 1338)); + unordered_map.insert(std::make_pair(2, 1339)); + unordered_map.insert(std::make_pair(0, 1340)); + unordered_map.insert(std::make_pair(0, 1341)); + unordered_map.insert(std::make_pair(0, 1342)); - int key_count = 8; + int key_count = key::count_; - BOOST_TEST_EQ(key::count_, key_count); + // do this so that multimap tests actually test a range with len > 1 + // + int const expected_range_len = static_cast(unordered_map.size() - 2); typedef typename UnorderedMap::value_type value_type; @@ -466,11 +478,12 @@ template void test_non_transparent_equal_range() BOOST_TEST(begin != end); BOOST_TEST(begin != map.end()); - BOOST_TEST_EQ(std::distance(begin, end), 1); + BOOST_TEST_EQ(std::distance(begin, end), expected_range_len); - value_type const& val = *begin; - BOOST_TEST_EQ(val.first.x_, 0); - BOOST_TEST_EQ(val.second, 1337); + for (iterator pos = begin; pos != end; ++pos) { + value_type const& val = *begin; + BOOST_TEST_EQ(val.first.x_, 0); + } iters = map.equal_range(1337); @@ -498,11 +511,12 @@ template void test_non_transparent_equal_range() BOOST_TEST(begin != end); BOOST_TEST(begin != map.end()); - BOOST_TEST_EQ(std::distance(begin, end), 1); + BOOST_TEST_EQ(std::distance(begin, end), expected_range_len); - value_type const& val = *begin; - BOOST_TEST_EQ(val.first.x_, 0); - BOOST_TEST_EQ(val.second, 1337); + for (iterator pos = begin; pos != end; ++pos) { + value_type const& val = *pos; + BOOST_TEST_EQ(val.first.x_, 0); + } iters = map.equal_range(1337); @@ -796,6 +810,7 @@ void test_unordered_multimap() unordered_multimap; test_transparent_find(); + test_transparent_equal_range(); } { @@ -805,6 +820,7 @@ void test_unordered_multimap() unordered_multimap; test_non_transparent_find(); + test_non_transparent_equal_range(); } { @@ -814,6 +830,7 @@ void test_unordered_multimap() unordered_multimap; test_non_transparent_find(); + test_non_transparent_equal_range(); } { @@ -823,6 +840,7 @@ void test_unordered_multimap() unordered_multimap; test_non_transparent_find(); + test_non_transparent_equal_range(); } } From 19d2fe87387911e5510c193d07fec57f3300880f Mon Sep 17 00:00:00 2001 From: Christian Mazakas Date: Mon, 20 Dec 2021 09:28:04 -0800 Subject: [PATCH 3/3] Implement heterogeneous `equal_range()` for multimap --- include/boost/unordered/unordered_map.hpp | 26 +++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/include/boost/unordered/unordered_map.hpp b/include/boost/unordered/unordered_map.hpp index c9fd46d2..82cb7f80 100644 --- a/include/boost/unordered/unordered_map.hpp +++ b/include/boost/unordered/unordered_map.hpp @@ -1477,6 +1477,32 @@ namespace boost { std::pair equal_range( const key_type&) const; + template + typename boost::enable_if_c::value, + std::pair >::type + equal_range(const Key& key) + { + node_pointer p = table_.find_node_impl( + table::policy::apply_hash(this->hash_function(), key), key, + this->key_eq()); + + return std::make_pair( + iterator(p), iterator(p ? table_.next_group(p) : p)); + } + + template + typename boost::enable_if_c::value, + std::pair >::type + equal_range(const Key& key) const + { + node_pointer p = table_.find_node_impl( + table::policy::apply_hash(this->hash_function(), key), key, + this->key_eq()); + + return std::make_pair( + const_iterator(p), const_iterator(p ? table_.next_group(p) : p)); + } + // bucket interface size_type bucket_count() const BOOST_NOEXCEPT