pw_preprocessor: Rename macro_arg_count.h

- Rename macro_arg_count.h to arguments.h
- Have macro_arg_count.h #include the renamed header for compatibility.

Change-Id: I781a457af88c6dd63ab8f8394bfe45cff9bc71e9
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/17500
Reviewed-by: Alexei Frolov <frolv@google.com>
Commit-Queue: Wyatt Hepler <hepler@google.com>
diff --git a/pw_assert/public/pw_assert/assert.h b/pw_assert/public/pw_assert/assert.h
index 36082c5..2a4c999 100644
--- a/pw_assert/public/pw_assert/assert.h
+++ b/pw_assert/public/pw_assert/assert.h
@@ -19,7 +19,7 @@
 //
 #pragma once
 
-#include "pw_preprocessor/macro_arg_count.h"
+#include "pw_preprocessor/arguments.h"
 
 // The pw_assert public API:
 //
diff --git a/pw_assert/public/pw_assert/internal/assert_impl.h b/pw_assert/public/pw_assert/internal/assert_impl.h
index 573c92f..95862f0 100644
--- a/pw_assert/public/pw_assert/internal/assert_impl.h
+++ b/pw_assert/public/pw_assert/internal/assert_impl.h
@@ -19,7 +19,7 @@
 
 // Note: This file depends on the backend header already being included.
 
-#include "pw_preprocessor/macro_arg_count.h"
+#include "pw_preprocessor/arguments.h"
 
 // Define PW_ASSERT_ENABLE_DCHECK, which controls whether DCHECKs are enabled.
 #if !defined(PW_ASSERT_ENABLE_DCHECK)
diff --git a/pw_log_basic/public/pw_log_basic/log_basic.h b/pw_log_basic/public/pw_log_basic/log_basic.h
index 6ebb4e1..963e7eb 100644
--- a/pw_log_basic/public/pw_log_basic/log_basic.h
+++ b/pw_log_basic/public/pw_log_basic/log_basic.h
@@ -13,8 +13,8 @@
 // the License.
 #pragma once
 
+#include "pw_preprocessor/arguments.h"
 #include "pw_preprocessor/compiler.h"
-#include "pw_preprocessor/macro_arg_count.h"
 #include "pw_preprocessor/util.h"
 
 PW_EXTERN_C_START
diff --git a/pw_metric/public/pw_metric/metric.h b/pw_metric/public/pw_metric/metric.h
index 25f79b9..3b8d79c 100644
--- a/pw_metric/public/pw_metric/metric.h
+++ b/pw_metric/public/pw_metric/metric.h
@@ -19,7 +19,7 @@
 
 #include "pw_assert/assert.h"
 #include "pw_containers/intrusive_list.h"
-#include "pw_preprocessor/macro_arg_count.h"
+#include "pw_preprocessor/arguments.h"
 #include "pw_tokenizer/tokenize.h"
 
 namespace pw::metric {
diff --git a/pw_preprocessor/BUILD b/pw_preprocessor/BUILD
index 439e383..d0d14d7 100644
--- a/pw_preprocessor/BUILD
+++ b/pw_preprocessor/BUILD
@@ -30,9 +30,9 @@
 )
 
 TESTS = [
+    "arguments_test",
     "boolean_test",
     "concat_test",
-    "macro_arg_count_test",
     "util_test",
 ]
 
diff --git a/pw_preprocessor/BUILD.gn b/pw_preprocessor/BUILD.gn
index b88ba32..94408f8 100644
--- a/pw_preprocessor/BUILD.gn
+++ b/pw_preprocessor/BUILD.gn
@@ -25,6 +25,7 @@
 pw_source_set("pw_preprocessor") {
   public_configs = [ ":default_config" ]
   public = [
+    "public/pw_preprocessor/arguments.h",
     "public/pw_preprocessor/boolean.h",
     "public/pw_preprocessor/compiler.h",
     "public/pw_preprocessor/concat.h",
@@ -41,13 +42,18 @@
 # All pw_preprocessor test binaries.
 pw_test_group("tests") {
   tests = [
+    ":arguments_test",
     ":boolean_test",
     ":concat_test",
-    ":macro_arg_count_test",
     ":util_test",
   ]
 }
 
+pw_test("arguments_test") {
+  deps = [ ":pw_preprocessor" ]
+  sources = [ "arguments_test.cc" ]
+}
+
 pw_test("boolean_test") {
   deps = [ ":pw_preprocessor" ]
   sources = [ "boolean_test.cc" ]
@@ -58,11 +64,6 @@
   sources = [ "concat_test.cc" ]
 }
 
-pw_test("macro_arg_count_test") {
-  deps = [ ":pw_preprocessor" ]
-  sources = [ "macro_arg_count_test.cc" ]
-}
-
 pw_test("util_test") {
   deps = [ ":pw_preprocessor" ]
   sources = [ "util_test.cc" ]
diff --git a/pw_preprocessor/macro_arg_count_test.cc b/pw_preprocessor/arguments_test.cc
similarity index 99%
rename from pw_preprocessor/macro_arg_count_test.cc
rename to pw_preprocessor/arguments_test.cc
index 7398e14..2ca76c5 100644
--- a/pw_preprocessor/macro_arg_count_test.cc
+++ b/pw_preprocessor/arguments_test.cc
@@ -1,4 +1,4 @@
-// Copyright 2019 The Pigweed Authors
+// Copyright 2020 The Pigweed Authors
 //
 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
 // use this file except in compliance with the License. You may obtain a copy of
@@ -15,7 +15,7 @@
 // All of these tests are static asserts. If the test compiles, it has already
 // passed. The TEST functions are used for organization only.
 
-#include "pw_preprocessor/macro_arg_count.h"
+#include "pw_preprocessor/arguments.h"
 
 #include "pw_unit_test/framework.h"
 
diff --git a/pw_preprocessor/public/pw_preprocessor/arguments.h b/pw_preprocessor/public/pw_preprocessor/arguments.h
new file mode 100644
index 0000000..2d9a51f
--- /dev/null
+++ b/pw_preprocessor/public/pw_preprocessor/arguments.h
@@ -0,0 +1,194 @@
+// Copyright 2020 The Pigweed Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+//
+// Macros for counting the number of arguments passed to a variadic
+// function-like macro.
+#pragma once
+
+#include "pw_preprocessor/boolean.h"
+#include "pw_preprocessor/internal/arg_count_impl.h"
+
+// PW_ARG_COUNT counts the number of arguments it was called with. It evalulates
+// to an integer literal in the range 0 to 64. Counting more than 64 arguments
+// is not currently supported.
+//
+// PW_ARG_COUNT is most commonly used to count __VA_ARGS__ in a variadic macro.
+// For example, the following code counts the number of arguments passed to a
+// logging macro:
+//
+/*   #define LOG_INFO(format, ...) {                             \
+         static const int kArgCount = PW_ARG_COUNT(__VA_ARGS__); \
+         SendLog(kArgCount, format, ##__VA_ARGS__);              \
+       }
+*/
+// clang-format off
+#define PW_ARG_COUNT(...)                            \
+  _PW_ARG_COUNT_IMPL(__VA_ARGS__,                    \
+                     64, 63, 62, 61, 60, 59, 58, 57, \
+                     56, 55, 54, 53, 52, 51, 50, 49, \
+                     48, 47, 46, 45, 44, 43, 42, 41, \
+                     40, 39, 38, 37, 36, 35, 34, 33, \
+                     32, 31, 30, 29, 28, 27, 26, 25, \
+                     24, 23, 22, 21, 20, 19, 18, 17, \
+                     16, 15, 14, 13, 12, 11, 10,  9, \
+                      8,  7,  6,  5, 4,  3,  2,  PW_HAS_ARGS(__VA_ARGS__))
+// clang-format on
+
+// Argument count for using with a C/C++ function or template parameter list.
+// The difference from PW_MACRO_ARG_COUNT is that the last argument is not
+// counted if it is empty. This makes it easier to drop the final comma when
+// expanding to C/C++ code.
+#define PW_FUNCTION_ARG_COUNT(...) \
+  _PW_FUNCTION_ARG_COUNT(PW_LAST_ARG(__VA_ARGS__), __VA_ARGS__)
+
+#define _PW_FUNCTION_ARG_COUNT(last_arg, ...) \
+  _PW_PASTE2(_PW_FUNCTION_ARG_COUNT_, PW_EMPTY_ARGS(last_arg))(__VA_ARGS__)
+
+#define _PW_FUNCTION_ARG_COUNT_0 PW_ARG_COUNT
+#define _PW_FUNCTION_ARG_COUNT_1(...) \
+  PW_ARG_COUNT(PW_DROP_LAST_ARG(__VA_ARGS__))
+
+// Evaluates to the last argument in the provided arguments.
+#define PW_LAST_ARG(...) \
+  _PW_PASTE2(_PW_LAST_ARG_, PW_ARG_COUNT(__VA_ARGS__))(__VA_ARGS__)
+
+// Evaluates to the provided arguments, excluding the final argument.
+#define PW_DROP_LAST_ARG(...) \
+  _PW_PASTE2(_PW_DROP_LAST_ARG_, PW_ARG_COUNT(__VA_ARGS__))(__VA_ARGS__)
+
+// Evaluates to the provided arguments excluding the final argument..
+#define PW_DROP_LAST_ARG_IF_EMPTY(...)                                       \
+  _PW_IF(                                                                    \
+      PW_EMPTY_ARGS(PW_LAST_ARG(__VA_ARGS__)), PW_DROP_LAST_ARG, _PW_EXPAND) \
+  (__VA_ARGS__)
+
+// Expands to 1 if one or more arguments are provided, 0 otherwise.
+#define PW_HAS_ARGS(...) PW_NOT(PW_EMPTY_ARGS(__VA_ARGS__))
+
+// Expands to 0 if one or more arguments are provided, 1 otherwise. This
+// approach is from Jens Gustedt's blog:
+//   https://gustedt.wordpress.com/2010/06/08/detect-empty-macro-arguments/
+//
+// Normally, with a standard-compliant C preprocessor, it's impossible to tell
+// whether a variadic macro was called with no arguments or with one argument.
+// A macro invoked with no arguments is actually passed one empty argument.
+//
+// This macro works by checking for the presence of a comma in four situations.
+// These situations give the following information about __VA_ARGS__:
+//
+//   1. It is two or more variadic arguments.
+//   2. It expands to one argument surrounded by parentheses.
+//   3. It is a function-like macro that produces a comma when invoked.
+//   4. It does not interfere with calling a macro when placed between it and
+//      parentheses.
+//
+// If a comma is not present in 1, 2, 3, but is present in 4, then __VA_ARGS__
+// is empty. For this case (0001), and only this case, a corresponding macro
+// that expands to a comma is defined. The presence of this comma determines
+// whether any arguments were passed in.
+//
+// C++20 introduces __VA_OPT__, which would greatly simplify this macro.
+#define PW_EMPTY_ARGS(...)                                             \
+  _PW_HAS_NO_ARGS(_PW_HAS_COMMA(__VA_ARGS__),                          \
+                  _PW_HAS_COMMA(_PW_MAKE_COMMA_IF_CALLED __VA_ARGS__), \
+                  _PW_HAS_COMMA(__VA_ARGS__()),                        \
+                  _PW_HAS_COMMA(_PW_MAKE_COMMA_IF_CALLED __VA_ARGS__()))
+
+// clang-format off
+
+#define _PW_HAS_COMMA(...)                                           \
+  _PW_ARG_COUNT_IMPL(__VA_ARGS__,                                    \
+                     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
+                     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
+                     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
+                     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0)
+
+#define _PW_ARG_COUNT_IMPL(a64, a63, a62, a61, a60, a59, a58, a57, \
+                           a56, a55, a54, a53, a52, a51, a50, a49, \
+                           a48, a47, a46, a45, a44, a43, a42, a41, \
+                           a40, a39, a38, a37, a36, a35, a34, a33, \
+                           a32, a31, a30, a29, a28, a27, a26, a25, \
+                           a24, a23, a22, a21, a20, a19, a18, a17, \
+                           a16, a15, a14, a13, a12, a11, a10, a09, \
+                           a08, a07, a06, a05, a04, a03, a02, a01, \
+                           count, ...)                             \
+  count
+
+// clang-format on
+
+#define _PW_HAS_NO_ARGS(a1, a2, a3, a4) \
+  _PW_HAS_COMMA(_PW_PASTE_RESULTS(a1, a2, a3, a4))
+#define _PW_PASTE_RESULTS(a1, a2, a3, a4) _PW_HAS_COMMA_CASE_##a1##a2##a3##a4
+#define _PW_HAS_COMMA_CASE_0001 ,
+#define _PW_MAKE_COMMA_IF_CALLED(...) ,
+
+// Expands to a comma followed by __VA_ARGS__, if __VA_ARGS__ is non-empty.
+// Otherwise, expands to nothing. If the final argument is empty, it is omitted.
+// This is useful when passing __VA_ARGS__ to a variadic function or template
+// parameter list, since it removes the extra comma when no arguments are
+// provided. PW_COMMA_ARGS must NOT be used when invoking a macro from another
+// macro.
+//
+// This is a more flexible, standard-compliant version of ##__VA_ARGS__. Unlike
+// ##__VA_ARGS__, this can be used to eliminate an unwanted comma when
+// __VA_ARGS__ expands to an empty argument because an outer macro was called
+// with __VA_ARGS__ instead of ##__VA_ARGS__. Also, since PW_COMMA_ARGS drops
+// the last argument if it is empty, both MY_MACRO(1, 2) and MY_MACRO(1, 2, )
+// can work correctly.
+//
+// PW_COMMA_ARGS must NOT be used to conditionally include a comma when invoking
+// a macro from another macro. PW_COMMA_ARGS only functions correctly when the
+// macro expands to C or C++ code! Using it with intermediate macros can result
+// in out-of-order parameters. When invoking one macro from another, simply pass
+// __VA_ARGS__. Only the final macro that expands to C/C++ code should use
+// PW_COMMA_ARGS.
+//
+// For example, the following does NOT work:
+/*
+     #define MY_MACRO(fmt, ...) \
+         NESTED_MACRO(fmt PW_COMMA_ARGS(__VA_ARGS__))  // BAD! Do not do this!
+*/
+// Instead, only use PW_COMMA_ARGS when the macro expands to C/C++ code:
+/*
+     #define MY_MACRO(fmt, ...) \
+         NESTED_MACRO(fmt, __VA_ARGS__)  // Pass __VA_ARGS__ to nested macros
+
+     #define NESTED_MACRO(fmt, ...) \
+         printf(fmt PW_COMMA_ARGS(__VA_ARGS__))  // PW_COMMA_ARGS is OK here
+*/
+#define PW_COMMA_ARGS(...)                                       \
+  _PW_IF(PW_EMPTY_ARGS(__VA_ARGS__), _PW_EXPAND, _PW_COMMA_ARGS) \
+  (PW_DROP_LAST_ARG_IF_EMPTY(__VA_ARGS__))
+
+#define _PW_COMMA_ARGS(...) , __VA_ARGS__
+
+// Allows calling a different function-like macro based on the number of
+// arguments.  For example:
+//
+//   #define ARG_PRINT(...)  PW_DELEGATE_BY_ARG_COUNT(_ARG_PRINT, __VA_ARGS__)
+//   #define _ARG_PRINT1(a)        LOG_INFO("1 arg: %s", a)
+//   #define _ARG_PRINT2(a, b)     LOG_INFO("2 args: %s, %s", a, b)
+//   #define _ARG_PRINT3(a, b, c)  LOG_INFO("3 args: %s, %s, %s", a, b, c)
+//
+// This can the be called in code:
+//    ARG_PRINT("a");            // Outputs: 1 arg: a
+//    ARG_PRINT("a", "b");       // Outputs: 2 arg: a, b
+//    ARG_PRINT("a", "b", "c");  // Outputs: 3 arg: a, b, c
+//
+#define PW_DELEGATE_BY_ARG_COUNT(function, ...)                 \
+  _PW_DELEGATE_BY_ARG_COUNT(                                    \
+      _PW_PASTE2(function, PW_FUNCTION_ARG_COUNT(__VA_ARGS__)), \
+      PW_DROP_LAST_ARG_IF_EMPTY(__VA_ARGS__))
+
+#define _PW_DELEGATE_BY_ARG_COUNT(function, ...) function(__VA_ARGS__)
diff --git a/pw_preprocessor/public/pw_preprocessor/concat.h b/pw_preprocessor/public/pw_preprocessor/concat.h
index 30f37ce..e8045e1 100644
--- a/pw_preprocessor/public/pw_preprocessor/concat.h
+++ b/pw_preprocessor/public/pw_preprocessor/concat.h
@@ -14,7 +14,7 @@
 
 #pragma once
 
-#include "pw_preprocessor/macro_arg_count.h"
+#include "pw_preprocessor/arguments.h"
 
 // Expands macros and concatenates the results using preprocessor ##
 // concatentation. Supports up to 32 arguments.
diff --git a/pw_preprocessor/public/pw_preprocessor/macro_arg_count.h b/pw_preprocessor/public/pw_preprocessor/macro_arg_count.h
index 7da4c6a..f5e4b23 100644
--- a/pw_preprocessor/public/pw_preprocessor/macro_arg_count.h
+++ b/pw_preprocessor/public/pw_preprocessor/macro_arg_count.h
@@ -1,4 +1,4 @@
-// Copyright 2019 The Pigweed Authors
+// Copyright 2020 The Pigweed Authors
 //
 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
 // use this file except in compliance with the License. You may obtain a copy of
@@ -11,184 +11,7 @@
 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 // License for the specific language governing permissions and limitations under
 // the License.
-//
-// Macros for counting the number of arguments passed to a variadic
-// function-like macro.
 #pragma once
 
-#include "pw_preprocessor/boolean.h"
-#include "pw_preprocessor/internal/arg_count_impl.h"
-
-// PW_ARG_COUNT counts the number of arguments it was called with. It evalulates
-// to an integer literal in the range 0 to 64. Counting more than 64 arguments
-// is not currently supported.
-//
-// PW_ARG_COUNT is most commonly used to count __VA_ARGS__ in a variadic macro.
-// For example, the following code counts the number of arguments passed to a
-// logging macro:
-//
-/*   #define LOG_INFO(format, ...) {                             \
-         static const int kArgCount = PW_ARG_COUNT(__VA_ARGS__); \
-         SendLog(kArgCount, format, ##__VA_ARGS__);              \
-       }
-*/
-// clang-format off
-#define PW_ARG_COUNT(...)                            \
-  _PW_ARG_COUNT_IMPL(__VA_ARGS__,                    \
-                     64, 63, 62, 61, 60, 59, 58, 57, \
-                     56, 55, 54, 53, 52, 51, 50, 49, \
-                     48, 47, 46, 45, 44, 43, 42, 41, \
-                     40, 39, 38, 37, 36, 35, 34, 33, \
-                     32, 31, 30, 29, 28, 27, 26, 25, \
-                     24, 23, 22, 21, 20, 19, 18, 17, \
-                     16, 15, 14, 13, 12, 11, 10,  9, \
-                      8,  7,  6,  5, 4,  3,  2,  PW_HAS_ARGS(__VA_ARGS__))
-// clang-format on
-
-// Argument count for using with a C/C++ function or template parameter list.
-// The difference from PW_MACRO_ARG_COUNT is that the last argument is not
-// counted if it is empty. This makes it easier to drop the final comma when
-// expanding to C/C++ code.
-#define PW_FUNCTION_ARG_COUNT(...) \
-  _PW_FUNCTION_ARG_COUNT(PW_LAST_ARG(__VA_ARGS__), __VA_ARGS__)
-
-#define _PW_FUNCTION_ARG_COUNT(last_arg, ...) \
-  _PW_PASTE2(_PW_FUNCTION_ARG_COUNT_, PW_EMPTY_ARGS(last_arg))(__VA_ARGS__)
-
-#define _PW_FUNCTION_ARG_COUNT_0 PW_ARG_COUNT
-#define _PW_FUNCTION_ARG_COUNT_1(...) \
-  PW_ARG_COUNT(PW_DROP_LAST_ARG(__VA_ARGS__))
-
-// Evaluates to the last argument in the provided arguments.
-#define PW_LAST_ARG(...) \
-  _PW_PASTE2(_PW_LAST_ARG_, PW_ARG_COUNT(__VA_ARGS__))(__VA_ARGS__)
-
-// Evaluates to the provided arguments, excluding the final argument.
-#define PW_DROP_LAST_ARG(...) \
-  _PW_PASTE2(_PW_DROP_LAST_ARG_, PW_ARG_COUNT(__VA_ARGS__))(__VA_ARGS__)
-
-// Evaluates to the provided arguments excluding the final argument..
-#define PW_DROP_LAST_ARG_IF_EMPTY(...)                                       \
-  _PW_IF(                                                                    \
-      PW_EMPTY_ARGS(PW_LAST_ARG(__VA_ARGS__)), PW_DROP_LAST_ARG, _PW_EXPAND) \
-  (__VA_ARGS__)
-
-// Expands to 1 if one or more arguments are provided, 0 otherwise.
-#define PW_HAS_ARGS(...) PW_NOT(PW_EMPTY_ARGS(__VA_ARGS__))
-
-// Expands to 0 if one or more arguments are provided, 1 otherwise. This
-// approach is from Jens Gustedt's blog:
-//   https://gustedt.wordpress.com/2010/06/08/detect-empty-macro-arguments/
-//
-// Normally, with a standard-compliant C preprocessor, it's impossible to tell
-// whether a variadic macro was called with no arguments or with one argument.
-// A macro invoked with no arguments is actually passed one empty argument.
-//
-// This macro works by checking for the presence of a comma in four situations.
-// These situations give the following information about __VA_ARGS__:
-//
-//   1. It is two or more variadic arguments.
-//   2. It expands to one argument surrounded by parentheses.
-//   3. It is a function-like macro that produces a comma when invoked.
-//   4. It does not interfere with calling a macro when placed between it and
-//      parentheses.
-//
-// If a comma is not present in 1, 2, 3, but is present in 4, then __VA_ARGS__
-// is empty. For this case (0001), and only this case, a corresponding macro
-// that expands to a comma is defined. The presence of this comma determines
-// whether any arguments were passed in.
-//
-// C++20 introduces __VA_OPT__, which would greatly simplify this macro.
-#define PW_EMPTY_ARGS(...)                                             \
-  _PW_HAS_NO_ARGS(_PW_HAS_COMMA(__VA_ARGS__),                          \
-                  _PW_HAS_COMMA(_PW_MAKE_COMMA_IF_CALLED __VA_ARGS__), \
-                  _PW_HAS_COMMA(__VA_ARGS__()),                        \
-                  _PW_HAS_COMMA(_PW_MAKE_COMMA_IF_CALLED __VA_ARGS__()))
-
-// clang-format off
-
-#define _PW_HAS_COMMA(...)                                           \
-  _PW_ARG_COUNT_IMPL(__VA_ARGS__,                                    \
-                     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
-                     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
-                     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
-                     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0)
-
-#define _PW_ARG_COUNT_IMPL(a64, a63, a62, a61, a60, a59, a58, a57, \
-                           a56, a55, a54, a53, a52, a51, a50, a49, \
-                           a48, a47, a46, a45, a44, a43, a42, a41, \
-                           a40, a39, a38, a37, a36, a35, a34, a33, \
-                           a32, a31, a30, a29, a28, a27, a26, a25, \
-                           a24, a23, a22, a21, a20, a19, a18, a17, \
-                           a16, a15, a14, a13, a12, a11, a10, a09, \
-                           a08, a07, a06, a05, a04, a03, a02, a01, \
-                           count, ...)                             \
-  count
-
-// clang-format on
-
-#define _PW_HAS_NO_ARGS(a1, a2, a3, a4) \
-  _PW_HAS_COMMA(_PW_PASTE_RESULTS(a1, a2, a3, a4))
-#define _PW_PASTE_RESULTS(a1, a2, a3, a4) _PW_HAS_COMMA_CASE_##a1##a2##a3##a4
-#define _PW_HAS_COMMA_CASE_0001 ,
-#define _PW_MAKE_COMMA_IF_CALLED(...) ,
-
-// Expands to a comma followed by __VA_ARGS__, if __VA_ARGS__ is non-empty.
-// Otherwise, expands to nothing. If the final argument is empty, it is omitted.
-// This is useful when passing __VA_ARGS__ to a variadic function or template
-// parameter list, since it removes the extra comma when no arguments are
-// provided. PW_COMMA_ARGS must NOT be used when invoking a macro from another
-// macro.
-//
-// This is a more flexible, standard-compliant version of ##__VA_ARGS__. Unlike
-// ##__VA_ARGS__, this can be used to eliminate an unwanted comma when
-// __VA_ARGS__ expands to an empty argument because an outer macro was called
-// with __VA_ARGS__ instead of ##__VA_ARGS__. Also, since PW_COMMA_ARGS drops
-// the last argument if it is empty, both MY_MACRO(1, 2) and MY_MACRO(1, 2, )
-// can work correctly.
-//
-// PW_COMMA_ARGS must NOT be used to conditionally include a comma when invoking
-// a macro from another macro. PW_COMMA_ARGS only functions correctly when the
-// macro expands to C or C++ code! Using it with intermediate macros can result
-// in out-of-order parameters. When invoking one macro from another, simply pass
-// __VA_ARGS__. Only the final macro that expands to C/C++ code should use
-// PW_COMMA_ARGS.
-//
-// For example, the following does NOT work:
-/*
-     #define MY_MACRO(fmt, ...) \
-         NESTED_MACRO(fmt PW_COMMA_ARGS(__VA_ARGS__))  // BAD! Do not do this!
-*/
-// Instead, only use PW_COMMA_ARGS when the macro expands to C/C++ code:
-/*
-     #define MY_MACRO(fmt, ...) \
-         NESTED_MACRO(fmt, __VA_ARGS__)  // Pass __VA_ARGS__ to nested macros
-
-     #define NESTED_MACRO(fmt, ...) \
-         printf(fmt PW_COMMA_ARGS(__VA_ARGS__))  // PW_COMMA_ARGS is OK here
-*/
-#define PW_COMMA_ARGS(...)                                       \
-  _PW_IF(PW_EMPTY_ARGS(__VA_ARGS__), _PW_EXPAND, _PW_COMMA_ARGS) \
-  (PW_DROP_LAST_ARG_IF_EMPTY(__VA_ARGS__))
-
-#define _PW_COMMA_ARGS(...) , __VA_ARGS__
-
-// Allows calling a different function-like macro based on the number of
-// arguments.  For example:
-//
-//   #define ARG_PRINT(...)  PW_DELEGATE_BY_ARG_COUNT(_ARG_PRINT, __VA_ARGS__)
-//   #define _ARG_PRINT1(a)        LOG_INFO("1 arg: %s", a)
-//   #define _ARG_PRINT2(a, b)     LOG_INFO("2 args: %s, %s", a, b)
-//   #define _ARG_PRINT3(a, b, c)  LOG_INFO("3 args: %s, %s, %s", a, b, c)
-//
-// This can the be called in code:
-//    ARG_PRINT("a");            // Outputs: 1 arg: a
-//    ARG_PRINT("a", "b");       // Outputs: 2 arg: a, b
-//    ARG_PRINT("a", "b", "c");  // Outputs: 3 arg: a, b, c
-//
-#define PW_DELEGATE_BY_ARG_COUNT(function, ...)                 \
-  _PW_DELEGATE_BY_ARG_COUNT(                                    \
-      _PW_PASTE2(function, PW_FUNCTION_ARG_COUNT(__VA_ARGS__)), \
-      PW_DROP_LAST_ARG_IF_EMPTY(__VA_ARGS__))
-
-#define _PW_DELEGATE_BY_ARG_COUNT(function, ...) function(__VA_ARGS__)
+// This header was renamed to arguments.h. Please include arguments.h instead.
+#include "pw_preprocessor/arguments.h"
diff --git a/pw_rpc/nanopb/public/pw_rpc/test_method_context.h b/pw_rpc/nanopb/public/pw_rpc/test_method_context.h
index 0f79dd6..eb39528 100644
--- a/pw_rpc/nanopb/public/pw_rpc/test_method_context.h
+++ b/pw_rpc/nanopb/public/pw_rpc/test_method_context.h
@@ -19,7 +19,7 @@
 #include "gtest/gtest.h"
 #include "pw_assert/assert.h"
 #include "pw_containers/vector.h"
-#include "pw_preprocessor/macro_arg_count.h"
+#include "pw_preprocessor/arguments.h"
 #include "pw_rpc/channel.h"
 #include "pw_rpc/internal/hash.h"
 #include "pw_rpc/internal/method.h"
diff --git a/pw_tokenizer/public/pw_tokenizer/internal/argument_types.h b/pw_tokenizer/public/pw_tokenizer/internal/argument_types.h
index 8611577..21f5b4c 100644
--- a/pw_tokenizer/public/pw_tokenizer/internal/argument_types.h
+++ b/pw_tokenizer/public/pw_tokenizer/internal/argument_types.h
@@ -17,7 +17,7 @@
 
 #include <stdint.h>
 
-#include "pw_preprocessor/macro_arg_count.h"
+#include "pw_preprocessor/arguments.h"
 #include "pw_tokenizer/config.h"
 
 // The size of the argument types variable determines the number of arguments
diff --git a/pw_tokenizer/public/pw_tokenizer/tokenize.h b/pw_tokenizer/public/pw_tokenizer/tokenize.h
index 94a076e..3c36950 100644
--- a/pw_tokenizer/public/pw_tokenizer/tokenize.h
+++ b/pw_tokenizer/public/pw_tokenizer/tokenize.h
@@ -27,9 +27,9 @@
 
 #endif  // __cplusplus
 
+#include "pw_preprocessor/arguments.h"
 #include "pw_preprocessor/compiler.h"
 #include "pw_preprocessor/concat.h"
-#include "pw_preprocessor/macro_arg_count.h"
 #include "pw_preprocessor/util.h"
 #include "pw_tokenizer/internal/argument_types.h"
 #include "pw_tokenizer/internal/tokenize_string.h"
diff --git a/pw_trace/public/pw_trace/internal/trace_internal.h b/pw_trace/public/pw_trace/internal/trace_internal.h
index c21b7ef..f3604db 100644
--- a/pw_trace/public/pw_trace/internal/trace_internal.h
+++ b/pw_trace/public/pw_trace/internal/trace_internal.h
@@ -16,7 +16,7 @@
 
 #pragma once
 
-#include "pw_preprocessor/macro_arg_count.h"
+#include "pw_preprocessor/arguments.h"
 #include "pw_trace_backend/trace_backend.h"
 
 // Default: Flag value if none set
diff --git a/pw_trace_tokenized/public/pw_trace_tokenized/internal/trace_tokenized_internal.h b/pw_trace_tokenized/public/pw_trace_tokenized/internal/trace_tokenized_internal.h
index 1ab8536..5038887 100644
--- a/pw_trace_tokenized/public/pw_trace_tokenized/internal/trace_tokenized_internal.h
+++ b/pw_trace_tokenized/public/pw_trace_tokenized/internal/trace_tokenized_internal.h
@@ -19,7 +19,7 @@
 #include <stdbool.h>
 #include <stdint.h>
 
-#include "pw_preprocessor/macro_arg_count.h"
+#include "pw_preprocessor/arguments.h"
 
 // Because __FUNCTION__ is not a string literal to the preprocessor it can't be
 // tokenized. So this backend redefines the implementation to instead use the