Add M_FILTER and M_FILTER_C macros (src, tests, doc)
This commit is contained in:
1 parent
0cb1a8054f
commit
f2d5de252b
3 files changed
+58
No files matched your search
@@ -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.
|
||||
|
||||
@@ -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__
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in new issue
Block a user