From 1a11fd145b96a613890d2fb06ad0b3fb7dd7d0c7 Mon Sep 17 00:00:00 2001 From: Patrick Pelissier Date: Sat, 4 Nov 2023 19:27:48 +0100 Subject: [PATCH] WIP --- m-generic.h | 58 +++++++++++++++++++++++-------------------- tests/test-mgeneric.c | 5 ++-- 2 files changed, 34 insertions(+), 29 deletions(-) diff --git a/m-generic.h b/m-generic.h index ce61c9b4..3d2b7bed 100644 --- a/m-generic.h +++ b/m-generic.h @@ -52,55 +52,59 @@ struct m_g3neric_dummys; // Call the OPERATOR call of the oplist registered to the variable 'x' // which takes one argument. -#define M_G3N_CALL_1(call, x) \ +#define M_G3N_CALL_1(op, x) \ _Generic( ((void)0, (x)), \ - M_MAP2(M_G3N_CALL_1_func, (call, x) M_G3N_REGISTERED_ITEMS() ) \ + M_MAP2(M_G3N_CALL_1_func, (op, x) M_G3N_REGISTERED_ITEMS() ) \ struct m_g3neric_dummys *: /* cannot happen */ (void)0) #define M_G3N_CALL_1_func(x, oplist) \ - M_G3N_CALL_1_func_expand(M_GET_GENTYPE oplist(), M_PAIR_1 x, M_PAIR_2 x, oplist) -#define M_G3N_CALL_1_func_expand(gentype, call, x, oplist) \ - gentype: call(oplist(), M_AS_TYPE(gentype, x)), \ - const gentype: call(oplist(), M_AS_LINKED_TYPE(const gentype, x, gentype, x)), + M_G3N_CALL_1_func_test(M_GET_GENTYPE oplist(), M_PAIR_1 x, M_PAIR_2 x, oplist) +#define M_G3N_CALL_1_func_test(gentype, op, x, oplist) \ + M_IF_METHOD(op, oplist())(M_G3N_CALL_1_func_expand, M_EAT)(gentype, op, x, oplist) +#define M_G3N_CALL_1_func_expand(gentype, op, x, oplist) \ + gentype: M_C(M_CALL_, op)(oplist(), M_AS_TYPE(gentype, x)), \ + const gentype: M_C(M_CALL_, op)(oplist(), M_AS_LINKED_TYPE(const gentype, x, gentype, x)), // Call the OPERATOR call of the oplist registered to the variable 'x' // which takes two argument (type, type) -#define M_G3N_CALL_2(call, x, y) \ +#define M_G3N_CALL_2(op, x, y) \ _Generic( ((void)0, (x)), \ - M_MAP2(M_G3N_CALL_2_func, (call, x, y) M_G3N_REGISTERED_ITEMS() ) \ + M_MAP2(M_G3N_CALL_2_func, (op, x, y) M_G3N_REGISTERED_ITEMS() ) \ struct m_g3neric_dummys *: /* cannot happen */ (void) 0) #define M_G3N_CALL_2_func(x, oplist) \ - M_G3N_CALL_2_func_expand(M_GET_GENTYPE oplist(), M_TRIPLE_1 x, M_TRIPLE_2 x, M_TRIPLE_3 x, oplist) -#define M_G3N_CALL_2_func_expand(gentype, call, x, y, oplist) \ - gentype: call(oplist(), M_AS_TYPE(gentype, x), M_AS_LINKED_TYPE(gentype, x, gentype, y)), \ - const gentype: call(oplist(), M_AS_TYPE(const gentype, x), M_AS_LINKED_TYPE(const gentype, x, gentype, y)), + M_G3N_CALL_2_func_test(M_GET_GENTYPE oplist(), M_TRIPLE_1 x, M_TRIPLE_2 x, M_TRIPLE_3 x, oplist) +#define M_G3N_CALL_2_func_test(gentype, op, x, y, oplist) \ + M_IF_METHOD(op, oplist())(M_G3N_CALL_2_func_expand, M_EAT)(gentype, op, x, y, oplist) +#define M_G3N_CALL_2_func_expand(gentype, op, x, y, oplist) \ + gentype: M_C(M_CALL_, op)(oplist(), M_AS_TYPE(gentype, x), M_AS_LINKED_TYPE(gentype, x, gentype, y)), \ + const gentype: M_C(M_CALL_, op)(oplist(), M_AS_LINKED_TYPE(const gentype, x, gentype, x), M_AS_LINKED_TYPE(const gentype, x, gentype, y)), // Call the OPERATOR call of the oplist registered to the variable 'x' // which takes two argument (type, subtype) -#define M_G3N_CALL_2t(call, x, y) \ +#define M_G3N_CALL_2t(op, x, y) \ _Generic( ((void)0, (x)), \ - M_MAP2(M_G3N_CALL_2t_func, (call, x, y) M_G3N_REGISTERED_ITEMS() ) \ + M_MAP2(M_G3N_CALL_2t_func, (op, x, y) M_G3N_REGISTERED_ITEMS() ) \ struct m_g3neric_dummys *: /* cannot happen */ (void) 0) #define M_G3N_CALL_2t_func(x, oplist) \ - M_G3N_CALL_2t_func_expand(M_GET_GENTYPE oplist(), \ + M_G3N_CALL_2t_func_test(M_GET_GENTYPE oplist(), \ M_IF_METHOD(GENTYPE, M_GET_OPLIST oplist())(M_GET_GENTYPE M_GET_OPLIST oplist(), M_GET_SUBTYPE oplist()), \ M_TRIPLE_1 x, M_TRIPLE_2 x, M_TRIPLE_3 x, oplist) -#define M_G3N_CALL_2t_func_expand(gentype, basictype, call, x, y, oplist) \ - gentype: call(oplist(), M_AS_TYPE(gentype, x), M_AS_LINKED_TYPE(gentype, x, basictype, y)), \ - const gentype: call(oplist(), M_AS_TYPE(const gentype, x), M_AS_LINKED_TYPE(const gentype, x, basictype, y)), +#define M_G3N_CALL_2t_func_test(gentype, basictype, op, x, y, oplist) \ + M_IF_METHOD(op, oplist())(M_G3N_CALL_2t_func_expand, M_EAT)(gentype, op, x, y, oplist) +#define M_G3N_CALL_2t_func_expand(gentype, basictype, op, x, y, oplist) \ + gentype: M_C(M_CALL_, op)(oplist(), M_AS_TYPE(gentype, x), M_AS_LINKED_TYPE(gentype, x, basictype, y)), \ + const gentype: M_C(M_CALL_, op)(oplist(), M_AS_LINKED_TYPE(const gentype, x, gentype, x), M_AS_LINKED_TYPE(const gentype, x, basictype, y)), #define M_AS_LINKED_TYPE(typex, x, typey, y) _Generic(((void)0,(x)), typex: (y), default: (typey) {0}) -//TODO: M_AS_TYPE is incorrect. We need M_AS_TYPE_???(gentype, x, basictype, y) ak if type(x) == gentype, then y else basictype - // Define generic functions // TODO: m_ prefix? -#define init(x) M_G3N_CALL_1(M_CALL_INIT, x) -#define init_set(x, y) M_G3N_CALL_2(M_CALL_INIT_SET, x, y) -#define set(x, y) M_G3N_CALL_2(M_CALL_SET, x, y) -#define clear(x) M_G3N_CALL_1(M_CALL_CLEAR, x) -#define init_move(x, y) M_G3N_CALL_2(M_CALL_INIT_MOVE, x, y) -#define push(x, y) M_G3N_CALL_2t(M_CALL_PUSH, x, y) -#define empty_p(x) M_G3N_CALL_1(M_CALL_EMPTY_P, x) +#define init(x) M_G3N_CALL_1(INIT, x) +#define init_set(x, y) M_G3N_CALL_2(INIT_SET, x, y) +#define set(x, y) M_G3N_CALL_2(SET, x, y) +#define clear(x) M_G3N_CALL_1(CLEAR, x) +#define init_move(x, y) M_G3N_CALL_2(INIT_MOVE, x, y) +#define push(x, y) M_G3N_CALL_2tPUSH, x, y) +#define empty_p(x) M_G3N_CALL_1(EMPTY_P, x) /* User code has to register oplists : diff --git a/tests/test-mgeneric.c b/tests/test-mgeneric.c index 6c5adff6..2ea50e48 100644 --- a/tests/test-mgeneric.c +++ b/tests/test-mgeneric.c @@ -28,7 +28,7 @@ #include "m-string.h" #include "m-generic.h" -// Serial json is not supported for standard types if not C11 +// Generic is not supported if not C11 #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L static void h(string_t x) @@ -71,7 +71,8 @@ const string_t gx; */ #define STR1 M_OPEXTEND(STRING_OPLIST, GENTYPE(struct m_string_s *)) -#define FLT1 (GENTYPE(float), TYPE(float), INIT(M_INIT_DEFAULT)) +#define FLT1 (GENTYPE(float), TYPE(float), INIT(M_INIT_BASIC), INIT_SET(M_SET_BASIC), SET(M_SET_BASIC), \ + CLEAR(M_NOTHING_DEFAULT) ) //#define M_GENERIC_ORG_MLIB_COMP_1() (CORE) //#define M_GENERIC_ORG_MLIB_COMP_CORE_OPLIST_1() STR1