dense_map: equal_range

This commit is contained in:
Michele Caini
2022-08-09 09:50:25 +02:00
parent e530b3d6f6
commit fccdff05e3
2 changed files with 93 additions and 11 deletions

View File

@@ -786,7 +786,7 @@ public:
/**
* @brief Finds an element with a key that compares _equivalent_ to a given
* value.
* key.
* @tparam Other Type of the key value of an element to search for.
* @param key Key value of an element to search for.
* @return An iterator to an element with the given key. If no such element
@@ -805,6 +805,46 @@ public:
return constrained_find(key, key_to_bucket(key));
}
/**
* @brief Returns a range containing all elements with a given key.
* @param key Key value of an element to search for.
* @return A pair of iterators pointing to the first element and past the
* last element of the range.
*/
[[nodiscard]] std::pair<iterator, iterator> equal_range(const key_type &key) {
const auto it = find(key);
return {it, it + !(it == end())};
}
/*! @copydoc equal_range */
[[nodiscard]] std::pair<const_iterator, const_iterator> equal_range(const key_type &key) const {
const auto it = find(key);
return {it, it + !(it == cend())};
}
/**
* @brief Returns a range containing all elements that compare _equivalent_
* to a given key.
* @tparam Other Type of an element to search for.
* @param key Key value of an element to search for.
* @return A pair of iterators pointing to the first element and past the
* last element of the range.
*/
template<typename Other>
[[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, std::pair<iterator, iterator>>>
equal_range(const Other &key) {
const auto it = find(key);
return {it, it + !(it == end())};
}
/*! @copydoc equal_range */
template<class Other>
[[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, std::pair<const_iterator, const_iterator>>>
equal_range(const Other &key) const {
const auto it = find(key);
return {it, it + !(it == cend())};
}
/**
* @brief Checks if the container contains an element with a given key.
* @param key Key value of an element to search for.

View File

@@ -28,6 +28,7 @@ struct transparent_equal_to {
TEST(DenseMap, Functionalities) {
entt::dense_map<int, int, entt::identity, transparent_equal_to> map;
const auto &cmap = map;
ASSERT_NO_THROW([[maybe_unused]] auto alloc = map.get_allocator());
@@ -42,7 +43,7 @@ TEST(DenseMap, Functionalities) {
ASSERT_EQ(map.max_load_factor(), .9f);
ASSERT_EQ(map.begin(), map.end());
ASSERT_EQ(std::as_const(map).begin(), std::as_const(map).end());
ASSERT_EQ(cmap.begin(), cmap.end());
ASSERT_EQ(map.cbegin(), map.cend());
ASSERT_NE(map.max_bucket_count(), 0u);
@@ -55,7 +56,7 @@ TEST(DenseMap, Functionalities) {
ASSERT_EQ(map.bucket(10), 2u);
ASSERT_EQ(map.begin(1u), map.end(1u));
ASSERT_EQ(std::as_const(map).begin(1u), std::as_const(map).end(1u));
ASSERT_EQ(cmap.begin(1u), cmap.end(1u));
ASSERT_EQ(map.cbegin(1u), map.cend(1u));
ASSERT_FALSE(map.contains(42));
@@ -63,8 +64,8 @@ TEST(DenseMap, Functionalities) {
ASSERT_EQ(map.find(42), map.end());
ASSERT_EQ(map.find(4.2), map.end());
ASSERT_EQ(std::as_const(map).find(42), map.cend());
ASSERT_EQ(std::as_const(map).find(4.2), map.cend());
ASSERT_EQ(cmap.find(42), map.cend());
ASSERT_EQ(cmap.find(4.2), map.cend());
ASSERT_EQ(map.hash_function()(42), 42);
ASSERT_TRUE(map.key_eq()(42, 42));
@@ -73,14 +74,14 @@ TEST(DenseMap, Functionalities) {
ASSERT_EQ(map.count(0), 1u);
ASSERT_EQ(map.count(4.2), 0u);
ASSERT_EQ(std::as_const(map).count(0.0), 1u);
ASSERT_EQ(std::as_const(map).count(42), 0u);
ASSERT_EQ(cmap.count(0.0), 1u);
ASSERT_EQ(cmap.count(42), 0u);
ASSERT_FALSE(map.empty());
ASSERT_EQ(map.size(), 1u);
ASSERT_NE(map.begin(), map.end());
ASSERT_NE(std::as_const(map).begin(), std::as_const(map).end());
ASSERT_NE(cmap.begin(), cmap.end());
ASSERT_NE(map.cbegin(), map.cend());
ASSERT_TRUE(map.contains(0));
@@ -92,7 +93,7 @@ TEST(DenseMap, Functionalities) {
ASSERT_EQ(map.size(), 0u);
ASSERT_EQ(map.begin(), map.end());
ASSERT_EQ(std::as_const(map).begin(), std::as_const(map).end());
ASSERT_EQ(cmap.begin(), cmap.end());
ASSERT_EQ(map.cbegin(), map.cend());
ASSERT_FALSE(map.contains(0));
@@ -925,8 +926,48 @@ TEST(DenseMap, Swap) {
ASSERT_TRUE(other.contains(0));
}
TEST(DenseMap, EqualRange) {
entt::dense_map<int, int, entt::identity, transparent_equal_to> map;
const auto &cmap = map;
map.emplace(42, 3);
ASSERT_EQ(map.equal_range(0).first, map.end());
ASSERT_EQ(map.equal_range(0).second, map.end());
ASSERT_EQ(cmap.equal_range(0).first, cmap.cend());
ASSERT_EQ(cmap.equal_range(0).second, cmap.cend());
ASSERT_EQ(map.equal_range(0.0).first, map.end());
ASSERT_EQ(map.equal_range(0.0).second, map.end());
ASSERT_EQ(cmap.equal_range(0.0).first, cmap.cend());
ASSERT_EQ(cmap.equal_range(0.0).second, cmap.cend());
ASSERT_NE(map.equal_range(42).first, map.end());
ASSERT_EQ(map.equal_range(42).first->first, 42);
ASSERT_EQ(map.equal_range(42).first->second, 3);
ASSERT_EQ(map.equal_range(42).second, map.end());
ASSERT_NE(cmap.equal_range(42).first, cmap.cend());
ASSERT_EQ(cmap.equal_range(42).first->first, 42);
ASSERT_EQ(cmap.equal_range(42).first->second, 3);
ASSERT_EQ(cmap.equal_range(42).second, cmap.cend());
ASSERT_NE(map.equal_range(42.0).first, map.end());
ASSERT_EQ(map.equal_range(42.0).first->first, 42);
ASSERT_EQ(map.equal_range(42.0).first->second, 3);
ASSERT_EQ(map.equal_range(42.0).second, map.end());
ASSERT_NE(cmap.equal_range(42.0).first, cmap.cend());
ASSERT_EQ(cmap.equal_range(42.0).first->first, 42);
ASSERT_EQ(cmap.equal_range(42.0).first->second, 3);
ASSERT_EQ(cmap.equal_range(42.0).second, cmap.cend());
}
TEST(DenseMap, Indexing) {
entt::dense_map<int, int> map;
const auto &cmap = map;
const auto key = 1;
ASSERT_FALSE(map.contains(key));
@@ -935,14 +976,15 @@ TEST(DenseMap, Indexing) {
ASSERT_TRUE(map.contains(key));
ASSERT_EQ(map[std::move(key)], 99);
ASSERT_EQ(std::as_const(map).at(key), 99);
ASSERT_EQ(cmap.at(key), 99);
ASSERT_EQ(map.at(key), 99);
}
ENTT_DEBUG_TEST(DenseMapDeathTest, Indexing) {
entt::dense_map<int, int> map;
const auto &cmap = map;
ASSERT_DEATH([[maybe_unused]] auto value = std::as_const(map).at(0), "");
ASSERT_DEATH([[maybe_unused]] auto value = cmap.at(0), "");
ASSERT_DEATH([[maybe_unused]] auto value = map.at(42), "");
}