Add support for given an argument for the initialization of a variable in M_LET
if the variable is within parenthesis: M_LET((a,b), string_t) ==> It will init a & set it to b. For the moment, we can only init with value of the same type (through init_set)
This commit is contained in:
1 parent
7ac54c0eb8
commit
dbcade3087
2 files changed
+30
-7
No files matched your search
@@ -507,6 +507,10 @@
|
|||||||
#define M_RETI_ARG53(_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, _53, ...) _53
|
#define M_RETI_ARG53(_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, _53, ...) _53
|
||||||
#define M_RET_ARG53(...) M_RETI_ARG53(__VA_ARGS__)
|
#define M_RET_ARG53(...) M_RETI_ARG53(__VA_ARGS__)
|
||||||
|
|
||||||
|
/* For a pair of argument (arg0, arg1), return either the first or the second.
|
||||||
|
Needed in case where M_RET_ARGn cannot be used */
|
||||||
|
#define M_PAIR_1(a,b) a
|
||||||
|
#define M_PAIR_2(a,b) b
|
||||||
|
|
||||||
/* Skip the Nth first arguments
|
/* Skip the Nth first arguments
|
||||||
Generated by:
|
Generated by:
|
||||||
@@ -2102,29 +2106,45 @@ m_core_hash (const void *str, size_t length)
|
|||||||
Example:
|
Example:
|
||||||
M_LET(a, STRING_OPLIST) { do something with a } or
|
M_LET(a, STRING_OPLIST) { do something with a } or
|
||||||
M_LET(a, b, c, STRING_OPLIST) { do something with a, b & c }
|
M_LET(a, b, c, STRING_OPLIST) { do something with a, b & c }
|
||||||
|
M_LET((a, b), c, STRING_OPLIST) { do something with a(init with b) & c }
|
||||||
NOTE: The user code can not perform a return or a goto within the {}
|
NOTE: The user code can not perform a return or a goto within the {}
|
||||||
other wise the clear code of the object won't be called .
|
other wise the clear code of the object won't be called .
|
||||||
Last argument can be the oplist or the type itself if a global
|
Last argument can be the oplist or the type itself if a global
|
||||||
oplist has been recorded for this type.
|
oplist has been recorded for this type.
|
||||||
*/
|
*/
|
||||||
#define M_LET(a, ...) \
|
#define M_LET(a, ...) \
|
||||||
M_ID(M_LETI1 M_INVERT(a, __VA_ARGS__, M_C3(local_cont_, a, __LINE__) ))
|
M_ID(M_LETI1 M_INVERT(a, __VA_ARGS__, \
|
||||||
|
M_IF(M_PARENTHESIS_P(a))(M_LETI_VAR_NAME_A, \
|
||||||
|
M_LETI_VAR_NAME_B)(a) ))
|
||||||
|
|
||||||
|
// 1b. Generate a unique name based on the first variable and the line number
|
||||||
|
#define M_LETI_VAR_NAME_A(var) M_C3(_local_cont_, M_RET_ARG1 var, __LINE__)
|
||||||
|
#define M_LETI_VAR_NAME_B(var) M_C3(_local_cont_, var, __LINE__)
|
||||||
|
// 2. Evaluate with or without
|
||||||
#define M_LETI1(cont, oplist, ...) \
|
#define M_LETI1(cont, oplist, ...) \
|
||||||
M_LETI2(cont, M_GLOBAL_OPLIST(oplist), __VA_ARGS__)
|
M_LETI2(cont, M_GLOBAL_OPLIST(oplist), __VA_ARGS__)
|
||||||
|
// 3. Map all variables to their own LET
|
||||||
#define M_LETI2(cont, oplist, ...) \
|
#define M_LETI2(cont, oplist, ...) \
|
||||||
for(bool cont = true; cont ; /* unused */) \
|
for(bool cont = true; cont ; /* unused */) \
|
||||||
M_MAP2(M_LETI_SINGLE, (cont, oplist,), __VA_ARGS__)
|
M_MAP2(M_LETI_SINGLE, (cont, oplist), __VA_ARGS__)
|
||||||
|
// 4. Dispatch the right LET in function of having or not arguments
|
||||||
#define M_LETI_SINGLE(data, name) \
|
#define M_LETI_SINGLE(data, name) \
|
||||||
M_LETI_SINGLE2(M_RET_ARG1 data, M_RET_ARG2 data, name)
|
M_IF(M_PARENTHESIS_P(name))( \
|
||||||
|
M_LETI_SINGLE2_SET(M_PAIR_1 data, M_PAIR_2 data, M_PAIR_1 name, M_PAIR_2 name), \
|
||||||
|
M_LETI_SINGLE2(M_PAIR_1 data, M_PAIR_2 data, name))
|
||||||
|
// 5a. Define without argument ==> use INIT
|
||||||
#define M_LETI_SINGLE2(cont, oplist, name) \
|
#define M_LETI_SINGLE2(cont, oplist, name) \
|
||||||
for(M_GET_TYPE oplist name; \
|
for(M_GET_TYPE oplist name; \
|
||||||
cont && (M_GET_INIT oplist (name), true); \
|
cont && (M_GET_INIT oplist (name), true); \
|
||||||
(M_GET_CLEAR oplist (name), cont = false)) \
|
(M_GET_CLEAR oplist (name), cont = false)) \
|
||||||
for(;cont;cont = false)
|
for(;cont;cont = false)
|
||||||
|
// 5b. Define with arguments ==> use INIT_SET (INIT_WITH support pending)
|
||||||
|
#define M_LETI_SINGLE2_SET(cont, oplist, name, val) \
|
||||||
|
for(M_GET_TYPE oplist name; \
|
||||||
|
cont && (M_GET_INIT_SET oplist (name, val), true); \
|
||||||
|
(M_GET_CLEAR oplist (name), cont = false)) \
|
||||||
|
for(;cont;cont = false)
|
||||||
|
|
||||||
|
|
||||||
/* Transform the va list by adding their number as the first argument of
|
/* Transform the va list by adding their number as the first argument of
|
||||||
the list.
|
the list.
|
||||||
|
|||||||
@@ -173,6 +173,9 @@ static void test_let(void)
|
|||||||
{
|
{
|
||||||
M_LET(z, M_CLASSIC_OPLIST(testobj)) {
|
M_LET(z, M_CLASSIC_OPLIST(testobj)) {
|
||||||
testobj_add(z,z,z);
|
testobj_add(z,z,z);
|
||||||
|
M_LET((zz,z), M_CLASSIC_OPLIST(testobj)) {
|
||||||
|
testobj_add(zz,zz,z);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user