From c4345c809e169e17ceabccc3e11ea6e7916415d7 Mon Sep 17 00:00:00 2001 From: Christian Mazakas Date: Wed, 22 Dec 2021 14:55:28 -0800 Subject: [PATCH 1/5] Add `ostream` support for `key` type used in transparent tests --- test/unordered/transparent_tests.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/unordered/transparent_tests.cpp b/test/unordered/transparent_tests.cpp index 6656e95f..06b2f7a1 100644 --- a/test/unordered/transparent_tests.cpp +++ b/test/unordered/transparent_tests.cpp @@ -24,6 +24,12 @@ struct key int key::count_; +std::ostream& operator<<(std::ostream& os, key const& k) +{ + os << "key { x_: " << k.x_ << " }"; + return os; +} + struct transparent_hasher { typedef void is_transparent; From c2d3713f408731b0b9b597748d763c4fae97f5dc Mon Sep 17 00:00:00 2001 From: Christian Mazakas Date: Wed, 22 Dec 2021 14:55:55 -0800 Subject: [PATCH 2/5] Update `key` type in transparent tests to be comparable with plain ints --- test/unordered/transparent_tests.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/test/unordered/transparent_tests.cpp b/test/unordered/transparent_tests.cpp index 06b2f7a1..c404b095 100644 --- a/test/unordered/transparent_tests.cpp +++ b/test/unordered/transparent_tests.cpp @@ -30,6 +30,9 @@ std::ostream& operator<<(std::ostream& os, key const& k) return os; } +bool operator==(key const& k, int const x) { return k.x_ == x; } +bool operator==(int const x, key const& k) { return k.x_ == x; } + struct transparent_hasher { typedef void is_transparent; @@ -47,8 +50,8 @@ struct transparent_key_equal typedef void is_transparent; bool operator()(key const& k1, key const& k2) const { return k1.x_ == k2.x_; } - bool operator()(int const x, key const& k1) const { return k1.x_ == x; } - bool operator()(key const& k1, int const x) const { return k1.x_ == x; } + bool operator()(int const x, key const& k1) const { return k1 == x; } + bool operator()(key const& k1, int const x) const { return k1 == x; } }; struct hasher From b39b6b76353ec1a7f27bf6bff41faf191d744721 Mon Sep 17 00:00:00 2001 From: Christian Mazakas Date: Wed, 22 Dec 2021 15:03:40 -0800 Subject: [PATCH 3/5] Rename transparent find tests to specify that they're for maps specifically --- test/unordered/transparent_tests.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/test/unordered/transparent_tests.cpp b/test/unordered/transparent_tests.cpp index c404b095..39c0186a 100644 --- a/test/unordered/transparent_tests.cpp +++ b/test/unordered/transparent_tests.cpp @@ -131,7 +131,7 @@ template void test_non_transparent_count() BOOST_TEST_EQ(key::count_, key_count); } -template void test_transparent_find() +template void test_map_transparent_find() { count_reset(); @@ -192,7 +192,7 @@ template void test_transparent_find() } } -template void test_non_transparent_find() +template void test_map_non_transparent_find() { count_reset(); @@ -770,7 +770,7 @@ void test_unordered_map() unordered_map; test_transparent_count(); - test_transparent_find(); + test_map_transparent_find(); test_transparent_equal_range(); test_transparent_erase(); test_transparent_extract(); @@ -782,7 +782,7 @@ void test_unordered_map() typedef boost::unordered_map unordered_map; test_non_transparent_count(); - test_non_transparent_find(); + test_map_non_transparent_find(); test_non_transparent_equal_range(); test_non_transparent_erase(); test_non_transparent_extract(); @@ -795,7 +795,7 @@ void test_unordered_map() unordered_map; test_non_transparent_count(); - test_non_transparent_find(); + test_map_non_transparent_find(); test_non_transparent_equal_range(); test_non_transparent_erase(); test_non_transparent_extract(); @@ -808,7 +808,7 @@ void test_unordered_map() unordered_map; test_non_transparent_count(); - test_non_transparent_find(); + test_map_non_transparent_find(); test_non_transparent_equal_range(); test_non_transparent_erase(); test_non_transparent_extract(); @@ -823,7 +823,7 @@ void test_unordered_multimap() unordered_multimap; test_transparent_count(); - test_transparent_find(); + test_map_transparent_find(); test_transparent_equal_range(); test_transparent_erase(); test_transparent_extract(); @@ -836,7 +836,7 @@ void test_unordered_multimap() unordered_multimap; test_non_transparent_count(); - test_non_transparent_find(); + test_map_non_transparent_find(); test_non_transparent_equal_range(); test_non_transparent_erase(); test_non_transparent_extract(); @@ -849,7 +849,7 @@ void test_unordered_multimap() unordered_multimap; test_non_transparent_count(); - test_non_transparent_find(); + test_map_non_transparent_find(); test_non_transparent_equal_range(); test_non_transparent_erase(); test_non_transparent_extract(); @@ -862,7 +862,7 @@ void test_unordered_multimap() unordered_multimap; test_non_transparent_count(); - test_non_transparent_find(); + test_map_non_transparent_find(); test_non_transparent_equal_range(); test_non_transparent_erase(); test_non_transparent_extract(); From 1b009da4d0f0b24bf93749e2da379866c32ae03d Mon Sep 17 00:00:00 2001 From: Christian Mazakas Date: Wed, 22 Dec 2021 15:03:59 -0800 Subject: [PATCH 4/5] Add transparent test support for set's `find()` --- test/unordered/transparent_tests.cpp | 149 +++++++++++++++++++++++++++ 1 file changed, 149 insertions(+) diff --git a/test/unordered/transparent_tests.cpp b/test/unordered/transparent_tests.cpp index 39c0186a..c53c2292 100644 --- a/test/unordered/transparent_tests.cpp +++ b/test/unordered/transparent_tests.cpp @@ -253,6 +253,118 @@ template void test_map_non_transparent_find() } } +template void test_set_transparent_find() +{ + count_reset(); + + typedef typename UnorderedSet::const_iterator set_iterator; + + UnorderedSet set; + + int n = 5; + + for (int i = 0; i < n; ++i) { + set.insert(i); + } + + int const expected_key_count = key::count_; + + // explicitly test `find()` and `find() const` separately + // + + { + UnorderedSet& m = set; + + for (int i = 0; i < n; ++i) { + set_iterator pos = m.find(i); + BOOST_TEST(pos != m.end()); + BOOST_TEST_EQ(*pos, i); + } + + BOOST_TEST_EQ(key::count_, expected_key_count); + + set_iterator pos = m.find(1337); + BOOST_TEST(pos == m.end()); + BOOST_TEST_EQ(key::count_, expected_key_count); + } + + { + UnorderedSet const& m = set; + + for (int i = 0; i < n; ++i) { + set_iterator pos = m.find(i); + BOOST_TEST(pos != m.end()); + BOOST_TEST_EQ(*pos, i); + } + + BOOST_TEST_EQ(key::count_, expected_key_count); + + set_iterator pos = m.find(1337); + BOOST_TEST(pos == m.end()); + BOOST_TEST_EQ(key::count_, expected_key_count); + } +} + +template void test_set_non_transparent_find() +{ + count_reset(); + + typedef typename UnorderedSet::const_iterator set_iterator; + + UnorderedSet set; + + int n = 5; + + for (int i = 0; i < n; ++i) { + set.insert(i); + } + + int key_count = key::count_; + + // explicitly test `find()` and `find() const` separately + // + + { + UnorderedSet& m = set; + + for (int i = 0; i < n; ++i) { + set_iterator pos = m.find(i); + ++key_count; + + BOOST_TEST(pos != m.end()); + BOOST_TEST_EQ(*pos, i); + } + + BOOST_TEST_EQ(key::count_, key_count); + + set_iterator pos = m.find(1337); + ++key_count; + + BOOST_TEST(pos == m.end()); + BOOST_TEST_EQ(key::count_, key_count); + } + + { + UnorderedSet const& m = set; + + for (int i = 0; i < n; ++i) { + set_iterator pos = m.find(i); + ++key_count; + + BOOST_TEST(pos != m.end()); + BOOST_TEST_EQ(*pos, i); + } + + BOOST_TEST_EQ(key::count_, key_count); + + set_iterator pos = m.find(1337); + ++key_count; + + BOOST_TEST(pos == m.end()); + BOOST_TEST_EQ(key::count_, key_count); + } +} + template void test_transparent_equal_range() { count_reset(); @@ -869,9 +981,46 @@ void test_unordered_multimap() } } +void test_unordered_set() +{ + { + typedef boost::unordered_set + unordered_set; + + test_set_transparent_find(); + } + + { + // non-transparent Hash, non-transparent KeyEqual + // + typedef boost::unordered_set unordered_set; + + test_set_non_transparent_find(); + } + + { + // transparent Hash, non-transparent KeyEqual + // + typedef boost::unordered_set + unordered_set; + + test_set_non_transparent_find(); + } + + { + // non-transparent Hash, transparent KeyEqual + // + typedef boost::unordered_set + unordered_set; + + test_set_non_transparent_find(); + } +} + UNORDERED_AUTO_TEST (transparent_ops) { test_unordered_map(); test_unordered_multimap(); + test_unordered_set(); } RUN_TESTS() From 05373cbb6ba510ad1b395413d0ee002688772854 Mon Sep 17 00:00:00 2001 From: Christian Mazakas Date: Thu, 23 Dec 2021 09:54:12 -0800 Subject: [PATCH 5/5] Implement heterogeneous `find()` for set --- include/boost/unordered/unordered_set.hpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/include/boost/unordered/unordered_set.hpp b/include/boost/unordered/unordered_set.hpp index f63b260b..78887a48 100644 --- a/include/boost/unordered/unordered_set.hpp +++ b/include/boost/unordered/unordered_set.hpp @@ -472,6 +472,16 @@ namespace boost { const_iterator find(const key_type&) const; + template + typename boost::enable_if_c::value, + const_iterator>::type + find(const Key& k) const + { + return const_iterator(table_.find_node_impl( + table::policy::apply_hash(this->hash_function(), k), k, + this->key_eq())); + } + template const_iterator find(CompatibleKey const&, CompatibleHash const&,