Skip to content

Commit

Permalink
Rename remove/remove_if to erase/erase_if / return count
Browse files Browse the repository at this point in the history
This fixes issue #7 and #9
  • Loading branch information
jesperkdab committed Oct 11, 2022
1 parent 7d470af commit 0f44e32
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 22 deletions.
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ struct S
bool hasEqualKeyValuePair() const { return x == y; }
};
std::vector<Struct> vec{{2, 3}, {1, 1}, {2, 2}, {4, 1}};
kdalgorithms::remove_if(vec, &Struct::hasEqualKeyValuePair);
kdalgorithms::erase_if(vec, &Struct::hasEqualKeyValuePair);
```

Be aware though that the method must be const.
Expand All @@ -98,7 +98,7 @@ Modifying algorithms
- <a href="#reverse">reverse</a>
- <a href="#sort">sort</a>
- <a href="#remove_duplicates">remove_duplicates</a>
- <a href="#remove">remove / remove_if</a>
- <a href="#erase">erase / erase_if</a>

Queries

Expand Down Expand Up @@ -537,13 +537,13 @@ auto result = kdalgorithms::has_duplicates(vec, kdalgorithms::do_sort);
// result = true
```

<a name="remove">remove / remove_if</a>
<a name="erase">erase / erase_if</a>
---------------------------------------
**remove** removes all instances of a given value, while **remove_if** remove all instances matching a predicate.
**erase** removes all instances of a given value, while **erase_if** remove all instances matching a predicate.

```
std::vector<int> vec{1, 2, 1, 3};
kdalgorithms::remove(vec, 1);
kdalgorithms::erase(vec, 1);
// vec = {2,3}
```

Expand All @@ -556,7 +556,7 @@ struct Struct
auto with_key = [](int key) { return [key](const Struct &s) { return s.key == key; }; };
std::vector<Struct> vec{{2, 3}, {1, 4}, {2, 2}, {4, 1}};
kdalgorithms::remove_if(vec, with_key(2));
kdalgorithms::erase_if(vec, with_key(2));
// vec = {{1,4}, {4,1}}
```

Expand Down
14 changes: 10 additions & 4 deletions src/kdalgorithms.h
Original file line number Diff line number Diff line change
Expand Up @@ -284,12 +284,14 @@ requires UnaryPredicateOnContainerValues<UnaryPredicate, Container>
// -------------------- remove_duplicates --------------------
enum SortOption { do_sort, do_not_sort };
template <typename Container>
void remove_duplicates(Container &container, SortOption sort)
auto remove_duplicates(Container &container, SortOption sort)
{
if (sort == do_sort)
kdalgorithms::sort(container);
auto it = std::unique(container.begin(), container.end());
auto count = std::distance(it, container.end());
container.erase(it, container.end());
return count;
}

// -------------------- has_duplicates --------------------
Expand All @@ -307,26 +309,30 @@ bool has_duplicates(Container &&container, SortOption sort)
return hasDuplicates(sorted(std::forward<Container>(container)));
}

// -------------------- remove / remove_if --------------------
// -------------------- erase / erase_if --------------------
template <typename Container, typename Value>
#if __cplusplus >= 202002L
requires ContainerOfType<Container, Value>
#endif
void remove(Container &container, Value &&value)
auto erase(Container &container, Value &&value)
{
auto it = std::remove(container.begin(), container.end(), std::forward<Value>(value));
auto count = std::distance(it, container.end());
container.erase(it, container.end());
return count;
}

template <typename Container, typename UnaryPredicate>
#if __cplusplus >= 202002L
requires UnaryPredicateOnContainerValues<UnaryPredicate, Container>
#endif
void remove_if(Container &container, UnaryPredicate &&predicate)
auto erase_if(Container &container, UnaryPredicate &&predicate)
{
auto it = std::remove_if(container.begin(), container.end(),
detail::to_function_object(std::forward<UnaryPredicate>(predicate)));
auto count = std::distance(it, container.end());
container.erase(it, container.end());
return count;
}

} // namespace kdalgorithms
32 changes: 20 additions & 12 deletions tests/tst_kdalgorithms.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,8 @@ private Q_SLOTS:
void remove_duplicates();
void has_duplicates();
void has_duplicates_data();
void remove();
void remove_if();
void erase();
void erase_if();
void combiningTests();
};

Expand Down Expand Up @@ -1138,24 +1138,27 @@ void TestAlgorithms::remove_duplicates()
{
std::vector<int> vec{3, 1, 2, 4};
auto expected = vec;
kdalgorithms::remove_duplicates(vec, kdalgorithms::do_not_sort);
int count = kdalgorithms::remove_duplicates(vec, kdalgorithms::do_not_sort);
QCOMPARE(vec, expected);
QCOMPARE(count, 0);
}

// Do not sort, so like std::unique
{
std::vector<int> vec{3, 1, 2, 2, 1};
kdalgorithms::remove_duplicates(vec, kdalgorithms::do_not_sort);
int count = kdalgorithms::remove_duplicates(vec, kdalgorithms::do_not_sort);
std::vector<int> expected{3, 1, 2, 1};
QCOMPARE(vec, expected);
QCOMPARE(count, 1);
}

// Sort first
{
std::vector<int> vec{3, 1, 2, 2, 1};
kdalgorithms::remove_duplicates(vec, kdalgorithms::do_sort);
int count = kdalgorithms::remove_duplicates(vec, kdalgorithms::do_sort);
std::vector<int> expected{1, 2, 3};
QCOMPARE(vec, expected);
QCOMPARE(count, 2);
}
}

Expand All @@ -1182,49 +1185,54 @@ void TestAlgorithms::has_duplicates_data()
QTest::newRow("unsorted not unique") << std::vector<int>{3, 1, 3, 4} << true << true;
}

void TestAlgorithms::remove()
void TestAlgorithms::erase()
{
// several duplicates to remove
{
std::vector<int> vec{1, 2, 1, 3};
kdalgorithms::remove(vec, 1);
int count = kdalgorithms::erase(vec, 1);
std::vector<int> expected{2, 3};
QCOMPARE(vec, expected);
QCOMPARE(count, 2);
}

// Nothing to remove
{
std::vector<int> vec{1, 2, 1, 3};
kdalgorithms::remove(vec, 42);
int count = kdalgorithms::erase(vec, 42);
std::vector<int> expected{1, 2, 1, 3};
QCOMPARE(vec, expected);
QCOMPARE(count, 0);
}
}

void TestAlgorithms::remove_if()
void TestAlgorithms::erase_if()
{
auto withKey = [](int key) { return [key](const Struct &s) { return s.key == key; }; };
// several duplicates to remove
{
std::vector<Struct> vec{{2, 3}, {1, 4}, {2, 2}, {4, 1}};
kdalgorithms::remove_if(vec, withKey(2));
int count = kdalgorithms::erase_if(vec, withKey(2));
std::vector<Struct> expected{{1, 4}, {4, 1}};
QCOMPARE(vec, expected);
QCOMPARE(count, 2);
}

// Nothing to remove
{
std::vector<Struct> vec{{2, 3}, {1, 4}, {2, 2}, {4, 1}};
auto expected = vec;
kdalgorithms::remove_if(vec, withKey(42));
int count = kdalgorithms::erase_if(vec, withKey(42));
QCOMPARE(vec, expected);
QCOMPARE(count, 0);
}

{
std::vector<Struct> vec{{2, 3}, {1, 1}, {2, 2}, {4, 1}};
std::vector<Struct> expected = {{2, 3}, {4, 1}};
kdalgorithms::remove_if(vec, &Struct::hasEqualKeyValuePair);
int count = kdalgorithms::erase_if(vec, &Struct::hasEqualKeyValuePair);
QCOMPARE(vec, expected);
QCOMPARE(count, 2);
}
}

Expand Down

0 comments on commit 0f44e32

Please sign in to comment.