aboutsummaryrefslogtreecommitdiff
path: root/libs/kstd
diff options
context:
space:
mode:
Diffstat (limited to 'libs/kstd')
-rw-r--r--libs/kstd/kstd/vector.hpp34
-rw-r--r--libs/kstd/kstd/vector.tests.cpp85
2 files changed, 119 insertions, 0 deletions
diff --git a/libs/kstd/kstd/vector.hpp b/libs/kstd/kstd/vector.hpp
index d6ad232a..71c380fc 100644
--- a/libs/kstd/kstd/vector.hpp
+++ b/libs/kstd/kstd/vector.hpp
@@ -1078,6 +1078,40 @@ namespace kstd
template<std::ranges::input_range Range, typename Allocator = kstd::allocator<std::ranges::range_value_t<Range>>>
vector(kstd::from_range_t, Range &&, Allocator = Allocator()) -> vector<std::ranges::range_value_t<Range>, Allocator>;
+ //! Erase all occurrences of a given element from a vector.
+ //!
+ //! @tparam ValueType The value type of the vector.
+ //! @tparam Allocator The allocator type used by the vector.
+ //! @tparam NeedleType The type of the element to erase.
+ //! @param haystack The vector to erase all occurrences of the element from.
+ //! @param needle The element to erase from the vector.
+ //! @return The number of erased elements.
+ template<typename ValueType, typename Allocator, typename NeedleType = ValueType>
+ constexpr auto erase(vector<ValueType, Allocator> & haystack, NeedleType const & needle)
+ -> std::remove_cvref_t<decltype(haystack)>::size_type
+ {
+ auto removed = std::ranges::remove(haystack, needle);
+ haystack.erase(removed.begin(), removed.end());
+ return std::ranges::distance(removed);
+ }
+
+ //! Erase all element fulfilling a given predicate from the vector.
+ //!
+ //! @tparam ValueType The value type of the vector.
+ //! @tparam Allocator The allocator type used by the vector.
+ //! @tparam Predicate The type of the predicate to check for the elements.
+ //! @param haystack The vector to erase all occurrences of the element from.
+ //! @param predicate The predicate to check for the element.
+ //! @return The number of erased elements.
+ template<typename ValueType, typename Allocator, typename Predicate>
+ constexpr auto erase_if(vector<ValueType, Allocator> & haystack, Predicate predicate)
+ -> std::remove_cvref_t<decltype(haystack)>::size_type
+ {
+ auto removed = std::ranges::remove_if(haystack, predicate);
+ haystack.erase(removed.begin(), removed.end());
+ return std::ranges::distance(removed);
+ }
+
} // namespace kstd
#endif
diff --git a/libs/kstd/kstd/vector.tests.cpp b/libs/kstd/kstd/vector.tests.cpp
index 72c1127a..24598bf9 100644
--- a/libs/kstd/kstd/vector.tests.cpp
+++ b/libs/kstd/kstd/vector.tests.cpp
@@ -1043,6 +1043,91 @@ SCENARIO("Vector modifiers", "[vector]")
}
}
+ WHEN("erasing an element using free erase")
+ {
+ auto erased = kstd::erase(v, 20);
+
+ THEN("the number of erased elements is 1")
+ {
+ REQUIRE(erased == 1);
+ }
+
+ THEN("the size is reduced")
+ {
+ REQUIRE(v.size() == 2);
+ }
+
+ THEN("the element is erased")
+ {
+ REQUIRE(v[0] == 10);
+ REQUIRE(v[1] == 30);
+ }
+ }
+
+ WHEN("erasing a non-existing element using free erase")
+ {
+ auto erased = kstd::erase(v, 40);
+
+ THEN("the number of erased elements is 0")
+ {
+ REQUIRE(erased == 0);
+ }
+
+ THEN("the size stays the same")
+ {
+ REQUIRE(v.size() == 3);
+ }
+
+ THEN("no element is erased")
+ {
+ REQUIRE(v[0] == 10);
+ REQUIRE(v[1] == 20);
+ REQUIRE(v[2] == 30);
+ }
+ }
+
+ WHEN("erasing a elements using free erase_if")
+ {
+ auto erased = kstd::erase_if(v, [](auto x) { return x >= 20; });
+
+ THEN("the number of erased elements is 2")
+ {
+ REQUIRE(erased == 2);
+ }
+
+ THEN("the size is reduced")
+ {
+ REQUIRE(v.size() == 1);
+ }
+
+ THEN("the elements are erased")
+ {
+ REQUIRE(v[0] == 10);
+ }
+ }
+
+ WHEN("erasing non-existing elements using free erase_if")
+ {
+ auto erased = kstd::erase_if(v, [](auto x) { return x >= 40; });
+
+ THEN("the number of erased elements is 0")
+ {
+ REQUIRE(erased == 0);
+ }
+
+ THEN("the size stays the same")
+ {
+ REQUIRE(v.size() == 3);
+ }
+
+ THEN("no element is erased")
+ {
+ REQUIRE(v[0] == 10);
+ REQUIRE(v[1] == 20);
+ REQUIRE(v[2] == 30);
+ }
+ }
+
WHEN("appending a range")
{
auto initial_size = v.size();