Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #define PP_NARG(...) \
- PP_NARG_(__VA_ARGS__,PP_RSEQ_N())
- #define PP_NARG_(...) \
- PP_ARG_N(__VA_ARGS__)
- #define PP_ARG_N( \
- _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,_54,_55,_56,_57,_58,_59,_60, \
- _61,_62,_63,N,...) N
- #define PP_RSEQ_N() \
- 63,62,61,60, \
- 59,58,57,56,55,54,53,52,51,50, \
- 49,48,47,46,45,44,43,42,41,40, \
- 39,38,37,36,35,34,33,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 CAT(a, ...) PRIMITIVE_CAT(a, __VA_ARGS__)
- #define PRIMITIVE_CAT(a, ...) a ## __VA_ARGS__
- #define IIF(c) PRIMITIVE_CAT(IIF_, c)
- #define IIF_0(t, ...) __VA_ARGS__
- #define IIF_1(t, ...) t
- #define COMPL(b) PRIMITIVE_CAT(COMPL_, b)
- #define COMPL_0 1
- #define COMPL_1 0
- #define INC(x) PRIMITIVE_CAT(INC_, x)
- #define INC_0 1
- #define INC_1 2
- #define INC_2 3
- #define INC_3 4
- #define INC_4 5
- #define INC_5 6
- #define INC_6 7
- #define INC_7 8
- #define INC_8 9
- #define INC_9 9
- #define DEC(x) PRIMITIVE_CAT(DEC_, x)
- #define DEC_0 0
- #define DEC_1 0
- #define DEC_2 1
- #define DEC_3 2
- #define DEC_4 3
- #define DEC_5 4
- #define DEC_6 5
- #define DEC_7 6
- #define DEC_8 7
- #define DEC_9 8
- #define CHECK_N(x, n, ...) n
- #define CHECK(...) CHECK_N(__VA_ARGS__, 0,)
- #define PROBE(x) x, 1,
- #define NOT(x) CHECK(PRIMITIVE_CAT(NOT_, x))
- #define NOT_0 PROBE(~)
- #define BOOL(x) COMPL(NOT(x))
- #define IF(c) IIF(BOOL(c))
- #define EAT(...)
- #define EXPAND(...) __VA_ARGS__
- #define WHEN(c) IF(c)(EXPAND, EAT)
- #define EMPTY()
- #define DEFER(id) id EMPTY()
- #define OBSTRUCT(...) __VA_ARGS__ DEFER(EMPTY)()
- #define EXPAND(...) __VA_ARGS__
- #define EVAL(...) EVAL1(EVAL1(EVAL1(__VA_ARGS__)))
- #define EVAL1(...) EVAL2(EVAL2(EVAL2(__VA_ARGS__)))
- #define EVAL2(...) EVAL3(EVAL3(EVAL3(__VA_ARGS__)))
- #define EVAL3(...) EVAL4(EVAL4(EVAL4(__VA_ARGS__)))
- #define EVAL4(...) EVAL5(EVAL5(EVAL5(__VA_ARGS__)))
- #define EVAL5(...) __VA_ARGS__
- #define MAYBE_BIND(count, condition, x1, x2, ...) ({ \
- typeof(x1) __res0 = (x1); \
- condition(__res0) ? __res0 : \
- IF(count) \
- ( \
- OBSTRUCT(MAYBE_BIND_INDIRECT) () \
- ( \
- DEC(count), condition, x2, __VA_ARGS__ \
- ), \
- (x2) \
- ) \
- ; \
- })
- #define MAYBE_BIND_INDIRECT() MAYBE_BIND
- #define MAYBE(condition, x1, ...) (EVAL(MAYBE_BIND(DEC(PP_NARG(__VA_ARGS__)), condition, x1, __VA_ARGS__)))
- #define IS_ERROR(x) ((x) < 0)
- int f1() {
- printf("f1()\n");
- return 0;
- }
- int f2() {
- printf("f2()\n");
- return -1;
- }
- int f3() {
- printf("f3()\n");
- return 2;
- }
- int f4() {
- printf("f4()\n");
- return 5;
- }
- int main(void) {
- int res = MAYBE(IS_ERROR,
- f1(),
- f2(),
- f3(),
- f4()
- );
- printf("res = %i\n\n", res);
- // f1()
- // f2()
- // res = -1
- int a, b, c;
- res = MAYBE(IS_ERROR,
- a = f1(),
- b = f3(),
- c = f4(),
- a + b + c
- );
- printf("res = %i\n", res);
- // f1()
- // f3()
- // f4()
- // res = 7
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement