diff --git a/include/boost/unordered/unordered_map.hpp b/include/boost/unordered/unordered_map.hpp index 20537bfa..f5d59c19 100644 --- a/include/boost/unordered/unordered_map.hpp +++ b/include/boost/unordered/unordered_map.hpp @@ -1487,6 +1487,18 @@ namespace boost { size_type count(const key_type&) const; + template + typename boost::enable_if_c::value, + size_type>::type + count(const Key& k) const + { + node_pointer n = table_.find_node_impl( + table::policy::apply_hash(this->hash_function(), k), k, + this->key_eq()); + + return n ? table_.group_count(n) : 0; + } + std::pair equal_range(const key_type&); std::pair equal_range( const key_type&) const; diff --git a/test/unordered/transparent_tests.cpp b/test/unordered/transparent_tests.cpp index f89eea99..6656e95f 100644 --- a/test/unordered/transparent_tests.cpp +++ b/test/unordered/transparent_tests.cpp @@ -40,23 +40,11 @@ struct transparent_key_equal { typedef void is_transparent; - static bool was_called_; - bool operator()(key const& k1, key const& k2) const { return k1.x_ == k2.x_; } - bool operator()(int const x, key const& k1) const - { - was_called_ = true; - return k1.x_ == x; - } - bool operator()(key const& k1, int const x) const - { - was_called_ = true; - return k1.x_ == 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 transparent_key_equal::was_called_; - struct hasher { std::size_t operator()(key const& k) const @@ -67,24 +55,10 @@ struct hasher struct key_equal { - static bool was_called_; - bool operator()(key const& k1, key const& k2) const { return k1.x_ == k2.x_; } - bool operator()(int const x, key const& k1) const - { - was_called_ = true; - return k1.x_ == x; - } }; -bool key_equal::was_called_; - -void count_reset() -{ - key::count_ = 0; - transparent_key_equal::was_called_ = false; - key_equal::was_called_ = false; -} +void count_reset() { key::count_ = 0; } template void test_transparent_count() { @@ -92,31 +66,26 @@ template void test_transparent_count() UnorderedMap map; - // initial `key(0)` expression increases the count - // then copying into the `unordered_map` increments the count again thus we - // have 2 - // - map[key(0)] = 1337; - BOOST_TEST(key::count_ == 2); + map.insert(std::make_pair(0, 1337)); + map.insert(std::make_pair(1, 1338)); + map.insert(std::make_pair(2, 1339)); + map.insert(std::make_pair(0, 1340)); + map.insert(std::make_pair(0, 1341)); + map.insert(std::make_pair(0, 1342)); + + int const expected_key_count = key::count_; - // now the number of `key` objects created should be a constant and never - // touched again - // std::size_t count = 0; count = map.count(0); - - BOOST_TEST(count == 1); - BOOST_TEST(key::count_ == 2); - BOOST_TEST(map.key_eq().was_called_); + BOOST_TEST_EQ(count, map.size() - 2); count = map.count(1); + BOOST_TEST_EQ(count, 1); - BOOST_TEST(count == 0); - BOOST_TEST(key::count_ == 2); + count = map.count(1337); + BOOST_TEST_EQ(count, 0); - count = map.count(key(0)); - BOOST_TEST(count == 1); - BOOST_TEST(key::count_ == 3); + BOOST_TEST_EQ(key::count_, expected_key_count); } template void test_non_transparent_count() @@ -125,31 +94,32 @@ template void test_non_transparent_count() UnorderedMap map; - // initial `key(0)` expression increases the count - // then copying into the `unordered_map` increments the count again thus we - // have 2 - // - map[key(0)] = 1337; - BOOST_TEST(key::count_ == 2); + map.insert(std::make_pair(0, 1337)); + map.insert(std::make_pair(1, 1338)); + map.insert(std::make_pair(2, 1339)); + map.insert(std::make_pair(0, 1340)); + map.insert(std::make_pair(0, 1341)); + map.insert(std::make_pair(0, 1342)); + + int key_count = key::count_; - // rely on the implicit constructor here to spawn a new object which - // increases the count - // std::size_t count = 0; count = map.count(0); + ++key_count; - BOOST_TEST(count == 1); - BOOST_TEST(key::count_ == 3); - BOOST_TEST(!map.key_eq().was_called_); + BOOST_TEST_EQ(count, map.size() - 2); + BOOST_TEST_EQ(key::count_, key_count); count = map.count(1); + ++key_count; - BOOST_TEST(count == 0); - BOOST_TEST(key::count_ == 4); + BOOST_TEST_EQ(count, 1); - count = map.count(key(0)); - BOOST_TEST(count == 1); - BOOST_TEST(key::count_ == 5); + count = map.count(1337); + ++key_count; + + BOOST_TEST_EQ(count, 0); + BOOST_TEST_EQ(key::count_, key_count); } template void test_transparent_find() @@ -772,7 +742,7 @@ template void test_non_transparent_extract() const_iterator_pair rng = map.equal_range(0); ++key_count; - + for (const_iterator pos = rng.first; pos != rng.second; ++pos) { BOOST_TEST_NE(pos->second, nh.mapped()); } @@ -843,6 +813,7 @@ void test_unordered_multimap() transparent_key_equal> unordered_multimap; + test_transparent_count(); test_transparent_find(); test_transparent_equal_range(); test_transparent_erase(); @@ -855,6 +826,7 @@ void test_unordered_multimap() typedef boost::unordered_multimap unordered_multimap; + test_non_transparent_count(); test_non_transparent_find(); test_non_transparent_equal_range(); test_non_transparent_erase(); @@ -867,6 +839,7 @@ void test_unordered_multimap() typedef boost::unordered_multimap unordered_multimap; + test_non_transparent_count(); test_non_transparent_find(); test_non_transparent_equal_range(); test_non_transparent_erase(); @@ -879,6 +852,7 @@ void test_unordered_multimap() typedef boost::unordered_multimap unordered_multimap; + test_non_transparent_count(); test_non_transparent_find(); test_non_transparent_equal_range(); test_non_transparent_erase();