ALGO macros accept now a type instead of an oplist

if a global oplist has been registered for the type.

Add macro ALGO_LET_INIT_VA which declares, initializes, sets and clears
a container.
This commit is contained in:
Patrick Pelissier committed 2018-05-22 20:39:51 +02:00
1 parent da9483aa3a
commit 64d0202f95
2 files changed
+55 -23

No files matched your search

+40 -20
View File
@@ -30,19 +30,18 @@
/* Define different kind of algorithms named 'name' over the container
which oplist is 'cont_oplist' as static inline functions.
USAGE:
ALGO_DEF(algogName, containerOplist) */
#define ALGO_DEF(name, cont_oplist) \
ALGOI_DEF(name, M_GET_TYPE cont_oplist, cont_oplist, \
M_GET_SUBTYPE cont_oplist, M_GET_OPLIST cont_oplist, M_GET_IT_TYPE cont_oplist)
ALGO_DEF(algogName, containerOplist|type if oplist has been registered) */
#define ALGO_DEF(name, cont_oplist) \
ALGOI_DEF(name, M_GLOBAL_OPLIST(cont_oplist))
/* Map a function or a macro to all elements of a container.
USAGE:
ALGO_MAP(container, containerOplist, function[, extra arguments of function]) */
#define ALGO_MAP(container, cont_oplist, ...) \
M_IF_NARGS_EQ1(__VA_ARGS__) \
(ALGOI_MAP(container, cont_oplist, __VA_ARGS__), \
ALGOI_MAP_ARG(container, cont_oplist, __VA_ARGS__ ))
#define ALGO_MAP(container, cont_oplist, ...) \
M_IF_NARGS_EQ1(__VA_ARGS__) \
(ALGOI_MAP(container, M_GLOBAL_OPLIST(cont_oplist), __VA_ARGS__), \
ALGOI_MAP_ARG(container, M_GLOBAL_OPLIST(cont_oplist), __VA_ARGS__ ))
/* Extract a subset of a container to fill in another container.
@@ -52,8 +51,8 @@
// TODO: without 'func' parameter, extract all.
#define ALGO_EXTRACT(contD, contDop, contS, contSop, ...) \
M_IF_NARGS_EQ1(__VA_ARGS__) \
(ALGOI_EXTRACT(contD, contDop, contS, contSop, __VA_ARGS__), \
ALGOI_EXTRACT_ARG(contD, contDop, contS, contSop, __VA_ARGS__ ))
(ALGOI_EXTRACT(contD, M_GLOBAL_OPLIST(contDop), M_GLOBAL_OPLIST(contS), contSop, __VA_ARGS__), \
ALGOI_EXTRACT_ARG(contD, M_GLOBAL_OPLIST(contDop), M_GLOBAL_OPLIST(contS), contSop, __VA_ARGS__ ))
/* Perform a Reduce operation over a container.
@@ -62,24 +61,34 @@
[, mapFunc[, extraParameters of map function]]) */
#define ALGO_REDUCE(dest, cont, contOp, ...) \
M_IF_NARGS_EQ1(__VA_ARGS__) \
(ALGOI_REDUCE(dest, cont, contOp, __VA_ARGS__), \
(ALGOI_REDUCE(dest, M_GLOBAL_OPLIST(cont), M_GLOBAL_OPLIST(contOp), __VA_ARGS__), \
M_IF_NARGS_EQ2(__VA_ARGS__) \
(ALGOI_REDUCE_MAP(dest, cont, contOp, __VA_ARGS__), \
ALGOI_REDUCE_MAP_ARG(dest, cont, contOp, __VA_ARGS__) ) )
(ALGOI_REDUCE_MAP(dest, M_GLOBAL_OPLIST(cont), M_GLOBAL_OPLIST(contOp), __VA_ARGS__), \
ALGOI_REDUCE_MAP_ARG(dest, M_GLOBAL_OPLIST(cont), M_GLOBAL_OPLIST(contOp), __VA_ARGS__) ) )
/* Initialize & set a container with a variable array list.
USAGE:
ALGO_INIT_VA(container, containerOplist, param1[, param2[, ...]]) */
#define ALGO_INIT_VA(dest, contOp, ...) do { \
M_GET_INIT contOp (dest); \
M_MAP2(ALGOI_INIT_VA_FUNC, (dest, M_GET_PUSH contOp, ) , __VA_ARGS__); \
} while (0)
#define ALGO_INIT_VA(dest, contOp, ...) \
ALGO_INIT_VAI(dest, M_GLOBAL_OPLIST(contOp), __VA_ARGS__)
/* Define, initialize, set & clear a container with a variable array list.
USAGE:
ALGO_LET_INIT_VA(container, containerOplist, param1[, param2[, ...]]) {
// Stuff with container
} */
#define ALGO_LET_INIT_VA(dest, contOp, ...) \
ALGO_LET_INIT_VAI(dest, M_GLOBAL_OPLIST(contOp), __VA_ARGS__)
/********************************** INTERNAL ************************************/
#define ALGOI_DEF(name, container_t, cont_oplist, type_t, type_oplist, it_t) \
#define ALGOI_DEF(name, cont_oplist) \
ALGOI_DEF2(name, M_GET_TYPE cont_oplist, cont_oplist, \
M_GET_SUBTYPE cont_oplist, M_GET_OPLIST cont_oplist, M_GET_IT_TYPE cont_oplist)
#define ALGOI_DEF2(name, container_t, cont_oplist, type_t, type_oplist, it_t) \
\
/* TODO: Add a specialization if container is sorted */ \
static inline void \
@@ -609,7 +618,18 @@
M_GET_CLEAR M_GET_OPLIST cont_oplist (m_tmp); \
} while (0)
#define ALGOI_INIT_VA_FUNC(d, a) \
M_RET_ARG2 d (M_RET_ARG1 d, a) ;
#define ALGOI_INIT_VA_FUNC(d, a) \
M_RET_ARG2 d (M_RET_ARG1 d, a) M_DEFERRED_COMMA
#define ALGO_INIT_VAI(dest, contOp, ...) \
(void)(M_GET_INIT contOp (dest) M_DEFERRED_COMMA \
M_MAP2(ALGOI_INIT_VA_FUNC, (dest, M_GET_PUSH contOp, ) , __VA_ARGS__) \
true)
#define ALGO_LET_INIT_VAI(dest, contOp, ...) \
for(bool cont = true; cont ; /* unused */) \
for(M_GET_TYPE contOp dest; \
cont && (ALGO_INIT_VAI (dest, contOp, __VA_ARGS__), true); \
(M_GET_CLEAR contOp (dest), cont = false))
#endif
+15 -3
View File
@@ -27,18 +27,21 @@
#include "test-obj.h"
#include "m-algo.h"
// TODO: Test other containers? HASHMAP, RBTREE, B+TREE, Intrusive List
// TODO: Test other containers (Intrusive List)
// HASHMAP, RBTREE, B+TREE: Is this useful?
ARRAY_DEF(array_int, int)
#define M_OPL_array_int_t() ARRAY_OPLIST(array_int)
LIST_DEF(list_int, int)
LIST_DEF(list_string, string_t, STRING_OPLIST)
DEQUE_DEF(deque_obj, testobj_t, TESTOBJ_CMP_OPLIST)
#define M_OPL_deque_obj_t() DEQUE_OPLIST(deque_obj, TESTOBJ_CMP_OPLIST)
#include "coverage.h"
START_COVERAGE
ALGO_DEF(algo_array, ARRAY_OPLIST(array_int))
ALGO_DEF(algo_array, array_int_t)
ALGO_DEF(algo_list, LIST_OPLIST(list_int))
ALGO_DEF(algo_string, LIST_OPLIST(list_string, STRING_OPLIST))
ALGO_DEF(algo_deque, DEQUE_OPLIST(deque_obj, TESTOBJ_CMP_OPLIST))
ALGO_DEF(algo_deque, deque_obj_t)
END_COVERAGE
int g_min, g_max, g_count;
@@ -137,6 +140,7 @@ static void test_array(void)
#define f(x) assert((x) >= 0 && (x) < 100);
ALGO_MAP(l, ARRAY_OPLIST(array_int), f);
ALGO_MAP(l, array_int_t, f);
g_min = 0;
g_max = 99;
@@ -207,6 +211,12 @@ static void test_array(void)
assert (algo_array_sort_dsc_p(l) == true);
array_int_clear(l);
ALGO_LET_INIT_VA(arr, array_int_t, 1, 5, 34) {
assert (array_int_size(arr) == 3);
assert (algo_array_sort_p(arr) == true);
assert (algo_array_sort_dsc_p(arr) == false);
}
}
static void test_string(void)
@@ -255,6 +265,8 @@ static void test_extract(void)
#define inc(d, c) (d) += (c)
ALGO_REDUCE(dst, a, ARRAY_OPLIST(array_int), inc);
assert (dst == 100*99/2-10*11/2);
ALGO_REDUCE(dst, a, array_int_t, inc);
assert (dst == 100*99/2-10*11/2);
#define sqr(d, c) (d) = (c)*(c)
ALGO_REDUCE(dst, a, ARRAY_OPLIST(array_int), inc, sqr);
assert (dst == 327965);