diff --git a/README.md b/README.md index 61379c2a..57e383ab 100644 --- a/README.md +++ b/README.md @@ -6206,12 +6206,26 @@ when the bracket associated to the M\_LET go out of scope. If 'var1' (resp. var2, ...) has the form (v1, arguments...), then the variable 'v1' will be initialized with the -contains of 'arguments...' given to the specialized initializer -operator INIT\_WITH -(and not the empty initializer INIT operator). -An argument shall not contain any comma or it shall be +contains of 'arguments...'. +If 'arguments' is within parenthesis +or if there is more one argument +or if the property LET\_AS\_INIT\_WITH is defined, +it will use the operator INIT\_WITH if it exists to emplace the variable +with the given arguments (The arguments are expected to be compatible with +the INIT\_WITH operator). +Otherwise it will use the operator INIT\_SET (argument is expected +to be the same type as the initialized type). +In both cases, the empty initializer INIT operator is not called. + +LIMITATION: +An argument shall not contain any comma or it shall be put between parenthesis. In particular, if the argument is a compound -litteral the full compound litteral shall be put between parenthesis. +litteral the full compound litteral shall be put between parenthesis +and casted to the right type outside the parenthesis (due to the conflict +with the INIT\_WITH detection it is needed to put something outside the +parenthesis like a cast). + +An argument shall not have any post effect when it is evaluated. There shall be at most one M\_LET macro per line of source code. @@ -6219,6 +6233,7 @@ Example: M_LET(a, STRING_OPLIST) { do something with a } or M_LET(a, b, c, string_t) { do something with a, b & c } + M_LET( (a, ("Hello")), string_t) { do something with a } NOTE: The user code shall not perform a return or a goto (or longjmp) outside the {} or a call to an exit function otherwise the clear code of the object won't be called . diff --git a/doc/API.txt b/doc/API.txt index cab0b797..ebc7b1f4 100644 --- a/doc/API.txt +++ b/doc/API.txt @@ -60,8 +60,11 @@ V0.4.*: * The order of a list initialized using M_LET is reversed V0.5.*: * M_INVERT is renamed into M_REVERSE to be more coherent with the REVERSE operator. M_INVERT is marked as obsolete. * Remove _it_to_p method of B+TREE / RB-TREE as it has been deprecated. - * Remove ALGO_INIT_VA & M_ALG0_LET_INIT_VAI of m-algo as it has been deprecated. Use of M_LET instead. + * Remove ALGO_INIT_VA & M_ALG0_LET_INIT_VAI of m-algo as it has been deprecated (Use of M_LET instead). * Some Internal name of user modifiable macros have been renamed to be properly customizable by the user. - * Rename M_HASH_SEED into M_USE_HASH_SEED as it is a user macro. + * Rename M_HASH_SEED into M_USE_HASH_SEED (as it is a user macro). + * M_LET: for initialization of variable with arguments, if there is only one argument, + it will default to use INIT_SET instead of INIT_WITH. Encapsulate the argument between () + to force use of INIT_WITH. \ No newline at end of file diff --git a/example/ex-string03.c b/example/ex-string03.c new file mode 100644 index 00000000..12aeaa5f --- /dev/null +++ b/example/ex-string03.c @@ -0,0 +1,44 @@ +#include +#include "m-string.h" +#include "m-dict.h" +#include "m-array.h" + +/* Definition of an associative map string_t --> size_t */ +DICT_DEF2(dict_str, string_t, size_t) +#define M_OPL_dict_str_t() DICT_OPLIST(dict_str, STRING_OPLIST, M_DEFAULT_OPLIST) + +/* Definition of an array of string_t */ +ARRAY_DEF(vector_str, string_t) +#define M_OPL_vector_str_t() ARRAY_OPLIST(vector_str, STRING_OPLIST) + +int main(void) +{ + // Construct an array of string, performing a convertion of the C const char * + // into a proper string_t at real time and push then into a dynamic array + // that is declared, initialized and cleared. + M_LET( (words, ("This"), ("is"), ("a"), ("useless"), ("sentence"), ("."), + ("It"), ("is"), ("used"), ("a"), ("bit"), ("to"), ("count"), ("words"), (".") ), + vector_str_t) { + // Print the arrays. + printf("The words are: "); + vector_str_out_str(stdout, words); + printf("\n"); + + // Count the words. + M_LET(map, dict_str_t) { + // Count the words: + for M_EACH(w, words, vector_str_t) { + (*dict_str_get_at(map, *w)) ++; + } + + // Print the count: + for M_EACH(p, map, dict_str_t) { +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L) + M_PRINT(p->value, " occurences of ", p->key, "\n"); +#else + printf ("%zu occurences of %s\n", p->value, string_get_cstr(p->key)); +#endif + } + } + } +} diff --git a/m-array.h b/m-array.h index 82cd0322..94018d5c 100644 --- a/m-array.h +++ b/m-array.h @@ -76,7 +76,7 @@ #define M_ARRA4_OPLIST_P3(name, oplist) \ (INIT(M_C(name, _init)) \ ,M_IF_METHOD2(INIT_SET,SET, oplist)(INIT_SET(M_C(name, _init_set)),) \ - ,M_IF_METHOD(INIT_SET, oplist)(INIT_WITH(API_1(M_INIT_VAI)),) \ + ,M_IF_METHOD(INIT_SET, oplist)(INIT_WITH(API_1(M_INIT_WITH_VAI)),) \ ,M_IF_METHOD2(INIT_SET,SET, oplist)(SET(M_C(name, _set)), ) \ ,CLEAR(M_C(name, _clear)) \ ,INIT_MOVE(M_C(name, _init_move)) \ diff --git a/m-core.h b/m-core.h index e9e114ef..77e30643 100644 --- a/m-core.h +++ b/m-core.h @@ -1220,9 +1220,62 @@ M_BEGIN_PROTECTED_CODE /* Map a macro to all given arguments with one additional fixed data (non recursive version) */ /* Example: M_MAP2(f, data, a, b, c) ==> f(data,a) f(data,b) f(data,c) */ -#define M_MAP2(f, d, ...) M_MAP2I(M_C(M_MAP2B_, M_NARGS(__VA_ARGS__)), f, d, __VA_ARGS__) +#define M_MAP2(f, d, ...) M_MAP2I(M_C(M_MAP2I_, M_NARGS(__VA_ARGS__)), f, d, __VA_ARGS__) #define M_MAP2I(F,...) F (__VA_ARGS__) +#define M_MAP2I_1(f, d, _1) f(d, _1) +#define M_MAP2I_2(f, d, _1, _2) f(d, _1) f(d, _2) +#define M_MAP2I_3(f, d, _1, _2, _3) f(d, _1) f(d, _2) f(d, _3) +#define M_MAP2I_4(f, d, _1, _2, _3, _4) f(d, _1) f(d, _2) f(d, _3) f(d, _4) +#define M_MAP2I_5(f, d, _1, _2, _3, _4, _5) f(d, _1) f(d, _2) f(d, _3) f(d, _4) f(d, _5) +#define M_MAP2I_6(f, d, _1, _2, _3, _4, _5, _6) f(d, _1) f(d, _2) f(d, _3) f(d, _4) f(d, _5) f(d, _6) +#define M_MAP2I_7(f, d, _1, _2, _3, _4, _5, _6, _7) f(d, _1) f(d, _2) f(d, _3) f(d, _4) f(d, _5) f(d, _6) f(d, _7) +#define M_MAP2I_8(f, d, _1, _2, _3, _4, _5, _6, _7, _8) f(d, _1) f(d, _2) f(d, _3) f(d, _4) f(d, _5) f(d, _6) f(d, _7) f(d, _8) +#define M_MAP2I_9(f, d, _1, _2, _3, _4, _5, _6, _7, _8, _9) f(d, _1) f(d, _2) f(d, _3) f(d, _4) f(d, _5) f(d, _6) f(d, _7) f(d, _8) f(d, _9) +#define M_MAP2I_10(f, d, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) f(d, _1) f(d, _2) f(d, _3) f(d, _4) f(d, _5) f(d, _6) f(d, _7) f(d, _8) f(d, _9) f(d, _10) +#define M_MAP2I_11(f, d, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11) f(d, _1) f(d, _2) f(d, _3) f(d, _4) f(d, _5) f(d, _6) f(d, _7) f(d, _8) f(d, _9) f(d, _10) f(d, _11) +#define M_MAP2I_12(f, d, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12) f(d, _1) f(d, _2) f(d, _3) f(d, _4) f(d, _5) f(d, _6) f(d, _7) f(d, _8) f(d, _9) f(d, _10) f(d, _11) f(d, _12) +#define M_MAP2I_13(f, d, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13) f(d, _1) f(d, _2) f(d, _3) f(d, _4) f(d, _5) f(d, _6) f(d, _7) f(d, _8) f(d, _9) f(d, _10) f(d, _11) f(d, _12) f(d, _13) +#define M_MAP2I_14(f, d, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14) f(d, _1) f(d, _2) f(d, _3) f(d, _4) f(d, _5) f(d, _6) f(d, _7) f(d, _8) f(d, _9) f(d, _10) f(d, _11) f(d, _12) f(d, _13) f(d, _14) +#define M_MAP2I_15(f, d, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15) f(d, _1) f(d, _2) f(d, _3) f(d, _4) f(d, _5) f(d, _6) f(d, _7) f(d, _8) f(d, _9) f(d, _10) f(d, _11) f(d, _12) f(d, _13) f(d, _14) f(d, _15) +#define M_MAP2I_16(f, d, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16) f(d, _1) f(d, _2) f(d, _3) f(d, _4) f(d, _5) f(d, _6) f(d, _7) f(d, _8) f(d, _9) f(d, _10) f(d, _11) f(d, _12) f(d, _13) f(d, _14) f(d, _15) f(d, _16) +#define M_MAP2I_17(f, d, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17) f(d, _1) f(d, _2) f(d, _3) f(d, _4) f(d, _5) f(d, _6) f(d, _7) f(d, _8) f(d, _9) f(d, _10) f(d, _11) f(d, _12) f(d, _13) f(d, _14) f(d, _15) f(d, _16) f(d, _17) +#define M_MAP2I_18(f, d, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18) f(d, _1) f(d, _2) f(d, _3) f(d, _4) f(d, _5) f(d, _6) f(d, _7) f(d, _8) f(d, _9) f(d, _10) f(d, _11) f(d, _12) f(d, _13) f(d, _14) f(d, _15) f(d, _16) f(d, _17) f(d, _18) +#define M_MAP2I_19(f, d, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19) f(d, _1) f(d, _2) f(d, _3) f(d, _4) f(d, _5) f(d, _6) f(d, _7) f(d, _8) f(d, _9) f(d, _10) f(d, _11) f(d, _12) f(d, _13) f(d, _14) f(d, _15) f(d, _16) f(d, _17) f(d, _18) f(d, _19) +#define M_MAP2I_20(f, d, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20) f(d, _1) f(d, _2) f(d, _3) f(d, _4) f(d, _5) f(d, _6) f(d, _7) f(d, _8) f(d, _9) f(d, _10) f(d, _11) f(d, _12) f(d, _13) f(d, _14) f(d, _15) f(d, _16) f(d, _17) f(d, _18) f(d, _19) f(d, _20) +#define M_MAP2I_21(f, d, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21) f(d, _1) f(d, _2) f(d, _3) f(d, _4) f(d, _5) f(d, _6) f(d, _7) f(d, _8) f(d, _9) f(d, _10) f(d, _11) f(d, _12) f(d, _13) f(d, _14) f(d, _15) f(d, _16) f(d, _17) f(d, _18) f(d, _19) f(d, _20) f(d, _21) +#define M_MAP2I_22(f, d, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22) f(d, _1) f(d, _2) f(d, _3) f(d, _4) f(d, _5) f(d, _6) f(d, _7) f(d, _8) f(d, _9) f(d, _10) f(d, _11) f(d, _12) f(d, _13) f(d, _14) f(d, _15) f(d, _16) f(d, _17) f(d, _18) f(d, _19) f(d, _20) f(d, _21) f(d, _22) +#define M_MAP2I_23(f, d, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23) f(d, _1) f(d, _2) f(d, _3) f(d, _4) f(d, _5) f(d, _6) f(d, _7) f(d, _8) f(d, _9) f(d, _10) f(d, _11) f(d, _12) f(d, _13) f(d, _14) f(d, _15) f(d, _16) f(d, _17) f(d, _18) f(d, _19) f(d, _20) f(d, _21) f(d, _22) f(d, _23) +#define M_MAP2I_24(f, d, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24) f(d, _1) f(d, _2) f(d, _3) f(d, _4) f(d, _5) f(d, _6) f(d, _7) f(d, _8) f(d, _9) f(d, _10) f(d, _11) f(d, _12) f(d, _13) f(d, _14) f(d, _15) f(d, _16) f(d, _17) f(d, _18) f(d, _19) f(d, _20) f(d, _21) f(d, _22) f(d, _23) f(d, _24) +#define M_MAP2I_25(f, d, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25) f(d, _1) f(d, _2) f(d, _3) f(d, _4) f(d, _5) f(d, _6) f(d, _7) f(d, _8) f(d, _9) f(d, _10) f(d, _11) f(d, _12) f(d, _13) f(d, _14) f(d, _15) f(d, _16) f(d, _17) f(d, _18) f(d, _19) f(d, _20) f(d, _21) f(d, _22) f(d, _23) f(d, _24) f(d, _25) +#define M_MAP2I_26(f, d, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26) f(d, _1) f(d, _2) f(d, _3) f(d, _4) f(d, _5) f(d, _6) f(d, _7) f(d, _8) f(d, _9) f(d, _10) f(d, _11) f(d, _12) f(d, _13) f(d, _14) f(d, _15) f(d, _16) f(d, _17) f(d, _18) f(d, _19) f(d, _20) f(d, _21) f(d, _22) f(d, _23) f(d, _24) f(d, _25) f(d, _26) +#define M_MAP2I_27(f, d, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27) f(d, _1) f(d, _2) f(d, _3) f(d, _4) f(d, _5) f(d, _6) f(d, _7) f(d, _8) f(d, _9) f(d, _10) f(d, _11) f(d, _12) f(d, _13) f(d, _14) f(d, _15) f(d, _16) f(d, _17) f(d, _18) f(d, _19) f(d, _20) f(d, _21) f(d, _22) f(d, _23) f(d, _24) f(d, _25) f(d, _26) f(d, _27) +#define M_MAP2I_28(f, d, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28) f(d, _1) f(d, _2) f(d, _3) f(d, _4) f(d, _5) f(d, _6) f(d, _7) f(d, _8) f(d, _9) f(d, _10) f(d, _11) f(d, _12) f(d, _13) f(d, _14) f(d, _15) f(d, _16) f(d, _17) f(d, _18) f(d, _19) f(d, _20) f(d, _21) f(d, _22) f(d, _23) f(d, _24) f(d, _25) f(d, _26) f(d, _27) f(d, _28) +#define M_MAP2I_29(f, d, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29) f(d, _1) f(d, _2) f(d, _3) f(d, _4) f(d, _5) f(d, _6) f(d, _7) f(d, _8) f(d, _9) f(d, _10) f(d, _11) f(d, _12) f(d, _13) f(d, _14) f(d, _15) f(d, _16) f(d, _17) f(d, _18) f(d, _19) f(d, _20) f(d, _21) f(d, _22) f(d, _23) f(d, _24) f(d, _25) f(d, _26) f(d, _27) f(d, _28) f(d, _29) +#define M_MAP2I_30(f, d, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30) f(d, _1) f(d, _2) f(d, _3) f(d, _4) f(d, _5) f(d, _6) f(d, _7) f(d, _8) f(d, _9) f(d, _10) f(d, _11) f(d, _12) f(d, _13) f(d, _14) f(d, _15) f(d, _16) f(d, _17) f(d, _18) f(d, _19) f(d, _20) f(d, _21) f(d, _22) f(d, _23) f(d, _24) f(d, _25) f(d, _26) f(d, _27) f(d, _28) f(d, _29) f(d, _30) +#define M_MAP2I_31(f, d, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31) f(d, _1) f(d, _2) f(d, _3) f(d, _4) f(d, _5) f(d, _6) f(d, _7) f(d, _8) f(d, _9) f(d, _10) f(d, _11) f(d, _12) f(d, _13) f(d, _14) f(d, _15) f(d, _16) f(d, _17) f(d, _18) f(d, _19) f(d, _20) f(d, _21) f(d, _22) f(d, _23) f(d, _24) f(d, _25) f(d, _26) f(d, _27) f(d, _28) f(d, _29) f(d, _30) f(d, _31) +#define M_MAP2I_32(f, d, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32) f(d, _1) f(d, _2) f(d, _3) f(d, _4) f(d, _5) f(d, _6) f(d, _7) f(d, _8) f(d, _9) f(d, _10) f(d, _11) f(d, _12) f(d, _13) f(d, _14) f(d, _15) f(d, _16) f(d, _17) f(d, _18) f(d, _19) f(d, _20) f(d, _21) f(d, _22) f(d, _23) f(d, _24) f(d, _25) f(d, _26) f(d, _27) f(d, _28) f(d, _29) f(d, _30) f(d, _31) f(d, _32) +#define M_MAP2I_33(f, d, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33) f(d, _1) f(d, _2) f(d, _3) f(d, _4) f(d, _5) f(d, _6) f(d, _7) f(d, _8) f(d, _9) f(d, _10) f(d, _11) f(d, _12) f(d, _13) f(d, _14) f(d, _15) f(d, _16) f(d, _17) f(d, _18) f(d, _19) f(d, _20) f(d, _21) f(d, _22) f(d, _23) f(d, _24) f(d, _25) f(d, _26) f(d, _27) f(d, _28) f(d, _29) f(d, _30) f(d, _31) f(d, _32) f(d, _33) +#define M_MAP2I_34(f, d, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34) f(d, _1) f(d, _2) f(d, _3) f(d, _4) f(d, _5) f(d, _6) f(d, _7) f(d, _8) f(d, _9) f(d, _10) f(d, _11) f(d, _12) f(d, _13) f(d, _14) f(d, _15) f(d, _16) f(d, _17) f(d, _18) f(d, _19) f(d, _20) f(d, _21) f(d, _22) f(d, _23) f(d, _24) f(d, _25) f(d, _26) f(d, _27) f(d, _28) f(d, _29) f(d, _30) f(d, _31) f(d, _32) f(d, _33) f(d, _34) +#define M_MAP2I_35(f, d, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35) f(d, _1) f(d, _2) f(d, _3) f(d, _4) f(d, _5) f(d, _6) f(d, _7) f(d, _8) f(d, _9) f(d, _10) f(d, _11) f(d, _12) f(d, _13) f(d, _14) f(d, _15) f(d, _16) f(d, _17) f(d, _18) f(d, _19) f(d, _20) f(d, _21) f(d, _22) f(d, _23) f(d, _24) f(d, _25) f(d, _26) f(d, _27) f(d, _28) f(d, _29) f(d, _30) f(d, _31) f(d, _32) f(d, _33) f(d, _34) f(d, _35) +#define M_MAP2I_36(f, d, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36) f(d, _1) f(d, _2) f(d, _3) f(d, _4) f(d, _5) f(d, _6) f(d, _7) f(d, _8) f(d, _9) f(d, _10) f(d, _11) f(d, _12) f(d, _13) f(d, _14) f(d, _15) f(d, _16) f(d, _17) f(d, _18) f(d, _19) f(d, _20) f(d, _21) f(d, _22) f(d, _23) f(d, _24) f(d, _25) f(d, _26) f(d, _27) f(d, _28) f(d, _29) f(d, _30) f(d, _31) f(d, _32) f(d, _33) f(d, _34) f(d, _35) f(d, _36) +#define M_MAP2I_37(f, d, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37) f(d, _1) f(d, _2) f(d, _3) f(d, _4) f(d, _5) f(d, _6) f(d, _7) f(d, _8) f(d, _9) f(d, _10) f(d, _11) f(d, _12) f(d, _13) f(d, _14) f(d, _15) f(d, _16) f(d, _17) f(d, _18) f(d, _19) f(d, _20) f(d, _21) f(d, _22) f(d, _23) f(d, _24) f(d, _25) f(d, _26) f(d, _27) f(d, _28) f(d, _29) f(d, _30) f(d, _31) f(d, _32) f(d, _33) f(d, _34) f(d, _35) f(d, _36) f(d, _37) +#define M_MAP2I_38(f, d, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38) f(d, _1) f(d, _2) f(d, _3) f(d, _4) f(d, _5) f(d, _6) f(d, _7) f(d, _8) f(d, _9) f(d, _10) f(d, _11) f(d, _12) f(d, _13) f(d, _14) f(d, _15) f(d, _16) f(d, _17) f(d, _18) f(d, _19) f(d, _20) f(d, _21) f(d, _22) f(d, _23) f(d, _24) f(d, _25) f(d, _26) f(d, _27) f(d, _28) f(d, _29) f(d, _30) f(d, _31) f(d, _32) f(d, _33) f(d, _34) f(d, _35) f(d, _36) f(d, _37) f(d, _38) +#define M_MAP2I_39(f, d, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39) f(d, _1) f(d, _2) f(d, _3) f(d, _4) f(d, _5) f(d, _6) f(d, _7) f(d, _8) f(d, _9) f(d, _10) f(d, _11) f(d, _12) f(d, _13) f(d, _14) f(d, _15) f(d, _16) f(d, _17) f(d, _18) f(d, _19) f(d, _20) f(d, _21) f(d, _22) f(d, _23) f(d, _24) f(d, _25) f(d, _26) f(d, _27) f(d, _28) f(d, _29) f(d, _30) f(d, _31) f(d, _32) f(d, _33) f(d, _34) f(d, _35) f(d, _36) f(d, _37) f(d, _38) f(d, _39) +#define M_MAP2I_40(f, d, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40) f(d, _1) f(d, _2) f(d, _3) f(d, _4) f(d, _5) f(d, _6) f(d, _7) f(d, _8) f(d, _9) f(d, _10) f(d, _11) f(d, _12) f(d, _13) f(d, _14) f(d, _15) f(d, _16) f(d, _17) f(d, _18) f(d, _19) f(d, _20) f(d, _21) f(d, _22) f(d, _23) f(d, _24) f(d, _25) f(d, _26) f(d, _27) f(d, _28) f(d, _29) f(d, _30) f(d, _31) f(d, _32) f(d, _33) f(d, _34) f(d, _35) f(d, _36) f(d, _37) f(d, _38) f(d, _39) f(d, _40) +#define M_MAP2I_41(f, d, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41) f(d, _1) f(d, _2) f(d, _3) f(d, _4) f(d, _5) f(d, _6) f(d, _7) f(d, _8) f(d, _9) f(d, _10) f(d, _11) f(d, _12) f(d, _13) f(d, _14) f(d, _15) f(d, _16) f(d, _17) f(d, _18) f(d, _19) f(d, _20) f(d, _21) f(d, _22) f(d, _23) f(d, _24) f(d, _25) f(d, _26) f(d, _27) f(d, _28) f(d, _29) f(d, _30) f(d, _31) f(d, _32) f(d, _33) f(d, _34) f(d, _35) f(d, _36) f(d, _37) f(d, _38) f(d, _39) f(d, _40) f(d, _41) +#define M_MAP2I_42(f, d, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42) f(d, _1) f(d, _2) f(d, _3) f(d, _4) f(d, _5) f(d, _6) f(d, _7) f(d, _8) f(d, _9) f(d, _10) f(d, _11) f(d, _12) f(d, _13) f(d, _14) f(d, _15) f(d, _16) f(d, _17) f(d, _18) f(d, _19) f(d, _20) f(d, _21) f(d, _22) f(d, _23) f(d, _24) f(d, _25) f(d, _26) f(d, _27) f(d, _28) f(d, _29) f(d, _30) f(d, _31) f(d, _32) f(d, _33) f(d, _34) f(d, _35) f(d, _36) f(d, _37) f(d, _38) f(d, _39) f(d, _40) f(d, _41) f(d, _42) +#define M_MAP2I_43(f, d, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43) f(d, _1) f(d, _2) f(d, _3) f(d, _4) f(d, _5) f(d, _6) f(d, _7) f(d, _8) f(d, _9) f(d, _10) f(d, _11) f(d, _12) f(d, _13) f(d, _14) f(d, _15) f(d, _16) f(d, _17) f(d, _18) f(d, _19) f(d, _20) f(d, _21) f(d, _22) f(d, _23) f(d, _24) f(d, _25) f(d, _26) f(d, _27) f(d, _28) f(d, _29) f(d, _30) f(d, _31) f(d, _32) f(d, _33) f(d, _34) f(d, _35) f(d, _36) f(d, _37) f(d, _38) f(d, _39) f(d, _40) f(d, _41) f(d, _42) f(d, _43) +#define M_MAP2I_44(f, d, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44) f(d, _1) f(d, _2) f(d, _3) f(d, _4) f(d, _5) f(d, _6) f(d, _7) f(d, _8) f(d, _9) f(d, _10) f(d, _11) f(d, _12) f(d, _13) f(d, _14) f(d, _15) f(d, _16) f(d, _17) f(d, _18) f(d, _19) f(d, _20) f(d, _21) f(d, _22) f(d, _23) f(d, _24) f(d, _25) f(d, _26) f(d, _27) f(d, _28) f(d, _29) f(d, _30) f(d, _31) f(d, _32) f(d, _33) f(d, _34) f(d, _35) f(d, _36) f(d, _37) f(d, _38) f(d, _39) f(d, _40) f(d, _41) f(d, _42) f(d, _43) f(d, _44) +#define M_MAP2I_45(f, d, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45) f(d, _1) f(d, _2) f(d, _3) f(d, _4) f(d, _5) f(d, _6) f(d, _7) f(d, _8) f(d, _9) f(d, _10) f(d, _11) f(d, _12) f(d, _13) f(d, _14) f(d, _15) f(d, _16) f(d, _17) f(d, _18) f(d, _19) f(d, _20) f(d, _21) f(d, _22) f(d, _23) f(d, _24) f(d, _25) f(d, _26) f(d, _27) f(d, _28) f(d, _29) f(d, _30) f(d, _31) f(d, _32) f(d, _33) f(d, _34) f(d, _35) f(d, _36) f(d, _37) f(d, _38) f(d, _39) f(d, _40) f(d, _41) f(d, _42) f(d, _43) f(d, _44) f(d, _45) +#define M_MAP2I_46(f, d, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46) f(d, _1) f(d, _2) f(d, _3) f(d, _4) f(d, _5) f(d, _6) f(d, _7) f(d, _8) f(d, _9) f(d, _10) f(d, _11) f(d, _12) f(d, _13) f(d, _14) f(d, _15) f(d, _16) f(d, _17) f(d, _18) f(d, _19) f(d, _20) f(d, _21) f(d, _22) f(d, _23) f(d, _24) f(d, _25) f(d, _26) f(d, _27) f(d, _28) f(d, _29) f(d, _30) f(d, _31) f(d, _32) f(d, _33) f(d, _34) f(d, _35) f(d, _36) f(d, _37) f(d, _38) f(d, _39) f(d, _40) f(d, _41) f(d, _42) f(d, _43) f(d, _44) f(d, _45) f(d, _46) +#define M_MAP2I_47(f, d, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47) f(d, _1) f(d, _2) f(d, _3) f(d, _4) f(d, _5) f(d, _6) f(d, _7) f(d, _8) f(d, _9) f(d, _10) f(d, _11) f(d, _12) f(d, _13) f(d, _14) f(d, _15) f(d, _16) f(d, _17) f(d, _18) f(d, _19) f(d, _20) f(d, _21) f(d, _22) f(d, _23) f(d, _24) f(d, _25) f(d, _26) f(d, _27) f(d, _28) f(d, _29) f(d, _30) f(d, _31) f(d, _32) f(d, _33) f(d, _34) f(d, _35) f(d, _36) f(d, _37) f(d, _38) f(d, _39) f(d, _40) f(d, _41) f(d, _42) f(d, _43) f(d, _44) f(d, _45) f(d, _46) f(d, _47) +#define M_MAP2I_48(f, d, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48) f(d, _1) f(d, _2) f(d, _3) f(d, _4) f(d, _5) f(d, _6) f(d, _7) f(d, _8) f(d, _9) f(d, _10) f(d, _11) f(d, _12) f(d, _13) f(d, _14) f(d, _15) f(d, _16) f(d, _17) f(d, _18) f(d, _19) f(d, _20) f(d, _21) f(d, _22) f(d, _23) f(d, _24) f(d, _25) f(d, _26) f(d, _27) f(d, _28) f(d, _29) f(d, _30) f(d, _31) f(d, _32) f(d, _33) f(d, _34) f(d, _35) f(d, _36) f(d, _37) f(d, _38) f(d, _39) f(d, _40) f(d, _41) f(d, _42) f(d, _43) f(d, _44) f(d, _45) f(d, _46) f(d, _47) f(d, _48) +#define M_MAP2I_49(f, d, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49) f(d, _1) f(d, _2) f(d, _3) f(d, _4) f(d, _5) f(d, _6) f(d, _7) f(d, _8) f(d, _9) f(d, _10) f(d, _11) f(d, _12) f(d, _13) f(d, _14) f(d, _15) f(d, _16) f(d, _17) f(d, _18) f(d, _19) f(d, _20) f(d, _21) f(d, _22) f(d, _23) f(d, _24) f(d, _25) f(d, _26) f(d, _27) f(d, _28) f(d, _29) f(d, _30) f(d, _31) f(d, _32) f(d, _33) f(d, _34) f(d, _35) f(d, _36) f(d, _37) f(d, _38) f(d, _39) f(d, _40) f(d, _41) f(d, _42) f(d, _43) f(d, _44) f(d, _45) f(d, _46) f(d, _47) f(d, _48) f(d, _49) +#define M_MAP2I_50(f, d, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50) f(d, _1) f(d, _2) f(d, _3) f(d, _4) f(d, _5) f(d, _6) f(d, _7) f(d, _8) f(d, _9) f(d, _10) f(d, _11) f(d, _12) f(d, _13) f(d, _14) f(d, _15) f(d, _16) f(d, _17) f(d, _18) f(d, _19) f(d, _20) f(d, _21) f(d, _22) f(d, _23) f(d, _24) f(d, _25) f(d, _26) f(d, _27) f(d, _28) f(d, _29) f(d, _30) f(d, _31) f(d, _32) f(d, _33) f(d, _34) f(d, _35) f(d, _36) f(d, _37) f(d, _38) f(d, _39) f(d, _40) f(d, _41) f(d, _42) f(d, _43) f(d, _44) f(d, _45) f(d, _46) f(d, _47) f(d, _48) f(d, _49) f(d, _50) +#define M_MAP2I_51(f, d, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51) f(d, _1) f(d, _2) f(d, _3) f(d, _4) f(d, _5) f(d, _6) f(d, _7) f(d, _8) f(d, _9) f(d, _10) f(d, _11) f(d, _12) f(d, _13) f(d, _14) f(d, _15) f(d, _16) f(d, _17) f(d, _18) f(d, _19) f(d, _20) f(d, _21) f(d, _22) f(d, _23) f(d, _24) f(d, _25) f(d, _26) f(d, _27) f(d, _28) f(d, _29) f(d, _30) f(d, _31) f(d, _32) f(d, _33) f(d, _34) f(d, _35) f(d, _36) f(d, _37) f(d, _38) f(d, _39) f(d, _40) f(d, _41) f(d, _42) f(d, _43) f(d, _44) f(d, _45) f(d, _46) f(d, _47) f(d, _48) f(d, _49) f(d, _50) f(d, _51) +#define M_MAP2I_52(f, d, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52) f(d, _1) f(d, _2) f(d, _3) f(d, _4) f(d, _5) f(d, _6) f(d, _7) f(d, _8) f(d, _9) f(d, _10) f(d, _11) f(d, _12) f(d, _13) f(d, _14) f(d, _15) f(d, _16) f(d, _17) f(d, _18) f(d, _19) f(d, _20) f(d, _21) f(d, _22) f(d, _23) f(d, _24) f(d, _25) f(d, _26) f(d, _27) f(d, _28) f(d, _29) f(d, _30) f(d, _31) f(d, _32) f(d, _33) f(d, _34) f(d, _35) f(d, _36) f(d, _37) f(d, _38) f(d, _39) f(d, _40) f(d, _41) f(d, _42) f(d, _43) f(d, _44) f(d, _45) f(d, _46) f(d, _47) f(d, _48) f(d, _49) f(d, _50) f(d, _51) f(d, _52) + /* Duplicate for GET_METHOD as it may be called in context where a M_MAP2 is in progress (for oplist). NOTE: Increase number of arguments to 76 due to the number of available methods. NOTE: Rewrite with another approach much more verbose but also much faster for the compiler. @@ -1684,8 +1737,10 @@ M_BEGIN_PROTECTED_CODE /* Remove the parenthesis if needed (internal macro) */ -#define M_REMOVE_PARENTHESIS(list) \ - M_IF(M_PARENTHESIS_P(list))( M_OPFLAT list, list) +#define M_REMOVE_PARENTHESIS(...) \ + M_IF(M_PARENTHESIS_P(__VA_ARGS__))(M_REMOVE_PARENTHESIS_2, M_REMOVE_PARENTHESIS_3)(__VA_ARGS__) +#define M_REMOVE_PARENTHESIS_2(...) M_OPFLAT __VA_ARGS__ +#define M_REMOVE_PARENTHESIS_3(...) __VA_ARGS__ /* Return the input (delay evaluation) */ #define M_ID(...) __VA_ARGS__ @@ -2724,6 +2779,9 @@ static inline size_t m_core_cstr_hash(const char str[]) #define M_LIMITS_LIMITS(a) ,a, #define M_PROPERTIES_PROPERTIES(a) ,a, +// Properties only +#define M_LET_AS_INIT_WITH_LET_AS_INIT_WITH(a) ,a, + /* From an oplist - an unorded list of methods : like "INIT(mpz_init),CLEAR(mpz_clear),SET(mpz_set)" - Return the given method in the oplist or the default method. Example: @@ -2879,9 +2937,13 @@ static inline size_t m_core_cstr_hash(const char str[]) /* API transformation support: transform the call to the method into the supported API by the method. - Example of usage in oplist: ( INIT_WITH(API_1(method)) ) */ + Example of usage in oplist: ( INIT_WITH(API_1(method)) ) + NOTE: It uses M_RET_ARG3 instead of M_RET_ARG2 since M_GET_METHOD + uses M_RET_ARG2: to be able to use M_GET_METHOD within a M_APPLY_API + we need another macro to avoid being marked. +*/ #define M_APPLY_API(method, oplist, ...) \ - M_RET_ARG2(M_C(M_OPLAPI_INDIRECT_, method)(M_C(M_OPLAPI_EXTRACT_,method),oplist,__VA_ARGS__), method(__VA_ARGS__),) + M_RET_ARG3( , M_C(M_OPLAPI_INDIRECT_, method)(M_C(M_OPLAPI_EXTRACT_,method),oplist,__VA_ARGS__), method(__VA_ARGS__),) /* API Transformation : 0: Method has been disable. It shall not be called. Raised an error. @@ -2889,16 +2951,18 @@ static inline size_t m_core_cstr_hash(const char str[]) API_2: by addr for first argument, API_3: oplist given, API_4 :by affectation for first argument, 5: API_by affectation + oplist API_6 :by addr for two arguments, 5: API_by address for both + oplist + + NOTE: It starts by a comma, to ack the success of the transformation. */ #define M_OPLAPI_ERROR(method, oplist, ...) , M_STATIC_FAILURE(M_LIB_DISABLED_METHOD, "The method has been explictly disabled for the requested operator, yet it has been called by the container") -#define M_OPLAPI_0(method, oplist, ...) , method(__VA_ARGS__) -#define M_OPLAPI_1(method, oplist, ...) , method(oplist, __VA_ARGS__) -#define M_OPLAPI_2(method, oplist, ...) , method(& __VA_ARGS__) -#define M_OPLAPI_3(method, oplist, ...) , method(oplist, &__VA_ARGS__) -#define M_OPLAPI_4(method, oplist, x, ...) , x = method(__VA_ARGS__) -#define M_OPLAPI_5(method, oplist, x, ...) , x = method(oplist, __VA_ARGS__) -#define M_OPLAPI_6(method, oplist, x, ...) , method(&x, &__VA_ARGS__) -#define M_OPLAPI_7(method, oplist, x, ...) , method(oplist, &x, &__VA_ARGS__) +#define M_OPLAPI_0(method, oplist, ...) , M_DELAY3(method)(__VA_ARGS__) +#define M_OPLAPI_1(method, oplist, ...) , M_DELAY3(method)(oplist, __VA_ARGS__) +#define M_OPLAPI_2(method, oplist, ...) , M_DELAY3(method)(& __VA_ARGS__) +#define M_OPLAPI_3(method, oplist, ...) , M_DELAY3(method)(oplist, &__VA_ARGS__) +#define M_OPLAPI_4(method, oplist, x, ...) , x = M_DELAY3(method)(__VA_ARGS__) +#define M_OPLAPI_5(method, oplist, x, ...) , x = M_DELAY3(method)(oplist, __VA_ARGS__) +#define M_OPLAPI_6(method, oplist, x, ...) , M_DELAY3(method)(&x, &__VA_ARGS__) +#define M_OPLAPI_7(method, oplist, x, ...) , M_DELAY3(method)(oplist, &x, &__VA_ARGS__) /* API transformation support for indirection */ #define M_OPLAPI_INDIRECT_0 M_OPLAPI_ERROR #define M_OPLAPI_INDIRECT_API_0(...) M_OPLAPI_0 @@ -3097,6 +3161,7 @@ static inline size_t m_core_cstr_hash(const char str[]) (INIT(M_INIT_DEFAULT), INIT_SET(M_SET_DEFAULT), SET(M_SET_DEFAULT), \ CLEAR(M_NOTHING_DEFAULT), EQUAL(M_EQUAL_DEFAULT), CMP(M_CMP_DEFAULT), \ INIT_MOVE(M_MOVE_DEFAULT), MOVE(M_MOVE_DEFAULT) , \ + CLEAN(M_INIT_DEFAULT), \ ADD(M_ADD_DEFAULT), SUB(M_SUB_DEFAULT), \ MUL(M_MUL_DEFAULT), DIV(M_DIV_DEFAULT), \ HASH(M_HASH_DEFAULT), SWAP(M_SWAP_DEFAULT) , \ @@ -3109,6 +3174,7 @@ static inline size_t m_core_cstr_hash(const char str[]) (INIT(M_INIT_DEFAULT), INIT_SET(M_SET_DEFAULT), SET(M_SET_DEFAULT), \ CLEAR(M_NOTHING_DEFAULT), EQUAL(M_EQUAL_DEFAULT), CMP(M_CMP_DEFAULT), \ INIT_MOVE(M_MOVE_DEFAULT), MOVE(M_MOVE_DEFAULT) , \ + CLEAN(M_INIT_DEFAULT), \ ADD(M_ADD_DEFAULT), SUB(M_SUB_DEFAULT), \ MUL(M_MUL_DEFAULT), DIV(M_DIV_DEFAULT), \ HASH(M_HASH_DEFAULT), SWAP(M_SWAP_DEFAULT) , \ @@ -3121,6 +3187,7 @@ static inline size_t m_core_cstr_hash(const char str[]) (INIT(M_INIT_DEFAULT), INIT_SET(M_SET_DEFAULT), SET(M_SET_DEFAULT), \ CLEAR(M_NOTHING_DEFAULT), EQUAL(M_EQUAL_DEFAULT), CMP(M_CMP_DEFAULT), \ INIT_MOVE(M_MOVE_DEFAULT), MOVE(M_MOVE_DEFAULT) , \ + CLEAN(M_INIT_DEFAULT), \ ADD(M_ADD_DEFAULT), SUB(M_SUB_DEFAULT), \ MUL(M_MUL_DEFAULT), DIV(M_DIV_DEFAULT), \ HASH(M_HASH_DEFAULT), SWAP(M_SWAP_DEFAULT) ) @@ -3266,7 +3333,7 @@ m_core_parse2_enum (const char str[], const char **endptr) /* Return the content of a property named 'propname' in the PROPERTIES field of oplist or 0, if it is not defined */ -#define M_GET_OPPROPERTY(oplist, propname) \ +#define M_GET_PROPERTY(oplist, propname) \ M_GET_METHOD (propname, 0, M_OPFLAT M_GET_PROPERTIES oplist) /* Test if a method is present in an oplist. @@ -3420,7 +3487,7 @@ m_core_parse2_enum (const char str[], const char **endptr) Second argument is the container to iterate. Third argument can be the oplist of the list or the type of the list if a global oplist has been recorded. - USAGE: for M_EACH(item, list, LIST_OPLIST) { M_LETaction; } + USAGE: for M_EACH(item, list, LIST_OPLIST) { action; } */ #define M_EACH(item, container, oplist) \ M_EACHI_OPLIST(item, container, M_GLOBAL_OPLIST(oplist)) @@ -3502,8 +3569,15 @@ m_core_parse2_enum (const char str[], const char **endptr) for(M_GET_TYPE oplist name; \ cont && (M_LETI_SINGLE2_INIT(oplist, name, __VA_ARGS__), true); \ (M_CALL_CLEAR(oplist, name), cont = false)) +// 6c. Use of INIT_SET or INIT_WITH. #define M_LETI_SINGLE2_INIT(oplist, name, ...) \ - M_IF_METHOD(INIT_WITH,oplist)(M_CALL_INIT_WITH, M_CALL_INIT_SET)(oplist, name, __VA_ARGS__) + M_IF_METHOD(INIT_WITH,oplist)(M_LETI_SINGLE3_INIT, M_CALL_INIT_SET)(oplist, name, __VA_ARGS__) +#define M_LETI_SINGLE3_INIT(oplist, name, ...) \ + M_IF(M_NOTEQUAL( M_NARGS(__VA_ARGS__), 1))(M_CALL_INIT_WITH, M_LETI_SINGLE4_INIT)(oplist, name, __VA_ARGS__) +#define M_LETI_SINGLE4_INIT(oplist, name, arg) \ + M_IF(M_GET_PROPERTY(oplist, LET_AS_INIT_WITH))(M_CALL_INIT_WITH, M_LETI_SINGLE5_INIT)(oplist, name, arg) +#define M_LETI_SINGLE5_INIT(oplist, name, arg) \ + M_IF(M_PARENTHESIS_P( arg ) )(M_CALL_INIT_WITH, M_CALL_INIT_SET)(oplist, name, M_REMOVE_PARENTHESIS (arg)) /* Transform the va list by adding their number as the first argument of @@ -3566,6 +3640,25 @@ m_core_parse2_enum (const char str[], const char **endptr) M_PAIR_2 d (M_PAIR_1 d, a) +/* Initialize the container 'dest' as per 'oplist' INIT operator + and fill it with the given VA arguments with the _push_raw method + allowing INIT_WITH operator for the pushed argument. + NOTE: If the REVERSE operator exists, it assumes a list, + so it reverses the final order. +*/ +#define M_INIT_WITH_VAI(oplist, dest, ...) \ + (void)(M_GET_INIT oplist (dest) , \ + M_MAP2_C(M_INIT_WITH_VAI22_FUNC, (dest, oplist) , __VA_ARGS__) \ + M_IF_METHOD(REVERSE, oplist)(M_DEFERRED_COMMA M_GET_REVERSE oplist(dest), ) \ + ) + +#define M_INIT_WITH_VAI22_FUNC(pair, a) \ + M_INIT_WITH_VAI23_FUNC(M_PAIR_1 pair, M_PAIR_2 pair, a) + +#define M_INIT_WITH_VAI23_FUNC(d, op, a) \ + M_IF(M_PARENTHESIS_P( a ))(M_CALL_INIT_WITH, M_CALL_INIT_SET)(M_GET_OPLIST op, *M_C( M_GET_NAME op , _push_raw)(d), M_REMOVE_PARENTHESIS (a)) + + /* Initialize the container 'dest' as per 'oplist' INIT operator and fill it with the given VA argument assumed to be pair (key,value) with the SET_KEY operator. diff --git a/m-deque.h b/m-deque.h index 493e2633..33a65748 100644 --- a/m-deque.h +++ b/m-deque.h @@ -264,6 +264,13 @@ return ret; \ } \ \ + /* Internal, for INIT_WITH */ \ + static inline type * \ + M_C(name, _push_raw)(deque_t d) \ + { \ + return M_C(name, _push_back_raw)(d); \ + } \ + \ static inline void \ M_C(name, _push_back)(deque_t d, type const x) \ { \ @@ -982,7 +989,7 @@ #define M_D3QU3_OPLIST_P3(name, oplist) \ (INIT(M_C(name, _init)) \ ,INIT_SET(M_C(name, _init_set)) \ - ,INIT_WITH(API_1(M_INIT_VAI)) \ + ,INIT_WITH(API_1(M_INIT_WITH_VAI)) \ ,SET(M_C(name, _set)) \ ,CLEAR(M_C(name, _clear)) \ ,INIT_MOVE(M_C(name, _init_move)) \ diff --git a/m-funcobj.h b/m-funcobj.h index ed252aa9..1ef096f4 100644 --- a/m-funcobj.h +++ b/m-funcobj.h @@ -131,6 +131,7 @@ INIT_WITH(M_C(name, _init_with)), \ CLEAR(M_C(name, _clear)), \ M_IF_METHOD_ALL(INIT, __VA_ARGS__)(INIT(M_C(name,_init)),), \ + PROPERTIES(( LET_AS_INIT_WITH(1) )) \ ) diff --git a/m-list.h b/m-list.h index ffb6fba6..838e939c 100644 --- a/m-list.h +++ b/m-list.h @@ -87,7 +87,7 @@ #define M_L1ST_OPLIST_P3(name, oplist) \ (INIT(M_C(name, _init)), \ INIT_SET(M_C(name, _init_set)), \ - INIT_WITH(API_1(M_INIT_VAI)), \ + INIT_WITH(API_1(M_INIT_WITH_VAI)), \ SET(M_C(name, _set)), \ CLEAR(M_C(name, _clear)), \ MOVE(M_C(name, _move)), \ @@ -990,6 +990,13 @@ return ret; \ } \ \ + /* Internal, for INIT_WITH */ \ + static inline type * \ + M_C(name, _push_raw)(list_t d) \ + { \ + return M_C(name, _push_back_raw)(d); \ + } \ + \ static inline void \ M_C(name, _push_back)(list_t v, type const x) \ { \ diff --git a/m-serial-bin.h b/m-serial-bin.h index 6aa98d17..0b77413d 100644 --- a/m-serial-bin.h +++ b/m-serial-bin.h @@ -345,7 +345,8 @@ static inline void m_serial_bin_write_clear(m_serial_write_t serial) /* Define a synonym of m_serial_read_t to the BIN serializer with its proper OPLIST */ typedef m_serial_write_t m_serial_bin_write_t; #define M_OPL_m_serial_bin_write_t() \ - (INIT_WITH(m_serial_bin_write_init), CLEAR(m_serial_bin_write_clear), TYPE(m_serial_bin_write_t) ) + (INIT_WITH(m_serial_bin_write_init), CLEAR(m_serial_bin_write_clear), \ + TYPE(m_serial_bin_write_t), PROPERTIES(( LET_AS_INIT_WITH(1) )) ) /* Read from the stream 'serial' a boolean. @@ -586,7 +587,8 @@ static inline void m_serial_bin_read_clear(m_serial_read_t serial) /* Define a synonym of m_serial_read_t to the BIN serializer with its proper OPLIST */ typedef m_serial_read_t m_serial_bin_read_t; #define M_OPL_m_serial_bin_read_t() \ - (INIT_WITH(m_serial_bin_read_init), CLEAR(m_serial_bin_read_clear), TYPE(m_serial_bin_read_t) ) + (INIT_WITH(m_serial_bin_read_init), CLEAR(m_serial_bin_read_clear), \ + TYPE(m_serial_bin_read_t), PROPERTIES(( LET_AS_INIT_WITH(1) )) ) M_END_PROTECTED_CODE diff --git a/m-serial-json.h b/m-serial-json.h index 1cd5b8ad..114b6b81 100644 --- a/m-serial-json.h +++ b/m-serial-json.h @@ -277,7 +277,8 @@ static inline void m_serial_json_write_clear(m_serial_write_t serial) /* Define a synonym to the JSON serializer with a proper OPLIST */ typedef m_serial_write_t m_serial_json_write_t; #define M_OPL_m_serial_json_write_t() \ - (INIT_WITH(m_serial_json_write_init), CLEAR(m_serial_json_write_clear), TYPE(m_serial_json_write_t) ) + (INIT_WITH(m_serial_json_write_init), CLEAR(m_serial_json_write_clear), \ + TYPE(m_serial_json_write_t), PROPERTIES(( LET_AS_INIT_WITH(1) )) ) @@ -584,7 +585,8 @@ static inline void m_serial_json_read_clear(m_serial_read_t serial) to the JSON serializer with its proper OPLIST */ typedef m_serial_read_t m_serial_json_read_t; #define M_OPL_m_serial_json_read_t() \ - (INIT_WITH(m_serial_json_read_init), CLEAR(m_serial_json_read_clear), TYPE(m_serial_json_read_t) ) + (INIT_WITH(m_serial_json_read_init), CLEAR(m_serial_json_read_clear), \ + TYPE(m_serial_json_read_t) , PROPERTIES(( LET_AS_INIT_WITH(1) )) ) @@ -834,7 +836,8 @@ static inline void m_serial_str_json_write_clear(m_serial_write_t serial) /* Define a synonym to the JSON serializer with a proper OPLIST */ typedef m_serial_write_t m_serial_str_json_write_t; #define M_OPL_m_serial_str_json_write_t() \ - (INIT_WITH(m_serial_str_json_write_init), CLEAR(m_serial_str_json_write_clear), TYPE(m_serial_str_json_write_t) ) + (INIT_WITH(m_serial_str_json_write_init), CLEAR(m_serial_str_json_write_clear), \ + TYPE(m_serial_str_json_write_t) , PROPERTIES(( LET_AS_INIT_WITH(1) )) ) @@ -1184,7 +1187,8 @@ static inline const char *m_serial_str_json_read_clear(m_serial_read_t serial) to the JSON serializer with its proper OPLIST */ typedef m_serial_read_t m_serial_str_json_read_t; #define M_OPL_m_serial_str_json_read_t() \ - (INIT_WITH(m_serial_str_json_read_init), CLEAR(m_serial_str_json_read_clear), TYPE(m_serial_str_json_read_t) ) + (INIT_WITH(m_serial_str_json_read_init), CLEAR(m_serial_str_json_read_clear), \ + TYPE(m_serial_str_json_read_t), PROPERTIES(( LET_AS_INIT_WITH(1) )) ) M_END_PROTECTED_CODE diff --git a/m-string.h b/m-string.h index 7d2dfd68..29c7733b 100644 --- a/m-string.h +++ b/m-string.h @@ -182,6 +182,7 @@ string_clear(string_t v) /* NOTE: Internaly used by STRING_DECL_INIT */ static inline void m_str1ng_clear2(string_t *v) { string_clear(*v); } +static inline string_ptr m_str1ng_init_ref(string_t v) { string_init(v); return v; } /* Clear the Dynamic string (destructor) and return a heap pointer to the string. @@ -1735,7 +1736,7 @@ string_utf8_p(string_t str) #ifndef __cplusplus /* Initialize a constant string with the given C string */ # define STRING_CTE(s) \ - ((const string_t){{.u.heap = { .size = sizeof(s)-1, .alloc = sizeof(s) } , \ + (string_srcptr)((const string_t){{.u.heap = { .size = sizeof(s)-1, .alloc = sizeof(s) } , \ .ptr = ((struct { long long _n; char _d[sizeof (s)]; }){ 0, s })._d }}) #else namespace m_lib { @@ -1762,11 +1763,11 @@ namespace m_lib { /* Initialize and set a string to the given formatted value. */ #define string_init_printf(v, ...) \ - (string_init (v), string_printf (v, __VA_ARGS__) ) + (string_printf ( m_str1ng_init_ref(v), __VA_ARGS__) ) /* Initialize and set a string to the given formatted value. */ #define string_init_vprintf(v, format, args) \ - (string_init (v), string_vprintf (v, format, args) ) + (string_vprintf ( m_str1ng_init_ref(v), format, args) ) /* Initialize a string with the given list of arguments. Check if it is a formatted input or not by counting the number of arguments. diff --git a/m-tuple.h b/m-tuple.h index b0704da4..76288f92 100644 --- a/m-tuple.h +++ b/m-tuple.h @@ -208,7 +208,11 @@ namespace m_lib { typedef struct M_C(name, _s) *M_C(name, _ptr); \ typedef const struct M_C(name, _s) *M_C(name, _srcptr); \ /* Define internal type for oplist */ \ - typedef name_t M_C(name, _ct); + typedef name_t M_C(name, _ct); \ + /* Save constant as the number of arguments (internal) */ \ + typedef enum { \ + M_C3(m_tupl3_, name, _num_args) = M_NARGS(__VA_ARGS__) \ + } M_C3(m_tupl3_, name, _num_args_ct); #define M_TUPL3_DEFINE_RECUR_TYPE_ELE(a) \ M_TUPL3_GET_TYPE a M_TUPL3_GET_FIELD a ; @@ -305,9 +309,9 @@ namespace m_lib { /* Define the GET_AT_field & CGET_AT methods for all params. */ #define M_TUPL3_DEFINE_GETTER_FIELD(name, ...) \ - M_MAP2(M_TUPL3_DEFINE_GETTER_FIELD_PROTO, name, __VA_ARGS__) + M_MAP3(M_TUPL3_DEFINE_GETTER_FIELD_PROTO, name, __VA_ARGS__) -#define M_TUPL3_DEFINE_GETTER_FIELD_PROTO(name, a) \ +#define M_TUPL3_DEFINE_GETTER_FIELD_PROTO(name, num, a) \ static inline M_TUPL3_GET_TYPE a * M_C3(name, _get_at_, M_TUPL3_GET_FIELD a) \ (M_C(name,_ct) my) { \ M_TUPL3_CONTRACT(my); \ @@ -317,7 +321,12 @@ namespace m_lib { (M_C(name,_ct) const my) { \ M_TUPL3_CONTRACT(my); \ return &(my->M_TUPL3_GET_FIELD a); \ - } + } \ + /* Same but uses numerical index for accessing the field (internal) */ \ + static inline M_TUPL3_GET_TYPE a * M_C4(m_tupl3_, name, _get_at_, num) \ + (M_C(name,_ct) my) { \ + return &(my->M_TUPL3_GET_FIELD a); \ + } \ /* Define the SET_field methods for all params. */ @@ -623,6 +632,51 @@ namespace m_lib { M_TUPL3_CALL_CLEAN(a, el1 -> M_TUPL3_GET_FIELD a); +/* INIT_WITH macro enabling recursive INIT_WITH initialization + tuple = { int, string_t, array } + USAGE: + M_LET( (x, 2, ("John"), ( ("Bear"), ("Rabbit") )), tuple_t) + + "If you think it's simple, you're deluding yourself." + + Several pass are done: + 1) If the number of arguments doesn't match the number of oplists of the + tuple oplist, it is assumed something is wrong. It uses the _init_emplace + function to provide proper warning in such case. + 2) Otherwise, it checks that the number of arguments matches the number + of arguments of the tuple definition. + 3) Mix all arguments with their associated oplists to have pair (arg, oplist), + 4) Map the following macro for each computed pair : + 4.a) If INIT_WITH macro is not defined for this pair, it uses INIT_SET + 4.b) If the argument is encapsulated with parenthesis, it uses INIT_WITH + 4.c) If the oplist property LET_AS_INIT_WITH is defined, it uses INIT_WITH + 4.d) Otherwise it uses INIT_SET. +*/ +#define M_TUPL3_INIT_WITH(oplist, dest, ...) \ + M_TUPL3_INIT_WITH_P1(M_GET_NAME oplist, M_GET_OPLIST oplist, dest, __VA_ARGS__) +#define M_TUPL3_INIT_WITH_P1(name, oplist_arglist, dest, ...) \ + M_IF(M_NOTEQUAL( M_NARGS oplist_arglist, M_NARGS (__VA_ARGS__))) \ + (M_TUPL3_INIT_WITH_P1_FUNC, M_TUPL3_INIT_WITH_P1_MACRO)(name, oplist_arglist, dest, __VA_ARGS__) +#define M_TUPL3_INIT_WITH_P1_FUNC(name, oplist_arglist, dest, ...) \ + M_C(name, _init_emplace)(dest, __VA_ARGS__) +#define M_TUPL3_INIT_WITH_P1_MACRO(name, oplist_arglist, dest, ...) \ + ( M_STATIC_ASSERT( M_NARGS oplist_arglist == M_C3(m_tupl3_, name, _num_args), M_LIB_DIMENSION_ERROR, "The number of oplists given to TUPLE_OPLIST don't match the number of oplists used to create the tuple." ), \ + M_STATIC_ASSERT( M_NARGS(__VA_ARGS__) == M_C3(m_tupl3_, name, _num_args), M_LIB_DIMENSION_ERROR, "Missing / Too many arguments for tuple"), \ + M_MAP3(M_TUPL3_INIT_WITH_P2, (name, dest), M_OPFLAT M_MERGE_ARGLIST( oplist_arglist, (__VA_ARGS__) ) ) \ + (void) 0) +#define M_TUPL3_INIT_WITH_P2(name_dest, num, pair) \ + M_TUPL3_INIT_WITH_P3( M_PAIR_1 name_dest, M_PAIR_2 name_dest, num, M_PAIR_1 pair, M_PAIR_2 pair ) +#define M_TUPL3_INIT_WITH_P3(name, dest, num, oplist, param) \ + M_IF(M_TEST_METHOD_P(INIT_WITH, oplist))(M_TUPL3_INIT_WITH_P4, M_TUPL3_INIT_WITH_SET)(name, dest, num, oplist, param) +#define M_TUPL3_INIT_WITH_SET(name, dest, num, oplist, param) \ + M_CALL_INIT_SET (oplist, *M_C4(m_tupl3_, name, _get_at_, num)(dest), param) , +#define M_TUPL3_INIT_WITH_P4(name, dest, num, oplist, param) \ + M_IF(M_PARENTHESIS_P( param))(M_TUPL3_INIT_WITH_P5, M_TUPL3_INIT_WITH_P6)(name, dest, num, oplist, param) +#define M_TUPL3_INIT_WITH_P5(name, dest, num, oplist, param) \ + M_CALL_INIT_WITH(oplist, *M_C4(m_tupl3_, name, _get_at_, num)(dest), M_REMOVE_PARENTHESIS (param) ) , +#define M_TUPL3_INIT_WITH_P6(name, dest, num, oplist, param) \ + M_IF(M_GET_PROPERTY(oplist, LET_AS_INIT_WITH))(M_TUPL3_INIT_WITH_P5, M_TUPL3_INIT_WITH_SET)(name, dest, num, oplist, param) + /* Macros for testing for the presence of a method in the parameter (name, type, oplist) */ #define M_TUPL3_TEST_METHOD_P(method, trio) \ M_APPLY(M_TUPL3_TEST_METHOD2_P, method, M_OPFLAT trio) @@ -650,11 +704,12 @@ namespace m_lib { #define M_TUPL3_OPLIST_P3(name, ...) \ (M_IF_METHOD_ALL(INIT, __VA_ARGS__)(INIT(M_C(name,_init)),), \ INIT_SET(M_C(name, _init_set)), \ - INIT_WITH(M_C(name, _init_emplace)), \ + INIT_WITH(API_1(M_TUPL3_INIT_WITH)), \ SET(M_C(name,_set)), \ CLEAR(M_C(name, _clear)), \ NAME(name), \ TYPE(M_C(name,_ct)), \ + OPLIST( (__VA_ARGS__) ), \ M_IF_METHOD_ALL(CMP, __VA_ARGS__)(CMP(M_C(name, _cmp)),), \ M_IF_METHOD_ALL(HASH, __VA_ARGS__)(HASH(M_C(name, _hash)),), \ M_IF_METHOD_ALL(EQUAL, __VA_ARGS__)(EQUAL(M_C(name, _equal_p)),), \ diff --git a/tests/test-malgo.c b/tests/test-malgo.c index 63e05295..44a96c58 100644 --- a/tests/test-malgo.c +++ b/tests/test-malgo.c @@ -239,7 +239,7 @@ static void test_list(void) assert(list_int_equal_p (l1, l3)); } - M_LET( (l1, 4, 28, 29, 31, 34), (l2, 1, 3, 31, 32, 33), (l3, 31), LIST_OPLIST(list_int, M_DEFAULT_OPLIST)) { + M_LET( (l1, 4, 28, 29, 31, 34), (l2, 1, 3, 31, 32, 33), (l3, (31)), LIST_OPLIST(list_int, M_DEFAULT_OPLIST)) { algo_list_sort_intersect(l1, l2); assert(list_int_equal_p (l1, l3)); } @@ -618,7 +618,7 @@ static void test_insert(void) static void test_string_utf8(void) { - M_LET( (s, "H€llo René Chaînôr¬"), string_t) + M_LET( (s, ("H€llo René Chaînôr¬") ), string_t) M_LET( (ref, 72, 8364, 108, 108, 111, 32, 82, 101, 110, 233, 32, 67, 104, 97, 238, 110, 244, 114, 172), a, array_uint_t) { // Convert the string into an array of unicode. ALGO_EXTRACT(a, array_uint_t, s, string_t); diff --git a/tests/test-mcore.c b/tests/test-mcore.c index efda592d..5b89b8a9 100644 --- a/tests/test-mcore.c +++ b/tests/test-mcore.c @@ -248,13 +248,13 @@ static void test_let(void) M_LET((zz,z), M_CLASSIC_OPLIST(testobj)) { assert( testobj_cmp_ui(zz, 12) == 0); } - M_LET((zz,42), M_OPEXTEND(M_CLASSIC_OPLIST(testobj), INIT_WITH(testobj_init_set_ui))) { + M_LET((zz,(42)), M_OPEXTEND(M_CLASSIC_OPLIST(testobj), INIT_WITH(testobj_init_set_ui))) { assert( testobj_cmp_ui(zz, 42) == 0); } M_LET((zz,z), z2, M_CLASSIC_OPLIST(testobj)) { assert( testobj_cmp_ui(zz, 12) == 0); } - M_LET(z3, (zz,42), M_OPEXTEND(M_CLASSIC_OPLIST(testobj), INIT_WITH(testobj_init_set_ui))) { + M_LET(z3, (zz,(42)), M_OPEXTEND(M_CLASSIC_OPLIST(testobj), INIT_WITH(testobj_init_set_ui))) { assert( testobj_cmp_ui(zz, 42) == 0); } b = true; @@ -263,6 +263,33 @@ static void test_let(void) } assert(b); + // Test of recursive INIT_WITH within M_LET +#define OPL1 (TYPE(int), INIT_WITH(OPL1_F)) +#define OPL1_F(d, x) ((d) = (x)) +#define OPL2 (TYPE(int), INIT_WITH(API_1(OPL2_F)), OPLIST(OPL1) ) +#define OPL2_F(opl, d, x) M_APPLY_API(M_GET_INIT_WITH M_GET_OPLIST opl, M_GET_OPLIST opl, d, x) +#define OPL3 (TYPE(int), INIT_WITH(API_1(OPL3_F)), OPLIST(OPL2) ) +#define OPL3_F(opl, d, x) M_APPLY_API(M_GET_INIT_WITH M_GET_OPLIST opl, M_GET_OPLIST opl, d, x) +#define OPL4 (TYPE(int), INIT_WITH(API_1(OPL4_F)), OPLIST(OPL3) ) +#define OPL4_F(opl, d, x) M_APPLY_API(M_GET_INIT_WITH M_GET_OPLIST opl, M_GET_OPLIST opl, d, x) +#define OPL5 (TYPE(int), INIT_WITH(API_1(OPL5_F)), OPLIST(OPL4) ) +#define OPL5_F(opl, d, x) M_APPLY_API(M_GET_INIT_WITH M_GET_OPLIST opl, M_GET_OPLIST opl, d, x) +#define OPL6 (TYPE(int), INIT_WITH(API_1(OPL6_F)), OPLIST(OPL5) ) +#define OPL6_F(opl, d, x) M_APPLY_API(M_GET_INIT_WITH M_GET_OPLIST opl, M_GET_OPLIST opl, d, x) + + M_LET( (x, 4585) , OPL1) + assert (x == 4585); + M_LET( (x, 4586) , OPL2) + assert (x == 4586); + M_LET( (x, 4587) , OPL3) + assert (x == 4587); + M_LET( (x, 4588) , OPL4) + assert (x == 4588); + M_LET( (x, 4589) , OPL5) + assert (x == 4589); + M_LET( (x, 4590) , OPL6) + assert (x == 4590); + int c = 0; M_LET_IF( assert(c++ == 0), (assert(c++ == 1), true), assert(c++ == 3)) { assert(c++ == 2); @@ -726,10 +753,10 @@ static void test_M_CSTR(void) static void test_properties(void) { #define OP_PROP() ( INIT(init), PROPERTIES((INIT(1), IT_TYPE(2), INIT_WITH(priority))) ) - assert( M_GET_OPPROPERTY (OP_PROP(), INIT ) == 1); - assert( M_GET_OPPROPERTY (OP_PROP(), CLEAR ) == 0); - assert( M_GET_OPPROPERTY (OP_PROP(), IT_TYPE ) == 2); - assert( M_KEYWORD_P( M_GET_OPPROPERTY (OP_PROP(), INIT_WITH ), priority)); + assert( M_GET_PROPERTY (OP_PROP(), INIT ) == 1); + assert( M_GET_PROPERTY (OP_PROP(), CLEAR ) == 0); + assert( M_GET_PROPERTY (OP_PROP(), IT_TYPE ) == 2); + assert( M_KEYWORD_P( M_GET_PROPERTY (OP_PROP(), INIT_WITH ), priority)); } int main(void) { diff --git a/tests/test-mlist.c b/tests/test-mlist.c index 216adb10..39f24c8c 100644 --- a/tests/test-mlist.c +++ b/tests/test-mlist.c @@ -39,6 +39,8 @@ LIST_DUAL_PUSH_DEF(list2_mpz, testobj_t, TESTOBJ_OPLIST) LIST_DEF(list_min_z, testobj_t, (INIT_SET(testobj_init_set), SET(testobj_set), CLEAR(testobj_clear))) LIST_DUAL_PUSH_DEF(list2_min_z, testobj_t, (INIT_SET(testobj_init_set), SET(testobj_set), CLEAR(testobj_clear))) +LIST_DEF(list_string, string_t) +#define M_OPL_list_string_t() LIST_OPLIST(list_string, STRING_OPLIST) LIST_DEF_AS(list_double, ListDouble, ListDoubleIt, double) #define M_OPL_ListDouble() LIST_OPLIST(list_double, M_DEFAULT_OPLIST) @@ -674,6 +676,31 @@ static void test_double(void) } } +static void test_let_string(void) +{ + M_LET( (y, ("!") ), string_t) // string_t y = string_t{"!"} + M_LET( (z, y), string_t) // string_t z = y + M_LET( (x, ("Hello"), ("%d World", 2), y ), list_string_t) // astr_t x = { string_t{"Hello"}, string_t{"World"}, z } + M_LET( (xx, x), list_string_t) // astr_t xx = x + M_LET( (zz, (("Hellno")) ), list_string_t) // astr_t zz = { string_t{"Hellno"} } + M_LET( (zx, (y) ), list_string_t) // astr_t zx = { z } + M_LET( (tab_name, STRING_CTE("My"), STRING_CTE("CD"), STRING_CTE("IS"), STRING_CTE("OUT")), list_string_t) + { + assert(string_equal_str_p( y, "!")); + assert(string_equal_str_p( z, "!")); + list_string_get_str(y, x, false); + assert(string_equal_str_p(y, "[\"Hello\",\"2 World\",\"!\"]")); + list_string_get_str(y, xx, false); + assert(string_equal_str_p(y, "[\"Hello\",\"2 World\",\"!\"]")); + list_string_get_str(y, zz, false); + assert(string_equal_str_p(y, "[\"Hellno\"]")); + list_string_get_str(y, zx, false); + assert(string_equal_str_p(y, "[\"!\"]")); + list_string_get_str(y, tab_name, false); + assert(string_equal_str_p(y, "[\"My\",\"CD\",\"IS\",\"OUT\"]")); + } +} + int main(void) { test_uint(); @@ -682,6 +709,7 @@ int main(void) test_dual_it1(); test_out_default_oplist(); test_double(); + test_let_string(); exit(0); } diff --git a/tests/test-mstring.c b/tests/test-mstring.c index 96d8bdf4..5c9a6a07 100644 --- a/tests/test-mstring.c +++ b/tests/test-mstring.c @@ -728,7 +728,7 @@ static void test_bounded_M_LET(void) assert (string16_empty_p(x)); } - M_LET( (x,"tree"), BOUNDED_STRING_OPLIST(string16)) { + M_LET( (x, ("tree")), BOUNDED_STRING_OPLIST(string16)) { assert (string16_equal_str_p(x, "tree")); } @@ -753,7 +753,7 @@ static void test_M_LET(void) string_set(s2, s1); assert(string_equal_p(s1, s2)); } - M_LET((s1,"OK"),string_t) { + M_LET((s1,("OK")),string_t) { assert(string_equal_str_p(s1, "OK")); } M_LET((s1,"OK S=%d", 16),string_t) { @@ -764,10 +764,9 @@ static void test_M_LET(void) assert(string_empty_p(s2)); assert(string_equal_str_p(s3, "42-17")); } - M_LET( (s1, "Hello"), string_t) { + M_LET( (s1, ("Hello")), string_t) { assert(string_equal_str_p(s1, "Hello")); #if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L) - // Initalization with another string is only supported in C11 mode. M_LET( (s2, s1), string_t) { // In C11 mode, string_equal_p accept also C string assert(string_equal_p(s2, "Hello")); diff --git a/tests/test-mtuple.c b/tests/test-mtuple.c index 0ac95441..67d6169b 100644 --- a/tests/test-mtuple.c +++ b/tests/test-mtuple.c @@ -118,6 +118,48 @@ static void check_clean(void) rtuple_clean(r); assert(string_equal_str_p (r->name, "")); } + + M_LET( (r, ("Hello"), 4), TUPLE_OPLIST(pair2_str, STRING_OPLIST, M_DEFAULT_OPLIST) ) { + assert(string_equal_str_p (r->str, "Hello")); + assert(r->value == 4); + pair2_str_clean(r); + assert(string_equal_str_p (r->str, "")); + } + + M_LET( (s, ("Goldy") ), STRING_OPLIST) + M_LET( (r, s, 46), TUPLE_OPLIST(pair2_str, STRING_OPLIST, M_DEFAULT_OPLIST) ) + M_LET( (q, r), TUPLE_OPLIST(pair2_str, STRING_OPLIST, M_DEFAULT_OPLIST) ) { + assert(string_equal_str_p (q->str, "Goldy")); + assert(q->value == 46); + pair2_str_clean(q); + assert(string_equal_str_p (q->str, "")); + } + + // Wrong oplist usage: fall back to _init_emplace. + M_LET( (s, ("Goldy McDuck") ), STRING_OPLIST) + M_LET((r, s, 460), TUPLE_OPLIST(pair2_str, STRING_OPLIST) ) { + assert(string_equal_str_p (r->str, "Goldy McDuck")); + assert(r->value == 460); + pair2_str_clean(r); + assert(string_equal_str_p (r->str, "")); + } + + // Two level of parenthesis needed: + // one to perform an emplace with INIT_WITH for the tuple + // another level to emplace the string_t + M_LET( (r, (("Two emplace"))), TUPLE_OPLIST(single_str, STRING_OPLIST) ) { + assert(string_equal_str_p (r->vala, "Two emplace")); + single_str_clean(r); + assert(string_equal_str_p (r->vala, "")); + } + + M_LET( (s, ("Goldy McDuck") ), STRING_OPLIST) + M_LET( (r, (s)), TUPLE_OPLIST(single_str, STRING_OPLIST) ) { + assert(string_equal_str_p (r->vala, "Goldy McDuck")); + single_str_clean(r); + assert(string_equal_str_p (r->vala, "")); + } + } static void check_io(void)