BLI: Return number of values removed from remove_if

Make the `remove_if` function for `Vector`, `VectorSet`, `Set`, and `Map` return the number of elements it removed.

Pull Request: https://projects.blender.org/blender/blender/pulls/107069
This commit is contained in:
Falk David 2023-04-18 13:28:14 +02:00 committed by Falk David
parent 25747301db
commit 66158498de
8 changed files with 28 additions and 16 deletions

View File

@ -885,12 +885,14 @@ class Map {
}
/**
* Remove all key-value-pairs for that the given predicate is true.
* Remove all key-value-pairs for that the given predicate is true and return the number of
* removed pairs.
*
* This is similar to std::erase_if.
*/
template<typename Predicate> void remove_if(Predicate &&predicate)
template<typename Predicate> int64_t remove_if(Predicate &&predicate)
{
const int64_t prev_size = this->size();
for (Slot &slot : slots_) {
if (slot.is_occupied()) {
const Key &key = *slot.key();
@ -901,6 +903,7 @@ class Map {
}
}
}
return prev_size - this->size();
}
/**

View File

@ -489,12 +489,14 @@ class Set {
}
/**
* Remove all values for which the given predicate is true.
* Remove all values for which the given predicate is true and return the number of removed
* values.
*
* This is similar to std::erase_if.
*/
template<typename Predicate> void remove_if(Predicate &&predicate)
template<typename Predicate> int64_t remove_if(Predicate &&predicate)
{
const int64_t prev_size = this->size();
for (Slot &slot : slots_) {
if (slot.is_occupied()) {
const Key &key = *slot.key();
@ -504,6 +506,7 @@ class Set {
}
}
}
return prev_size - this->size();
}
/**

View File

@ -816,14 +816,17 @@ class Vector {
}
/**
* Remove all values for which the given predicate is true.
* Remove all values for which the given predicate is true and return the number of values
* removed.
*
* This is similar to std::erase_if.
*/
template<typename Predicate> void remove_if(Predicate &&predicate)
template<typename Predicate> int64_t remove_if(Predicate &&predicate)
{
const T *prev_end = this->end();
end_ = std::remove_if(this->begin(), this->end(), predicate);
UPDATE_VECTOR_SIZE(this);
return int64_t(prev_end - end_);
}
/**

View File

@ -347,13 +347,14 @@ class VectorSet {
}
/**
* Remove all values for which the given predicate is true. This may change the order of elements
* in the vector.
* Remove all values for which the given predicate is true and return the number or values
* removed. This may change the order of elements in the vector.
*
* This is similar to std::erase_if.
*/
template<typename Predicate> void remove_if(Predicate &&predicate)
template<typename Predicate> int64_t remove_if(Predicate &&predicate)
{
const int64_t prev_size = this->size();
for (Slot &slot : slots_) {
if (slot.is_occupied()) {
const int64_t index = slot.index();
@ -363,6 +364,7 @@ class VectorSet {
}
}
}
return prev_size - this->size();
}
/**

View File

@ -646,8 +646,8 @@ TEST(map, RemoveIf)
for (const int64_t i : IndexRange(100)) {
map.add(i * i, i);
}
map.remove_if([](auto item) { return item.key > 100; });
EXPECT_EQ(map.size(), 11);
const int64_t removed = map.remove_if([](auto item) { return item.key > 100; });
EXPECT_EQ(map.size() + removed, 100);
for (const int64_t i : IndexRange(100)) {
if (i <= 10) {
EXPECT_EQ(map.lookup(i * i), i);

View File

@ -582,8 +582,8 @@ TEST(set, RemoveIf)
for (const int64_t i : IndexRange(100)) {
set.add(i * i);
}
set.remove_if([](const int64_t key) { return key > 100; });
EXPECT_EQ(set.size(), 11);
const int64_t removed = set.remove_if([](const int64_t key) { return key > 100; });
EXPECT_EQ(set.size() + removed, 100);
for (const int64_t i : IndexRange(100)) {
EXPECT_EQ(set.contains(i * i), i <= 10);
}

View File

@ -134,8 +134,8 @@ TEST(vector_set, RemoveIf)
for (const int64_t i : IndexRange(100)) {
set.add(i * i);
}
set.remove_if([](const int64_t key) { return key % 2 == 0; });
EXPECT_EQ(set.size(), 50);
const int64_t removed = set.remove_if([](const int64_t key) { return key % 2 == 0; });
EXPECT_EQ(set.size() + removed, 100);
for (const int64_t i : IndexRange(100)) {
EXPECT_EQ(set.contains(i * i), i % 2 == 1);
}

View File

@ -422,7 +422,8 @@ TEST(vector, Remove)
TEST(vector, RemoveIf)
{
Vector<int> vec = {1, 2, 3, 4, 5, 6, 7, 8};
vec.remove_if([](const int x) { return x % 2 == 0; });
const int64_t removed = vec.remove_if([](const int x) { return x % 2 == 0; });
EXPECT_EQ(vec.size() + removed, 8);
const Vector<int> expected_vec = {1, 3, 5, 7};
EXPECT_EQ(vec.size(), expected_vec.size());
EXPECT_EQ_ARRAY(vec.data(), expected_vec.data(), size_t(vec.size()));