diff --git a/m-algo.h b/m-algo.h index 7b93ce1e..5e7022ee 100644 --- a/m-algo.h +++ b/m-algo.h @@ -71,13 +71,11 @@ USAGE: ALGO_REDUCE(dstVar, container, contOplist, reduceFunc [, mapFunc[, extraParameters of map function]]) */ -#define ALGO_REDUCE(dest, cont, contOp, ...) \ - M_IF_NARGS_EQ1(__VA_ARGS__) \ - (ALGOI_REDUCE(dest, M_GLOBAL_OPLIST(cont), M_GLOBAL_OPLIST(contOp), __VA_ARGS__), \ - M_IF_NARGS_EQ2(__VA_ARGS__) \ - (ALGOI_REDUCE_FOR_EACH(dest, M_GLOBAL_OPLIST(cont), M_GLOBAL_OPLIST(contOp), __VA_ARGS__), \ - ALGOI_REDUCE_FOR_EACH_ARG(dest, M_GLOBAL_OPLIST(cont), M_GLOBAL_OPLIST(contOp), __VA_ARGS__) ) ) - +#define ALGO_REDUCE(dest, cont, contOp, ...) \ + M_IF(M_PARENTHESIS_P(dest)) \ + (ALGOI_REDUCE_DISPATCH(M_PAIR_1 dest, M_GLOBAL_OPLIST(M_PAIR_2 dest), M_GLOBAL_TYPE(M_PAIR_2 dest),cont, M_GLOBAL_OPLIST(contOp), __VA_ARGS__), \ + ALGOI_REDUCE_DISPATCH(dest, M_GET_OPLIST M_GLOBAL_OPLIST(contOp), M_GET_SUBTYPE M_GLOBAL_OPLIST(contOp), cont, contOp, __VA_ARGS__)) \ + /* Initialize & set a container with a variable array list. USAGE: @@ -931,6 +929,13 @@ } while (0) +#define ALGOI_REDUCE_DISPATCH(dest, destOp, dest_t, cont, contOp, ...) \ + M_IF_NARGS_EQ1(__VA_ARGS__) \ + (ALGOI_REDUCE_BASIC(dest, dest_t, destOp, cont, contOp, __VA_ARGS__), \ + M_IF_NARGS_EQ2(__VA_ARGS__) \ + (ALGOI_REDUCE_FOR_EACH(dest, dest_t, destOp, cont, contOp, __VA_ARGS__), \ + ALGOI_REDUCE_FOR_EACH_ARG(dest, dest_t, destOp, cont, contOp, __VA_ARGS__) ) ) + /* The special function handler */ #define ALGOI_REDUCE_AND(a,b) ((a) &= (b)) #define ALGOI_REDUCE_OR(a,b) ((a) |= (b)) @@ -954,49 +959,48 @@ ) \ ) -#define ALGOI_REDUCE(dest, cont, cont_oplist, reduceFunc) do { \ - bool _init_done = false; \ - for M_EACH(_item, cont, cont_oplist) { \ - if (_init_done) { \ - ALGOI_REDUCE_FUNC(reduceFunc) (dest, *_item); \ - } else { \ - M_CALL_SET(M_GET_OPLIST cont_oplist, dest, *_item); \ - _init_done = true; \ - } \ - } \ +#define ALGOI_REDUCE_BASIC(dest, dest_t, destOp, cont, cont_oplist, reduceFunc) do { \ + bool _init_done = false; \ + for M_EACH(_item, cont, cont_oplist) { \ + if (_init_done) { \ + ALGOI_REDUCE_FUNC(reduceFunc) (dest, *_item); \ + } else { \ + M_CALL_SET(destOp, dest, *_item); \ + _init_done = true; \ + } \ + } \ } while (0) - -#define ALGOI_REDUCE_FOR_EACH(dest, cont, cont_oplist, reduceFunc, mapFunc) do { \ +#define ALGOI_REDUCE_FOR_EACH(dest, dest_t, destOp, cont, cont_oplist, reduceFunc, mapFunc) do { \ bool _init_done = false; \ - M_GET_SUBTYPE cont_oplist _tmp; \ - M_CALL_INIT(M_GET_OPLIST cont_oplist, _tmp); \ + dest_t _tmp; \ + M_CALL_INIT(destOp, _tmp); \ for M_EACH(_item, cont, cont_oplist) { \ mapFunc(_tmp, *_item); \ if (_init_done) { \ ALGOI_REDUCE_FUNC(reduceFunc) (dest, _tmp); \ } else { \ - M_CALL_SET(M_GET_OPLIST cont_oplist, dest, _tmp); \ + M_CALL_SET(destOp, dest, _tmp); \ _init_done = true; \ } \ } \ - M_CALL_CLEAR(M_GET_OPLIST cont_oplist, _tmp); \ + M_CALL_CLEAR(destOp, _tmp); \ } while (0) -#define ALGOI_REDUCE_FOR_EACH_ARG(dest, cont, cont_oplist, reduceFunc, mapFunc, ...) do { \ +#define ALGOI_REDUCE_FOR_EACH_ARG(dest, dest_t, destOp, cont, cont_oplist, reduceFunc, mapFunc, ...) do { \ bool _init_done = false; \ - M_GET_SUBTYPE cont_oplist _tmp; \ - M_CALL_INIT(M_GET_OPLIST cont_oplist, _tmp); \ + dest_t _tmp; \ + M_CALL_INIT(destOp, _tmp); \ for M_EACH(_item, cont, cont_oplist) { \ mapFunc(_tmp, __VA_ARGS__, *_item); \ if (_init_done) { \ ALGOI_REDUCE_FUNC(reduceFunc) (dest, _tmp); \ } else { \ - M_CALL_SET(M_GET_OPLIST cont_oplist, dest, _tmp); \ + M_CALL_SET(destOp, dest, _tmp); \ _init_done = true; \ } \ } \ - M_CALL_CLEAR(M_GET_OPLIST cont_oplist, _tmp); \ + M_CALL_CLEAR(destOp, _tmp); \ } while (0) diff --git a/m-core.h b/m-core.h index 302bc90a..ac9cd256 100644 --- a/m-core.h +++ b/m-core.h @@ -2416,6 +2416,9 @@ m_core_hash (const void *str, size_t length) #define M_GLOBALI_OPLIST_ELSE(a) M_GLOBALI_OPLIST_ELSE2(a, M_C(M_OPL_, a)()) #define M_GLOBALI_OPLIST_ELSE2(a, op) M_IF( M_OPLIST_P (op))(op, a) +#define M_GLOBAL_TYPE(a) \ + M_IF( M_OPLIST_P(a))(M_GLOBALI_TYPE_GET, M_GLOBALI_ID)(a) +#define M_GLOBALI_TYPE_GET(a) M_GET_TYPE a /* If a symbol composed of M_OPL_##a() exists and is defined as an oplist, it returns it otherwise it returns M_DEFAULT_OPLIST.