Add special (and frequent !) handler for functions add, sum, and and or

for the reduction macro.
This commit is contained in:
Patrick Pelissier committed 2017-03-04 19:10:56 +01:00
1 parent dee40608d7
commit 9ce1c69753
2 files changed
+38 -3

No files matched your search

+29 -3
View File
@@ -265,11 +265,37 @@
M_IF_METHOD(REVERSE, contDstOplist) (M_GET_REVERSE contDstOplist (contDstOplist);, ) \
} while (0)
/* The different special patterns which will interpret as special */
#define ALGOI_PATTERN_and_and ,
#define ALGOI_PATTERN_or_or ,
#define ALGOI_PATTERN_sum_sum ,
#define ALGOI_PATTERN_sum_add ,
/* Test function for theses patterns */
#define ALGOI_REDUCE_IS_FUNC(refFunc, reduceFunc) \
M_COMMA_P(M_C4(ALGOI_PATTERN_, refFunc, _, reduceFunc))
#define ALGOI_REDUCE_AND(a,b) ((a) &= (b))
#define ALGOI_REDUCE_OR(a,b) ((a) |= (b))
#define ALGOI_REDUCE_SUM(a,b) ((a) += (b))
/* Get function pointer.
It returns special macros if function is and, or, sum or add.
Otherwise it returns the original function */
#define ALGOI_REDUCE_FUNC(reduceFunc) \
M_IF(ALGOI_REDUCE_IS_FUNC(and, reduceFunc)) \
(ALGOI_REDUCE_AND, \
M_IF(ALGOI_REDUCE_IS_FUNC(or, reduceFunc)) \
(ALGOI_REDUCE_OR, \
M_IF(ALGOI_REDUCE_IS_FUNC(sum, reduceFunc)) \
(ALGOI_REDUCE_SUM, reduceFunc) \
) \
)
#define ALGOI_REDUCE(dest, cont, cont_oplist, reduceFunc) do { \
bool m_init_done = false; \
for M_EACH(item, cont, cont_oplist) { \
if (m_init_done) { \
reduceFunc(dest, *item); \
ALGOI_REDUCE_FUNC(reduceFunc) (dest, *item); \
} else { \
M_GET_SET M_GET_OPLIST cont_oplist (dest, *item); \
m_init_done = true; \
@@ -284,7 +310,7 @@
for M_EACH(item, cont, cont_oplist) { \
mapFunc(m_tmp, *item); \
if (m_init_done) { \
reduceFunc(dest, m_tmp); \
ALGOI_REDUCE_FUNC(reduceFunc) (dest, m_tmp); \
} else { \
M_GET_SET M_GET_OPLIST cont_oplist (dest, m_tmp); \
m_init_done = true; \
@@ -300,7 +326,7 @@
for M_EACH(item, cont, cont_oplist) { \
mapFunc(m_tmp, __VA_ARGS__, *item); \
if (m_init_done) { \
reduceFunc(dest, m_tmp); \
ALGOI_REDUCE_FUNC(reduceFunc) (dest, m_tmp); \
} else { \
M_GET_SET M_GET_OPLIST cont_oplist (dest, m_tmp); \
m_init_done = true; \
+9
View File
@@ -99,6 +99,15 @@ static void test_extract(void)
ALGO_REDUCE(dst, a, ARRAY_OPLIST(int), inc, sqr2, 4);
assert (dst == (100*99/2-10*11/2) *4 );
ALGO_REDUCE(dst, a, ARRAY_OPLIST(int), sum);
assert (dst == 100*99/2-10*11/2);
ALGO_REDUCE(dst, a, ARRAY_OPLIST(int), add);
assert (dst == 100*99/2-10*11/2);
ALGO_REDUCE(dst, a, ARRAY_OPLIST(int), and);
assert (dst == 0);
ALGO_REDUCE(dst, a, ARRAY_OPLIST(int), or);
assert (dst == 127);
array_int_clear(a);
list_int_clear(l);
}