pw_preprocessor: PW_COMMA_ARGS improvements
- Update PW_COMMA_ARGS so that it drops the last argument if it is
empty. This means that PW_COMMA_ARGS(1, ) expands to '1' instead of
'1, ' as it did before. This makes PW_COMMA_ARGS more robust when
working with nested variadic macros that may add arguments.
- Rename PW_HAS_NO_ARGS to PW_EMPTY_ARGS. This more accurately
represents what it does: detect if there are zero arguments or one
empty argument. It also switches to positive logic which is easier to
reason about.
Change-Id: Ieeef9f1eda52c38239d46c50f095b2a06bb832f1
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/16221
Commit-Queue: Wyatt Hepler <hepler@google.com>
Reviewed-by: Keir Mierle <keir@google.com>
diff --git a/pw_preprocessor/macro_arg_count_test.cc b/pw_preprocessor/macro_arg_count_test.cc
index 0ce8831..f450b24 100644
--- a/pw_preprocessor/macro_arg_count_test.cc
+++ b/pw_preprocessor/macro_arg_count_test.cc
@@ -22,10 +22,13 @@
namespace pw {
namespace {
+#define EMPTY_ARG
+
TEST(HasArgs, WithoutArguments) {
static_assert(PW_HAS_ARGS() == 0);
static_assert(PW_HAS_ARGS(/**/) == 0);
static_assert(PW_HAS_ARGS(/* uhm, hi */) == 0);
+ static_assert(PW_HAS_ARGS(EMPTY_ARG) == 0);
// Test how the macro handles whitespace and comments.
// clang-format off
@@ -38,9 +41,9 @@
) == 0); // NOLINT
// clang-format on
- static_assert(PW_HAS_NO_ARGS() == 1);
- static_assert(PW_HAS_NO_ARGS(/* hello */) == 1);
- static_assert(PW_HAS_NO_ARGS(
+ static_assert(PW_EMPTY_ARGS() == 1);
+ static_assert(PW_EMPTY_ARGS(/* hello */) == 1);
+ static_assert(PW_EMPTY_ARGS(
// hello
/* goodbye */) == 1);
}
@@ -53,11 +56,11 @@
static_assert(PW_HAS_ARGS(PW_HAS_ARGS) == 1);
static_assert(PW_HAS_ARGS(PW_HAS_ARGS()) == 1);
- static_assert(PW_HAS_NO_ARGS(0) == 0);
- static_assert(PW_HAS_NO_ARGS(, ) == 0); // NOLINT
- static_assert(PW_HAS_NO_ARGS(a, b, c) == 0);
- static_assert(PW_HAS_NO_ARGS(PW_HAS_ARGS) == 0);
- static_assert(PW_HAS_NO_ARGS(PW_HAS_ARGS()) == 0);
+ static_assert(PW_EMPTY_ARGS(0) == 0);
+ static_assert(PW_EMPTY_ARGS(, ) == 0); // NOLINT
+ static_assert(PW_EMPTY_ARGS(a, b, c) == 0);
+ static_assert(PW_EMPTY_ARGS(PW_HAS_ARGS) == 0);
+ static_assert(PW_EMPTY_ARGS(PW_HAS_ARGS()) == 0);
}
constexpr int TestFunc(int arg, ...) { return arg; }
@@ -107,6 +110,16 @@
static_assert(COUNT_ARGS_TEMPLATE(int, int, int) == 3);
}
+TEST(CommaVarargs, EmptyFinalArgument) {
+ static_assert(COUNT_ARGS_TEMPLATE(EMPTY_ARG) == 0);
+ static_assert(COUNT_ARGS_TEMPLATE(int, ) == 1);
+ static_assert(COUNT_ARGS_TEMPLATE(int, EMPTY_ARG) == 1);
+ static_assert(COUNT_ARGS_TEMPLATE(int, /* EMPTY_ARG */) == 1);
+ static_assert(COUNT_ARGS_TEMPLATE(int, int, ) == 2);
+ static_assert(COUNT_ARGS_TEMPLATE(int, int, int, ) == 3);
+ static_assert(COUNT_ARGS_TEMPLATE(int, int, int, EMPTY_ARG) == 3);
+}
+
TEST(CountArgs, Zero) {
static_assert(PW_ARG_COUNT() == 0);
static_assert(PW_ARG_COUNT(/**/) == 0);