Add M_FILTER and M_FILTER_C macros (src, tests, doc)

This commit is contained in:
Patrick Pelissier committed 2021-02-06 23:24:55 +01:00
1 parent 0cb1a8054f
commit f2d5de252b
3 files changed
+58

No files matched your search

+17
View File
@@ -5710,6 +5710,23 @@ Replicate the value 'value' N times, separating then by commas.
==>
D , D , D , D , D
##### M\_FILTER(func, data, ...)
Filter the arglists by keeping only the element that match the function 'func(data, element)'
M_FILTER(M_NOTEQUAL, 8, 1, 3, 4, 8, 9, 8, 10)
==>
1 3 4 9 10
##### M\_FILTER\_C(func, data, ...)
Filter the arglists by keeping only the element that match the function 'func(data, element)'
separated by commas.
M_FILTER(M_NOTEQUAL, 8, 1, 3, 4, 8, 9, 8, 10)
==>
1 , 3 , 4 , 9 , 10
##### M\_NARGS(args...)
Return the number of argument of the given list.
+30
View File
@@ -1575,6 +1575,36 @@ M_BEGIN_PROTECTED_CODE
#define M_REPLICATE_C(N, value) \
M_MAP2_C(M_RET_ARG1, value, M_SEQ(1, N))
/* Filter the elements of the list so that only the elements
that match the function f are returned.
f takes as argument (extra, item) and shall return 0 or 1. */
#define M_FILTER(f, extra, ...) \
M_MAP2( M_FILTER_00, (f, extra), __VA_ARGS__)
/* Filter the elements of the list so that only the elements
that match the function f are returned.
f takes as argument (extra, item) and shall return 0 or 1. */
#define M_FILTER_C(f, extra, ...) \
M_REMOVE_PARENTHESIS (M_REDUCE2(M_FILTER_00, M_CAT_ARGLIST, (f, extra), __VA_ARGS__) )
/* d is (filter_function, extra_value) item is the element ot test */
#define M_FILTER_00(d, item) \
M_IF(M_PAIR_1 d(M_PAIR_2 d, item))(item, )
/* Concatene two arglists 'a' and 'b',
handling the case of empty arglist
handling the cases where the arglists are within parenthesis.
and returning an arglist within parenthesis if it concats.
(internal macro)
*/
#define M_CAT_ARGLIST(a, b) \
M_IF_EMPTY(a)(b, M_IF_EMPTY(b)(a,( M_REMOVE_PARENTHESIS (a) , M_REMOVE_PARENTHESIS (b))))
/* Remove the parenthesis if needed
(internal macro) */
#define M_REMOVE_PARENTHESIS(list) \
M_IF(M_PARENTHESIS_P(list))( M_OPFLAT list, list)
/* Return the input (delay evaluation) */
#define M_ID(...) __VA_ARGS__
+11
View File
@@ -305,10 +305,21 @@ static void test_list(void)
assert(M_KEEP_ARGS(1, 1, 0, 0, 0, 0));
assert(M_SKIP_ARGS(4, 0, 0, 0, 0, 1));
assert(M_MID_ARGS(2, 1, 0, 0, 1, 0));
const int tab[] = { M_REPLICATE_C(5, 1) };
for(int i = 0; i < 5; i++) assert(tab[i] == 1);
const char str[] = M_REPLICATE(10, "N");
assert(strcmp(str, "NNNNNNNNNN") == 0);
assert(M_EQUAL(M_REMOVE_PARENTHESIS( 17 ), 17));
assert(M_EQUAL(M_REMOVE_PARENTHESIS( (17) ), 17));
assert( M_FILTER(M_EQUAL, 17, 1, 42, 17, 89) );
assert( M_FILTER_C(M_EQUAL, 17, 1, 42, 17, 89) );
const int tab2[] = { M_FILTER_C(M_NOTEQUAL, 8, 1, 3, 4, 8, 9, 8, 10) };
const int tabref[] = { 1, 3, 4, 9, 10 };
assert (sizeof tab2 == sizeof tabref);
for(int i = 0; i < 5 ; i++) assert(tab2[i] == tabref[i]);
}
static void test_oplist(void)