mirror of
https://github.com/Wack0/entii-for-workcubes.git
synced 2025-12-19 18:06:24 -05:00
258 lines
8.2 KiB
C
258 lines
8.2 KiB
C
/**
|
|
* You have been WARNED
|
|
*
|
|
* Many of the preprocessor metaprogramming techniques used here are from this
|
|
* excellent article:
|
|
* https://github.com/pfultz2/Cloak/wiki/C-Preprocessor-tricks,-tips,-and-idioms
|
|
*
|
|
* In general, it's best not to try to decipher this.
|
|
*/
|
|
|
|
#define CPP_PASTE(a,...) a ## __VA_ARGS__
|
|
#define CPP_CAT(a,...) CPP_PASTE(a,__VA_ARGS__)
|
|
|
|
#define CPP_ENUMERATE(x) x,
|
|
#define CPP_ID(x) x
|
|
|
|
#define CPP_EMPTY()
|
|
#define CPP_BLOCK_EXPANSION(x) x CPP_EMPTY()
|
|
#define CPP_DEFER(...) __VA_ARGS__ CPP_BLOCK_EXPANSION(CPP_EMPTY)()
|
|
#define CPP_EXPAND(...) __VA_ARGS__
|
|
#define CPP_EAT(...)
|
|
|
|
#define CPP_EVAL(...) CPP_EVAL1(CPP_EVAL1(CPP_EVAL1(__VA_ARGS__)))
|
|
#define CPP_EVAL1(...) CPP_EVAL2(CPP_EVAL2(CPP_EVAL2(__VA_ARGS__)))
|
|
#define CPP_EVAL2(...) CPP_EVAL3(CPP_EVAL3(CPP_EVAL3(__VA_ARGS__)))
|
|
#define CPP_EVAL3(...) CPP_EVAL4(CPP_EVAL4(CPP_EVAL4(__VA_ARGS__)))
|
|
#define CPP_EVAL4(...) CPP_EVAL5(CPP_EVAL5(CPP_EVAL5(__VA_ARGS__)))
|
|
#define CPP_EVAL5(...) CPP_EXPAND(CPP_EXPAND(CPP_EXPAND(__VA_ARGS__)))
|
|
|
|
#define CPP_IF_(b) CPP_PASTE(CPP_IF__,b)
|
|
#define CPP_IF__0(t,...) __VA_ARGS__
|
|
#define CPP_IF__1(t,...) t
|
|
|
|
#define CPP_NEGATE(x) CPP_PASTE(CPP_NEGATE_,x)
|
|
#define CPP_NEGATE_0 1
|
|
#define CPP_NEGATE_1 0
|
|
|
|
// Lord knows how this works or how I once understood it.
|
|
#define CPP_CHECK_N(x,n,...) n
|
|
#define CPP_CHECK(...) CPP_CHECK_N(__VA_ARGS__,0,)
|
|
#define CPP_PROBE(x) x, 1,
|
|
#define CPP_IS_PAREN_PROBE(...) CPP_PROBE(~)
|
|
#define CPP_IS_PAREN(x) CPP_CHECK(CPP_IS_PAREN_PROBE x)
|
|
|
|
#define CPP_NOT(x) CPP_CHECK(CPP_PASTE(CPP_NOT_,x))
|
|
#define CPP_NOT_0 CPP_PROBE(~)
|
|
#define CPP_AND(x) CPP_PASTE(CPP_AND_,x)
|
|
#define CPP_AND_0(y) 0
|
|
#define CPP_AND_1(y) y
|
|
#define CPP_OR(x) CPP_PASTE(CPP_OR_,x)
|
|
#define CPP_OR_0(y) y
|
|
#define CPP_OR_1(y) 1
|
|
|
|
#define CPP_IS_TRUTHY(x) CPP_NEGATE(CPP_NOT(x))
|
|
#define CPP_IF(pred) CPP_IF_(CPP_IS_TRUTHY(pred))
|
|
|
|
#define CPP_WHEN(pred) CPP_IF(pred)(CPP_EXPAND,CPP_EAT)
|
|
#define CPP_UNLESS(pred) CPP_IF(pred)(CPP_EAT,CPP_EXPAND)
|
|
|
|
#define CPP_NEQ_COMPARABLE(x,y) CPP_IS_PAREN(COMPARE_##x(COMPARE_##y)(()))
|
|
#define CPP_IS_COMPARABLE(x) CPP_IS_PAREN(CPP_CAT(COMPARE_,x)(()))
|
|
#define CPP_NOT_EQUAL(x,y) \
|
|
CPP_IF_(CPP_AND(CPP_IS_COMPARABLE(x))(CPP_IS_COMPARABLE(y))) \
|
|
( \
|
|
CPP_NEQ_COMPARABLE, \
|
|
1 CPP_EAT \
|
|
)(x,y)
|
|
#define CPP_EQUAL(x,y) CPP_NEGATE(CPP_NOT_EQUAL(x,y))
|
|
|
|
#define CPP_REPEAT_(n,f,...) \
|
|
CPP_WHEN(n) \
|
|
( \
|
|
CPP_DEFER(CPP_REPEAT__) () (CPP_DEC(n), f, __VA_ARGS__) \
|
|
CPP_DEFER(f) (CPP_DEC(n), __VA_ARGS__) \
|
|
)
|
|
|
|
#define CPP_REPEAT__() CPP_REPEAT_
|
|
|
|
#define CPP_REPEAT(...) CPP_EVAL(CPP_REPEAT_(__VA_ARGS__))
|
|
|
|
// Could use GCC's ,##__VA_ARGS__ extension to support 0 arguments.
|
|
#define CPP_N_VA_ARGS_(_0,_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,N,...) N
|
|
#define CPP_N_VA_ARGS(...) CPP_N_VA_ARGS_(__VA_ARGS__,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 CPP_OVERLOAD(fn, ...) CPP_CAT(fn, CPP_N_VA_ARGS(__VA_ARGS__))(__VA_ARGS__)
|
|
|
|
#define CPP_FOREACH_0(f,x)
|
|
#define CPP_FOREACH_1(f,x) f(x)
|
|
#define CPP_FOREACH_2(f,x,...) f(x)CPP_FOREACH_1(f,__VA_ARGS__)
|
|
#define CPP_FOREACH_3(f,x,...) f(x)CPP_FOREACH_2(f,__VA_ARGS__)
|
|
#define CPP_FOREACH_4(f,x,...) f(x)CPP_FOREACH_3(f,__VA_ARGS__)
|
|
#define CPP_FOREACH_5(f,x,...) f(x)CPP_FOREACH_4(f,__VA_ARGS__)
|
|
#define CPP_FOREACH_6(f,x,...) f(x)CPP_FOREACH_5(f,__VA_ARGS__)
|
|
#define CPP_FOREACH_7(f,x,...) f(x)CPP_FOREACH_6(f,__VA_ARGS__)
|
|
#define CPP_FOREACH_8(f,x,...) f(x)CPP_FOREACH_7(f,__VA_ARGS__)
|
|
#define CPP_FOREACH_9(f,x,...) f(x)CPP_FOREACH_8(f,__VA_ARGS__)
|
|
#define CPP_FOREACH_10(f,x,...) f(x)CPP_FOREACH_9(f,__VA_ARGS__)
|
|
#define CPP_FOREACH_11(f,x,...) f(x)CPP_FOREACH_10(f,__VA_ARGS__)
|
|
#define CPP_FOREACH_12(f,x,...) f(x)CPP_FOREACH_11(f,__VA_ARGS__)
|
|
#define CPP_FOREACH_13(f,x,...) f(x)CPP_FOREACH_12(f,__VA_ARGS__)
|
|
#define CPP_FOREACH_14(f,x,...) f(x)CPP_FOREACH_13(f,__VA_ARGS__)
|
|
#define CPP_FOREACH_15(f,x,...) f(x)CPP_FOREACH_14(f,__VA_ARGS__)
|
|
#define CPP_FOREACH_16(f,x,...) f(x)CPP_FOREACH_15(f,__VA_ARGS__)
|
|
#define CPP_FOREACH_17(f,x,...) f(x)CPP_FOREACH_16(f,__VA_ARGS__)
|
|
#define CPP_FOREACH_18(f,x,...) f(x)CPP_FOREACH_17(f,__VA_ARGS__)
|
|
#define CPP_FOREACH_19(f,x,...) f(x)CPP_FOREACH_18(f,__VA_ARGS__)
|
|
#define CPP_FOREACH_20(f,x,...) f(x)CPP_FOREACH_19(f,__VA_ARGS__)
|
|
#define CPP_FOREACH_21(f,x,...) f(x)CPP_FOREACH_20(f,__VA_ARGS__)
|
|
#define CPP_FOREACH_22(f,x,...) f(x)CPP_FOREACH_21(f,__VA_ARGS__)
|
|
#define CPP_FOREACH_23(f,x,...) f(x)CPP_FOREACH_22(f,__VA_ARGS__)
|
|
#define CPP_FOREACH_24(f,x,...) f(x)CPP_FOREACH_23(f,__VA_ARGS__)
|
|
#define CPP_FOREACH_25(f,x,...) f(x)CPP_FOREACH_24(f,__VA_ARGS__)
|
|
#define CPP_FOREACH_26(f,x,...) f(x)CPP_FOREACH_25(f,__VA_ARGS__)
|
|
#define CPP_FOREACH_27(f,x,...) f(x)CPP_FOREACH_26(f,__VA_ARGS__)
|
|
#define CPP_FOREACH_28(f,x,...) f(x)CPP_FOREACH_27(f,__VA_ARGS__)
|
|
#define CPP_FOREACH_29(f,x,...) f(x)CPP_FOREACH_28(f,__VA_ARGS__)
|
|
#define CPP_FOREACH_30(f,x,...) f(x)CPP_FOREACH_29(f,__VA_ARGS__)
|
|
#define CPP_FOREACH_31(f,x,...) f(x)CPP_FOREACH_30(f,__VA_ARGS__)
|
|
#define CPP_FOREACH_32(f,x,...) f(x)CPP_FOREACH_31(f,__VA_ARGS__)
|
|
|
|
#define CPP_FOREACH(f,...) CPP_OVERLOAD(CPP_FOREACH_, f, __VA_ARGS__)
|
|
|
|
|
|
|
|
// No nicer way to write this. More cases can be added on an as-needed basis.
|
|
// Saturate instead of wraparound.
|
|
#define CPP_INC(x) CPP_PASTE(CPP_INC_,x)
|
|
#define CPP_INC_0 1
|
|
#define CPP_INC_1 2
|
|
#define CPP_INC_2 3
|
|
#define CPP_INC_3 4
|
|
#define CPP_INC_4 5
|
|
#define CPP_INC_5 6
|
|
#define CPP_INC_6 7
|
|
#define CPP_INC_7 8
|
|
#define CPP_INC_8 9
|
|
#define CPP_INC_9 10
|
|
#define CPP_INC_10 11
|
|
#define CPP_INC_11 12
|
|
#define CPP_INC_12 13
|
|
#define CPP_INC_13 14
|
|
#define CPP_INC_14 15
|
|
#define CPP_INC_15 16
|
|
#define CPP_INC_16 17
|
|
#define CPP_INC_17 18
|
|
#define CPP_INC_18 19
|
|
#define CPP_INC_19 20
|
|
#define CPP_INC_20 21
|
|
#define CPP_INC_21 22
|
|
#define CPP_INC_22 23
|
|
#define CPP_INC_23 24
|
|
#define CPP_INC_24 25
|
|
#define CPP_INC_25 26
|
|
#define CPP_INC_26 27
|
|
#define CPP_INC_27 28
|
|
#define CPP_INC_28 29
|
|
#define CPP_INC_29 30
|
|
#define CPP_INC_30 31
|
|
#define CPP_INC_31 32
|
|
#define CPP_INC_32 33
|
|
#define CPP_INC_33 34
|
|
#define CPP_INC_34 35
|
|
#define CPP_INC_35 36
|
|
#define CPP_INC_36 37
|
|
#define CPP_INC_37 38
|
|
#define CPP_INC_38 39
|
|
#define CPP_INC_39 40
|
|
#define CPP_INC_40 41
|
|
#define CPP_INC_41 42
|
|
#define CPP_INC_42 43
|
|
#define CPP_INC_43 44
|
|
#define CPP_INC_44 45
|
|
#define CPP_INC_45 46
|
|
#define CPP_INC_46 47
|
|
#define CPP_INC_47 48
|
|
#define CPP_INC_48 49
|
|
#define CPP_INC_49 50
|
|
#define CPP_INC_50 51
|
|
#define CPP_INC_51 52
|
|
#define CPP_INC_52 53
|
|
#define CPP_INC_53 54
|
|
#define CPP_INC_54 55
|
|
#define CPP_INC_55 56
|
|
#define CPP_INC_56 57
|
|
#define CPP_INC_57 58
|
|
#define CPP_INC_58 59
|
|
#define CPP_INC_59 60
|
|
#define CPP_INC_60 61
|
|
#define CPP_INC_61 62
|
|
#define CPP_INC_62 63
|
|
#define CPP_INC_63 63
|
|
|
|
#define CPP_DEC(x) CPP_PASTE(CPP_DEC_,x)
|
|
#define CPP_DEC_0 0
|
|
#define CPP_DEC_1 0
|
|
#define CPP_DEC_2 1
|
|
#define CPP_DEC_3 2
|
|
#define CPP_DEC_4 3
|
|
#define CPP_DEC_5 4
|
|
#define CPP_DEC_6 5
|
|
#define CPP_DEC_7 6
|
|
#define CPP_DEC_8 7
|
|
#define CPP_DEC_9 8
|
|
#define CPP_DEC_10 9
|
|
#define CPP_DEC_11 10
|
|
#define CPP_DEC_12 11
|
|
#define CPP_DEC_13 12
|
|
#define CPP_DEC_14 13
|
|
#define CPP_DEC_15 14
|
|
#define CPP_DEC_16 15
|
|
#define CPP_DEC_17 16
|
|
#define CPP_DEC_18 17
|
|
#define CPP_DEC_19 18
|
|
#define CPP_DEC_20 19
|
|
#define CPP_DEC_21 20
|
|
#define CPP_DEC_22 21
|
|
#define CPP_DEC_23 22
|
|
#define CPP_DEC_24 23
|
|
#define CPP_DEC_25 24
|
|
#define CPP_DEC_26 25
|
|
#define CPP_DEC_27 26
|
|
#define CPP_DEC_28 27
|
|
#define CPP_DEC_29 28
|
|
#define CPP_DEC_30 29
|
|
#define CPP_DEC_31 30
|
|
#define CPP_DEC_32 31
|
|
#define CPP_DEC_33 32
|
|
#define CPP_DEC_34 33
|
|
#define CPP_DEC_35 34
|
|
#define CPP_DEC_36 35
|
|
#define CPP_DEC_37 36
|
|
#define CPP_DEC_38 37
|
|
#define CPP_DEC_39 38
|
|
#define CPP_DEC_40 39
|
|
#define CPP_DEC_41 40
|
|
#define CPP_DEC_42 41
|
|
#define CPP_DEC_43 42
|
|
#define CPP_DEC_44 43
|
|
#define CPP_DEC_45 44
|
|
#define CPP_DEC_46 45
|
|
#define CPP_DEC_47 46
|
|
#define CPP_DEC_48 47
|
|
#define CPP_DEC_49 48
|
|
#define CPP_DEC_50 49
|
|
#define CPP_DEC_51 50
|
|
#define CPP_DEC_52 51
|
|
#define CPP_DEC_53 52
|
|
#define CPP_DEC_54 53
|
|
#define CPP_DEC_55 54
|
|
#define CPP_DEC_56 55
|
|
#define CPP_DEC_57 56
|
|
#define CPP_DEC_58 57
|
|
#define CPP_DEC_59 58
|
|
#define CPP_DEC_60 59
|
|
#define CPP_DEC_61 60
|
|
#define CPP_DEC_62 61
|
|
#define CPP_DEC_63 62
|