From edb4ccf63e7c7ae6763fb071d41559f7915239b9 Mon Sep 17 00:00:00 2001 From: Patrick Pelissier Date: Tue, 7 May 2019 16:35:39 +0200 Subject: [PATCH] Add algo functions _remove_val & _remove_if --- README.md | 10 ++++++++++ m-algo.h | 32 +++++++++++++++++++++++++++++++- tests/test-malgo.c | 20 +++++++++++++++++++- 3 files changed, 60 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f0586d19..f5489d6c 100644 --- a/README.md +++ b/README.md @@ -5549,6 +5549,16 @@ Assuming the container 'c' has been sorted, remove any duplicate elements of the container. This method is available if the CMP and IT\_REMOVE operators have been defined. +##### void name\_remove\_val(container\_t c, type\_t val) + +Remove all elements equal to 'val' of the container. +This method is available if the CMP and IT\_REMOVE operators have been defined. + +##### void name\_remove\_if(container\_t c, bool (*func)(type\_t) ) + +Remove all elements matching the given condition (function func() returns true) of the container. +This method is available if the CMP and IT\_REMOVE operators have been defined. + ##### void name\_add(container\_t dest, const container\_t value) For each element of the container 'dest', diff --git a/m-algo.h b/m-algo.h index 0a9d9fb0..6ffa8a79 100644 --- a/m-algo.h +++ b/m-algo.h @@ -44,7 +44,7 @@ ALGOI_FOR_EACH_ARG(container, M_GLOBAL_OPLIST(cont_oplist), __VA_ARGS__ )) -/* Extract a subset of a container to fill in another container. +/* Extract a subset of a container to copy into another container. USAGE: ALGO_EXTRACT(contDst, contDstOplist, contSrc, contSrcOplist, function [, extra arguments of function]) */ @@ -400,6 +400,36 @@ M_CALL_IT_NEXT(cont_oplist, it2); \ } \ } \ + } \ + \ + static inline void \ + M_C(name, _remove_val)(container_t l, type_t const val) \ + { \ + it_t it1; \ + M_CALL_IT_FIRST(cont_oplist, it1, l); \ + while (!M_CALL_IT_END_P(cont_oplist, it1)) { \ + type_t const *ref1 = M_CALL_IT_CREF(cont_oplist, it1); \ + if (M_CALL_EQUAL(type_oplist, *ref1, val)) { \ + M_CALL_IT_REMOVE(cont_oplist, l, it1); \ + } else { \ + M_CALL_IT_NEXT(cont_oplist, it1); \ + } \ + } \ + } \ + \ + static inline void \ + M_C(name, _remove_if)(container_t l, bool (*func)(type_t const)) \ + { \ + it_t it1; \ + M_CALL_IT_FIRST(cont_oplist, it1, l); \ + while (!M_CALL_IT_END_P(cont_oplist, it1)) { \ + type_t const *ref1 = M_CALL_IT_CREF(cont_oplist, it1); \ + if (func(*ref1)) { \ + M_CALL_IT_REMOVE(cont_oplist, l, it1); \ + } else { \ + M_CALL_IT_NEXT(cont_oplist, it1); \ + } \ + } \ } \ , /* No IT_REMOVE method */) \ \ diff --git a/tests/test-malgo.c b/tests/test-malgo.c index 0f74ec27..a2c0860c 100644 --- a/tests/test-malgo.c +++ b/tests/test-malgo.c @@ -160,11 +160,29 @@ static void test_list(void) assert (!algo_list_sort_p(l)); algo_list_sort(l); assert (algo_list_sort_p(l)); - + list_int_clear(l); ALGO_INIT_VA(l, LIST_OPLIST(list_int), 1, 2, 3, 4, 5); assert (list_int_size(l) == 5); + + algo_list_remove_val(l, 3); + assert (list_int_size(l) == 4); + algo_list_find (it1, l, 3); + assert (list_int_end_p (it1)); + algo_list_remove_val(l, 3); + assert (list_int_size(l) == 4); + + algo_list_remove_if(l, func_test_42); + assert (list_int_size(l) == 4); + list_int_push_back(l, 42); + list_int_push_back(l, 43); + list_int_push_back(l, 42); + algo_list_remove_if(l, func_test_42); + assert (list_int_size(l) == 5); + algo_list_find (it1, l, 42); + assert (list_int_end_p (it1)); + list_int_clear(l); }