Add WIP version for a M_LET recursive

This commit is contained in:
Patrick Pelissier committed 2021-07-01 22:12:14 +02:00
1 parent 36003b6bb3
commit a19a010d1e
2 files changed
+40 -10

No files matched your search

+16 -10
View File
@@ -2879,9 +2879,13 @@ static inline size_t m_core_cstr_hash(const char str[])
/* API transformation support: /* API transformation support:
transform the call to the method into the supported API by the method. 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, ...) \ #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__), M_DELAY2(method)(__VA_ARGS__),)
/* API Transformation : /* API Transformation :
0: Method has been disable. It shall not be called. Raised an error. 0: Method has been disable. It shall not be called. Raised an error.
@@ -2889,16 +2893,18 @@ static inline size_t m_core_cstr_hash(const char str[])
API_2: by addr for first argument, API_3: oplist given, API_2: by addr for first argument, API_3: oplist given,
API_4 :by affectation for first argument, 5: API_by affectation + oplist 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 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_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_0(method, oplist, ...) , M_DELAY3(method)(__VA_ARGS__)
#define M_OPLAPI_1(method, oplist, ...) , method(oplist, __VA_ARGS__) #define M_OPLAPI_1(method, oplist, ...) , M_DELAY3(method)(oplist, __VA_ARGS__)
#define M_OPLAPI_2(method, oplist, ...) , method(& __VA_ARGS__) #define M_OPLAPI_2(method, oplist, ...) , M_DELAY3(method)(& __VA_ARGS__)
#define M_OPLAPI_3(method, oplist, ...) , method(oplist, &__VA_ARGS__) #define M_OPLAPI_3(method, oplist, ...) , M_DELAY(method)(oplist, &__VA_ARGS__)
#define M_OPLAPI_4(method, oplist, x, ...) , x = method(__VA_ARGS__) #define M_OPLAPI_4(method, oplist, x, ...) , x = M_DELAY3(method)(__VA_ARGS__)
#define M_OPLAPI_5(method, oplist, x, ...) , x = method(oplist, __VA_ARGS__) #define M_OPLAPI_5(method, oplist, x, ...) , x = M_DELAY3(method)(oplist, __VA_ARGS__)
#define M_OPLAPI_6(method, oplist, x, ...) , method(&x, &__VA_ARGS__) #define M_OPLAPI_6(method, oplist, x, ...) , M_DELAY3(method)(&x, &__VA_ARGS__)
#define M_OPLAPI_7(method, oplist, x, ...) , method(oplist, &x, &__VA_ARGS__) #define M_OPLAPI_7(method, oplist, x, ...) , M_DELAY3(method)(oplist, &x, &__VA_ARGS__)
/* API transformation support for indirection */ /* API transformation support for indirection */
#define M_OPLAPI_INDIRECT_0 M_OPLAPI_ERROR #define M_OPLAPI_INDIRECT_0 M_OPLAPI_ERROR
#define M_OPLAPI_INDIRECT_API_0(...) M_OPLAPI_0 #define M_OPLAPI_INDIRECT_API_0(...) M_OPLAPI_0
+24
View File
@@ -263,6 +263,30 @@ static void test_let(void)
} }
assert(b); assert(b);
// Test of recursive INIT_WITH within M_LET
// We need to use M_APPLY_APIA / M_APPLY_APIB for this.
#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)
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);
int c = 0; int c = 0;
M_LET_IF( assert(c++ == 0), (assert(c++ == 1), true), assert(c++ == 3)) { M_LET_IF( assert(c++ == 0), (assert(c++ == 1), true), assert(c++ == 3)) {
assert(c++ == 2); assert(c++ == 2);