Wyatt Hepler | f9fb90f | 2020-09-30 18:59:33 -0700 | [diff] [blame] | 1 | .. _module-pw_preprocessor: |
Alexei Frolov | c10c812 | 2019-11-01 16:31:19 -0700 | [diff] [blame] | 2 | |
Wyatt Hepler | b82f995 | 2019-11-25 13:56:31 -0800 | [diff] [blame] | 3 | --------------- |
| 4 | pw_preprocessor |
| 5 | --------------- |
Alexei Frolov | c10c812 | 2019-11-01 16:31:19 -0700 | [diff] [blame] | 6 | The preprocessor module provides various helpful preprocessor macros. |
| 7 | |
| 8 | Compatibility |
| 9 | ============= |
| 10 | C and C++ |
| 11 | |
Alexei Frolov | c10c812 | 2019-11-01 16:31:19 -0700 | [diff] [blame] | 12 | Headers |
| 13 | ======= |
| 14 | The preprocessor module provides several headers. |
| 15 | |
Wyatt Hepler | 5191f58 | 2020-08-24 09:26:23 -0700 | [diff] [blame] | 16 | pw_preprocessor/arguments.h |
| 17 | --------------------------------- |
| 18 | Defines macros for handling variadic arguments to function-like macros. Macros |
| 19 | include the following: |
| 20 | |
Keir Mierle | b191402 | 2021-04-12 09:08:33 -0700 | [diff] [blame] | 21 | .. c:macro:: PW_DELEGATE_BY_ARG_COUNT(name, ...) |
Wyatt Hepler | 5191f58 | 2020-08-24 09:26:23 -0700 | [diff] [blame] | 22 | |
| 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 Rajagopal | 9e51656 | 2021-05-11 17:04:15 -0700 | [diff] [blame^] | 33 | #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 Hepler | 5191f58 | 2020-08-24 09:26:23 -0700 | [diff] [blame] | 37 | |
Shiva Rajagopal | 9e51656 | 2021-05-11 17:04:15 -0700 | [diff] [blame^] | 38 | When used, ``ARG_PRINT`` expands to the ``_ARG_PRINT#`` macro corresponding |
Wyatt Hepler | 5191f58 | 2020-08-24 09:26:23 -0700 | [diff] [blame] | 39 | 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 Mierle | b191402 | 2021-04-12 09:08:33 -0700 | [diff] [blame] | 48 | .. c:macro:: PW_COMMA_ARGS(...) |
Wyatt Hepler | 5191f58 | 2020-08-24 09:26:23 -0700 | [diff] [blame] | 49 | |
| 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 Frolov | c10c812 | 2019-11-01 16:31:19 -0700 | [diff] [blame] | 61 | pw_preprocessor/boolean.h |
| 62 | ------------------------- |
| 63 | Defines macros for boolean logic on literal 1s and 0s. This is useful for |
| 64 | situations when a literal is needed to build the name of a function or macro. |
| 65 | |
| 66 | pw_preprocessor/compiler.h |
| 67 | -------------------------- |
| 68 | Macros for compiler-specific features, such as attributes or builtins. |
| 69 | |
Wyatt Hepler | 38b6d44 | 2021-04-09 15:32:34 -0700 | [diff] [blame] | 70 | Modifying compiler diagnostics |
| 71 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 72 | ``pw_preprocessor/compiler.h`` provides macros for enabling or disabling |
| 73 | compiler 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 | |
| 94 | These macros can be used to disable warnings for precise sections of code, even |
| 95 | a 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 Frolov | c10c812 | 2019-11-01 16:31:19 -0700 | [diff] [blame] | 112 | pw_preprocessor/concat.h |
| 113 | ------------------------ |
| 114 | Defines the ``PW_CONCAT(...)`` macro, which expands its arguments if they are |
| 115 | macros and token pastes the results. This can be used for building names of |
| 116 | classes, variables, macros, etc. |
| 117 | |
Alexei Frolov | c10c812 | 2019-11-01 16:31:19 -0700 | [diff] [blame] | 118 | pw_preprocessor/util.h |
| 119 | ---------------------- |
| 120 | General purpose, useful macros. |
| 121 | |
| 122 | * ``PW_ARRAY_SIZE(array)`` -- calculates the size of a C array |
Alexei Frolov | c10c812 | 2019-11-01 16:31:19 -0700 | [diff] [blame] | 123 | * ``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 |