|
41 | 41 | _24, _25, _26, _27, _28, _29, _30, _31, \ |
42 | 42 | _32, name, ...) name |
43 | 43 |
|
44 | | -/* Get the number of arguments (up to 32) */ |
45 | | - |
46 | | -#define GET_ARG_COUNT(...) \ |
| 44 | +/* Get the number of arguments (up to 32) |
| 45 | + * |
| 46 | + * C++ strict mode drops the GNU ", ##__VA_ARGS__" comma elision, which |
| 47 | + * would shift the selector off by one for the zero-argument case; use the |
| 48 | + * standard __VA_OPT__ there instead. This is the only place where the |
| 49 | + * empty-argument case needs special handling: every higher-level macro |
| 50 | + * (REVERSE_ARG, FOREACH_ARG, ...) dispatches on top of GET_ARG_COUNT. |
| 51 | + */ |
| 52 | + |
| 53 | +#if defined(__cplusplus) |
| 54 | +# define GET_ARG_COUNT(...) \ |
| 55 | + GET_ARG_VALUE(_0 __VA_OPT__(,) __VA_ARGS__, 32, 31, 30, \ |
| 56 | + 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, \ |
| 57 | + 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, \ |
| 58 | + 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) |
| 59 | +#else |
| 60 | +# define GET_ARG_COUNT(...) \ |
47 | 61 | GET_ARG_VALUE(_0, ##__VA_ARGS__, 32, 31, 30, \ |
48 | 62 | 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, \ |
49 | 63 | 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, \ |
50 | 64 | 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) |
| 65 | +#endif |
51 | 66 |
|
52 | 67 | /* Expand the arguments */ |
53 | 68 |
|
|
56 | 71 |
|
57 | 72 | /* Reverse the arguments */ |
58 | 73 |
|
59 | | -#define REVERSE_00() |
60 | | -#define REVERSE_01(a) a |
61 | | -#define REVERSE_02(a,b) b,a |
62 | | -#define REVERSE_03(a,...) EXPAND(REVERSE_02(__VA_ARGS__)),a |
63 | | -#define REVERSE_04(a,...) EXPAND(REVERSE_03(__VA_ARGS__)),a |
64 | | -#define REVERSE_05(a,...) EXPAND(REVERSE_04(__VA_ARGS__)),a |
65 | | -#define REVERSE_06(a,...) EXPAND(REVERSE_05(__VA_ARGS__)),a |
66 | | -#define REVERSE_07(a,...) EXPAND(REVERSE_06(__VA_ARGS__)),a |
67 | | -#define REVERSE_08(a,...) EXPAND(REVERSE_07(__VA_ARGS__)),a |
68 | | -#define REVERSE_09(a,...) EXPAND(REVERSE_08(__VA_ARGS__)),a |
69 | | -#define REVERSE_10(a,...) EXPAND(REVERSE_09(__VA_ARGS__)),a |
| 74 | +#define REVERSE_0() |
| 75 | +#define REVERSE_1(a) a |
| 76 | +#define REVERSE_2(a,b) b,a |
| 77 | +#define REVERSE_3(a,...) EXPAND(REVERSE_2(__VA_ARGS__)),a |
| 78 | +#define REVERSE_4(a,...) EXPAND(REVERSE_3(__VA_ARGS__)),a |
| 79 | +#define REVERSE_5(a,...) EXPAND(REVERSE_4(__VA_ARGS__)),a |
| 80 | +#define REVERSE_6(a,...) EXPAND(REVERSE_5(__VA_ARGS__)),a |
| 81 | +#define REVERSE_7(a,...) EXPAND(REVERSE_6(__VA_ARGS__)),a |
| 82 | +#define REVERSE_8(a,...) EXPAND(REVERSE_7(__VA_ARGS__)),a |
| 83 | +#define REVERSE_9(a,...) EXPAND(REVERSE_8(__VA_ARGS__)),a |
| 84 | +#define REVERSE_10(a,...) EXPAND(REVERSE_9(__VA_ARGS__)),a |
70 | 85 | #define REVERSE_11(a,...) EXPAND(REVERSE_10(__VA_ARGS__)),a |
71 | 86 | #define REVERSE_12(a,...) EXPAND(REVERSE_11(__VA_ARGS__)),a |
72 | 87 | #define REVERSE_13(a,...) EXPAND(REVERSE_12(__VA_ARGS__)),a |
|
90 | 105 | #define REVERSE_31(a,...) EXPAND(REVERSE_30(__VA_ARGS__)),a |
91 | 106 | #define REVERSE_32(a,...) EXPAND(REVERSE_31(__VA_ARGS__)),a |
92 | 107 |
|
93 | | -#define REVERSE_ARG_(...) \ |
94 | | - GET_ARG_VALUE(0, ##__VA_ARGS__, \ |
95 | | - REVERSE_32, REVERSE_31, REVERSE_30, REVERSE_29, REVERSE_28, REVERSE_27, \ |
96 | | - REVERSE_26, REVERSE_25, REVERSE_24, REVERSE_23, REVERSE_22, REVERSE_21, \ |
97 | | - REVERSE_20, REVERSE_19, REVERSE_18, REVERSE_17, REVERSE_16, REVERSE_15, \ |
98 | | - REVERSE_14, REVERSE_13, REVERSE_12, REVERSE_11, REVERSE_10, REVERSE_09, \ |
99 | | - REVERSE_08, REVERSE_07, REVERSE_06, REVERSE_05, REVERSE_04, REVERSE_03, \ |
100 | | - REVERSE_02, REVERSE_01, REVERSE_00)(__VA_ARGS__) |
| 108 | +/* Select the worker through GET_ARG_COUNT so the zero-argument case |
| 109 | + * expands correctly in both C and C++ (see GET_ARG_COUNT). |
| 110 | + */ |
101 | 111 |
|
102 | | -#define REVERSE_ARG(...) REVERSE_ARG_(##__VA_ARGS__) |
| 112 | +#define REVERSE_ARG(...) \ |
| 113 | + CONCATENATE(REVERSE_, GET_ARG_COUNT(__VA_ARGS__))(__VA_ARGS__) |
103 | 114 |
|
104 | 115 | /* Apply the macro to each argument */ |
105 | 116 |
|
106 | | -#define FOREACH_00(action, count, param, ...) 0 |
107 | | -#define FOREACH_01(action, count, param, arg, ...) action(param, arg, count - 1 ) |
108 | | -#define FOREACH_02(action, count, param, arg, ...) action(param, arg, count - 2 ) FOREACH_01(action, count, param, __VA_ARGS__) |
109 | | -#define FOREACH_03(action, count, param, arg, ...) action(param, arg, count - 3 ) FOREACH_02(action, count, param, __VA_ARGS__) |
110 | | -#define FOREACH_04(action, count, param, arg, ...) action(param, arg, count - 4 ) FOREACH_03(action, count, param, __VA_ARGS__) |
111 | | -#define FOREACH_05(action, count, param, arg, ...) action(param, arg, count - 5 ) FOREACH_04(action, count, param, __VA_ARGS__) |
112 | | -#define FOREACH_06(action, count, param, arg, ...) action(param, arg, count - 6 ) FOREACH_05(action, count, param, __VA_ARGS__) |
113 | | -#define FOREACH_07(action, count, param, arg, ...) action(param, arg, count - 7 ) FOREACH_06(action, count, param, __VA_ARGS__) |
114 | | -#define FOREACH_08(action, count, param, arg, ...) action(param, arg, count - 8 ) FOREACH_07(action, count, param, __VA_ARGS__) |
115 | | -#define FOREACH_09(action, count, param, arg, ...) action(param, arg, count - 9 ) FOREACH_08(action, count, param, __VA_ARGS__) |
116 | | -#define FOREACH_10(action, count, param, arg, ...) action(param, arg, count - 10) FOREACH_09(action, count, param, __VA_ARGS__) |
| 117 | +#define FOREACH_0(action, count, param, ...) 0 |
| 118 | +#define FOREACH_1(action, count, param, arg, ...) action(param, arg, count - 1 ) |
| 119 | +#define FOREACH_2(action, count, param, arg, ...) action(param, arg, count - 2 ) FOREACH_1(action, count, param, __VA_ARGS__) |
| 120 | +#define FOREACH_3(action, count, param, arg, ...) action(param, arg, count - 3 ) FOREACH_2(action, count, param, __VA_ARGS__) |
| 121 | +#define FOREACH_4(action, count, param, arg, ...) action(param, arg, count - 4 ) FOREACH_3(action, count, param, __VA_ARGS__) |
| 122 | +#define FOREACH_5(action, count, param, arg, ...) action(param, arg, count - 5 ) FOREACH_4(action, count, param, __VA_ARGS__) |
| 123 | +#define FOREACH_6(action, count, param, arg, ...) action(param, arg, count - 6 ) FOREACH_5(action, count, param, __VA_ARGS__) |
| 124 | +#define FOREACH_7(action, count, param, arg, ...) action(param, arg, count - 7 ) FOREACH_6(action, count, param, __VA_ARGS__) |
| 125 | +#define FOREACH_8(action, count, param, arg, ...) action(param, arg, count - 8 ) FOREACH_7(action, count, param, __VA_ARGS__) |
| 126 | +#define FOREACH_9(action, count, param, arg, ...) action(param, arg, count - 9 ) FOREACH_8(action, count, param, __VA_ARGS__) |
| 127 | +#define FOREACH_10(action, count, param, arg, ...) action(param, arg, count - 10) FOREACH_9(action, count, param, __VA_ARGS__) |
117 | 128 | #define FOREACH_11(action, count, param, arg, ...) action(param, arg, count - 11) FOREACH_10(action, count, param, __VA_ARGS__) |
118 | 129 | #define FOREACH_12(action, count, param, arg, ...) action(param, arg, count - 12) FOREACH_11(action, count, param, __VA_ARGS__) |
119 | 130 | #define FOREACH_13(action, count, param, arg, ...) action(param, arg, count - 13) FOREACH_12(action, count, param, __VA_ARGS__) |
|
138 | 149 | #define FOREACH_32(action, count, param, arg, ...) action(param, arg, count - 32) FOREACH_31(action, count, param, __VA_ARGS__) |
139 | 150 |
|
140 | 151 | #define FOREACH_ARG_(action, count, param, ...) \ |
141 | | - GET_ARG_VALUE(0, ##__VA_ARGS__, \ |
142 | | - FOREACH_32, FOREACH_31, FOREACH_30, FOREACH_29, FOREACH_28, FOREACH_27, \ |
143 | | - FOREACH_26, FOREACH_25, FOREACH_24, FOREACH_23, FOREACH_22, FOREACH_21, \ |
144 | | - FOREACH_20, FOREACH_19, FOREACH_18, FOREACH_17, FOREACH_16, FOREACH_15, \ |
145 | | - FOREACH_14, FOREACH_13, FOREACH_12, FOREACH_11, FOREACH_10, FOREACH_09, \ |
146 | | - FOREACH_08, FOREACH_07, FOREACH_06, FOREACH_05, FOREACH_04, FOREACH_03, \ |
147 | | - FOREACH_02, FOREACH_01, FOREACH_00)(action, count, param, ##__VA_ARGS__) |
| 152 | + CONCATENATE(FOREACH_, count)(action, count, param, __VA_ARGS__) |
148 | 153 |
|
149 | 154 | #define FOREACH_ARG(action, param, ...) \ |
150 | | - FOREACH_ARG_(action, GET_ARG_COUNT(__VA_ARGS__), param, ##__VA_ARGS__) |
| 155 | + FOREACH_ARG_(action, GET_ARG_COUNT(__VA_ARGS__), param, __VA_ARGS__) |
151 | 156 |
|
152 | 157 | #endif /* __INCLUDE_NUTTX_MACRO_H */ |
0 commit comments