|
| 1 | +// 2020/08/30 - Created by netcan: https://github.com/netcan |
| 2 | +// ref https://github.com/Erlkoenig90/map-macro/ |
| 3 | +#pragma once |
| 4 | +#ifdef _MSC_VER |
| 5 | +#define TF_EMPTY() |
| 6 | +#define TF_GET_ARG_COUNT_(...) \ |
| 7 | + TF_PASTE(TF_GET_ARG_COUNT_I(__VA_ARGS__, 64, 63, 62, 61, 60, 59, 58, 57, 56, \ |
| 8 | + 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, \ |
| 9 | + 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, \ |
| 10 | + 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, \ |
| 11 | + 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, \ |
| 12 | + 6, 5, 4, 3, 2, 1, 0, ), \ |
| 13 | + TF_EMPTY()) |
| 14 | + |
| 15 | +#else |
| 16 | +#define TF_GET_ARG_COUNT_(...) \ |
| 17 | + TF_GET_ARG_COUNT_I(__VA_ARGS__, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, \ |
| 18 | + 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, \ |
| 19 | + 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, \ |
| 20 | + 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, \ |
| 21 | + 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, ) |
| 22 | +#endif |
| 23 | + |
| 24 | +#define TF_GET_ARG_COUNT(...) TF_GET_ARG_COUNT_(__dummy__, ##__VA_ARGS__) |
| 25 | +#define TF_GET_ARG_COUNT_I( \ |
| 26 | + e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, \ |
| 27 | + e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, \ |
| 28 | + e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, \ |
| 29 | + e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, \ |
| 30 | + e62, e63, e64, size, ...) \ |
| 31 | + size |
| 32 | + |
| 33 | +#define TF_GET_FIRST(a, ...) a |
| 34 | +#define TF_GET_SECOND(a, b, ...) b |
| 35 | +#define TF_CONCATE(x, y) x##y |
| 36 | +#define TF_PASTE(x, y) TF_CONCATE(x, y) |
| 37 | + |
| 38 | +#define TF_EVAL0(...) __VA_ARGS__ |
| 39 | +#define TF_EVAL1(...) TF_EVAL0(TF_EVAL0(TF_EVAL0(__VA_ARGS__))) |
| 40 | +#define TF_EVAL2(...) TF_EVAL1(TF_EVAL1(TF_EVAL1(__VA_ARGS__))) |
| 41 | +#define TF_EVAL3(...) TF_EVAL2(TF_EVAL2(TF_EVAL2(__VA_ARGS__))) |
| 42 | +#define TF_EVAL4(...) TF_EVAL3(TF_EVAL3(TF_EVAL3(__VA_ARGS__))) |
| 43 | +#define TF_EVAL5(...) TF_EVAL4(TF_EVAL4(TF_EVAL4(__VA_ARGS__))) |
| 44 | + |
| 45 | +#ifdef _MSC_VER |
| 46 | +// MSVC needs more evaluations |
| 47 | +#define TF_EVAL6(...) TF_EVAL5(TF_EVAL5(TF_EVAL5(__VA_ARGS__))) |
| 48 | +#define TF_EVAL(...) TF_EVAL6(TF_EVAL6(__VA_ARGS__)) |
| 49 | +#else |
| 50 | +#define TF_EVAL(...) TF_EVAL5(__VA_ARGS__) |
| 51 | +#endif |
| 52 | + |
| 53 | +#define TF_MAP_END(...) |
| 54 | +#define TF_MAP_OUT |
| 55 | + |
| 56 | +#define EMPTY() |
| 57 | +#define DEFER(id) id EMPTY() |
| 58 | + |
| 59 | +#define TF_MAP_GET_END2() 0, TF_MAP_END |
| 60 | +#define TF_MAP_GET_END1(...) TF_MAP_GET_END2 |
| 61 | +#define TF_MAP_GET_END(...) TF_MAP_GET_END1 |
| 62 | +#define TF_MAP_NEXT0(test, next, ...) next TF_MAP_OUT |
| 63 | +#define TF_MAP_NEXT1(test, next) DEFER(TF_MAP_NEXT0)(test, next, 0) |
| 64 | +#define TF_MAP_NEXT(test, next) TF_MAP_NEXT1(TF_MAP_GET_END test, next) |
| 65 | + |
| 66 | +#define TF_MAP0(f, x, peek, ...) \ |
| 67 | + f(x) DEFER(TF_MAP_NEXT(peek, TF_MAP1))(f, peek, __VA_ARGS__) |
| 68 | +#define TF_MAP1(f, x, peek, ...) \ |
| 69 | + f(x) DEFER(TF_MAP_NEXT(peek, TF_MAP0))(f, peek, __VA_ARGS__) |
| 70 | + |
| 71 | +#define TF_MAP(f, ...) \ |
| 72 | + TF_EVAL(TF_MAP1(f, __VA_ARGS__, ()()(), ()()(), ()()(), 0)) |
0 commit comments