dense_set: equal_range

This commit is contained in:
Michele Caini
2022-08-09 09:50:10 +02:00
parent 0f0b70be23
commit e530b3d6f6
2 changed files with 86 additions and 10 deletions

View File

@@ -603,11 +603,11 @@ public:
}
/**
* @brief Returns the number of elements matching a key (either 1 or 0).
* @brief Returns the number of elements matching a value (either 1 or 0).
* @param key Key value of an element to search for.
* @return Number of elements matching the key (either 1 or 0).
*/
[[nodiscard]] size_type count(const key_type &key) const {
[[nodiscard]] size_type count(const value_type &key) const {
return find(key) != end();
}
@@ -658,6 +658,46 @@ public:
return constrained_find(value, value_to_bucket(value));
}
/**
* @brief Returns a range containing all elements with a given value.
* @param value 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 value_type &value) {
const auto it = find(value);
return {it, it + !(it == end())};
}
/*! @copydoc equal_range */
[[nodiscard]] std::pair<const_iterator, const_iterator> equal_range(const value_type &value) const {
const auto it = find(value);
return {it, it + !(it == cend())};
}
/**
* @brief Returns a range containing all elements that compare _equivalent_
* to a given value.
* @tparam Other Type of an element to search for.
* @param value 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 &value) {
const auto it = find(value);
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 &value) const {
const auto it = find(value);
return {it, it + !(it == cend())};
}
/**
* @brief Checks if the container contains an element with a given value.
* @param value Value of an element to search for.

View File

@@ -26,6 +26,7 @@ struct transparent_equal_to {
TEST(DenseSet, Functionalities) {
entt::dense_set<int, entt::identity, transparent_equal_to> set;
const auto &cset = set;
ASSERT_NO_THROW([[maybe_unused]] auto alloc = set.get_allocator());
@@ -40,7 +41,7 @@ TEST(DenseSet, Functionalities) {
ASSERT_EQ(set.max_load_factor(), .9f);
ASSERT_EQ(set.begin(), set.end());
ASSERT_EQ(std::as_const(set).begin(), std::as_const(set).end());
ASSERT_EQ(cset.begin(), cset.end());
ASSERT_EQ(set.cbegin(), set.cend());
ASSERT_NE(set.max_bucket_count(), 0u);
@@ -53,7 +54,7 @@ TEST(DenseSet, Functionalities) {
ASSERT_EQ(set.bucket(10), 2u);
ASSERT_EQ(set.begin(1u), set.end(1u));
ASSERT_EQ(std::as_const(set).begin(1u), std::as_const(set).end(1u));
ASSERT_EQ(cset.begin(1u), cset.end(1u));
ASSERT_EQ(set.cbegin(1u), set.cend(1u));
ASSERT_FALSE(set.contains(42));
@@ -61,8 +62,8 @@ TEST(DenseSet, Functionalities) {
ASSERT_EQ(set.find(42), set.end());
ASSERT_EQ(set.find(4.2), set.end());
ASSERT_EQ(std::as_const(set).find(42), set.cend());
ASSERT_EQ(std::as_const(set).find(4.2), set.cend());
ASSERT_EQ(cset.find(42), set.cend());
ASSERT_EQ(cset.find(4.2), set.cend());
ASSERT_EQ(set.hash_function()(42), 42);
ASSERT_TRUE(set.key_eq()(42, 42));
@@ -71,14 +72,14 @@ TEST(DenseSet, Functionalities) {
ASSERT_EQ(set.count(0), 1u);
ASSERT_EQ(set.count(4.2), 0u);
ASSERT_EQ(std::as_const(set).count(0.0), 1u);
ASSERT_EQ(std::as_const(set).count(42), 0u);
ASSERT_EQ(cset.count(0.0), 1u);
ASSERT_EQ(cset.count(42), 0u);
ASSERT_FALSE(set.empty());
ASSERT_EQ(set.size(), 1u);
ASSERT_NE(set.begin(), set.end());
ASSERT_NE(std::as_const(set).begin(), std::as_const(set).end());
ASSERT_NE(cset.begin(), cset.end());
ASSERT_NE(set.cbegin(), set.cend());
ASSERT_TRUE(set.contains(0));
@@ -90,7 +91,7 @@ TEST(DenseSet, Functionalities) {
ASSERT_EQ(set.size(), 0u);
ASSERT_EQ(set.begin(), set.end());
ASSERT_EQ(std::as_const(set).begin(), std::as_const(set).end());
ASSERT_EQ(cset.begin(), cset.end());
ASSERT_EQ(set.cbegin(), set.cend());
ASSERT_FALSE(set.contains(0));
@@ -678,6 +679,41 @@ TEST(DenseSet, Swap) {
ASSERT_TRUE(other.contains(0));
}
TEST(DenseSet, EqualRange) {
entt::dense_set<int, entt::identity, transparent_equal_to> set;
const auto &cset = set;
set.emplace(42);
ASSERT_EQ(set.equal_range(0).first, set.end());
ASSERT_EQ(set.equal_range(0).second, set.end());
ASSERT_EQ(cset.equal_range(0).first, cset.cend());
ASSERT_EQ(cset.equal_range(0).second, cset.cend());
ASSERT_EQ(set.equal_range(0.0).first, set.end());
ASSERT_EQ(set.equal_range(0.0).second, set.end());
ASSERT_EQ(cset.equal_range(0.0).first, cset.cend());
ASSERT_EQ(cset.equal_range(0.0).second, cset.cend());
ASSERT_NE(set.equal_range(42).first, set.end());
ASSERT_EQ(*set.equal_range(42).first, 42);
ASSERT_EQ(set.equal_range(42).second, set.end());
ASSERT_NE(cset.equal_range(42).first, cset.cend());
ASSERT_EQ(*cset.equal_range(42).first, 42);
ASSERT_EQ(cset.equal_range(42).second, cset.cend());
ASSERT_NE(set.equal_range(42.0).first, set.end());
ASSERT_EQ(*set.equal_range(42.0).first, 42);
ASSERT_EQ(set.equal_range(42.0).second, set.end());
ASSERT_NE(cset.equal_range(42.0).first, cset.cend());
ASSERT_EQ(*cset.equal_range(42.0).first, 42);
ASSERT_EQ(cset.equal_range(42.0).second, cset.cend());
}
TEST(DenseSet, LocalIterator) {
using iterator = typename entt::dense_set<std::size_t, entt::identity>::local_iterator;