• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2020 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14 
15 // Many of these tests are static asserts. If these compile, they pass. The TEST
16 // functions are used for organization only.
17 
18 #include "pw_preprocessor/arguments.h"
19 
20 #include <tuple>
21 
22 #include "pw_unit_test/framework.h"
23 
24 namespace pw {
25 namespace {
26 
27 #define EMPTY_ARG
28 
TEST(HasArgs,WithoutArguments)29 TEST(HasArgs, WithoutArguments) {
30   static_assert(PW_HAS_ARGS() == 0);
31   static_assert(PW_HAS_ARGS(/**/) == 0);
32   static_assert(PW_HAS_ARGS(/* uhm, hi */) == 0);
33   static_assert(PW_HAS_ARGS(EMPTY_ARG) == 0);
34 
35   // Test how the macro handles whitespace and comments.
36   // clang-format off
37   static_assert(PW_HAS_ARGS(     ) == 0);
38   static_assert(PW_HAS_ARGS(
39       ) == 0);
40   static_assert(PW_HAS_ARGS(
41       // wow
42       // This is a comment.
43       ) == 0);
44   // clang-format on
45 
46   static_assert(PW_EMPTY_ARGS() == 1);
47   static_assert(PW_EMPTY_ARGS(/* hello */) == 1);
48   static_assert(PW_EMPTY_ARGS(
49                     // hello
50                     /* goodbye */) == 1);
51 }
52 
TEST(HasArgs,WithArguments)53 TEST(HasArgs, WithArguments) {
54   static_assert(PW_HAS_ARGS(()) == 1);
55   static_assert(PW_HAS_ARGS(0) == 1);
56   static_assert(PW_HAS_ARGS(, ) == 1);
57   static_assert(PW_HAS_ARGS(a, b, c) == 1);
58   static_assert(PW_HAS_ARGS(PW_HAS_ARGS) == 1);
59   static_assert(PW_HAS_ARGS(PW_HAS_ARGS()) == 1);
60 
61   static_assert(PW_EMPTY_ARGS(0) == 0);
62   static_assert(PW_EMPTY_ARGS(, ) == 0);
63   static_assert(PW_EMPTY_ARGS(a, b, c) == 0);
64   static_assert(PW_EMPTY_ARGS(PW_HAS_ARGS) == 0);
65   static_assert(PW_EMPTY_ARGS(PW_HAS_ARGS()) == 0);
66 }
67 
TestFunc(int arg,...)68 constexpr int TestFunc(int arg, ...) { return arg; }
69 
70 #define CALL_FUNCTION(arg, ...) TestFunc(arg PW_COMMA_ARGS(__VA_ARGS__))
71 
72 template <typename T, typename... Args>
TemplateArgCount()73 constexpr T TemplateArgCount() {
74   return sizeof...(Args);
75 }
76 
77 #define COUNT_ARGS_TEMPLATE(...) \
78   TemplateArgCount<int PW_COMMA_ARGS(__VA_ARGS__)>()
79 
TEST(CommaVarargs,NoArguments)80 TEST(CommaVarargs, NoArguments) {
81   static_assert(TestFunc(0 PW_COMMA_ARGS()) == 0);
82   static_assert(TestFunc(1 /* whoa */ PW_COMMA_ARGS(
83                     /* this macro */) /* is cool! */) == 1);
84 
85   static_assert(TemplateArgCount<int PW_COMMA_ARGS()>() == 0);
86   static_assert(TemplateArgCount<int PW_COMMA_ARGS(/* nothing */)>() == 0);
87 
88   static_assert(CALL_FUNCTION(2) == 2);
89   static_assert(CALL_FUNCTION(3, ) == 3);
90   static_assert(CALL_FUNCTION(4, /* nothing */) == 4);
91 
92   static_assert(COUNT_ARGS_TEMPLATE() == 0);
93   static_assert(COUNT_ARGS_TEMPLATE(/* nothing */) == 0);
94 }
95 
TEST(CommaVarargs,WithArguments)96 TEST(CommaVarargs, WithArguments) {
97   static_assert(TestFunc(0 PW_COMMA_ARGS(1)) == 0);
98   static_assert(TestFunc(1 PW_COMMA_ARGS(1, 2)) == 1);
99   static_assert(TestFunc(2 PW_COMMA_ARGS(1, 2, "three")) == 2);
100 
101   static_assert(TemplateArgCount<int PW_COMMA_ARGS(bool)>() == 1);
102   static_assert(TemplateArgCount<int PW_COMMA_ARGS(char, const char*)>() == 2);
103   static_assert(TemplateArgCount<int PW_COMMA_ARGS(int, char, const char*)>() ==
104                 3);
105 
106   static_assert(CALL_FUNCTION(3) == 3);
107   static_assert(CALL_FUNCTION(4, ) == 4);
108   static_assert(CALL_FUNCTION(5, /* nothing */) == 5);
109 
110   static_assert(COUNT_ARGS_TEMPLATE(int) == 1);
111   static_assert(COUNT_ARGS_TEMPLATE(int, int) == 2);
112   static_assert(COUNT_ARGS_TEMPLATE(int, int, int) == 3);
113 }
114 
TEST(CommaVarargs,EmptyFinalArgument)115 TEST(CommaVarargs, EmptyFinalArgument) {
116   static_assert(COUNT_ARGS_TEMPLATE(EMPTY_ARG) == 0);
117   static_assert(COUNT_ARGS_TEMPLATE(int, ) == 1);
118   static_assert(COUNT_ARGS_TEMPLATE(int, EMPTY_ARG) == 1);
119   static_assert(COUNT_ARGS_TEMPLATE(int, /* EMPTY_ARG */) == 1);
120   static_assert(COUNT_ARGS_TEMPLATE(int, int, ) == 2);
121   static_assert(COUNT_ARGS_TEMPLATE(int, int, int, ) == 3);
122   static_assert(COUNT_ARGS_TEMPLATE(int, int, int, EMPTY_ARG) == 3);
123 }
124 
125 // This test demonstrates that PW_COMMA_ARGS behaves unexpectedly when it is
126 // used when invoking another macro. DO NOT use PW_COMMA_ARGS when invoking
127 // another macro!
128 #define BAD_DEMO(fmt, ...) _BAD_DEMO_ADD_123(fmt PW_COMMA_ARGS(__VA_ARGS__))
129 
130 #define _BAD_DEMO_ADD_123(fmt, ...) \
131   _CAPTURE_ARGS_AS_TUPLE("%d: " fmt, 123 PW_COMMA_ARGS(__VA_ARGS__))
132 
133 #define _CAPTURE_ARGS_AS_TUPLE(...) std::make_tuple(__VA_ARGS__)
134 
TEST(CommaVarargs,MisbehavesWithMacroToMacroUse_NoArgs_ArgsAreOkay)135 TEST(CommaVarargs, MisbehavesWithMacroToMacroUse_NoArgs_ArgsAreOkay) {
136   auto [a1, a2] = BAD_DEMO("Hello world");
137   EXPECT_STREQ(a1, "%d: Hello world");
138   EXPECT_EQ(a2, 123);
139 }
140 
TEST(CommaVarargs,MisbehavesWithMacroToMacroUse_WithArgs_ArgsOutOfOrder)141 TEST(CommaVarargs, MisbehavesWithMacroToMacroUse_WithArgs_ArgsOutOfOrder) {
142   // If there is an additional argument, the order is incorrect! The 123
143   // argument should go before the "world?" argument, but it is inserted after.
144   // This would be a compilation error if these arguments were passed to printf.
145   // What's worse is that this can silently fail if the arguments happen to be
146   // compatible types.
147   const auto [a1, a2, a3] = BAD_DEMO("Hello %s", "world?");
148   EXPECT_STREQ(a1, "%d: Hello %s");
149   EXPECT_STREQ(a2, "world?");
150   EXPECT_EQ(a3, 123);
151 }
152 
TEST(CountArgs,Zero)153 TEST(CountArgs, Zero) {
154   static_assert(PW_MACRO_ARG_COUNT() == 0);
155   static_assert(PW_MACRO_ARG_COUNT(/**/) == 0);
156   static_assert(PW_MACRO_ARG_COUNT(/* uhm, hi */) == 0);
157 
158   // clang-format off
159   static_assert(PW_MACRO_ARG_COUNT(     ) == 0);
160   static_assert(PW_MACRO_ARG_COUNT(
161       ) == 0);
162   static_assert(PW_MACRO_ARG_COUNT(
163       // wow
164       // This is a comment.
165       ) == 0);
166   // clang-format on
167 }
168 
TEST(CountArgs,Commas)169 TEST(CountArgs, Commas) {
170   // clang-format off
171   static_assert(PW_MACRO_ARG_COUNT(,) == 2);
172   static_assert(PW_MACRO_ARG_COUNT(,,) == 3);
173   static_assert(PW_MACRO_ARG_COUNT(,,,) == 4);
174   // clang-format on
175   static_assert(PW_MACRO_ARG_COUNT(, ) == 2);
176   static_assert(PW_MACRO_ARG_COUNT(, , ) == 3);
177   static_assert(PW_MACRO_ARG_COUNT(, , , ) == 4);
178 
179   static_assert(PW_MACRO_ARG_COUNT(a, ) == 2);
180   static_assert(PW_MACRO_ARG_COUNT(a, , ) == 3);
181   static_assert(PW_MACRO_ARG_COUNT(a, b, c, ) == 4);
182 }
183 
TEST(CountArgs,Parentheses)184 TEST(CountArgs, Parentheses) {
185   static_assert(PW_MACRO_ARG_COUNT(()) == 1);
186   static_assert(PW_MACRO_ARG_COUNT((1, 2, 3, 4)) == 1);
187   static_assert(PW_MACRO_ARG_COUNT((1, 2, 3), (1, 2, 3, 4)) == 2);
188   static_assert(PW_MACRO_ARG_COUNT((), ()) == 2);
189   static_assert(PW_MACRO_ARG_COUNT((-), (o)) == 2);
190   static_assert(PW_MACRO_ARG_COUNT((, , (, , ), ), (123, 4)) == 2);
191   static_assert(PW_MACRO_ARG_COUNT(1, (2, 3, 4), (<5, 6>)) == 3);
192 }
193 
194 template <typename... Args>
FunctionArgCount(Args...)195 constexpr size_t FunctionArgCount(Args...) {
196   return sizeof...(Args);
197 }
198 
199 static_assert(FunctionArgCount() == 0);
200 static_assert(FunctionArgCount(1) == 1);
201 static_assert(FunctionArgCount(1, 2) == 2);
202 
TEST(CountFunctionArgs,NonEmptyLastArg)203 TEST(CountFunctionArgs, NonEmptyLastArg) {
204   static_assert(PW_FUNCTION_ARG_COUNT(a) == 1);
205   static_assert(PW_FUNCTION_ARG_COUNT(1, 2) == 2);
206   static_assert(PW_FUNCTION_ARG_COUNT(1, 2, 3) == 3);
207 }
208 
TEST(CountFunctionArgs,EmptyLastArg)209 TEST(CountFunctionArgs, EmptyLastArg) {
210   static_assert(PW_FUNCTION_ARG_COUNT() == 0);
211   static_assert(PW_FUNCTION_ARG_COUNT(a, ) == 1);
212   static_assert(PW_FUNCTION_ARG_COUNT(1, 2, ) == 2);
213   static_assert(PW_FUNCTION_ARG_COUNT(1, 2, 3, ) == 3);
214 
215   static_assert(PW_FUNCTION_ARG_COUNT(a, EMPTY_ARG) == 1);
216   static_assert(PW_FUNCTION_ARG_COUNT(1, 2, EMPTY_ARG) == 2);
217   static_assert(PW_FUNCTION_ARG_COUNT(1, 2, 3, EMPTY_ARG) == 3);
218 }
219 
Value(const char * str=nullptr)220 constexpr const char* Value(const char* str = nullptr) { return str; }
221 
TEST(LastArg,NonEmptyLastArg)222 TEST(LastArg, NonEmptyLastArg) {
223   constexpr const char* last = "last!";
224   static_assert(Value(PW_LAST_ARG(last)) == last);
225   static_assert(Value(PW_LAST_ARG(1, last)) == last);
226   static_assert(Value(PW_LAST_ARG(1, 2, last)) == last);
227 }
228 
TEST(LastArg,EmptyLastArg)229 TEST(LastArg, EmptyLastArg) {
230   static_assert(Value(PW_LAST_ARG()) == nullptr);
231   static_assert(Value(PW_LAST_ARG(1, )) == nullptr);
232   static_assert(Value(PW_LAST_ARG(1, 2, )) == nullptr);
233   static_assert(Value(PW_LAST_ARG(1, 2, 3, )) == nullptr);
234 }
235 
TEST(DropLastArg,NonEmptyLastArg)236 TEST(DropLastArg, NonEmptyLastArg) {
237   static_assert(FunctionArgCount(PW_DROP_LAST_ARG(1)) == 0);
238   static_assert(FunctionArgCount(PW_DROP_LAST_ARG(1, 2)) == 1);
239   static_assert(FunctionArgCount(PW_DROP_LAST_ARG(1, 2, 3)) == 2);
240 }
241 
TEST(DropLastArg,EmptyLastArg)242 TEST(DropLastArg, EmptyLastArg) {
243   static_assert(FunctionArgCount(PW_DROP_LAST_ARG()) == 0);
244   static_assert(FunctionArgCount(PW_DROP_LAST_ARG(1, )) == 1);
245   static_assert(FunctionArgCount(PW_DROP_LAST_ARG(1, 2, )) == 2);
246   static_assert(FunctionArgCount(PW_DROP_LAST_ARG(1, 2, 3, )) == 3);
247 }
248 
TEST(DropLastArgIfEmpty,NonEmptyLastArg)249 TEST(DropLastArgIfEmpty, NonEmptyLastArg) {
250   static_assert(FunctionArgCount(PW_DROP_LAST_ARG_IF_EMPTY(1)) == 1);
251   static_assert(FunctionArgCount(PW_DROP_LAST_ARG_IF_EMPTY(1, 2)) == 2);
252   static_assert(FunctionArgCount(PW_DROP_LAST_ARG_IF_EMPTY(1, 2, 3)) == 3);
253 }
254 
TEST(DropLastArgIfEmpty,EmptyLastArg)255 TEST(DropLastArgIfEmpty, EmptyLastArg) {
256   static_assert(FunctionArgCount(PW_DROP_LAST_ARG_IF_EMPTY()) == 0);
257   static_assert(FunctionArgCount(PW_DROP_LAST_ARG_IF_EMPTY(1, )) == 1);
258   static_assert(FunctionArgCount(PW_DROP_LAST_ARG_IF_EMPTY(1, 2, )) == 2);
259   static_assert(FunctionArgCount(PW_DROP_LAST_ARG_IF_EMPTY(1, 2, 3, )) == 3);
260 }
261 
262 // This test demonstrates that PW_DROP_LAST_ARG_IF_EMPTY behaves unexpectedly
263 // when it is used when invoking another macro. DO NOT use
264 // PW_DROP_LAST_ARG_IF_EMPTY when invoking another macro!
265 #define BAD_DROP_LAST_DEMO(fmt, ...) \
266   _BAD_DROP_LAST_DEMO_ADD_123(PW_DROP_LAST_ARG_IF_EMPTY(fmt, __VA_ARGS__))
267 
268 #define _BAD_DROP_LAST_DEMO_ADD_123(fmt, ...) \
269   _CAPTURE_ARGS_AS_TUPLE("%d: " fmt,          \
270                          PW_DROP_LAST_ARG_IF_EMPTY(123, __VA_ARGS__))
271 
TEST(DropLastArgIfEmpty,EmptyLastArgArgsLoseOrder)272 TEST(DropLastArgIfEmpty, EmptyLastArgArgsLoseOrder) {
273   // If there are any additional arguments, the order is incorrect! The 123
274   // argument should go before the 3, 2, 1 arguments, but it is inserted after.
275   // This would be a compilation error if these arguments were passed to printf.
276   // What's worse is that this can silently fail if the arguments happen to be
277   // compatible types.
278   auto [a1, a2, a3, a4, a5] =
279       BAD_DROP_LAST_DEMO("Countdown in %d %d %d", 3, 2, 1, );
280   EXPECT_STREQ(a1, "%d: Countdown in %d %d %d");
281   EXPECT_EQ(a2, 3);
282   EXPECT_EQ(a3, 2);
283   EXPECT_EQ(a4, 1);
284   EXPECT_EQ(a5, 123);
285 }
286 
TEST(DropLastArgIfEmpty,NonEmptyLastArgArgsLoseOrder)287 TEST(DropLastArgIfEmpty, NonEmptyLastArgArgsLoseOrder) {
288   // If there are any additional arguments, the order is incorrect! The 123
289   // argument should go before the 3, 2, 1 arguments, but it is inserted after.
290   // This would be a compilation error if these arguments were passed to printf.
291   // What's worse is that this can silently fail if the arguments happen to be
292   // compatible types.
293   auto [a1, a2, a3, a4, a5] =
294       BAD_DROP_LAST_DEMO("Countdown in %d %d %d", 3, 2, 1);
295   EXPECT_STREQ(a1, "%d: Countdown in %d %d %d");
296   EXPECT_EQ(a2, 3);
297   EXPECT_EQ(a3, 2);
298   EXPECT_EQ(a4, 1);
299   EXPECT_EQ(a5, 123);
300 }
301 
302 // When PW_DROP_LAST_ARG_IF_EMPTY is used once, and there are no other
303 // modifications to __VA_ARGS__, then the order is kept.
304 #define DROP_LAST_DEMO(fmt, arg_a, arg_b, ...) \
305   _CAPTURE_ARGS_AS_TUPLE(                      \
306       "%d: " fmt, PW_DROP_LAST_ARG_IF_EMPTY(123, arg_a, arg_b, __VA_ARGS__))
307 
TEST(DropLastArgIfEmpty,EmptyLastArgAllArgsInOrder)308 TEST(DropLastArgIfEmpty, EmptyLastArgAllArgsInOrder) {
309   const auto [a1, a2, a3, a4, a5] =
310       DROP_LAST_DEMO("Countdown in %d %d %d", 3, 2, 1, );
311   EXPECT_STREQ(a1, "%d: Countdown in %d %d %d");
312   EXPECT_EQ(a2, 123);
313   EXPECT_EQ(a3, 3);
314   EXPECT_EQ(a4, 2);
315   EXPECT_EQ(a5, 1);
316 }
317 
TEST(DropLastArgIfEmpty,NonEmptyLastArgAllArgsInOrder)318 TEST(DropLastArgIfEmpty, NonEmptyLastArgAllArgsInOrder) {
319   const auto [a1, a2, a3, a4, a5] =
320       DROP_LAST_DEMO("Countdown in %d %d %d", 3, 2, 1);
321   EXPECT_STREQ(a1, "%d: Countdown in %d %d %d");
322   EXPECT_EQ(a2, 123);
323   EXPECT_EQ(a3, 3);
324   EXPECT_EQ(a4, 2);
325   EXPECT_EQ(a5, 1);
326 }
327 
328 #define SOME_VARIADIC_MACRO(...) PW_MACRO_ARG_COUNT(__VA_ARGS__)
329 
330 #define ANOTHER_VARIADIC_MACRO(arg, ...) SOME_VARIADIC_MACRO(__VA_ARGS__)
331 
332 #define ALWAYS_ONE_ARG(...) SOME_VARIADIC_MACRO((__VA_ARGS__))
333 
TEST(CountArgs,NestedMacros)334 TEST(CountArgs, NestedMacros) {
335   static_assert(SOME_VARIADIC_MACRO() == 0);
336   static_assert(SOME_VARIADIC_MACRO(X1) == 1);
337   static_assert(SOME_VARIADIC_MACRO(X1, X2) == 2);
338   static_assert(SOME_VARIADIC_MACRO(X1, X2, X3) == 3);
339   static_assert(SOME_VARIADIC_MACRO(X1, X2, X3, X4) == 4);
340   static_assert(SOME_VARIADIC_MACRO(X1, X2, X3, X4, X5) == 5);
341 
342   static_assert(ANOTHER_VARIADIC_MACRO() == 0);
343   static_assert(ANOTHER_VARIADIC_MACRO(X0) == 0);
344   static_assert(ANOTHER_VARIADIC_MACRO(X0, X1) == 1);
345   static_assert(ANOTHER_VARIADIC_MACRO(X0, X1, X2) == 2);
346   static_assert(ANOTHER_VARIADIC_MACRO(X0, X1, X2, X3) == 3);
347   static_assert(ANOTHER_VARIADIC_MACRO(X0, X1, X2, X3, X4) == 4);
348   static_assert(ANOTHER_VARIADIC_MACRO(X0, X1, X2, X3, X4, X5) == 5);
349 
350   static_assert(ALWAYS_ONE_ARG() == 1);
351   static_assert(ALWAYS_ONE_ARG(X0) == 1);
352   static_assert(ALWAYS_ONE_ARG(X0, X1) == 1);
353   static_assert(ALWAYS_ONE_ARG(X0, X1, X2) == 1);
354   static_assert(ALWAYS_ONE_ARG(X0, X1, X2, X3) == 1);
355   static_assert(ALWAYS_ONE_ARG(X0, X1, X2, X3, X4) == 1);
356   static_assert(ALWAYS_ONE_ARG(X0, X1, X2, X3, X4, X5) == 1);
357 }
358 
359 /* Tests all supported arg counts. This test was generated by the following
360    Python 3 code:
361 for i in range(64 + 1):
362   args = [f'X{x}' for x in range(1, i + 1)]
363   print(f'  static_assert(PW_MACRO_ARG_COUNT({", ".join(args)}) == {i})  ')
364 */
TEST(CountArgs,AllSupported)365 TEST(CountArgs, AllSupported) {
366   // clang-format off
367   static_assert(PW_MACRO_ARG_COUNT() == 0);
368   static_assert(PW_MACRO_ARG_COUNT(X1) == 1);
369   static_assert(PW_MACRO_ARG_COUNT(X1, X2) == 2);
370   static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3) == 3);
371   static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3, X4) == 4);
372   static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3, X4, X5) == 5);
373   static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3, X4, X5, X6) == 6);
374   static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3, X4, X5, X6, X7) == 7);
375   static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3, X4, X5, X6, X7, X8) == 8);
376   static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3, X4, X5, X6, X7, X8, X9) == 9);
377   static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10) == 10);
378   static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11) == 11);
379   static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12) == 12);
380   static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13) == 13);
381   static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14) == 14);
382   static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15) == 15);
383   static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16) == 16);
384   static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17) == 17);
385   static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17, X18) == 18);
386   static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17, X18, X19) == 19);
387   static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17, X18, X19, X20) == 20);
388   static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17, X18, X19, X20, X21) == 21);
389   static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17, X18, X19, X20, X21, X22) == 22);
390   static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17, X18, X19, X20, X21, X22, X23) == 23);
391   static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17, X18, X19, X20, X21, X22, X23, X24) == 24);
392   static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17, X18, X19, X20, X21, X22, X23, X24, X25) == 25);
393   static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17, X18, X19, X20, X21, X22, X23, X24, X25, X26) == 26);
394   static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17, X18, X19, X20, X21, X22, X23, X24, X25, X26, X27) == 27);
395   static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17, X18, X19, X20, X21, X22, X23, X24, X25, X26, X27, X28) == 28);
396   static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17, X18, X19, X20, X21, X22, X23, X24, X25, X26, X27, X28, X29) == 29);
397   static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17, X18, X19, X20, X21, X22, X23, X24, X25, X26, X27, X28, X29, X30) == 30);
398   static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17, X18, X19, X20, X21, X22, X23, X24, X25, X26, X27, X28, X29, X30, X31) == 31);
399   static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17, X18, X19, X20, X21, X22, X23, X24, X25, X26, X27, X28, X29, X30, X31, X32) == 32);
400   static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17, X18, X19, X20, X21, X22, X23, X24, X25, X26, X27, X28, X29, X30, X31, X32, X33) == 33);
401   static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17, X18, X19, X20, X21, X22, X23, X24, X25, X26, X27, X28, X29, X30, X31, X32, X33, X34) == 34);
402   static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17, X18, X19, X20, X21, X22, X23, X24, X25, X26, X27, X28, X29, X30, X31, X32, X33, X34, X35) == 35);
403   static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17, X18, X19, X20, X21, X22, X23, X24, X25, X26, X27, X28, X29, X30, X31, X32, X33, X34, X35, X36) == 36);
404   static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17, X18, X19, X20, X21, X22, X23, X24, X25, X26, X27, X28, X29, X30, X31, X32, X33, X34, X35, X36, X37) == 37);
405   static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17, X18, X19, X20, X21, X22, X23, X24, X25, X26, X27, X28, X29, X30, X31, X32, X33, X34, X35, X36, X37, X38) == 38);
406   static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17, X18, X19, X20, X21, X22, X23, X24, X25, X26, X27, X28, X29, X30, X31, X32, X33, X34, X35, X36, X37, X38, X39) == 39);
407   static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17, X18, X19, X20, X21, X22, X23, X24, X25, X26, X27, X28, X29, X30, X31, X32, X33, X34, X35, X36, X37, X38, X39, X40) == 40);
408   static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17, X18, X19, X20, X21, X22, X23, X24, X25, X26, X27, X28, X29, X30, X31, X32, X33, X34, X35, X36, X37, X38, X39, X40, X41) == 41);
409   static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17, X18, X19, X20, X21, X22, X23, X24, X25, X26, X27, X28, X29, X30, X31, X32, X33, X34, X35, X36, X37, X38, X39, X40, X41, X42) == 42);
410   static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17, X18, X19, X20, X21, X22, X23, X24, X25, X26, X27, X28, X29, X30, X31, X32, X33, X34, X35, X36, X37, X38, X39, X40, X41, X42, X43) == 43);
411   static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17, X18, X19, X20, X21, X22, X23, X24, X25, X26, X27, X28, X29, X30, X31, X32, X33, X34, X35, X36, X37, X38, X39, X40, X41, X42, X43, X44) == 44);
412   static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17, X18, X19, X20, X21, X22, X23, X24, X25, X26, X27, X28, X29, X30, X31, X32, X33, X34, X35, X36, X37, X38, X39, X40, X41, X42, X43, X44, X45) == 45);
413   static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17, X18, X19, X20, X21, X22, X23, X24, X25, X26, X27, X28, X29, X30, X31, X32, X33, X34, X35, X36, X37, X38, X39, X40, X41, X42, X43, X44, X45, X46) == 46);
414   static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17, X18, X19, X20, X21, X22, X23, X24, X25, X26, X27, X28, X29, X30, X31, X32, X33, X34, X35, X36, X37, X38, X39, X40, X41, X42, X43, X44, X45, X46, X47) == 47);
415   static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17, X18, X19, X20, X21, X22, X23, X24, X25, X26, X27, X28, X29, X30, X31, X32, X33, X34, X35, X36, X37, X38, X39, X40, X41, X42, X43, X44, X45, X46, X47, X48) == 48);
416   static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17, X18, X19, X20, X21, X22, X23, X24, X25, X26, X27, X28, X29, X30, X31, X32, X33, X34, X35, X36, X37, X38, X39, X40, X41, X42, X43, X44, X45, X46, X47, X48, X49) == 49);
417   static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17, X18, X19, X20, X21, X22, X23, X24, X25, X26, X27, X28, X29, X30, X31, X32, X33, X34, X35, X36, X37, X38, X39, X40, X41, X42, X43, X44, X45, X46, X47, X48, X49, X50) == 50);
418   static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17, X18, X19, X20, X21, X22, X23, X24, X25, X26, X27, X28, X29, X30, X31, X32, X33, X34, X35, X36, X37, X38, X39, X40, X41, X42, X43, X44, X45, X46, X47, X48, X49, X50, X51) == 51);
419   static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17, X18, X19, X20, X21, X22, X23, X24, X25, X26, X27, X28, X29, X30, X31, X32, X33, X34, X35, X36, X37, X38, X39, X40, X41, X42, X43, X44, X45, X46, X47, X48, X49, X50, X51, X52) == 52);
420   static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17, X18, X19, X20, X21, X22, X23, X24, X25, X26, X27, X28, X29, X30, X31, X32, X33, X34, X35, X36, X37, X38, X39, X40, X41, X42, X43, X44, X45, X46, X47, X48, X49, X50, X51, X52, X53) == 53);
421   static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17, X18, X19, X20, X21, X22, X23, X24, X25, X26, X27, X28, X29, X30, X31, X32, X33, X34, X35, X36, X37, X38, X39, X40, X41, X42, X43, X44, X45, X46, X47, X48, X49, X50, X51, X52, X53, X54) == 54);
422   static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17, X18, X19, X20, X21, X22, X23, X24, X25, X26, X27, X28, X29, X30, X31, X32, X33, X34, X35, X36, X37, X38, X39, X40, X41, X42, X43, X44, X45, X46, X47, X48, X49, X50, X51, X52, X53, X54, X55) == 55);
423   static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17, X18, X19, X20, X21, X22, X23, X24, X25, X26, X27, X28, X29, X30, X31, X32, X33, X34, X35, X36, X37, X38, X39, X40, X41, X42, X43, X44, X45, X46, X47, X48, X49, X50, X51, X52, X53, X54, X55, X56) == 56);
424   static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17, X18, X19, X20, X21, X22, X23, X24, X25, X26, X27, X28, X29, X30, X31, X32, X33, X34, X35, X36, X37, X38, X39, X40, X41, X42, X43, X44, X45, X46, X47, X48, X49, X50, X51, X52, X53, X54, X55, X56, X57) == 57);
425   static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17, X18, X19, X20, X21, X22, X23, X24, X25, X26, X27, X28, X29, X30, X31, X32, X33, X34, X35, X36, X37, X38, X39, X40, X41, X42, X43, X44, X45, X46, X47, X48, X49, X50, X51, X52, X53, X54, X55, X56, X57, X58) == 58);
426   static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17, X18, X19, X20, X21, X22, X23, X24, X25, X26, X27, X28, X29, X30, X31, X32, X33, X34, X35, X36, X37, X38, X39, X40, X41, X42, X43, X44, X45, X46, X47, X48, X49, X50, X51, X52, X53, X54, X55, X56, X57, X58, X59) == 59);
427   static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17, X18, X19, X20, X21, X22, X23, X24, X25, X26, X27, X28, X29, X30, X31, X32, X33, X34, X35, X36, X37, X38, X39, X40, X41, X42, X43, X44, X45, X46, X47, X48, X49, X50, X51, X52, X53, X54, X55, X56, X57, X58, X59, X60) == 60);
428   static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17, X18, X19, X20, X21, X22, X23, X24, X25, X26, X27, X28, X29, X30, X31, X32, X33, X34, X35, X36, X37, X38, X39, X40, X41, X42, X43, X44, X45, X46, X47, X48, X49, X50, X51, X52, X53, X54, X55, X56, X57, X58, X59, X60, X61) == 61);
429   static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17, X18, X19, X20, X21, X22, X23, X24, X25, X26, X27, X28, X29, X30, X31, X32, X33, X34, X35, X36, X37, X38, X39, X40, X41, X42, X43, X44, X45, X46, X47, X48, X49, X50, X51, X52, X53, X54, X55, X56, X57, X58, X59, X60, X61, X62) == 62);
430   static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17, X18, X19, X20, X21, X22, X23, X24, X25, X26, X27, X28, X29, X30, X31, X32, X33, X34, X35, X36, X37, X38, X39, X40, X41, X42, X43, X44, X45, X46, X47, X48, X49, X50, X51, X52, X53, X54, X55, X56, X57, X58, X59, X60, X61, X62, X63) == 63);
431   static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17, X18, X19, X20, X21, X22, X23, X24, X25, X26, X27, X28, X29, X30, X31, X32, X33, X34, X35, X36, X37, X38, X39, X40, X41, X42, X43, X44, X45, X46, X47, X48, X49, X50, X51, X52, X53, X54, X55, X56, X57, X58, X59, X60, X61, X62, X63, X64) == 64);
432   // clang-format on
433 }
434 
TEST(DelegateByArgCount,WithoutAndWithoutArguments)435 TEST(DelegateByArgCount, WithoutAndWithoutArguments) {
436 #define TEST_SUM0() (0)
437 #define TEST_SUM1(a) (a)
438 #define TEST_SUM2(a, b) ((a) + (b))
439 #define TEST_SUM3(a, b, c) ((a) + (b) + (c))
440 
441   static_assert(PW_DELEGATE_BY_ARG_COUNT(TEST_SUM) == 0);
442   static_assert(PW_DELEGATE_BY_ARG_COUNT(TEST_SUM, 5) == 5);
443   static_assert(PW_DELEGATE_BY_ARG_COUNT(TEST_SUM, 1, 2) == 3);
444   static_assert(PW_DELEGATE_BY_ARG_COUNT(TEST_SUM, 1, 2, 3) == 6);
445 }
446 
447 }  // namespace
448 }  // namespace pw
449