Created
November 2, 2022 19:33
-
-
Save AlexCeleste/4a996b5f505b7dd9d5f7492d168b133b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Simple (i.e. very limited) metaprogramming macros | |
// | |
#ifndef C_MACROS_H | |
#define C_MACROS_H 1 | |
#define M_MAX_DEPTH 32 | |
#define M_NARGS(...) M_NARGS_(__VA_ARGS__, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, \ | |
20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) | |
#define M_NARGS_(_32, _31, _30, _29, _28, _27, _26, _25, _24, _23, _22, _21, _20, _19, _18, _17, \ | |
_16, _15, _14, _13, _12, _11, _10, _9, _8, _7, _6, _5, _4, _3, _2, _1, N, ...) N | |
#define M_2ORMORE(...) M_NARGS_(__VA_ARGS__, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \ | |
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0) | |
#define M_ILIST (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, \ | |
17, 18, 19, 20, 21, 23, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32) | |
#define M_ID(...) __VA_ARGS__ | |
#define M_FIRST(...) M_FIRST_(__VA_ARGS__,) | |
#define M_REST(...) M_REST_(__VA_ARGS__) | |
#define M_FIRST_(A, ...) A | |
#define M_REST_(A, ...) __VA_ARGS__ | |
#define M_FIRST2(A, B, ...) A, B | |
#define M_REST2(A, B, ...) __VA_ARGS__ | |
#define M_ROT(A, ...) __VA_ARGS__, A | |
#define M_REVERSE(...) M_RECUR(M_REVERSE_, M_NARGS(__VA_ARGS__), (__VA_ARGS__)) | |
#define M_REVERSE_(...) (M_REST(__VA_ARGS__)), M_FIRST(__VA_ARGS__) | |
#define M_CONC(A, B) M_CONC_(A, B) | |
#define M_CONC_(A, B) A##B | |
#define M_DIV2(N) M_CONC(M_DIV2_, N) | |
#define M_DECR(N) M_CONC(M_DECR_, N) | |
#define M_IF(P, T, E) M_CONC(M_IF_, P)(T, E) | |
#define M_IF_0(T, E) M_ID E | |
#define M_IF_1(T, E) M_ID T | |
#define M_ENLIST(X, N) M_DO_1(M_REST M_ENLIST_1(X, N)) | |
#define M_ENLIST_1(X, N) (M_CONC(M_NEST_, N)(M_ENLIST_2, X)) | |
#define M_ENLIST_2(...) M_FIRST(__VA_ARGS__), __VA_ARGS__ | |
#define M_BEFORE_AFTER(BEF, AFT) for(int _b = (BEF, 1); _b; (AFT, _b = 0)) | |
#define M_STATIC_ASSERT(EXP, NAME) {if(sizeof(struct{unsigned int NAME:((EXP)?1:-1);}));} | |
#define M_RECUR(ACT, N, ARG) M_CONC(M, _REST M_CONC(M_DO_, N)(M_CONC(M_REPT_, N)(ACT)ARG)) | |
#define M_FOR_EACH(ACTN, ...) M_CONC(M_FOR_EACH_, M_NARGS(__VA_ARGS__)) (ACTN, __VA_ARGS__) | |
#define M_FOR_E2(ACTN, ...) M_REST(M_FOR_EACH(ACTN, __VA_ARGS__)) | |
#define M_FOR_EACH_0(ACTN, E) E | |
#define M_FOR_EACH_1(ACTN, E) ACTN(E) | |
#define M_FOR_EACH_2(ACTN, E, ...) ACTN(E) M_FOR_EACH_1(ACTN, __VA_ARGS__) | |
#define M_FOR_EACH_3(ACTN, E, ...) ACTN(E) M_FOR_EACH_2(ACTN, __VA_ARGS__) | |
#define M_FOR_EACH_4(ACTN, E, ...) ACTN(E) M_FOR_EACH_3(ACTN, __VA_ARGS__) | |
#define M_FOR_EACH_5(ACTN, E, ...) ACTN(E) M_FOR_EACH_4(ACTN, __VA_ARGS__) | |
#define M_FOR_EACH_6(ACTN, E, ...) ACTN(E) M_FOR_EACH_5(ACTN, __VA_ARGS__) | |
#define M_FOR_EACH_7(ACTN, E, ...) ACTN(E) M_FOR_EACH_6(ACTN, __VA_ARGS__) | |
#define M_FOR_EACH_8(ACTN, E, ...) ACTN(E) M_FOR_EACH_7(ACTN, __VA_ARGS__) | |
#define M_FOR_EACH_9(ACTN, E, ...) ACTN(E) M_FOR_EACH_8(ACTN, __VA_ARGS__) | |
#define M_FOR_EACH_10(ACTN, E, ...) ACTN(E) M_FOR_EACH_9(ACTN, __VA_ARGS__) | |
#define M_FOR_EACH_11(ACTN, E, ...) ACTN(E) M_FOR_EACH_10(ACTN, __VA_ARGS__) | |
#define M_FOR_EACH_12(ACTN, E, ...) ACTN(E) M_FOR_EACH_11(ACTN, __VA_ARGS__) | |
#define M_FOR_EACH_13(ACTN, E, ...) ACTN(E) M_FOR_EACH_12(ACTN, __VA_ARGS__) | |
#define M_FOR_EACH_14(ACTN, E, ...) ACTN(E) M_FOR_EACH_13(ACTN, __VA_ARGS__) | |
#define M_FOR_EACH_15(ACTN, E, ...) ACTN(E) M_FOR_EACH_14(ACTN, __VA_ARGS__) | |
#define M_FOR_EACH_16(ACTN, E, ...) ACTN(E) M_FOR_EACH_15(ACTN, __VA_ARGS__) | |
#define M_FOR_EACH_17(ACTN, E, ...) ACTN(E) M_FOR_EACH_16(ACTN, __VA_ARGS__) | |
#define M_FOR_EACH_18(ACTN, E, ...) ACTN(E) M_FOR_EACH_17(ACTN, __VA_ARGS__) | |
#define M_FOR_EACH_19(ACTN, E, ...) ACTN(E) M_FOR_EACH_18(ACTN, __VA_ARGS__) | |
#define M_FOR_EACH_20(ACTN, E, ...) ACTN(E) M_FOR_EACH_19(ACTN, __VA_ARGS__) | |
#define M_FOR_EACH_21(ACTN, E, ...) ACTN(E) M_FOR_EACH_20(ACTN, __VA_ARGS__) | |
#define M_FOR_EACH_22(ACTN, E, ...) ACTN(E) M_FOR_EACH_21(ACTN, __VA_ARGS__) | |
#define M_FOR_EACH_23(ACTN, E, ...) ACTN(E) M_FOR_EACH_22(ACTN, __VA_ARGS__) | |
#define M_FOR_EACH_24(ACTN, E, ...) ACTN(E) M_FOR_EACH_23(ACTN, __VA_ARGS__) | |
#define M_FOR_EACH_25(ACTN, E, ...) ACTN(E) M_FOR_EACH_24(ACTN, __VA_ARGS__) | |
#define M_FOR_EACH_26(ACTN, E, ...) ACTN(E) M_FOR_EACH_25(ACTN, __VA_ARGS__) | |
#define M_FOR_EACH_27(ACTN, E, ...) ACTN(E) M_FOR_EACH_26(ACTN, __VA_ARGS__) | |
#define M_FOR_EACH_28(ACTN, E, ...) ACTN(E) M_FOR_EACH_27(ACTN, __VA_ARGS__) | |
#define M_FOR_EACH_29(ACTN, E, ...) ACTN(E) M_FOR_EACH_28(ACTN, __VA_ARGS__) | |
#define M_FOR_EACH_30(ACTN, E, ...) ACTN(E) M_FOR_EACH_29(ACTN, __VA_ARGS__) | |
#define M_FOR_EACH_31(ACTN, E, ...) ACTN(E) M_FOR_EACH_30(ACTN, __VA_ARGS__) | |
#define M_FOR_EACH_32(ACTN, E, ...) ACTN(E) M_FOR_EACH_31(ACTN, __VA_ARGS__) | |
#define M_ZIP_WITH(ACTN, L1, L2) M_CONC(M_ZIP_WITH_, M_NARGS L1)(ACTN, L1, L2) | |
#define M_ZIP_W2(ACTN, L1, L2) M_REST(M_ZIP_WITH(ACTN, L1, L2)) | |
#define M_ZIP_WITH_0(ACTN, L1, L2) | |
#define M_ZIP_WITH_1(ACTN, L1, L2) ACTN(M_FIRST L1, M_FIRST L2) | |
#define M_ZIP_WITH_2(ACTN, L1, L2) ACTN(M_FIRST L1, M_FIRST L2) M_ZIP_WITH_1(ACTN, (M_REST L1), (M_REST L2)) | |
#define M_ZIP_WITH_3(ACTN, L1, L2) ACTN(M_FIRST L1, M_FIRST L2) M_ZIP_WITH_2(ACTN, (M_REST L1), (M_REST L2)) | |
#define M_ZIP_WITH_4(ACTN, L1, L2) ACTN(M_FIRST L1, M_FIRST L2) M_ZIP_WITH_3(ACTN, (M_REST L1), (M_REST L2)) | |
#define M_ZIP_WITH_5(ACTN, L1, L2) ACTN(M_FIRST L1, M_FIRST L2) M_ZIP_WITH_4(ACTN, (M_REST L1), (M_REST L2)) | |
#define M_ZIP_WITH_6(ACTN, L1, L2) ACTN(M_FIRST L1, M_FIRST L2) M_ZIP_WITH_5(ACTN, (M_REST L1), (M_REST L2)) | |
#define M_ZIP_WITH_7(ACTN, L1, L2) ACTN(M_FIRST L1, M_FIRST L2) M_ZIP_WITH_6(ACTN, (M_REST L1), (M_REST L2)) | |
#define M_ZIP_WITH_8(ACTN, L1, L2) ACTN(M_FIRST L1, M_FIRST L2) M_ZIP_WITH_7(ACTN, (M_REST L1), (M_REST L2)) | |
#define M_ZIP_WITH_9(ACTN, L1, L2) ACTN(M_FIRST L1, M_FIRST L2) M_ZIP_WITH_8(ACTN, (M_REST L1), (M_REST L2)) | |
#define M_ZIP_WITH_10(ACTN, L1, L2) ACTN(M_FIRST L1, M_FIRST L2) M_ZIP_WITH_9(ACTN, (M_REST L1), (M_REST L2)) | |
#define M_ZIP_WITH_11(ACTN, L1, L2) ACTN(M_FIRST L1, M_FIRST L2) M_ZIP_WITH_10(ACTN, (M_REST L1), (M_REST L2)) | |
#define M_ZIP_WITH_12(ACTN, L1, L2) ACTN(M_FIRST L1, M_FIRST L2) M_ZIP_WITH_11(ACTN, (M_REST L1), (M_REST L2)) | |
#define M_ZIP_WITH_13(ACTN, L1, L2) ACTN(M_FIRST L1, M_FIRST L2) M_ZIP_WITH_12(ACTN, (M_REST L1), (M_REST L2)) | |
#define M_ZIP_WITH_14(ACTN, L1, L2) ACTN(M_FIRST L1, M_FIRST L2) M_ZIP_WITH_13(ACTN, (M_REST L1), (M_REST L2)) | |
#define M_ZIP_WITH_15(ACTN, L1, L2) ACTN(M_FIRST L1, M_FIRST L2) M_ZIP_WITH_14(ACTN, (M_REST L1), (M_REST L2)) | |
#define M_ZIP_WITH_16(ACTN, L1, L2) ACTN(M_FIRST L1, M_FIRST L2) M_ZIP_WITH_15(ACTN, (M_REST L1), (M_REST L2)) | |
#define M_ZIP_WITH_17(ACTN, L1, L2) ACTN(M_FIRST L1, M_FIRST L2) M_ZIP_WITH_16(ACTN, (M_REST L1), (M_REST L2)) | |
#define M_ZIP_WITH_18(ACTN, L1, L2) ACTN(M_FIRST L1, M_FIRST L2) M_ZIP_WITH_17(ACTN, (M_REST L1), (M_REST L2)) | |
#define M_ZIP_WITH_19(ACTN, L1, L2) ACTN(M_FIRST L1, M_FIRST L2) M_ZIP_WITH_18(ACTN, (M_REST L1), (M_REST L2)) | |
#define M_ZIP_WITH_20(ACTN, L1, L2) ACTN(M_FIRST L1, M_FIRST L2) M_ZIP_WITH_19(ACTN, (M_REST L1), (M_REST L2)) | |
#define M_ZIP_WITH_21(ACTN, L1, L2) ACTN(M_FIRST L1, M_FIRST L2) M_ZIP_WITH_20(ACTN, (M_REST L1), (M_REST L2)) | |
#define M_ZIP_WITH_22(ACTN, L1, L2) ACTN(M_FIRST L1, M_FIRST L2) M_ZIP_WITH_21(ACTN, (M_REST L1), (M_REST L2)) | |
#define M_ZIP_WITH_23(ACTN, L1, L2) ACTN(M_FIRST L1, M_FIRST L2) M_ZIP_WITH_22(ACTN, (M_REST L1), (M_REST L2)) | |
#define M_ZIP_WITH_24(ACTN, L1, L2) ACTN(M_FIRST L1, M_FIRST L2) M_ZIP_WITH_23(ACTN, (M_REST L1), (M_REST L2)) | |
#define M_ZIP_WITH_25(ACTN, L1, L2) ACTN(M_FIRST L1, M_FIRST L2) M_ZIP_WITH_24(ACTN, (M_REST L1), (M_REST L2)) | |
#define M_ZIP_WITH_26(ACTN, L1, L2) ACTN(M_FIRST L1, M_FIRST L2) M_ZIP_WITH_25(ACTN, (M_REST L1), (M_REST L2)) | |
#define M_ZIP_WITH_27(ACTN, L1, L2) ACTN(M_FIRST L1, M_FIRST L2) M_ZIP_WITH_26(ACTN, (M_REST L1), (M_REST L2)) | |
#define M_ZIP_WITH_28(ACTN, L1, L2) ACTN(M_FIRST L1, M_FIRST L2) M_ZIP_WITH_27(ACTN, (M_REST L1), (M_REST L2)) | |
#define M_ZIP_WITH_29(ACTN, L1, L2) ACTN(M_FIRST L1, M_FIRST L2) M_ZIP_WITH_28(ACTN, (M_REST L1), (M_REST L2)) | |
#define M_ZIP_WITH_30(ACTN, L1, L2) ACTN(M_FIRST L1, M_FIRST L2) M_ZIP_WITH_29(ACTN, (M_REST L1), (M_REST L2)) | |
#define M_ZIP_WITH_31(ACTN, L1, L2) ACTN(M_FIRST L1, M_FIRST L2) M_ZIP_WITH_30(ACTN, (M_REST L1), (M_REST L2)) | |
#define M_ZIP_WITH_32(ACTN, L1, L2) ACTN(M_FIRST L1, M_FIRST L2) M_ZIP_WITH_31(ACTN, (M_REST L1), (M_REST L2)) | |
#define M_REPT_0(A, ...) | |
#define M_REPT_1(A, ...) A __VA_ARGS__ | |
#define M_REPT_2(A, ...) M_REPT_1(A, A __VA_ARGS__) | |
#define M_REPT_3(A, ...) M_REPT_2(A, A __VA_ARGS__) | |
#define M_REPT_4(A, ...) M_REPT_3(A, A __VA_ARGS__) | |
#define M_REPT_5(A, ...) M_REPT_4(A, A __VA_ARGS__) | |
#define M_REPT_6(A, ...) M_REPT_5(A, A __VA_ARGS__) | |
#define M_REPT_7(A, ...) M_REPT_6(A, A __VA_ARGS__) | |
#define M_REPT_8(A, ...) M_REPT_7(A, A __VA_ARGS__) | |
#define M_REPT_9(A, ...) M_REPT_8(A, A __VA_ARGS__) | |
#define M_REPT_10(A, ...) M_REPT_9(A, A __VA_ARGS__) | |
#define M_REPT_11(A, ...) M_REPT_10(A, A __VA_ARGS__) | |
#define M_REPT_12(A, ...) M_REPT_11(A, A __VA_ARGS__) | |
#define M_REPT_13(A, ...) M_REPT_12(A, A __VA_ARGS__) | |
#define M_REPT_14(A, ...) M_REPT_13(A, A __VA_ARGS__) | |
#define M_REPT_15(A, ...) M_REPT_14(A, A __VA_ARGS__) | |
#define M_REPT_16(A, ...) M_REPT_15(A, A __VA_ARGS__) | |
#define M_REPT_17(A, ...) M_REPT_16(A, A __VA_ARGS__) | |
#define M_REPT_18(A, ...) M_REPT_17(A, A __VA_ARGS__) | |
#define M_REPT_19(A, ...) M_REPT_18(A, A __VA_ARGS__) | |
#define M_REPT_20(A, ...) M_REPT_19(A, A __VA_ARGS__) | |
#define M_REPT_21(A, ...) M_REPT_20(A, A __VA_ARGS__) | |
#define M_REPT_22(A, ...) M_REPT_21(A, A __VA_ARGS__) | |
#define M_REPT_23(A, ...) M_REPT_22(A, A __VA_ARGS__) | |
#define M_REPT_24(A, ...) M_REPT_23(A, A __VA_ARGS__) | |
#define M_REPT_25(A, ...) M_REPT_24(A, A __VA_ARGS__) | |
#define M_REPT_26(A, ...) M_REPT_25(A, A __VA_ARGS__) | |
#define M_REPT_27(A, ...) M_REPT_26(A, A __VA_ARGS__) | |
#define M_REPT_28(A, ...) M_REPT_27(A, A __VA_ARGS__) | |
#define M_REPT_29(A, ...) M_REPT_28(A, A __VA_ARGS__) | |
#define M_REPT_30(A, ...) M_REPT_29(A, A __VA_ARGS__) | |
#define M_REPT_31(A, ...) M_REPT_30(A, A __VA_ARGS__) | |
#define M_REPT_32(A, ...) M_REPT_31(A, A __VA_ARGS__) | |
#define M_NEST_0(A, ...) | |
#define M_NEST_1(A, ...) A(__VA_ARGS__) | |
#define M_NEST_2(A, ...) M_NEST_1(A, A(__VA_ARGS__)) | |
#define M_NEST_3(A, ...) M_NEST_2(A, A(__VA_ARGS__)) | |
#define M_NEST_4(A, ...) M_NEST_3(A, A(__VA_ARGS__)) | |
#define M_NEST_5(A, ...) M_NEST_4(A, A(__VA_ARGS__)) | |
#define M_NEST_6(A, ...) M_NEST_5(A, A(__VA_ARGS__)) | |
#define M_NEST_7(A, ...) M_NEST_6(A, A(__VA_ARGS__)) | |
#define M_NEST_8(A, ...) M_NEST_7(A, A(__VA_ARGS__)) | |
#define M_NEST_9(A, ...) M_NEST_8(A, A(__VA_ARGS__)) | |
#define M_NEST_10(A, ...) M_NEST_9(A, A(__VA_ARGS__)) | |
#define M_NEST_11(A, ...) M_NEST_10(A, A(__VA_ARGS__)) | |
#define M_NEST_12(A, ...) M_NEST_11(A, A(__VA_ARGS__)) | |
#define M_NEST_13(A, ...) M_NEST_12(A, A(__VA_ARGS__)) | |
#define M_NEST_14(A, ...) M_NEST_13(A, A(__VA_ARGS__)) | |
#define M_NEST_15(A, ...) M_NEST_14(A, A(__VA_ARGS__)) | |
#define M_NEST_16(A, ...) M_NEST_15(A, A(__VA_ARGS__)) | |
#define M_NEST_17(A, ...) M_NEST_16(A, A(__VA_ARGS__)) | |
#define M_NEST_18(A, ...) M_NEST_17(A, A(__VA_ARGS__)) | |
#define M_NEST_19(A, ...) M_NEST_18(A, A(__VA_ARGS__)) | |
#define M_NEST_20(A, ...) M_NEST_19(A, A(__VA_ARGS__)) | |
#define M_NEST_21(A, ...) M_NEST_20(A, A(__VA_ARGS__)) | |
#define M_NEST_22(A, ...) M_NEST_21(A, A(__VA_ARGS__)) | |
#define M_NEST_23(A, ...) M_NEST_22(A, A(__VA_ARGS__)) | |
#define M_NEST_24(A, ...) M_NEST_23(A, A(__VA_ARGS__)) | |
#define M_NEST_25(A, ...) M_NEST_24(A, A(__VA_ARGS__)) | |
#define M_NEST_26(A, ...) M_NEST_25(A, A(__VA_ARGS__)) | |
#define M_NEST_27(A, ...) M_NEST_26(A, A(__VA_ARGS__)) | |
#define M_NEST_28(A, ...) M_NEST_27(A, A(__VA_ARGS__)) | |
#define M_NEST_29(A, ...) M_NEST_28(A, A(__VA_ARGS__)) | |
#define M_NEST_30(A, ...) M_NEST_29(A, A(__VA_ARGS__)) | |
#define M_NEST_31(A, ...) M_NEST_30(A, A(__VA_ARGS__)) | |
#define M_NEST_32(A, ...) M_NEST_31(A, A(__VA_ARGS__)) | |
#define M_DO_0(...) | |
#define M_DO_1(...) (__VA_ARGS__) | |
#define M_DO_2(...) M_DO_1(__VA_ARGS__) | |
#define M_DO_3(...) M_DO_2(__VA_ARGS__) | |
#define M_DO_4(...) M_DO_3(__VA_ARGS__) | |
#define M_DO_5(...) M_DO_4(__VA_ARGS__) | |
#define M_DO_6(...) M_DO_5(__VA_ARGS__) | |
#define M_DO_7(...) M_DO_6(__VA_ARGS__) | |
#define M_DO_8(...) M_DO_7(__VA_ARGS__) | |
#define M_DO_9(...) M_DO_8(__VA_ARGS__) | |
#define M_DO_10(...) M_DO_9(__VA_ARGS__) | |
#define M_DO_11(...) M_DO_10(__VA_ARGS__) | |
#define M_DO_12(...) M_DO_11(__VA_ARGS__) | |
#define M_DO_13(...) M_DO_12(__VA_ARGS__) | |
#define M_DO_14(...) M_DO_13(__VA_ARGS__) | |
#define M_DO_15(...) M_DO_14(__VA_ARGS__) | |
#define M_DO_16(...) M_DO_15(__VA_ARGS__) | |
#define M_DO_17(...) M_DO_16(__VA_ARGS__) | |
#define M_DO_18(...) M_DO_17(__VA_ARGS__) | |
#define M_DO_19(...) M_DO_18(__VA_ARGS__) | |
#define M_DO_20(...) M_DO_19(__VA_ARGS__) | |
#define M_DO_21(...) M_DO_20(__VA_ARGS__) | |
#define M_DO_22(...) M_DO_21(__VA_ARGS__) | |
#define M_DO_23(...) M_DO_22(__VA_ARGS__) | |
#define M_DO_24(...) M_DO_23(__VA_ARGS__) | |
#define M_DO_25(...) M_DO_24(__VA_ARGS__) | |
#define M_DO_26(...) M_DO_25(__VA_ARGS__) | |
#define M_DO_27(...) M_DO_26(__VA_ARGS__) | |
#define M_DO_28(...) M_DO_27(__VA_ARGS__) | |
#define M_DO_29(...) M_DO_28(__VA_ARGS__) | |
#define M_DO_30(...) M_DO_29(__VA_ARGS__) | |
#define M_DO_31(...) M_DO_30(__VA_ARGS__) | |
#define M_DO_32(...) M_DO_31(__VA_ARGS__) | |
#define M_DIV2_2 1 | |
#define M_DIV2_4 2 | |
#define M_DIV2_6 3 | |
#define M_DIV2_8 4 | |
#define M_DIV2_10 5 | |
#define M_DIV2_12 6 | |
#define M_DIV2_14 7 | |
#define M_DIV2_16 8 | |
#define M_DIV2_18 9 | |
#define M_DIV2_20 10 | |
#define M_DIV2_22 11 | |
#define M_DIV2_24 12 | |
#define M_DIV2_26 13 | |
#define M_DIV2_28 14 | |
#define M_DIV2_30 15 | |
#define M_DIV2_32 16 | |
#endif | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stddef.h> | |
#include <stdio.h> | |
#include "cmacros.h" | |
#define ToLvalue(V) (&(struct { typeof ((void)0, V) v; }){ V }.v) | |
struct VaPack { | |
size_t count; | |
void * const * args; | |
}; | |
#define ToVaArg(Val) (void*)ToLvalue(Val), | |
#define VaCallN(F, N, ...) ((F) (&(struct VaPack) { .count = (N) \ | |
, (void * [N]){ M_FOR_EACH (ToVaArg, __VA_ARGS__) } })) | |
#define VaCall(F, ...) VaCallN (F, M_NARGS(__VA_ARGS__), __VA_ARGS__) | |
int (va_sum) (struct VaPack const * args) { | |
int sum = 0; | |
for (int i = 0; i < args->count; ++ i) { | |
sum += *(int *)(args->args)[i]; | |
} | |
return sum; | |
} | |
#define va_sum(...) VaCall(va_sum, __VA_ARGS__) | |
int main (void) { | |
int k = va_sum (1, 2 + 3, 4 * 5); | |
printf("%d\n", k); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment