blob: ac507b77f4d75be039e772cdc4251b5691eba38d [file] [log] [blame]
/*
* 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))