diff --git a/include/boost/unordered/unordered_map.hpp b/include/boost/unordered/unordered_map.hpp index a566dee9..17dc987d 100644 --- a/include/boost/unordered/unordered_map.hpp +++ b/include/boost/unordered/unordered_map.hpp @@ -799,6 +799,34 @@ namespace boost { std::pair equal_range( const key_type&) const; + template + typename boost::enable_if_c::value && + detail::is_transparent::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_node(p) : p)); + } + + template + typename boost::enable_if_c::value && + detail::is_transparent::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_node(p) : p)); + } + mapped_type& operator[](const key_type&); mapped_type& operator[](BOOST_RV_REF(key_type)); mapped_type& at(const key_type&); diff --git a/test/unordered/transparent_tests.cpp b/test/unordered/transparent_tests.cpp index f4173d84..a37e3cf2 100644 --- a/test/unordered/transparent_tests.cpp +++ b/test/unordered/transparent_tests.cpp @@ -272,6 +272,153 @@ template void test_non_transparent_find() } } +template void test_transparent_equal_range() +{ + count_reset(); + + UnorderedMap unordered_map; + + unordered_map[key(0)] = 1337; + + int const expected_key_count = 2; + + BOOST_TEST(key::count_ == expected_key_count); + + typedef typename UnorderedMap::value_type value_type; + + // explicitly test `equal_range()` vs `equal_range() const` + // + { + typedef typename UnorderedMap::iterator iterator; + typedef std::pair iterator_pair; + + UnorderedMap& map = unordered_map; + + iterator_pair iters = map.equal_range(0); + + iterator begin = iters.first; + iterator end = iters.second; + + BOOST_TEST(begin != end); + BOOST_TEST(begin != map.end()); + + value_type const& val = *begin; + BOOST_TEST(val.second == 1337); + + iters = map.equal_range(1337); + + begin = iters.first; + end = iters.second; + + BOOST_TEST(begin == end); + BOOST_TEST(begin == map.end()); + + BOOST_TEST(key::count_ == expected_key_count); + } + + { + typedef typename UnorderedMap::const_iterator iterator; + typedef std::pair iterator_pair; + + UnorderedMap const& map = unordered_map; + + iterator_pair iters = map.equal_range(0); + + iterator begin = iters.first; + iterator end = iters.second; + + BOOST_TEST(begin != end); + BOOST_TEST(begin != map.end()); + + value_type const& val = *begin; + BOOST_TEST(val.second == 1337); + + iters = map.equal_range(1337); + + begin = iters.first; + end = iters.second; + + BOOST_TEST(begin == end); + BOOST_TEST(begin == map.end()); + + BOOST_TEST(key::count_ == expected_key_count); + } +} + +template void test_non_transparent_equal_range() +{ + count_reset(); + + UnorderedMap unordered_map; + + unordered_map[key(0)] = 1337; + + int key_count = 2; + + BOOST_TEST(key::count_ == key_count); + + typedef typename UnorderedMap::value_type value_type; + + // explicitly test `equal_range()` vs `equal_range() const` + // + { + typedef typename UnorderedMap::iterator iterator; + typedef std::pair iterator_pair; + + UnorderedMap& map = unordered_map; + + iterator_pair iters = map.equal_range(0); + + iterator begin = iters.first; + iterator end = iters.second; + + BOOST_TEST(begin != end); + BOOST_TEST(begin != map.end()); + + value_type const& val = *begin; + BOOST_TEST(val.second == 1337); + + iters = map.equal_range(1337); + + begin = iters.first; + end = iters.second; + + BOOST_TEST(begin == end); + BOOST_TEST(begin == map.end()); + + BOOST_TEST(key::count_ == 2 + key_count); + key_count += 2; + } + + { + typedef typename UnorderedMap::const_iterator iterator; + typedef std::pair iterator_pair; + + UnorderedMap const& map = unordered_map; + + iterator_pair iters = map.equal_range(0); + + iterator begin = iters.first; + iterator end = iters.second; + + BOOST_TEST(begin != end); + BOOST_TEST(begin != map.end()); + + value_type const& val = *begin; + BOOST_TEST(val.second == 1337); + + iters = map.equal_range(1337); + + begin = iters.first; + end = iters.second; + + BOOST_TEST(begin == end); + BOOST_TEST(begin == map.end()); + + BOOST_TEST(key::count_ == 2 + key_count); + } +} + UNORDERED_AUTO_TEST (unordered_map_transparent_count) { { typedef boost::unordered_map(); test_transparent_find(); + test_transparent_equal_range(); } { @@ -289,6 +437,7 @@ UNORDERED_AUTO_TEST (unordered_map_transparent_count) { test_non_transparent_count(); test_non_transparent_find(); + test_non_transparent_equal_range(); } { @@ -299,6 +448,7 @@ UNORDERED_AUTO_TEST (unordered_map_transparent_count) { test_non_transparent_count(); test_non_transparent_find(); + test_non_transparent_equal_range(); } { @@ -309,6 +459,7 @@ UNORDERED_AUTO_TEST (unordered_map_transparent_count) { test_non_transparent_count(); test_non_transparent_find(); + test_non_transparent_equal_range(); } }