// IF_ELSE(1)(if body)(else body) #define FIRST(a, ...) a #define SECOND(a, b, ...) b #define CONCAT(a, b) a ## b #define CAT(a, b) CONCAT(a, b) #define IF_ELSE(a) CAT(_IF_, BOOL(a)) #define _IF_0(...) _ELSE_0 #define _IF_1(...) __VA_ARGS__ _ELSE_1 #define _ELSE_0(...) __VA_ARGS__ #define _ELSE_1(...) #define _CHECK(...) SECOND(__VA_ARGS__, 0) #define NOT(a) _CHECK(CONCAT(_NOT_, a)) #define _NOT_0 ~, 1 #define _NOT_NULL ~, 1 #define BOOL(a) NOT(NOT(a)) #define NONE() #define HAS_ARGS(...) BOOL(FIRST(_END_ARGS __VA_ARGS__ ())) #define _END_ARGS() 0 #define PUSH2(macr) macr NONE NONE()() #define _MAP() MAP #define MAP(macr, a, ...) \ IF_ELSE(HAS_ARGS(__VA_ARGS__))\ (macr(a) PUSH2(_MAP)()(macr, __VA_ARGS__))\ () #define WORKING_MAP(...) MAP(__VA_ARGS__, 0) #define SCAN1(...) __VA_ARGS__ #define SCAN2(...) SCAN1(SCAN1(__VA_ARGS__)) #define SCAN4(...) SCAN2(SCAN2(__VA_ARGS__)) #define SCAN8(...) SCAN4(SCAN4(__VA_ARGS__)) #define SCAN16(...) SCAN8(SCAN8(__VA_ARGS__)) #define SCAN32(...) SCAN16(SCAN16(__VA_ARGS__)) #define SCAN64(...) SCAN32(SCAN32(__VA_ARGS__)) #define SCAN128(...) SCAN64(SCAN64(__VA_ARGS__)) #define SCAN256(...) SCAN128(SCAN128(__VA_ARGS__)) #define SCAN512(...) SCAN256(SCAN256(__VA_ARGS__)) #define SCAN1024(...) SCAN512(SCAN512(__VA_ARGS__)) #define SCAN2048(...) SCAN1024(SCAN1024(__VA_ARGS__)) #define SCAN4096(...) SCAN2048(SCAN2048(__VA_ARGS__)) #define SCAN8192(...) SCAN4096(SCAN4096(__VA_ARGS__)) #define SCAN16384(...) SCAN8192(SCAN8192(__VA_ARGS__)) #define SCAN32768(...) SCAN16384(SCAN16384(__VA_ARGS__)) #define ZERO 0 #define ONE 1 #define DEC(a) CAT(_DEC_, a) #define _DEC_1 0 #define _DEC_2 1 #define _DEC_3 2 #define _DEC_4 3 #define _DEC_5 4 #define _FOR() FOR #define FOR(a) a IF_ELSE(a)\ (PUSH2(_FOR)()(DEC(a)))\ () #define PUSH(macr) macr NONE() #define _OLD_MAP() OLD_MAP #define OLD_MAP(macr, a, ...)\ macr(a) PUSH(_OLD_MAP)()(macr, __VA_ARGS__) int main() { // SCAN64(OLD_MAP(BOOL, 1)); SCAN64(WORKING_MAP(BOOL, 5, EMPTY, ZERO)) // SCAN32768(SCAN32768(SCAN32768(SCAN32768(SCAN32768(SCAN32768(SCAN32768(OLD_MAP(BOOL, 1)))))))); }