blob: 03d22bbd9ce19c1724ecc5f1d9c72043806eb6fb [file] [log] [blame]
Wyatt Heplerf9fb90f2020-09-30 18:59:33 -07001.. _module-pw_preprocessor:
Alexei Frolovc10c8122019-11-01 16:31:19 -07002
Wyatt Heplerb82f9952019-11-25 13:56:31 -08003---------------
4pw_preprocessor
5---------------
Alexei Frolovc10c8122019-11-01 16:31:19 -07006The preprocessor module provides various helpful preprocessor macros.
7
8Compatibility
9=============
10C and C++
11
Alexei Frolovc10c8122019-11-01 16:31:19 -070012Headers
13=======
14The preprocessor module provides several headers.
15
Wyatt Hepler5191f582020-08-24 09:26:23 -070016pw_preprocessor/arguments.h
17---------------------------------
18Defines macros for handling variadic arguments to function-like macros. Macros
19include the following:
20
Keir Mierleb1914022021-04-12 09:08:33 -070021.. c:macro:: PW_DELEGATE_BY_ARG_COUNT(name, ...)
Wyatt Hepler5191f582020-08-24 09:26:23 -070022
23 Selects and invokes a macro based on the number of arguments provided. Expands
24 to ``<name><arg_count>(...)``. For example,
25 ``PW_DELEGATE_BY_ARG_COUNT(foo_, 1, 2, 3)`` expands to ``foo_3(1, 2, 3)``.
26
27 This example shows how ``PW_DELEGATE_BY_ARG_COUNT`` could be used to log a
28 customized message based on the number of arguments provided.
29
30 .. code-block:: cpp
31
32 #define ARG_PRINT(...) PW_DELEGATE_BY_ARG_COUNT(_ARG_PRINT, __VA_ARGS__)
Shiva Rajagopal9e516562021-05-11 17:04:15 -070033 #define _ARG_PRINT0(a) LOG_INFO("nothing!")
34 #define _ARG_PRINT1(a) LOG_INFO("1 arg: %s", a)
35 #define _ARG_PRINT2(a, b) LOG_INFO("2 args: %s, %s", a, b)
36 #define _ARG_PRINT3(a, b, c) LOG_INFO("3 args: %s, %s, %s", a, b, c)
Wyatt Hepler5191f582020-08-24 09:26:23 -070037
Shiva Rajagopal9e516562021-05-11 17:04:15 -070038 When used, ``ARG_PRINT`` expands to the ``_ARG_PRINT#`` macro corresponding
Wyatt Hepler5191f582020-08-24 09:26:23 -070039 to the number of arguments.
40
41 .. code-block:: cpp
42
43 ARG_PRINT(); // Outputs: nothing!
44 ARG_PRINT("a"); // Outputs: 1 arg: a
45 ARG_PRINT("a", "b"); // Outputs: 2 args: a, b
46 ARG_PRINT("a", "b", "c"); // Outputs: 3 args: a, b, c
47
Keir Mierleb1914022021-04-12 09:08:33 -070048.. c:macro:: PW_COMMA_ARGS(...)
Wyatt Hepler5191f582020-08-24 09:26:23 -070049
50 Expands to a comma followed by the arguments if any arguments are provided.
51 Otherwise, expands to nothing. If the final argument is empty, it is omitted.
52 This is useful when passing ``__VA_ARGS__`` to a variadic function or template
53 parameter list, since it removes the extra comma when no arguments are
54 provided. ``PW_COMMA_ARGS`` must NOT be used when invoking a macro from
55 another macro.
56
57 For example. ``PW_COMMA_ARGS(1, 2, 3)``, expands to ``, 1, 2, 3``, while
58 ``PW_COMMA_ARGS()`` expands to nothing. ``PW_COMMA_ARGS(1, 2, )`` expands to
59 ``, 1, 2``.
60
Alexei Frolovc10c8122019-11-01 16:31:19 -070061pw_preprocessor/boolean.h
62-------------------------
63Defines macros for boolean logic on literal 1s and 0s. This is useful for
64situations when a literal is needed to build the name of a function or macro.
65
66pw_preprocessor/compiler.h
67--------------------------
68Macros for compiler-specific features, such as attributes or builtins.
69
Wyatt Hepler38b6d442021-04-09 15:32:34 -070070Modifying compiler diagnostics
71^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
72``pw_preprocessor/compiler.h`` provides macros for enabling or disabling
73compiler diagnostics (warnings or errors).
74
75.. c:macro:: PW_MODIFY_DIAGNOSTICS_PUSH()
76
77 Starts a new group of :c:macro:`PW_MODIFY_DIAGNOSTIC` statements. A
78 :c:macro:`PW_MODIFY_DIAGNOSTICS_POP` statement must follow.
79
80.. c:macro:: PW_MODIFY_DIAGNOSTICS_POP()
81
82 :c:macro:`PW_MODIFY_DIAGNOSTIC` statements since the most recent
83 :c:macro:`PW_MODIFY_DIAGNOSTICS_PUSH` no longer apply after this statement.
84
85.. c:macro:: PW_MODIFY_DIAGNOSTIC(kind, option)
86
87 Changes how a diagnostic (warning or error) is handled. Most commonly used to
88 disable warnings. ``PW_MODIFY_DIAGNOSTIC`` should be used between
89 :c:macro:`PW_MODIFY_DIAGNOSTICS_PUSH` and :c:macro:`PW_MODIFY_DIAGNOSTICS_POP`
90 statements to avoid applying the modifications too broadly.
91
92 ``kind`` may be ``warning``, ``error``, or ``ignored``.
93
94These macros can be used to disable warnings for precise sections of code, even
95a single line if necessary.
96
97.. code-block:: c
98
99 PW_MODIFY_DIAGNOSTICS_PUSH();
100 PW_MODIFY_DIAGNOSTIC(ignored, "-Wunused-variable");
101
102 static int this_variable_is_never_used;
103
104 PW_MODIFY_DIAGNOSTICS_POP();
105
106.. tip::
107
108 :c:macro:`PW_MODIFY_DIAGNOSTIC` and related macros should rarely be used.
109 Whenever possible, fix the underlying issues about which the compiler is
110 warning, rather than silencing the diagnostics.
111
Alexei Frolovc10c8122019-11-01 16:31:19 -0700112pw_preprocessor/concat.h
113------------------------
114Defines the ``PW_CONCAT(...)`` macro, which expands its arguments if they are
115macros and token pastes the results. This can be used for building names of
116classes, variables, macros, etc.
117
Alexei Frolovc10c8122019-11-01 16:31:19 -0700118pw_preprocessor/util.h
119----------------------
120General purpose, useful macros.
121
122* ``PW_ARRAY_SIZE(array)`` -- calculates the size of a C array
Alexei Frolovc10c8122019-11-01 16:31:19 -0700123* ``PW_STRINGIFY(...)`` -- expands its arguments as macros and converts them to
124 a string literal
125* ``PW_EXTERN_C`` -- declares a name to be ``extern "C"`` in C++; expands to
126 nothing in C
127* ``PW_EXTERN_C_START`` / ``PW_EXTERN_C_END`` -- declares an ``extern "C" { }``
128 block in C++; expands to nothing in C