1*61c4878aSAndroid Build Coastguard Worker // Copyright 2020 The Pigweed Authors
2*61c4878aSAndroid Build Coastguard Worker //
3*61c4878aSAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4*61c4878aSAndroid Build Coastguard Worker // use this file except in compliance with the License. You may obtain a copy of
5*61c4878aSAndroid Build Coastguard Worker // the License at
6*61c4878aSAndroid Build Coastguard Worker //
7*61c4878aSAndroid Build Coastguard Worker // https://www.apache.org/licenses/LICENSE-2.0
8*61c4878aSAndroid Build Coastguard Worker //
9*61c4878aSAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*61c4878aSAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11*61c4878aSAndroid Build Coastguard Worker // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12*61c4878aSAndroid Build Coastguard Worker // License for the specific language governing permissions and limitations under
13*61c4878aSAndroid Build Coastguard Worker // the License.
14*61c4878aSAndroid Build Coastguard Worker
15*61c4878aSAndroid Build Coastguard Worker // Many of these tests are static asserts. If these compile, they pass. The TEST
16*61c4878aSAndroid Build Coastguard Worker // functions are used for organization only.
17*61c4878aSAndroid Build Coastguard Worker
18*61c4878aSAndroid Build Coastguard Worker #include <tuple>
19*61c4878aSAndroid Build Coastguard Worker
20*61c4878aSAndroid Build Coastguard Worker #include "pw_preprocessor/apply.h"
21*61c4878aSAndroid Build Coastguard Worker #include "pw_unit_test/framework.h"
22*61c4878aSAndroid Build Coastguard Worker
23*61c4878aSAndroid Build Coastguard Worker namespace pw {
24*61c4878aSAndroid Build Coastguard Worker namespace {
25*61c4878aSAndroid Build Coastguard Worker
26*61c4878aSAndroid Build Coastguard Worker #define EMPTY_ARG
27*61c4878aSAndroid Build Coastguard Worker
TEST(HasArgs,WithoutArguments)28*61c4878aSAndroid Build Coastguard Worker TEST(HasArgs, WithoutArguments) {
29*61c4878aSAndroid Build Coastguard Worker static_assert(PW_HAS_ARGS() == 0);
30*61c4878aSAndroid Build Coastguard Worker static_assert(PW_HAS_ARGS(/**/) == 0);
31*61c4878aSAndroid Build Coastguard Worker static_assert(PW_HAS_ARGS(/* uhm, hi */) == 0);
32*61c4878aSAndroid Build Coastguard Worker static_assert(PW_HAS_ARGS(EMPTY_ARG) == 0);
33*61c4878aSAndroid Build Coastguard Worker
34*61c4878aSAndroid Build Coastguard Worker // Test how the macro handles whitespace and comments.
35*61c4878aSAndroid Build Coastguard Worker // clang-format off
36*61c4878aSAndroid Build Coastguard Worker static_assert(PW_HAS_ARGS( ) == 0);
37*61c4878aSAndroid Build Coastguard Worker static_assert(PW_HAS_ARGS(
38*61c4878aSAndroid Build Coastguard Worker ) == 0);
39*61c4878aSAndroid Build Coastguard Worker static_assert(PW_HAS_ARGS(
40*61c4878aSAndroid Build Coastguard Worker // wow
41*61c4878aSAndroid Build Coastguard Worker // This is a comment.
42*61c4878aSAndroid Build Coastguard Worker ) == 0);
43*61c4878aSAndroid Build Coastguard Worker // clang-format on
44*61c4878aSAndroid Build Coastguard Worker
45*61c4878aSAndroid Build Coastguard Worker static_assert(PW_EMPTY_ARGS() == 1);
46*61c4878aSAndroid Build Coastguard Worker static_assert(PW_EMPTY_ARGS(/* hello */) == 1);
47*61c4878aSAndroid Build Coastguard Worker static_assert(PW_EMPTY_ARGS(
48*61c4878aSAndroid Build Coastguard Worker // hello
49*61c4878aSAndroid Build Coastguard Worker /* goodbye */) == 1);
50*61c4878aSAndroid Build Coastguard Worker }
51*61c4878aSAndroid Build Coastguard Worker
TEST(HasArgs,WithArguments)52*61c4878aSAndroid Build Coastguard Worker TEST(HasArgs, WithArguments) {
53*61c4878aSAndroid Build Coastguard Worker static_assert(PW_HAS_ARGS(()) == 1);
54*61c4878aSAndroid Build Coastguard Worker static_assert(PW_HAS_ARGS(0) == 1);
55*61c4878aSAndroid Build Coastguard Worker static_assert(PW_HAS_ARGS(, ) == 1);
56*61c4878aSAndroid Build Coastguard Worker static_assert(PW_HAS_ARGS(a, b, c) == 1);
57*61c4878aSAndroid Build Coastguard Worker static_assert(PW_HAS_ARGS(PW_HAS_ARGS) == 1);
58*61c4878aSAndroid Build Coastguard Worker static_assert(PW_HAS_ARGS(PW_HAS_ARGS()) == 1);
59*61c4878aSAndroid Build Coastguard Worker
60*61c4878aSAndroid Build Coastguard Worker static_assert(PW_EMPTY_ARGS(0) == 0);
61*61c4878aSAndroid Build Coastguard Worker static_assert(PW_EMPTY_ARGS(, ) == 0);
62*61c4878aSAndroid Build Coastguard Worker static_assert(PW_EMPTY_ARGS(a, b, c) == 0);
63*61c4878aSAndroid Build Coastguard Worker static_assert(PW_EMPTY_ARGS(PW_HAS_ARGS) == 0);
64*61c4878aSAndroid Build Coastguard Worker static_assert(PW_EMPTY_ARGS(PW_HAS_ARGS()) == 0);
65*61c4878aSAndroid Build Coastguard Worker }
66*61c4878aSAndroid Build Coastguard Worker
TestFunc(int arg,...)67*61c4878aSAndroid Build Coastguard Worker constexpr int TestFunc(int arg, ...) { return arg; }
68*61c4878aSAndroid Build Coastguard Worker
69*61c4878aSAndroid Build Coastguard Worker #define CALL_FUNCTION(arg, ...) TestFunc(arg PW_COMMA_ARGS(__VA_ARGS__))
70*61c4878aSAndroid Build Coastguard Worker
71*61c4878aSAndroid Build Coastguard Worker template <typename T, typename... Args>
TemplateArgCount()72*61c4878aSAndroid Build Coastguard Worker constexpr T TemplateArgCount() {
73*61c4878aSAndroid Build Coastguard Worker return sizeof...(Args);
74*61c4878aSAndroid Build Coastguard Worker }
75*61c4878aSAndroid Build Coastguard Worker
76*61c4878aSAndroid Build Coastguard Worker #define COUNT_ARGS_TEMPLATE(...) \
77*61c4878aSAndroid Build Coastguard Worker TemplateArgCount<int PW_COMMA_ARGS(__VA_ARGS__)>()
78*61c4878aSAndroid Build Coastguard Worker
TEST(CommaVarargs,NoArguments)79*61c4878aSAndroid Build Coastguard Worker TEST(CommaVarargs, NoArguments) {
80*61c4878aSAndroid Build Coastguard Worker static_assert(TestFunc(0 PW_COMMA_ARGS()) == 0);
81*61c4878aSAndroid Build Coastguard Worker static_assert(TestFunc(1 /* whoa */ PW_COMMA_ARGS(
82*61c4878aSAndroid Build Coastguard Worker /* this macro */) /* is cool! */) == 1);
83*61c4878aSAndroid Build Coastguard Worker
84*61c4878aSAndroid Build Coastguard Worker static_assert(TemplateArgCount<int PW_COMMA_ARGS()>() == 0);
85*61c4878aSAndroid Build Coastguard Worker static_assert(TemplateArgCount<int PW_COMMA_ARGS(/* nothing */)>() == 0);
86*61c4878aSAndroid Build Coastguard Worker
87*61c4878aSAndroid Build Coastguard Worker static_assert(CALL_FUNCTION(2) == 2);
88*61c4878aSAndroid Build Coastguard Worker static_assert(CALL_FUNCTION(3, ) == 3);
89*61c4878aSAndroid Build Coastguard Worker static_assert(CALL_FUNCTION(4, /* nothing */) == 4);
90*61c4878aSAndroid Build Coastguard Worker
91*61c4878aSAndroid Build Coastguard Worker static_assert(COUNT_ARGS_TEMPLATE() == 0);
92*61c4878aSAndroid Build Coastguard Worker static_assert(COUNT_ARGS_TEMPLATE(/* nothing */) == 0);
93*61c4878aSAndroid Build Coastguard Worker }
94*61c4878aSAndroid Build Coastguard Worker
TEST(CommaVarargs,WithArguments)95*61c4878aSAndroid Build Coastguard Worker TEST(CommaVarargs, WithArguments) {
96*61c4878aSAndroid Build Coastguard Worker static_assert(TestFunc(0 PW_COMMA_ARGS(1)) == 0);
97*61c4878aSAndroid Build Coastguard Worker static_assert(TestFunc(1 PW_COMMA_ARGS(1, 2)) == 1);
98*61c4878aSAndroid Build Coastguard Worker static_assert(TestFunc(2 PW_COMMA_ARGS(1, 2, "three")) == 2);
99*61c4878aSAndroid Build Coastguard Worker
100*61c4878aSAndroid Build Coastguard Worker static_assert(TemplateArgCount<int PW_COMMA_ARGS(bool)>() == 1);
101*61c4878aSAndroid Build Coastguard Worker static_assert(TemplateArgCount<int PW_COMMA_ARGS(char, const char*)>() == 2);
102*61c4878aSAndroid Build Coastguard Worker static_assert(TemplateArgCount<int PW_COMMA_ARGS(int, char, const char*)>() ==
103*61c4878aSAndroid Build Coastguard Worker 3);
104*61c4878aSAndroid Build Coastguard Worker
105*61c4878aSAndroid Build Coastguard Worker static_assert(CALL_FUNCTION(3) == 3);
106*61c4878aSAndroid Build Coastguard Worker static_assert(CALL_FUNCTION(4, ) == 4);
107*61c4878aSAndroid Build Coastguard Worker static_assert(CALL_FUNCTION(5, /* nothing */) == 5);
108*61c4878aSAndroid Build Coastguard Worker
109*61c4878aSAndroid Build Coastguard Worker static_assert(COUNT_ARGS_TEMPLATE(int) == 1);
110*61c4878aSAndroid Build Coastguard Worker static_assert(COUNT_ARGS_TEMPLATE(int, int) == 2);
111*61c4878aSAndroid Build Coastguard Worker static_assert(COUNT_ARGS_TEMPLATE(int, int, int) == 3);
112*61c4878aSAndroid Build Coastguard Worker }
113*61c4878aSAndroid Build Coastguard Worker
TEST(CommaVarargs,EmptyFinalArgument)114*61c4878aSAndroid Build Coastguard Worker TEST(CommaVarargs, EmptyFinalArgument) {
115*61c4878aSAndroid Build Coastguard Worker static_assert(COUNT_ARGS_TEMPLATE(EMPTY_ARG) == 0);
116*61c4878aSAndroid Build Coastguard Worker static_assert(COUNT_ARGS_TEMPLATE(int, ) == 1);
117*61c4878aSAndroid Build Coastguard Worker static_assert(COUNT_ARGS_TEMPLATE(int, EMPTY_ARG) == 1);
118*61c4878aSAndroid Build Coastguard Worker static_assert(COUNT_ARGS_TEMPLATE(int, /* EMPTY_ARG */) == 1);
119*61c4878aSAndroid Build Coastguard Worker static_assert(COUNT_ARGS_TEMPLATE(int, int, ) == 2);
120*61c4878aSAndroid Build Coastguard Worker static_assert(COUNT_ARGS_TEMPLATE(int, int, int, ) == 3);
121*61c4878aSAndroid Build Coastguard Worker static_assert(COUNT_ARGS_TEMPLATE(int, int, int, EMPTY_ARG) == 3);
122*61c4878aSAndroid Build Coastguard Worker }
123*61c4878aSAndroid Build Coastguard Worker
124*61c4878aSAndroid Build Coastguard Worker // This test demonstrates that PW_COMMA_ARGS behaves unexpectedly when it is
125*61c4878aSAndroid Build Coastguard Worker // used when invoking another macro. DO NOT use PW_COMMA_ARGS when invoking
126*61c4878aSAndroid Build Coastguard Worker // another macro!
127*61c4878aSAndroid Build Coastguard Worker #define BAD_DEMO(fmt, ...) _BAD_DEMO_ADD_123(fmt PW_COMMA_ARGS(__VA_ARGS__))
128*61c4878aSAndroid Build Coastguard Worker
129*61c4878aSAndroid Build Coastguard Worker #define _BAD_DEMO_ADD_123(fmt, ...) \
130*61c4878aSAndroid Build Coastguard Worker _CAPTURE_ARGS_AS_TUPLE("%d: " fmt, 123 PW_COMMA_ARGS(__VA_ARGS__))
131*61c4878aSAndroid Build Coastguard Worker
132*61c4878aSAndroid Build Coastguard Worker #define _CAPTURE_ARGS_AS_TUPLE(...) std::make_tuple(__VA_ARGS__)
133*61c4878aSAndroid Build Coastguard Worker
TEST(CommaVarargs,MisbehavesWithMacroToMacroUse_NoArgs_ArgsAreOkay)134*61c4878aSAndroid Build Coastguard Worker TEST(CommaVarargs, MisbehavesWithMacroToMacroUse_NoArgs_ArgsAreOkay) {
135*61c4878aSAndroid Build Coastguard Worker auto [a1, a2] = BAD_DEMO("Hello world");
136*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ(a1, "%d: Hello world");
137*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(a2, 123);
138*61c4878aSAndroid Build Coastguard Worker }
139*61c4878aSAndroid Build Coastguard Worker
TEST(CommaVarargs,MisbehavesWithMacroToMacroUse_WithArgs_ArgsOutOfOrder)140*61c4878aSAndroid Build Coastguard Worker TEST(CommaVarargs, MisbehavesWithMacroToMacroUse_WithArgs_ArgsOutOfOrder) {
141*61c4878aSAndroid Build Coastguard Worker // If there is an additional argument, the order is incorrect! The 123
142*61c4878aSAndroid Build Coastguard Worker // argument should go before the "world?" argument, but it is inserted after.
143*61c4878aSAndroid Build Coastguard Worker // This would be a compilation error if these arguments were passed to printf.
144*61c4878aSAndroid Build Coastguard Worker // What's worse is that this can silently fail if the arguments happen to be
145*61c4878aSAndroid Build Coastguard Worker // compatible types.
146*61c4878aSAndroid Build Coastguard Worker const auto [a1, a2, a3] = BAD_DEMO("Hello %s", "world?");
147*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ(a1, "%d: Hello %s");
148*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ(a2, "world?");
149*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(a3, 123);
150*61c4878aSAndroid Build Coastguard Worker }
151*61c4878aSAndroid Build Coastguard Worker
TEST(CountArgs,Zero)152*61c4878aSAndroid Build Coastguard Worker TEST(CountArgs, Zero) {
153*61c4878aSAndroid Build Coastguard Worker static_assert(PW_MACRO_ARG_COUNT() == 0);
154*61c4878aSAndroid Build Coastguard Worker static_assert(PW_MACRO_ARG_COUNT(/**/) == 0);
155*61c4878aSAndroid Build Coastguard Worker static_assert(PW_MACRO_ARG_COUNT(/* uhm, hi */) == 0);
156*61c4878aSAndroid Build Coastguard Worker
157*61c4878aSAndroid Build Coastguard Worker // clang-format off
158*61c4878aSAndroid Build Coastguard Worker static_assert(PW_MACRO_ARG_COUNT( ) == 0);
159*61c4878aSAndroid Build Coastguard Worker static_assert(PW_MACRO_ARG_COUNT(
160*61c4878aSAndroid Build Coastguard Worker ) == 0);
161*61c4878aSAndroid Build Coastguard Worker static_assert(PW_MACRO_ARG_COUNT(
162*61c4878aSAndroid Build Coastguard Worker // wow
163*61c4878aSAndroid Build Coastguard Worker // This is a comment.
164*61c4878aSAndroid Build Coastguard Worker ) == 0);
165*61c4878aSAndroid Build Coastguard Worker // clang-format on
166*61c4878aSAndroid Build Coastguard Worker }
167*61c4878aSAndroid Build Coastguard Worker
TEST(CountArgs,Commas)168*61c4878aSAndroid Build Coastguard Worker TEST(CountArgs, Commas) {
169*61c4878aSAndroid Build Coastguard Worker // clang-format off
170*61c4878aSAndroid Build Coastguard Worker static_assert(PW_MACRO_ARG_COUNT(,) == 2);
171*61c4878aSAndroid Build Coastguard Worker static_assert(PW_MACRO_ARG_COUNT(,,) == 3);
172*61c4878aSAndroid Build Coastguard Worker static_assert(PW_MACRO_ARG_COUNT(,,,) == 4);
173*61c4878aSAndroid Build Coastguard Worker // clang-format on
174*61c4878aSAndroid Build Coastguard Worker static_assert(PW_MACRO_ARG_COUNT(, ) == 2);
175*61c4878aSAndroid Build Coastguard Worker static_assert(PW_MACRO_ARG_COUNT(, , ) == 3);
176*61c4878aSAndroid Build Coastguard Worker static_assert(PW_MACRO_ARG_COUNT(, , , ) == 4);
177*61c4878aSAndroid Build Coastguard Worker
178*61c4878aSAndroid Build Coastguard Worker static_assert(PW_MACRO_ARG_COUNT(a, ) == 2);
179*61c4878aSAndroid Build Coastguard Worker static_assert(PW_MACRO_ARG_COUNT(a, , ) == 3);
180*61c4878aSAndroid Build Coastguard Worker static_assert(PW_MACRO_ARG_COUNT(a, b, c, ) == 4);
181*61c4878aSAndroid Build Coastguard Worker }
182*61c4878aSAndroid Build Coastguard Worker
TEST(CountArgs,Parentheses)183*61c4878aSAndroid Build Coastguard Worker TEST(CountArgs, Parentheses) {
184*61c4878aSAndroid Build Coastguard Worker static_assert(PW_MACRO_ARG_COUNT(()) == 1);
185*61c4878aSAndroid Build Coastguard Worker static_assert(PW_MACRO_ARG_COUNT((1, 2, 3, 4)) == 1);
186*61c4878aSAndroid Build Coastguard Worker static_assert(PW_MACRO_ARG_COUNT((1, 2, 3), (1, 2, 3, 4)) == 2);
187*61c4878aSAndroid Build Coastguard Worker static_assert(PW_MACRO_ARG_COUNT((), ()) == 2);
188*61c4878aSAndroid Build Coastguard Worker static_assert(PW_MACRO_ARG_COUNT((-), (o)) == 2);
189*61c4878aSAndroid Build Coastguard Worker static_assert(PW_MACRO_ARG_COUNT((, , (, , ), ), (123, 4)) == 2);
190*61c4878aSAndroid Build Coastguard Worker static_assert(PW_MACRO_ARG_COUNT(1, (2, 3, 4), (<5, 6>)) == 3);
191*61c4878aSAndroid Build Coastguard Worker }
192*61c4878aSAndroid Build Coastguard Worker
193*61c4878aSAndroid Build Coastguard Worker template <typename... Args>
FunctionArgCount(Args...)194*61c4878aSAndroid Build Coastguard Worker constexpr size_t FunctionArgCount(Args...) {
195*61c4878aSAndroid Build Coastguard Worker return sizeof...(Args);
196*61c4878aSAndroid Build Coastguard Worker }
197*61c4878aSAndroid Build Coastguard Worker
198*61c4878aSAndroid Build Coastguard Worker static_assert(FunctionArgCount() == 0);
199*61c4878aSAndroid Build Coastguard Worker static_assert(FunctionArgCount(1) == 1);
200*61c4878aSAndroid Build Coastguard Worker static_assert(FunctionArgCount(1, 2) == 2);
201*61c4878aSAndroid Build Coastguard Worker
TEST(CountFunctionArgs,NonEmptyLastArg)202*61c4878aSAndroid Build Coastguard Worker TEST(CountFunctionArgs, NonEmptyLastArg) {
203*61c4878aSAndroid Build Coastguard Worker static_assert(PW_FUNCTION_ARG_COUNT(a) == 1);
204*61c4878aSAndroid Build Coastguard Worker static_assert(PW_FUNCTION_ARG_COUNT(1, 2) == 2);
205*61c4878aSAndroid Build Coastguard Worker static_assert(PW_FUNCTION_ARG_COUNT(1, 2, 3) == 3);
206*61c4878aSAndroid Build Coastguard Worker }
207*61c4878aSAndroid Build Coastguard Worker
TEST(CountFunctionArgs,EmptyLastArg)208*61c4878aSAndroid Build Coastguard Worker TEST(CountFunctionArgs, EmptyLastArg) {
209*61c4878aSAndroid Build Coastguard Worker static_assert(PW_FUNCTION_ARG_COUNT() == 0);
210*61c4878aSAndroid Build Coastguard Worker static_assert(PW_FUNCTION_ARG_COUNT(a, ) == 1);
211*61c4878aSAndroid Build Coastguard Worker static_assert(PW_FUNCTION_ARG_COUNT(1, 2, ) == 2);
212*61c4878aSAndroid Build Coastguard Worker static_assert(PW_FUNCTION_ARG_COUNT(1, 2, 3, ) == 3);
213*61c4878aSAndroid Build Coastguard Worker
214*61c4878aSAndroid Build Coastguard Worker static_assert(PW_FUNCTION_ARG_COUNT(a, EMPTY_ARG) == 1);
215*61c4878aSAndroid Build Coastguard Worker static_assert(PW_FUNCTION_ARG_COUNT(1, 2, EMPTY_ARG) == 2);
216*61c4878aSAndroid Build Coastguard Worker static_assert(PW_FUNCTION_ARG_COUNT(1, 2, 3, EMPTY_ARG) == 3);
217*61c4878aSAndroid Build Coastguard Worker }
218*61c4878aSAndroid Build Coastguard Worker
Value(const char * str=nullptr)219*61c4878aSAndroid Build Coastguard Worker constexpr const char* Value(const char* str = nullptr) { return str; }
220*61c4878aSAndroid Build Coastguard Worker
TEST(LastArg,NonEmptyLastArg)221*61c4878aSAndroid Build Coastguard Worker TEST(LastArg, NonEmptyLastArg) {
222*61c4878aSAndroid Build Coastguard Worker constexpr const char* last = "last!";
223*61c4878aSAndroid Build Coastguard Worker static_assert(Value(PW_LAST_ARG(last)) == last);
224*61c4878aSAndroid Build Coastguard Worker static_assert(Value(PW_LAST_ARG(1, last)) == last);
225*61c4878aSAndroid Build Coastguard Worker static_assert(Value(PW_LAST_ARG(1, 2, last)) == last);
226*61c4878aSAndroid Build Coastguard Worker }
227*61c4878aSAndroid Build Coastguard Worker
TEST(LastArg,EmptyLastArg)228*61c4878aSAndroid Build Coastguard Worker TEST(LastArg, EmptyLastArg) {
229*61c4878aSAndroid Build Coastguard Worker static_assert(Value(PW_LAST_ARG()) == nullptr);
230*61c4878aSAndroid Build Coastguard Worker static_assert(Value(PW_LAST_ARG(1, )) == nullptr);
231*61c4878aSAndroid Build Coastguard Worker static_assert(Value(PW_LAST_ARG(1, 2, )) == nullptr);
232*61c4878aSAndroid Build Coastguard Worker static_assert(Value(PW_LAST_ARG(1, 2, 3, )) == nullptr);
233*61c4878aSAndroid Build Coastguard Worker }
234*61c4878aSAndroid Build Coastguard Worker
TEST(DropLastArg,NonEmptyLastArg)235*61c4878aSAndroid Build Coastguard Worker TEST(DropLastArg, NonEmptyLastArg) {
236*61c4878aSAndroid Build Coastguard Worker static_assert(FunctionArgCount(PW_DROP_LAST_ARG(1)) == 0);
237*61c4878aSAndroid Build Coastguard Worker static_assert(FunctionArgCount(PW_DROP_LAST_ARG(1, 2)) == 1);
238*61c4878aSAndroid Build Coastguard Worker static_assert(FunctionArgCount(PW_DROP_LAST_ARG(1, 2, 3)) == 2);
239*61c4878aSAndroid Build Coastguard Worker }
240*61c4878aSAndroid Build Coastguard Worker
TEST(DropLastArg,EmptyLastArg)241*61c4878aSAndroid Build Coastguard Worker TEST(DropLastArg, EmptyLastArg) {
242*61c4878aSAndroid Build Coastguard Worker static_assert(FunctionArgCount(PW_DROP_LAST_ARG()) == 0);
243*61c4878aSAndroid Build Coastguard Worker static_assert(FunctionArgCount(PW_DROP_LAST_ARG(1, )) == 1);
244*61c4878aSAndroid Build Coastguard Worker static_assert(FunctionArgCount(PW_DROP_LAST_ARG(1, 2, )) == 2);
245*61c4878aSAndroid Build Coastguard Worker static_assert(FunctionArgCount(PW_DROP_LAST_ARG(1, 2, 3, )) == 3);
246*61c4878aSAndroid Build Coastguard Worker }
247*61c4878aSAndroid Build Coastguard Worker
TEST(DropLastArgIfEmpty,NonEmptyLastArg)248*61c4878aSAndroid Build Coastguard Worker TEST(DropLastArgIfEmpty, NonEmptyLastArg) {
249*61c4878aSAndroid Build Coastguard Worker static_assert(FunctionArgCount(PW_DROP_LAST_ARG_IF_EMPTY(1)) == 1);
250*61c4878aSAndroid Build Coastguard Worker static_assert(FunctionArgCount(PW_DROP_LAST_ARG_IF_EMPTY(1, 2)) == 2);
251*61c4878aSAndroid Build Coastguard Worker static_assert(FunctionArgCount(PW_DROP_LAST_ARG_IF_EMPTY(1, 2, 3)) == 3);
252*61c4878aSAndroid Build Coastguard Worker }
253*61c4878aSAndroid Build Coastguard Worker
TEST(DropLastArgIfEmpty,EmptyLastArg)254*61c4878aSAndroid Build Coastguard Worker TEST(DropLastArgIfEmpty, EmptyLastArg) {
255*61c4878aSAndroid Build Coastguard Worker static_assert(FunctionArgCount(PW_DROP_LAST_ARG_IF_EMPTY()) == 0);
256*61c4878aSAndroid Build Coastguard Worker static_assert(FunctionArgCount(PW_DROP_LAST_ARG_IF_EMPTY(1, )) == 1);
257*61c4878aSAndroid Build Coastguard Worker static_assert(FunctionArgCount(PW_DROP_LAST_ARG_IF_EMPTY(1, 2, )) == 2);
258*61c4878aSAndroid Build Coastguard Worker static_assert(FunctionArgCount(PW_DROP_LAST_ARG_IF_EMPTY(1, 2, 3, )) == 3);
259*61c4878aSAndroid Build Coastguard Worker }
260*61c4878aSAndroid Build Coastguard Worker
261*61c4878aSAndroid Build Coastguard Worker // This test demonstrates that PW_DROP_LAST_ARG_IF_EMPTY behaves unexpectedly
262*61c4878aSAndroid Build Coastguard Worker // when it is used when invoking another macro. DO NOT use
263*61c4878aSAndroid Build Coastguard Worker // PW_DROP_LAST_ARG_IF_EMPTY when invoking another macro!
264*61c4878aSAndroid Build Coastguard Worker #define BAD_DROP_LAST_DEMO(fmt, ...) \
265*61c4878aSAndroid Build Coastguard Worker _BAD_DROP_LAST_DEMO_ADD_123(PW_DROP_LAST_ARG_IF_EMPTY(fmt, __VA_ARGS__))
266*61c4878aSAndroid Build Coastguard Worker
267*61c4878aSAndroid Build Coastguard Worker #define _BAD_DROP_LAST_DEMO_ADD_123(fmt, ...) \
268*61c4878aSAndroid Build Coastguard Worker _CAPTURE_ARGS_AS_TUPLE("%d: " fmt, \
269*61c4878aSAndroid Build Coastguard Worker PW_DROP_LAST_ARG_IF_EMPTY(123, __VA_ARGS__))
270*61c4878aSAndroid Build Coastguard Worker
TEST(DropLastArgIfEmpty,EmptyLastArgArgsLoseOrder)271*61c4878aSAndroid Build Coastguard Worker TEST(DropLastArgIfEmpty, EmptyLastArgArgsLoseOrder) {
272*61c4878aSAndroid Build Coastguard Worker // If there are any additional arguments, the order is incorrect! The 123
273*61c4878aSAndroid Build Coastguard Worker // argument should go before the 3, 2, 1 arguments, but it is inserted after.
274*61c4878aSAndroid Build Coastguard Worker // This would be a compilation error if these arguments were passed to printf.
275*61c4878aSAndroid Build Coastguard Worker // What's worse is that this can silently fail if the arguments happen to be
276*61c4878aSAndroid Build Coastguard Worker // compatible types.
277*61c4878aSAndroid Build Coastguard Worker auto [a1, a2, a3, a4, a5] =
278*61c4878aSAndroid Build Coastguard Worker BAD_DROP_LAST_DEMO("Countdown in %d %d %d", 3, 2, 1, );
279*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ(a1, "%d: Countdown in %d %d %d");
280*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(a2, 3);
281*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(a3, 2);
282*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(a4, 1);
283*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(a5, 123);
284*61c4878aSAndroid Build Coastguard Worker }
285*61c4878aSAndroid Build Coastguard Worker
TEST(DropLastArgIfEmpty,NonEmptyLastArgArgsLoseOrder)286*61c4878aSAndroid Build Coastguard Worker TEST(DropLastArgIfEmpty, NonEmptyLastArgArgsLoseOrder) {
287*61c4878aSAndroid Build Coastguard Worker // If there are any additional arguments, the order is incorrect! The 123
288*61c4878aSAndroid Build Coastguard Worker // argument should go before the 3, 2, 1 arguments, but it is inserted after.
289*61c4878aSAndroid Build Coastguard Worker // This would be a compilation error if these arguments were passed to printf.
290*61c4878aSAndroid Build Coastguard Worker // What's worse is that this can silently fail if the arguments happen to be
291*61c4878aSAndroid Build Coastguard Worker // compatible types.
292*61c4878aSAndroid Build Coastguard Worker auto [a1, a2, a3, a4, a5] =
293*61c4878aSAndroid Build Coastguard Worker BAD_DROP_LAST_DEMO("Countdown in %d %d %d", 3, 2, 1);
294*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ(a1, "%d: Countdown in %d %d %d");
295*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(a2, 3);
296*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(a3, 2);
297*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(a4, 1);
298*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(a5, 123);
299*61c4878aSAndroid Build Coastguard Worker }
300*61c4878aSAndroid Build Coastguard Worker
301*61c4878aSAndroid Build Coastguard Worker // When PW_DROP_LAST_ARG_IF_EMPTY is used once, and there are no other
302*61c4878aSAndroid Build Coastguard Worker // modifications to __VA_ARGS__, then the order is kept.
303*61c4878aSAndroid Build Coastguard Worker #define DROP_LAST_DEMO(fmt, arg_a, arg_b, ...) \
304*61c4878aSAndroid Build Coastguard Worker _CAPTURE_ARGS_AS_TUPLE( \
305*61c4878aSAndroid Build Coastguard Worker "%d: " fmt, PW_DROP_LAST_ARG_IF_EMPTY(123, arg_a, arg_b, __VA_ARGS__))
306*61c4878aSAndroid Build Coastguard Worker
TEST(DropLastArgIfEmpty,EmptyLastArgAllArgsInOrder)307*61c4878aSAndroid Build Coastguard Worker TEST(DropLastArgIfEmpty, EmptyLastArgAllArgsInOrder) {
308*61c4878aSAndroid Build Coastguard Worker const auto [a1, a2, a3, a4, a5] =
309*61c4878aSAndroid Build Coastguard Worker DROP_LAST_DEMO("Countdown in %d %d %d", 3, 2, 1, );
310*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ(a1, "%d: Countdown in %d %d %d");
311*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(a2, 123);
312*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(a3, 3);
313*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(a4, 2);
314*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(a5, 1);
315*61c4878aSAndroid Build Coastguard Worker }
316*61c4878aSAndroid Build Coastguard Worker
TEST(DropLastArgIfEmpty,NonEmptyLastArgAllArgsInOrder)317*61c4878aSAndroid Build Coastguard Worker TEST(DropLastArgIfEmpty, NonEmptyLastArgAllArgsInOrder) {
318*61c4878aSAndroid Build Coastguard Worker const auto [a1, a2, a3, a4, a5] =
319*61c4878aSAndroid Build Coastguard Worker DROP_LAST_DEMO("Countdown in %d %d %d", 3, 2, 1);
320*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ(a1, "%d: Countdown in %d %d %d");
321*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(a2, 123);
322*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(a3, 3);
323*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(a4, 2);
324*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(a5, 1);
325*61c4878aSAndroid Build Coastguard Worker }
326*61c4878aSAndroid Build Coastguard Worker
327*61c4878aSAndroid Build Coastguard Worker #define SOME_VARIADIC_MACRO(...) PW_MACRO_ARG_COUNT(__VA_ARGS__)
328*61c4878aSAndroid Build Coastguard Worker
329*61c4878aSAndroid Build Coastguard Worker #define ANOTHER_VARIADIC_MACRO(arg, ...) SOME_VARIADIC_MACRO(__VA_ARGS__)
330*61c4878aSAndroid Build Coastguard Worker
331*61c4878aSAndroid Build Coastguard Worker #define ALWAYS_ONE_ARG(...) SOME_VARIADIC_MACRO((__VA_ARGS__))
332*61c4878aSAndroid Build Coastguard Worker
TEST(CountArgs,NestedMacros)333*61c4878aSAndroid Build Coastguard Worker TEST(CountArgs, NestedMacros) {
334*61c4878aSAndroid Build Coastguard Worker static_assert(SOME_VARIADIC_MACRO() == 0);
335*61c4878aSAndroid Build Coastguard Worker static_assert(SOME_VARIADIC_MACRO(X1) == 1);
336*61c4878aSAndroid Build Coastguard Worker static_assert(SOME_VARIADIC_MACRO(X1, X2) == 2);
337*61c4878aSAndroid Build Coastguard Worker static_assert(SOME_VARIADIC_MACRO(X1, X2, X3) == 3);
338*61c4878aSAndroid Build Coastguard Worker static_assert(SOME_VARIADIC_MACRO(X1, X2, X3, X4) == 4);
339*61c4878aSAndroid Build Coastguard Worker static_assert(SOME_VARIADIC_MACRO(X1, X2, X3, X4, X5) == 5);
340*61c4878aSAndroid Build Coastguard Worker
341*61c4878aSAndroid Build Coastguard Worker static_assert(ANOTHER_VARIADIC_MACRO() == 0);
342*61c4878aSAndroid Build Coastguard Worker static_assert(ANOTHER_VARIADIC_MACRO(X0) == 0);
343*61c4878aSAndroid Build Coastguard Worker static_assert(ANOTHER_VARIADIC_MACRO(X0, X1) == 1);
344*61c4878aSAndroid Build Coastguard Worker static_assert(ANOTHER_VARIADIC_MACRO(X0, X1, X2) == 2);
345*61c4878aSAndroid Build Coastguard Worker static_assert(ANOTHER_VARIADIC_MACRO(X0, X1, X2, X3) == 3);
346*61c4878aSAndroid Build Coastguard Worker static_assert(ANOTHER_VARIADIC_MACRO(X0, X1, X2, X3, X4) == 4);
347*61c4878aSAndroid Build Coastguard Worker static_assert(ANOTHER_VARIADIC_MACRO(X0, X1, X2, X3, X4, X5) == 5);
348*61c4878aSAndroid Build Coastguard Worker
349*61c4878aSAndroid Build Coastguard Worker static_assert(ALWAYS_ONE_ARG() == 1);
350*61c4878aSAndroid Build Coastguard Worker static_assert(ALWAYS_ONE_ARG(X0) == 1);
351*61c4878aSAndroid Build Coastguard Worker static_assert(ALWAYS_ONE_ARG(X0, X1) == 1);
352*61c4878aSAndroid Build Coastguard Worker static_assert(ALWAYS_ONE_ARG(X0, X1, X2) == 1);
353*61c4878aSAndroid Build Coastguard Worker static_assert(ALWAYS_ONE_ARG(X0, X1, X2, X3) == 1);
354*61c4878aSAndroid Build Coastguard Worker static_assert(ALWAYS_ONE_ARG(X0, X1, X2, X3, X4) == 1);
355*61c4878aSAndroid Build Coastguard Worker static_assert(ALWAYS_ONE_ARG(X0, X1, X2, X3, X4, X5) == 1);
356*61c4878aSAndroid Build Coastguard Worker }
357*61c4878aSAndroid Build Coastguard Worker
358*61c4878aSAndroid Build Coastguard Worker /* Tests all supported arg counts. This test was generated by the following
359*61c4878aSAndroid Build Coastguard Worker Python 3 code:
360*61c4878aSAndroid Build Coastguard Worker for i in range(256 + 1):
361*61c4878aSAndroid Build Coastguard Worker args = [f'X{x}' for x in range(1, i + 1)]
362*61c4878aSAndroid Build Coastguard Worker print(f' static_assert(PW_MACRO_ARG_COUNT({", ".join(args)}) == {i});')
363*61c4878aSAndroid Build Coastguard Worker */
364*61c4878aSAndroid Build Coastguard Worker // Most tests above 16 arguments were skipped to keep this a reasonable size.
TEST(CountArgs,AllSupported)365*61c4878aSAndroid Build Coastguard Worker TEST(CountArgs, AllSupported) {
366*61c4878aSAndroid Build Coastguard Worker // clang-format off
367*61c4878aSAndroid Build Coastguard Worker static_assert(PW_MACRO_ARG_COUNT() == 0);
368*61c4878aSAndroid Build Coastguard Worker static_assert(PW_MACRO_ARG_COUNT(X1) == 1);
369*61c4878aSAndroid Build Coastguard Worker static_assert(PW_MACRO_ARG_COUNT(X1, X2) == 2);
370*61c4878aSAndroid Build Coastguard Worker static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3) == 3);
371*61c4878aSAndroid Build Coastguard Worker static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3, X4) == 4);
372*61c4878aSAndroid Build Coastguard Worker static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3, X4, X5) == 5);
373*61c4878aSAndroid Build Coastguard Worker static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3, X4, X5, X6) == 6);
374*61c4878aSAndroid Build Coastguard Worker static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3, X4, X5, X6, X7) == 7);
375*61c4878aSAndroid Build Coastguard Worker static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3, X4, X5, X6, X7, X8) == 8);
376*61c4878aSAndroid Build Coastguard Worker static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3, X4, X5, X6, X7, X8, X9) == 9);
377*61c4878aSAndroid Build Coastguard Worker static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10) == 10);
378*61c4878aSAndroid Build Coastguard Worker static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11) == 11);
379*61c4878aSAndroid Build Coastguard Worker static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12) == 12);
380*61c4878aSAndroid Build Coastguard Worker static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13) == 13);
381*61c4878aSAndroid Build Coastguard Worker static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14) == 14);
382*61c4878aSAndroid Build Coastguard Worker static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15) == 15);
383*61c4878aSAndroid Build Coastguard Worker static_assert(PW_MACRO_ARG_COUNT(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16) == 16);
384*61c4878aSAndroid Build Coastguard Worker 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*61c4878aSAndroid Build Coastguard Worker 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);
386*61c4878aSAndroid Build Coastguard Worker 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);
387*61c4878aSAndroid Build Coastguard Worker 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);
388*61c4878aSAndroid Build Coastguard Worker 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);
389*61c4878aSAndroid Build Coastguard Worker 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);
390*61c4878aSAndroid Build Coastguard Worker 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, X65) == 65);
391*61c4878aSAndroid Build Coastguard Worker 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, X65, X66, X67, X68, X69, X70, X71, X72, X73, X74, X75, X76, X77, X78, X79, X80, X81, X82, X83, X84, X85, X86, X87, X88, X89, X90, X91, X92, X93, X94, X95, X96, X97, X98, X99, X100, X101, X102, X103, X104, X105, X106, X107, X108, X109, X110, X111, X112, X113, X114, X115, X116, X117, X118, X119, X120, X121, X122, X123, X124, X125, X126, X127) == 127);
392*61c4878aSAndroid Build Coastguard Worker 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, X65, X66, X67, X68, X69, X70, X71, X72, X73, X74, X75, X76, X77, X78, X79, X80, X81, X82, X83, X84, X85, X86, X87, X88, X89, X90, X91, X92, X93, X94, X95, X96, X97, X98, X99, X100, X101, X102, X103, X104, X105, X106, X107, X108, X109, X110, X111, X112, X113, X114, X115, X116, X117, X118, X119, X120, X121, X122, X123, X124, X125, X126, X127, X128) == 128);
393*61c4878aSAndroid Build Coastguard Worker 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, X65, X66, X67, X68, X69, X70, X71, X72, X73, X74, X75, X76, X77, X78, X79, X80, X81, X82, X83, X84, X85, X86, X87, X88, X89, X90, X91, X92, X93, X94, X95, X96, X97, X98, X99, X100, X101, X102, X103, X104, X105, X106, X107, X108, X109, X110, X111, X112, X113, X114, X115, X116, X117, X118, X119, X120, X121, X122, X123, X124, X125, X126, X127, X128, X129) == 129);
394*61c4878aSAndroid Build Coastguard Worker 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, X65, X66, X67, X68, X69, X70, X71, X72, X73, X74, X75, X76, X77, X78, X79, X80, X81, X82, X83, X84, X85, X86, X87, X88, X89, X90, X91, X92, X93, X94, X95, X96, X97, X98, X99, X100, X101, X102, X103, X104, X105, X106, X107, X108, X109, X110, X111, X112, X113, X114, X115, X116, X117, X118, X119, X120, X121, X122, X123, X124, X125, X126, X127, X128, X129, X130, X131, X132, X133, X134, X135, X136, X137, X138, X139, X140, X141, X142, X143, X144, X145, X146, X147, X148, X149, X150, X151, X152, X153, X154, X155, X156, X157, X158, X159, X160, X161, X162, X163, X164, X165, X166, X167, X168, X169, X170, X171, X172, X173, X174, X175, X176, X177, X178, X179, X180, X181, X182, X183, X184, X185, X186, X187, X188, X189, X190, X191, X192, X193, X194, X195, X196, X197, X198, X199, X200, X201, X202, X203, X204, X205, X206, X207, X208, X209, X210, X211, X212, X213, X214, X215, X216, X217, X218, X219, X220, X221, X222, X223, X224, X225, X226, X227, X228, X229, X230, X231, X232, X233, X234, X235, X236, X237, X238, X239, X240, X241, X242, X243, X244, X245, X246, X247, X248, X249, X250, X251, X252, X253, X254, X255) == 255);
395*61c4878aSAndroid Build Coastguard Worker 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, X65, X66, X67, X68, X69, X70, X71, X72, X73, X74, X75, X76, X77, X78, X79, X80, X81, X82, X83, X84, X85, X86, X87, X88, X89, X90, X91, X92, X93, X94, X95, X96, X97, X98, X99, X100, X101, X102, X103, X104, X105, X106, X107, X108, X109, X110, X111, X112, X113, X114, X115, X116, X117, X118, X119, X120, X121, X122, X123, X124, X125, X126, X127, X128, X129, X130, X131, X132, X133, X134, X135, X136, X137, X138, X139, X140, X141, X142, X143, X144, X145, X146, X147, X148, X149, X150, X151, X152, X153, X154, X155, X156, X157, X158, X159, X160, X161, X162, X163, X164, X165, X166, X167, X168, X169, X170, X171, X172, X173, X174, X175, X176, X177, X178, X179, X180, X181, X182, X183, X184, X185, X186, X187, X188, X189, X190, X191, X192, X193, X194, X195, X196, X197, X198, X199, X200, X201, X202, X203, X204, X205, X206, X207, X208, X209, X210, X211, X212, X213, X214, X215, X216, X217, X218, X219, X220, X221, X222, X223, X224, X225, X226, X227, X228, X229, X230, X231, X232, X233, X234, X235, X236, X237, X238, X239, X240, X241, X242, X243, X244, X245, X246, X247, X248, X249, X250, X251, X252, X253, X254, X255, X256) == 256);
396*61c4878aSAndroid Build Coastguard Worker // clang-format on
397*61c4878aSAndroid Build Coastguard Worker }
398*61c4878aSAndroid Build Coastguard Worker
TEST(DelegateByArgCount,WithoutAndWithoutArguments)399*61c4878aSAndroid Build Coastguard Worker TEST(DelegateByArgCount, WithoutAndWithoutArguments) {
400*61c4878aSAndroid Build Coastguard Worker #define TEST_SUM0() (0)
401*61c4878aSAndroid Build Coastguard Worker #define TEST_SUM1(a) (a)
402*61c4878aSAndroid Build Coastguard Worker #define TEST_SUM2(a, b) ((a) + (b))
403*61c4878aSAndroid Build Coastguard Worker #define TEST_SUM3(a, b, c) ((a) + (b) + (c))
404*61c4878aSAndroid Build Coastguard Worker
405*61c4878aSAndroid Build Coastguard Worker static_assert(PW_DELEGATE_BY_ARG_COUNT(TEST_SUM) == 0);
406*61c4878aSAndroid Build Coastguard Worker static_assert(PW_DELEGATE_BY_ARG_COUNT(TEST_SUM, 5) == 5);
407*61c4878aSAndroid Build Coastguard Worker static_assert(PW_DELEGATE_BY_ARG_COUNT(TEST_SUM, 1, 2) == 3);
408*61c4878aSAndroid Build Coastguard Worker static_assert(PW_DELEGATE_BY_ARG_COUNT(TEST_SUM, 1, 2, 3) == 6);
409*61c4878aSAndroid Build Coastguard Worker }
410*61c4878aSAndroid Build Coastguard Worker
411*61c4878aSAndroid Build Coastguard Worker #define SEMICOLON(...) ;
412*61c4878aSAndroid Build Coastguard Worker #define STRING_THING(index, name, arg) #arg
413*61c4878aSAndroid Build Coastguard Worker
414*61c4878aSAndroid Build Coastguard Worker #define TO_STRING_CASE(index, name, arg) \
415*61c4878aSAndroid Build Coastguard Worker case arg: \
416*61c4878aSAndroid Build Coastguard Worker return #arg
417*61c4878aSAndroid Build Coastguard Worker
418*61c4878aSAndroid Build Coastguard Worker #define APPLY_STRING_THING(...) PW_APPLY(STRING_THING, SEMICOLON, , __VA_ARGS__)
419*61c4878aSAndroid Build Coastguard Worker
ValueToStr(int value)420*61c4878aSAndroid Build Coastguard Worker constexpr const char* ValueToStr(int value) {
421*61c4878aSAndroid Build Coastguard Worker switch (value) {
422*61c4878aSAndroid Build Coastguard Worker PW_APPLY(TO_STRING_CASE, SEMICOLON, , 100, 200, 300, 400, 500);
423*61c4878aSAndroid Build Coastguard Worker }
424*61c4878aSAndroid Build Coastguard Worker return "Unknown value";
425*61c4878aSAndroid Build Coastguard Worker }
426*61c4878aSAndroid Build Coastguard Worker
TEST(ApplyMacroExpansion,OneStringValue)427*61c4878aSAndroid Build Coastguard Worker TEST(ApplyMacroExpansion, OneStringValue) {
428*61c4878aSAndroid Build Coastguard Worker constexpr const char* test = APPLY_STRING_THING(100);
429*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("100", test);
430*61c4878aSAndroid Build Coastguard Worker }
431*61c4878aSAndroid Build Coastguard Worker
TEST(ApplyMacroExpansion,SwitchValue)432*61c4878aSAndroid Build Coastguard Worker TEST(ApplyMacroExpansion, SwitchValue) {
433*61c4878aSAndroid Build Coastguard Worker constexpr const char* test = ValueToStr(300);
434*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("300", test);
435*61c4878aSAndroid Build Coastguard Worker }
436*61c4878aSAndroid Build Coastguard Worker
TEST(ApplyMacroExpansion,UnknownSwitchValue)437*61c4878aSAndroid Build Coastguard Worker TEST(ApplyMacroExpansion, UnknownSwitchValue) {
438*61c4878aSAndroid Build Coastguard Worker constexpr const char* test = ValueToStr(600);
439*61c4878aSAndroid Build Coastguard Worker EXPECT_STREQ("Unknown value", test);
440*61c4878aSAndroid Build Coastguard Worker }
441*61c4878aSAndroid Build Coastguard Worker
442*61c4878aSAndroid Build Coastguard Worker } // namespace
443*61c4878aSAndroid Build Coastguard Worker } // namespace pw
444