Skip to content

Instantly share code, notes, and snippets.

@gengar
Last active May 2, 2020 18:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gengar/928210ee4093d936bfcc56361c7d2a86 to your computer and use it in GitHub Desktop.
Save gengar/928210ee4093d936bfcc56361c7d2a86 to your computer and use it in GitHub Desktop.
#define PP_AUX_STR(s) #s
#define PP_STR(s) PP_AUX_STR(s)
#define PP_AUX_CAT(x, y) x ## y
#define PP_CAT(x, y) PP_AUX_CAT(x, y)
#define PP_ARG_HEAD(arg, ...) arg
#define PP_ARG_TAIL(arg, ...) __VA_ARGS__
#define PP_AUX_ARG_GET_0(a0, ...) a0
#define PP_AUX_ARG_GET_1(a0, a1, ...) a1
#define PP_AUX_ARG_GET_2(a0, a1, a2, ...) a2
#define PP_AUX_ARG_GET_3(a0, a1, a2, a3, ...) a3
#define PP_AUX_ARG_GET_4(a0, a1, a2, a3, a4, ...) a4
#define PP_AUX_ARG_GET_5(a0, a1, a2, a3, a4, a5, ...) a5
#define PP_AUX_ARG_GET_6(a0, a1, a2, a3, a4, a5, a6, ...) a6
#define PP_AUX_ARG_GET_7(a0, a1, a2, a3, a4, a5, a6, a7, ...) a7
#define PP_AUX_ARG_GET_8(a0, a1, a2, a3, a4, a5, a6, a7, a8, ...) a8
#define PP_AUX_ARG_GET_9(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, ...) a9
#define PP_ARG_GET(n, ...) PP_CAT(PP_AUX_ARG_GET_, n)(__VA_ARGS__)
#define PP_ARG_LENGTH(...) PP_AUX_ARG_GET_9(__VA_OPT__(,) __VA_ARGS__, 8, 7, 6, 5, 4, 3, 2, 1, 0)
#define PP_AUX_BOOL_0 0
#define PP_AUX_BOOL_1 1
#define PP_AUX_BOOL_2 1
#define PP_AUX_BOOL_3 1
#define PP_AUX_BOOL_4 1
#define PP_AUX_BOOL_5 1
#define PP_AUX_BOOL_6 1
#define PP_AUX_BOOL_7 1
#define PP_AUX_BOOL_8 1
#define PP_AUX_BOOL_9 1
#define PP_BOOL(test) PP_CAT(PP_AUX_BOOL_, test)
#define PP_AUX_NOT_0 1
#define PP_AUX_NOT_1 0
#define PP_NOT(x) PP_CAT(PP_AUX_NOT_, PP_BOOL(x))
#define PP_AUX_ARG_NULL_O 1
#define PP_AUX_ARG_NULL_NO 0
#define PP_ARG_NULL_P(...) PP_CAT(PP_CAT(PP_AUX_ARG_NULL_, __VA_OPT__(N)), O)
#define PP_AUX_SEQ_SPLICE(...) __VA_ARGS__
#define PP_SEQ_SPLICE(seq) PP_AUX_SEQ_SPLICE seq
#define PP_SEQ_HEAD(seq) PP_ARG_HEAD seq
#define PP_SEQ_TAIL(seq) (PP_ARG_TAIL seq)
#define PP_SEQ_GET(seq, n) PP_CAT(PP_AUX_ARG_GET_, n) seq
#define PP_SEQ_NULL_P(seq) PP_ARG_NULL_P seq
#define PP_SEQ_CONS(x, seq) PP_IF(PP_SEQ_NULL_P(seq))((x), (x, PP_SEQ_SPLICE(seq)))
#define PP_SEQ_RCONS(seq, x) PP_IF(PP_SEQ_NULL_P(seq))((x), (PP_SEQ_SPLICE(seq), x))
#define PP_AUX_IF_0(x, y) y
#define PP_AUX_IF_1(x, y) x
#define PP_IF(test) PP_CAT(PP_AUX_IF_, PP_BOOL(test))
#define PP_AUX_DO0(p, f, x) PP_IF(p(x))(x, f(x))
#define PP_AUX_DO1(p, f, x) PP_IF(p(x))(x, PP_AUX_DO0(p, f, PP_AUX_DO0(p, f, x)))
#define PP_AUX_DO2(p, f, x) PP_IF(p(x))(x, PP_AUX_DO1(p, f, PP_AUX_DO1(p, f, x)))
#define PP_AUX_DO3(p, f, x) PP_IF(p(x))(x, PP_AUX_DO2(p, f, PP_AUX_DO2(p, f, x)))
#define PP_AUX_DO4(p, f, x) PP_IF(p(x))(x, PP_AUX_DO3(p, f, PP_AUX_DO3(p, f, x)))
#define PP_DO PP_AUX_DO4
#define PP_AUX_MAP_F3(f, r, seq) (f, PP_SEQ_RCONS(r, f(PP_SEQ_HEAD(seq))), PP_SEQ_TAIL(seq))
#define PP_AUX_MAP_F(tuple) PP_AUX_MAP_F3 tuple
#define PP_AUX_MAP_END_P(tuple) PP_SEQ_NULL_P(PP_SEQ_GET(tuple, 2))
#define PP_MAP(f, seq) PP_SEQ_GET(PP_DO(PP_AUX_MAP_END_P, PP_AUX_MAP_F, (f, (), seq)), 1)
#define PP_AUX_MAP_SPLICING_CONJ(a, x) (PP_SEQ_SPLICE(a) x)
#define PP_AUX_MAP_SPLICING_F3(f, r, seq) (f, PP_AUX_MAP_SPLICING_CONJ(r, f(PP_SEQ_HEAD(seq))), PP_SEQ_TAIL(seq))
#define PP_AUX_MAP_SPLICING_F(tuple) PP_AUX_MAP_SPLICING_F3 tuple
#define PP_AUX_MAP_SPLICING_END_P(tuple) PP_SEQ_NULL_P(PP_SEQ_GET(tuple, 2))
#define PP_MAP_SPLICING(f, seq) PP_SEQ_SPLICE(PP_SEQ_GET(PP_DO(PP_AUX_MAP_SPLICING_END_P, PP_AUX_MAP_SPLICING_F, (f, (), seq)), 1))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment