| /* | |
| * Created by William Swanson in 2012. | |
| * | |
| * I, William Swanson, dedicate this work to the public domain. | |
| * I waive all rights to the work worldwide under copyright law, | |
| * including all related and neighboring rights, | |
| * to the extent allowed by law. | |
| * | |
| * You can copy, modify, distribute and perform the work, | |
| * even for commercial purposes, all without asking permission. | |
| * | |
| * CHERIoT modifications: | |
| * - Added CHERIOT_ prefix to all macros to avoid namespace pollution | |
| * - Used pragma once instead of include guards | |
| */ | |
| #pragma once | |
| #define CHERIOT_EVAL0(...) __VA_ARGS__ | |
| #define CHERIOT_EVAL1(...) \ | |
| CHERIOT_EVAL0(CHERIOT_EVAL0(CHERIOT_EVAL0(__VA_ARGS__))) | |
| #define CHERIOT_EVAL2(...) \ | |
| CHERIOT_EVAL1(CHERIOT_EVAL1(CHERIOT_EVAL1(__VA_ARGS__))) | |
| #define CHERIOT_EVAL3(...) \ | |
| CHERIOT_EVAL2(CHERIOT_EVAL2(CHERIOT_EVAL2(__VA_ARGS__))) | |
| #define CHERIOT_EVAL4(...) \ | |
| CHERIOT_EVAL3(CHERIOT_EVAL3(CHERIOT_EVAL3(__VA_ARGS__))) | |
| #define CHERIOT_EVAL(...) \ | |
| CHERIOT_EVAL4(CHERIOT_EVAL4(CHERIOT_EVAL4(__VA_ARGS__))) | |
| #define CHERIOT_MAP_END(...) | |
| #define CHERIOT_MAP_OUT | |
| #define CHERIOT_MAP_COMMA , | |
| #define CHERIOT_MAP_GET_END2() 0, CHERIOT_MAP_END | |
| #define CHERIOT_MAP_GET_END1(...) CHERIOT_MAP_GET_END2 | |
| #define CHERIOT_MAP_GET_END(...) CHERIOT_MAP_GET_END1 | |
| #define CHERIOT_MAP_NEXT0(test, next, ...) next CHERIOT_MAP_OUT | |
| #define CHERIOT_MAP_NEXT1(test, next) CHERIOT_MAP_NEXT0(test, next, 0) | |
| #define CHERIOT_MAP_NEXT(test, next) \ | |
| CHERIOT_MAP_NEXT1(CHERIOT_MAP_GET_END test, next) | |
| #define CHERIOT_MAP0(f, x, peek, ...) \ | |
| f(x) CHERIOT_MAP_NEXT(peek, CHERIOT_MAP1)(f, peek, __VA_ARGS__) | |
| #define CHERIOT_MAP1(f, x, peek, ...) \ | |
| f(x) CHERIOT_MAP_NEXT(peek, CHERIOT_MAP0)(f, peek, __VA_ARGS__) | |
| #define CHERIOT_MAP_LIST_NEXT1(test, next) \ | |
| CHERIOT_MAP_NEXT0(test, CHERIOT_MAP_COMMA next, 0) | |
| #define CHERIOT_MAP_LIST_NEXT(test, next) \ | |
| CHERIOT_MAP_LIST_NEXT1(CHERIOT_MAP_GET_END test, next) | |
| #define CHERIOT_MAP_LIST0(f, x, peek, ...) \ | |
| f(x) CHERIOT_MAP_LIST_NEXT(peek, CHERIOT_MAP_LIST1)(f, peek, __VA_ARGS__) | |
| #define CHERIOT_MAP_LIST1(f, x, peek, ...) \ | |
| f(x) CHERIOT_MAP_LIST_NEXT(peek, CHERIOT_MAP_LIST0)(f, peek, __VA_ARGS__) | |
| /** | |
| * Applies the function macro `f` to each of the remaining parameters. | |
| */ | |
| #define CHERIOT_MAP(f, ...) \ | |
| CHERIOT_EVAL(CHERIOT_MAP1(f, __VA_ARGS__, ()()(), ()()(), ()()(), 0)) | |
| /** | |
| * Applies the function macro `f` to each of the remaining parameters and | |
| * inserts commas between the results. | |
| */ | |
| #define CHERIOT_MAP_LIST(f, ...) \ | |
| CHERIOT_EVAL(CHERIOT_MAP_LIST1(f, __VA_ARGS__, ()()(), ()()(), ()()(), 0)) |