1 /* 2 * Copyright (c) 2022 NVIDIA Corporation 3 * 4 * Licensed under the Apache License Version 2.0 with LLVM Exceptions 5 * (the "License"); you may not use this file except in compliance with 6 * the License. You may obtain a copy of the License at 7 * 8 * https://llvm.org/LICENSE.txt 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 #pragma once 17 18 #define STDEXEC_STRINGIZE_(...) #__VA_ARGS__ 19 #define STDEXEC_STRINGIZE(...) STDEXEC_STRINGIZE_(__VA_ARGS__) 20 21 #define STDEXEC_CAT_(_XP, ...) _XP##__VA_ARGS__ 22 #define STDEXEC_CAT(_XP, ...) STDEXEC_CAT_(_XP, __VA_ARGS__) 23 24 #define STDEXEC_EXPAND(...) __VA_ARGS__ 25 #define STDEXEC_EVAL(_MACRO, ...) _MACRO(__VA_ARGS__) 26 #define STDEXEC_EAT(...) 27 28 #define STDEXEC_IIF(_XP, _YP, ...) \ 29 STDEXEC_IIF_EVAL(STDEXEC_CAT(STDEXEC_IIF_, _XP), _YP, __VA_ARGS__) 30 #define STDEXEC_IIF_0(_YP, ...) __VA_ARGS__ 31 #define STDEXEC_IIF_1(_YP, ...) _YP 32 #define STDEXEC_IIF_EVAL(_MACRO, ...) _MACRO(__VA_ARGS__) 33 34 #define STDEXEC_COMPL(_B) STDEXEC_COMPL_CAT(STDEXEC_COMPL_, _B) 35 #define STDEXEC_COMPL_0 1 // NOLINT(modernize-macro-to-enum) 36 #define STDEXEC_COMPL_1 0 // NOLINT(modernize-macro-to-enum) 37 #define STDEXEC_COMPL_CAT(_XP, ...) _XP##__VA_ARGS__ 38 39 #define STDEXEC_COUNT(...) \ 40 STDEXEC_EXPAND(STDEXEC_COUNT_(__VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)) 41 #define STDEXEC_COUNT_(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _NP, ...) _NP 42 43 #define STDEXEC_CHECK(...) STDEXEC_EXPAND(STDEXEC_CHECK_(__VA_ARGS__, 0, )) 44 #define STDEXEC_CHECK_(_XP, _NP, ...) _NP 45 #define STDEXEC_PROBE(...) STDEXEC_PROBE_(__VA_ARGS__, 1) 46 #define STDEXEC_PROBE_(_XP, _NP, ...) _XP, _NP, 47 48 #define STDEXEC_NOT(_XP) STDEXEC_CHECK(STDEXEC_CAT(STDEXEC_NOT_, _XP)) 49 #define STDEXEC_NOT_0 STDEXEC_PROBE(~, 1) 50 51 #define STDEXEC_BOOL(_XP) STDEXEC_COMPL(STDEXEC_NOT(_XP)) 52 #define STDEXEC_IF(_XP, _YP, ...) STDEXEC_IIF(STDEXEC_BOOL(_XP), _YP, __VA_ARGS__) 53 54 #define STDEXEC_WHEN(_XP, ...) STDEXEC_IF(_XP, STDEXEC_EXPAND, STDEXEC_EAT)(__VA_ARGS__) 55 56 //////////////////////////////////////////////////////////////////////////////// 57 // STDEXEC_FOR_EACH 58 // Inspired by "Recursive macros with C++20 __VA_OPT__", by David Mazières 59 // https://www.scs.stanford.edu/~dm/blog/va-opt.html 60 #define STDEXEC_EXPAND_R(...) \ 61 STDEXEC_EXPAND_R1(STDEXEC_EXPAND_R1(STDEXEC_EXPAND_R1(STDEXEC_EXPAND_R1(__VA_ARGS__)))) \ 62 /**/ 63 #define STDEXEC_EXPAND_R1(...) \ 64 STDEXEC_EXPAND_R2(STDEXEC_EXPAND_R2(STDEXEC_EXPAND_R2(STDEXEC_EXPAND_R2(__VA_ARGS__)))) \ 65 /**/ 66 #define STDEXEC_EXPAND_R2(...) \ 67 STDEXEC_EXPAND_R3(STDEXEC_EXPAND_R3(STDEXEC_EXPAND_R3(STDEXEC_EXPAND_R3(__VA_ARGS__)))) \ 68 /**/ 69 #define STDEXEC_EXPAND_R3(...) \ 70 STDEXEC_EXPAND(STDEXEC_EXPAND(STDEXEC_EXPAND(STDEXEC_EXPAND(__VA_ARGS__)))) \ 71 /**/ 72 73 #define STDEXEC_PARENS () 74 #define STDEXEC_FOR_EACH(_MACRO, ...) \ 75 __VA_OPT__(STDEXEC_EXPAND_R(STDEXEC_FOR_EACH_HELPER(_MACRO, __VA_ARGS__))) \ 76 /**/ 77 #define STDEXEC_FOR_EACH_HELPER(_MACRO, _A1, ...) \ 78 _MACRO(_A1) __VA_OPT__(STDEXEC_FOR_EACH_AGAIN STDEXEC_PARENS(_MACRO, __VA_ARGS__)) /**/ 79 #define STDEXEC_FOR_EACH_AGAIN() STDEXEC_FOR_EACH_HELPER 80 //////////////////////////////////////////////////////////////////////////////////////////////////// 81 82 #define STDEXEC_FRONT(...) __VA_OPT__(STDEXEC_FRONT_HELPER(__VA_ARGS__)) 83 #define STDEXEC_FRONT_HELPER(_A1, ...) _A1 84 #define STDEXEC_BACK(...) __VA_OPT__(STDEXEC_EXPAND_R(STDEXEC_BACK_HELPER(__VA_ARGS__))) 85 #define STDEXEC_BACK_HELPER(_A1, ...) \ 86 STDEXEC_FRONT(__VA_OPT__(, ) _A1, ) __VA_OPT__(STDEXEC_BACK_AGAIN STDEXEC_PARENS(__VA_ARGS__)) 87 #define STDEXEC_BACK_AGAIN() STDEXEC_BACK_HELPER 88 89 #define STDEXEC_TAIL(_, ...) __VA_ARGS__ 90 91 #define STDEXEC_REPEAT(_N, _MACRO, ...) STDEXEC_REPEAT_(_N, _MACRO, __VA_ARGS__) 92 #define STDEXEC_REPEAT_(_N, _MACRO, ...) STDEXEC_REPEAT_##_N(_MACRO, __VA_ARGS__) 93 #define STDEXEC_REPEAT_0(_MACRO, ...) 94 #define STDEXEC_REPEAT_1(_MACRO, ...) _MACRO(0 __VA_OPT__(, ) __VA_ARGS__) 95 #define STDEXEC_REPEAT_2(_MACRO, ...) \ 96 STDEXEC_REPEAT_1(_MACRO, __VA_ARGS__) _MACRO(1 __VA_OPT__(, ) __VA_ARGS__) 97 #define STDEXEC_REPEAT_3(_MACRO, ...) \ 98 STDEXEC_REPEAT_2(_MACRO, __VA_ARGS__) _MACRO(2 __VA_OPT__(, ) __VA_ARGS__) 99 #define STDEXEC_REPEAT_4(_MACRO, ...) \ 100 STDEXEC_REPEAT_3(_MACRO, __VA_ARGS__) _MACRO(3 __VA_OPT__(, ) __VA_ARGS__) 101 #define STDEXEC_REPEAT_5(_MACRO, ...) \ 102 STDEXEC_REPEAT_4(_MACRO, __VA_ARGS__) _MACRO(4 __VA_OPT__(, ) __VA_ARGS__) 103 #define STDEXEC_REPEAT_6(_MACRO, ...) \ 104 STDEXEC_REPEAT_5(_MACRO, __VA_ARGS__) _MACRO(5 __VA_OPT__(, ) __VA_ARGS__) 105 #define STDEXEC_REPEAT_7(_MACRO, ...) \ 106 STDEXEC_REPEAT_6(_MACRO, __VA_ARGS__) _MACRO(6 __VA_OPT__(, ) __VA_ARGS__) 107 #define STDEXEC_REPEAT_8(_MACRO, ...) \ 108 STDEXEC_REPEAT_7(_MACRO, __VA_ARGS__) _MACRO(7 __VA_OPT__(, ) __VA_ARGS__) 109 #define STDEXEC_REPEAT_9(_MACRO, ...) \ 110 STDEXEC_REPEAT_8(_MACRO, __VA_ARGS__) _MACRO(8 __VA_OPT__(, ) __VA_ARGS__) 111 #define STDEXEC_REPEAT_10(_MACRO, ...) \ 112 STDEXEC_REPEAT_9(_MACRO, __VA_ARGS__) _MACRO(9 __VA_OPT__(, ) __VA_ARGS__) 113