Add special (and frequent !) handler for functions add, sum, and and or
for the reduction macro.
This commit is contained in:
1 parent
dee40608d7
commit
9ce1c69753
2 files changed
+38
-3
No files matched your search
@@ -265,11 +265,37 @@
|
|||||||
M_IF_METHOD(REVERSE, contDstOplist) (M_GET_REVERSE contDstOplist (contDstOplist);, ) \
|
M_IF_METHOD(REVERSE, contDstOplist) (M_GET_REVERSE contDstOplist (contDstOplist);, ) \
|
||||||
} while (0)
|
} 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 { \
|
#define ALGOI_REDUCE(dest, cont, cont_oplist, reduceFunc) do { \
|
||||||
bool m_init_done = false; \
|
bool m_init_done = false; \
|
||||||
for M_EACH(item, cont, cont_oplist) { \
|
for M_EACH(item, cont, cont_oplist) { \
|
||||||
if (m_init_done) { \
|
if (m_init_done) { \
|
||||||
reduceFunc(dest, *item); \
|
ALGOI_REDUCE_FUNC(reduceFunc) (dest, *item); \
|
||||||
} else { \
|
} else { \
|
||||||
M_GET_SET M_GET_OPLIST cont_oplist (dest, *item); \
|
M_GET_SET M_GET_OPLIST cont_oplist (dest, *item); \
|
||||||
m_init_done = true; \
|
m_init_done = true; \
|
||||||
@@ -284,7 +310,7 @@
|
|||||||
for M_EACH(item, cont, cont_oplist) { \
|
for M_EACH(item, cont, cont_oplist) { \
|
||||||
mapFunc(m_tmp, *item); \
|
mapFunc(m_tmp, *item); \
|
||||||
if (m_init_done) { \
|
if (m_init_done) { \
|
||||||
reduceFunc(dest, m_tmp); \
|
ALGOI_REDUCE_FUNC(reduceFunc) (dest, m_tmp); \
|
||||||
} else { \
|
} else { \
|
||||||
M_GET_SET M_GET_OPLIST cont_oplist (dest, m_tmp); \
|
M_GET_SET M_GET_OPLIST cont_oplist (dest, m_tmp); \
|
||||||
m_init_done = true; \
|
m_init_done = true; \
|
||||||
@@ -300,7 +326,7 @@
|
|||||||
for M_EACH(item, cont, cont_oplist) { \
|
for M_EACH(item, cont, cont_oplist) { \
|
||||||
mapFunc(m_tmp, __VA_ARGS__, *item); \
|
mapFunc(m_tmp, __VA_ARGS__, *item); \
|
||||||
if (m_init_done) { \
|
if (m_init_done) { \
|
||||||
reduceFunc(dest, m_tmp); \
|
ALGOI_REDUCE_FUNC(reduceFunc) (dest, m_tmp); \
|
||||||
} else { \
|
} else { \
|
||||||
M_GET_SET M_GET_OPLIST cont_oplist (dest, m_tmp); \
|
M_GET_SET M_GET_OPLIST cont_oplist (dest, m_tmp); \
|
||||||
m_init_done = true; \
|
m_init_done = true; \
|
||||||
|
|||||||
@@ -99,6 +99,15 @@ static void test_extract(void)
|
|||||||
ALGO_REDUCE(dst, a, ARRAY_OPLIST(int), inc, sqr2, 4);
|
ALGO_REDUCE(dst, a, ARRAY_OPLIST(int), inc, sqr2, 4);
|
||||||
assert (dst == (100*99/2-10*11/2) *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);
|
array_int_clear(a);
|
||||||
list_int_clear(l);
|
list_int_clear(l);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user