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&, diff --git a/test/unordered/transparent_tests.cpp b/test/unordered/transparent_tests.cpp index 6656e95f..c53c2292 100644 --- a/test/unordered/transparent_tests.cpp +++ b/test/unordered/transparent_tests.cpp @@ -24,6 +24,15 @@ struct key int key::count_; +std::ostream& operator<<(std::ostream& os, key const& k) +{ + os << "key { x_: " << k.x_ << " }"; + 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; @@ -41,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 @@ -122,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(); @@ -183,7 +192,7 @@ template void test_transparent_find() } } -template void test_non_transparent_find() +template void test_map_non_transparent_find() { count_reset(); @@ -244,6 +253,118 @@ template void test_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(); @@ -761,7 +882,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(); @@ -773,7 +894,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(); @@ -786,7 +907,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(); @@ -799,7 +920,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(); @@ -814,7 +935,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(); @@ -827,7 +948,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(); @@ -840,7 +961,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(); @@ -853,16 +974,53 @@ 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(); } } +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()