From 1ebc26fb787cf0f713b2df95ed80f7d715443be5 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 16 Jul 2026 11:45:24 +0200 Subject: kstd: implement erase and erase_if for vector --- libs/kstd/kstd/vector.hpp | 34 +++++++++++++++++ libs/kstd/kstd/vector.tests.cpp | 85 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 119 insertions(+) (limited to 'libs/kstd') 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>> vector(kstd::from_range_t, Range &&, Allocator = Allocator()) -> vector, 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 + constexpr auto erase(vector & haystack, NeedleType const & needle) + -> std::remove_cvref_t::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 + constexpr auto erase_if(vector & haystack, Predicate predicate) + -> std::remove_cvref_t::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(); -- cgit v1.2.3