From 79429b68701e306caa609c4940ae06e058e1ec2a Mon Sep 17 00:00:00 2001 From: jeffro256 Date: Mon, 28 Apr 2025 12:31:01 -0500 Subject: [PATCH] upstream: add vector erase if container helper --- src/common/container_helpers.h | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/common/container_helpers.h b/src/common/container_helpers.h index 421d195..48642c5 100644 --- a/src/common/container_helpers.h +++ b/src/common/container_helpers.h @@ -167,6 +167,38 @@ void for_all_in_map_erase_if(std::unordered_map &map_inout, PredT } } +/// convenience erasor for vectors, with total O(N) runtime. Erases all elements X when predicate(X) +/// returns true. No guarantees are made about order of resulting vector if predicate(X) returns +// true for any element X in vec_inout. Otherwise, vec_inout is not modified +template +void for_all_in_vector_erase_no_preserve_order_if(std::vector &vec_inout, PredT predicate) +{ + static_assert( + std::is_same< + bool, + decltype(predicate(std::declval>())) + >::value, + "invalid callable - expected callable in form bool(Value)" + ); + + for (auto vec_it = vec_inout.begin(); vec_it != vec_inout.end();) + { + if (predicate(*vec_it)) + { + const auto it_to_last = vec_inout.end() - 1; + if (vec_it != it_to_last) // i.e. not last element + { + *vec_it = std::move(*it_to_last); + } + vec_inout.pop_back(); + } + else + { + ++vec_it; + } + } +} + /// erase with a reverse iterator /// returned iterator is (pos + 1) if pos hadn't been erased template