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_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
|
||||
Generated by:
|
||||
@@ -2102,29 +2106,45 @@ m_core_hash (const void *str, size_t length)
|
||||
Example:
|
||||
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(init with b) & c }
|
||||
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 .
|
||||
Last argument can be the oplist or the type itself if a global
|
||||
oplist has been recorded for this type.
|
||||
*/
|
||||
#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, ...) \
|
||||
M_LETI2(cont, M_GLOBAL_OPLIST(oplist), __VA_ARGS__)
|
||||
|
||||
// 3. Map all variables to their own LET
|
||||
#define M_LETI2(cont, oplist, ...) \
|
||||
for(bool cont = true; cont ; /* unused */) \
|
||||
M_MAP2(M_LETI_SINGLE, (cont, oplist,), __VA_ARGS__)
|
||||
|
||||
#define M_LETI_SINGLE(data, name) \
|
||||
M_LETI_SINGLE2(M_RET_ARG1 data, M_RET_ARG2 data, name)
|
||||
|
||||
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) \
|
||||
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) \
|
||||
for(M_GET_TYPE oplist name; \
|
||||
cont && (M_GET_INIT oplist (name), true); \
|
||||
(M_GET_CLEAR oplist (name), 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
|
||||
the list.
|
||||
|
||||
@@ -173,6 +173,9 @@ static void test_let(void)
|
||||
{
|
||||
M_LET(z, M_CLASSIC_OPLIST(testobj)) {
|
||||
testobj_add(z,z,z);
|
||||
M_LET((zz,z), M_CLASSIC_OPLIST(testobj)) {
|
||||
testobj_add(zz,zz,z);
|
||||
}
|
||||
break;
|
||||
assert(0);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user