xref: /openbmc/sdbusplus/include/sdbusplus/async/stdexec/__detail/__preprocessor.hpp (revision 10d0b4b7d1498cfd5c3d37edea271a54d1984e41)
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