LCOV - code coverage report
Current view: top level - zephyr/sys - util_macro.h Coverage Total Hit
Test: new.info Lines: 100.0 % 41 41
Test Date: 2025-09-05 16:43:28

            Line data    Source code
       1            1 : /*
       2              :  * Copyright (c) 2011-2014, Wind River Systems, Inc.
       3              :  *
       4              :  * SPDX-License-Identifier: Apache-2.0
       5              :  */
       6              : 
       7              : /**
       8              :  * @file
       9              :  * @brief Macro utilities
      10              :  *
      11              :  * Macro utilities are the public interface for C/C++ code and device tree
      12              :  * related implementation.  In general, C/C++ will include <sys/util.h>
      13              :  * instead this file directly.  For device tree implementation, this file
      14              :  * should be include instead <sys/util_internal.h>
      15              :  */
      16              : 
      17              : #ifndef ZEPHYR_INCLUDE_SYS_UTIL_MACROS_H_
      18              : #define ZEPHYR_INCLUDE_SYS_UTIL_MACROS_H_
      19              : 
      20              : #ifdef __cplusplus
      21              : extern "C" {
      22              : #endif
      23              : 
      24              : /**
      25              :  * @addtogroup sys-util
      26              :  * @{
      27              :  */
      28              : 
      29              : /*
      30              :  * Most of the eldritch implementation details for all the macrobatics
      31              :  * below (APIs like IS_ENABLED(), COND_CODE_1(), etc.) are hidden away
      32              :  * in this file.
      33              :  */
      34              : #include <zephyr/sys/util_internal.h>
      35              : 
      36              : #ifndef BIT
      37              : #if defined(_ASMLANGUAGE)
      38              : #define BIT(n)  (1 << (n))
      39              : #else
      40              : /**
      41              :  * @brief Unsigned integer with bit position @p n set (signed in
      42              :  * assembly language).
      43              :  */
      44            1 : #define BIT(n)  (1UL << (n))
      45              : #endif
      46              : #endif
      47              : 
      48              : /** @brief 64-bit unsigned integer with bit position @p _n set. */
      49            1 : #define BIT64(_n) (1ULL << (_n))
      50              : 
      51              : /**
      52              :  * @brief Set or clear a bit depending on a boolean value
      53              :  *
      54              :  * The argument @p var is a variable whose value is written to as a
      55              :  * side effect.
      56              :  *
      57              :  * @param var Variable to be altered
      58              :  * @param bit Bit number
      59              :  * @param set if 0, clears @p bit in @p var; any other value sets @p bit
      60              :  */
      61            1 : #define WRITE_BIT(var, bit, set) \
      62              :         ((var) = (set) ? ((var) | BIT(bit)) : ((var) & ~BIT(bit)))
      63              : 
      64              : /**
      65              :  * @brief Bit mask with bits 0 through <tt>n-1</tt> (inclusive) set,
      66              :  * or 0 if @p n is 0.
      67              :  */
      68            1 : #define BIT_MASK(n) (BIT(n) - 1UL)
      69              : 
      70              : /**
      71              :  * @brief 64-bit bit mask with bits 0 through <tt>n-1</tt> (inclusive) set,
      72              :  * or 0 if @p n is 0.
      73              :  */
      74            1 : #define BIT64_MASK(n) (BIT64(n) - 1ULL)
      75              : 
      76              : /** @brief Check if a @p x is a power of two */
      77            1 : #define IS_POWER_OF_TWO(x) (((x) != 0U) && (((x) & ((x) - 1U)) == 0U))
      78              : 
      79              : /**
      80              :  * @brief Check if bits are set continuously from the specified bit
      81              :  *
      82              :  * The macro is not dependent on the bit-width.
      83              :  *
      84              :  * @param m Check whether the bits are set continuously or not.
      85              :  * @param s Specify the lowest bit for that is continuously set bits.
      86              :  */
      87            1 : #define IS_SHIFTED_BIT_MASK(m, s) (!(((m) >> (s)) & (((m) >> (s)) + 1U)))
      88              : 
      89              : /**
      90              :  * @brief Check if bits are set continuously from the LSB.
      91              :  *
      92              :  * @param m Check whether the bits are set continuously from LSB.
      93              :  */
      94            1 : #define IS_BIT_MASK(m) IS_SHIFTED_BIT_MASK(m, 0)
      95              : 
      96              : /**
      97              :  * @brief Check if bit is set in a value
      98              :  *
      99              :  * @param value Value that contain checked bit
     100              :  * @param bit Bit number
     101              :  */
     102            1 : #define IS_BIT_SET(value, bit) ((((value) >> (bit)) & (0x1)) != 0)
     103              : 
     104              : /** @brief Extract the Least Significant Bit from @p value. */
     105            1 : #define LSB_GET(value) ((value) & -(value))
     106              : 
     107              : /**
     108              :  * @brief Extract a bitfield element from @p value corresponding to
     109              :  *        the field mask @p mask.
     110              :  */
     111            1 : #define FIELD_GET(mask, value)  (((value) & (mask)) / LSB_GET(mask))
     112              : 
     113              : /**
     114              :  * @brief Prepare a bitfield element using @p value with @p mask representing
     115              :  *        its field position and width. The result should be combined
     116              :  *        with other fields using a logical OR.
     117              :  */
     118            1 : #define FIELD_PREP(mask, value) (((value) * LSB_GET(mask)) & (mask))
     119              : 
     120              : /**
     121              :  * @brief Check for macro definition in compiler-visible expressions
     122              :  *
     123              :  * This trick was pioneered in Linux as the config_enabled() macro. It
     124              :  * has the effect of taking a macro value that may be defined to "1"
     125              :  * or may not be defined at all and turning it into a literal
     126              :  * expression that can be handled by the C compiler instead of just
     127              :  * the preprocessor. It is often used with a @p CONFIG_FOO macro which
     128              :  * may be defined to 1 via Kconfig, or left undefined.
     129              :  *
     130              :  * That is, it works similarly to <tt>\#if defined(CONFIG_FOO)</tt>
     131              :  * except that its expansion is a C expression. Thus, much <tt>\#ifdef</tt>
     132              :  * usage can be replaced with equivalents like:
     133              :  *
     134              :  *     if (IS_ENABLED(CONFIG_FOO)) {
     135              :  *             do_something_with_foo
     136              :  *     }
     137              :  *
     138              :  * This is cleaner since the compiler can generate errors and warnings
     139              :  * for @p do_something_with_foo even when @p CONFIG_FOO is undefined.
     140              :  *
     141              :  * Note: Use of IS_ENABLED in a <tt>\#if</tt> statement is discouraged
     142              :  *       as it doesn't provide any benefit vs plain <tt>\#if defined()</tt>
     143              :  *
     144              :  * @param config_macro Macro to check
     145              :  * @return 1 if @p config_macro is defined to 1, 0 otherwise (including
     146              :  *         if @p config_macro is not defined)
     147              :  */
     148            1 : #define IS_ENABLED(config_macro) Z_IS_ENABLED1(config_macro)
     149              : /* INTERNAL: the first pass above is just to expand any existing
     150              :  * macros, we need the macro value to be e.g. a literal "1" at
     151              :  * expansion time in the next macro, not "(1)", etc... Standard
     152              :  * recursive expansion does not work.
     153              :  */
     154              : 
     155              : /**
     156              :  * @brief Insert code depending on whether @p _flag expands to 1 or not.
     157              :  *
     158              :  * This relies on similar tricks as IS_ENABLED(), but as the result of
     159              :  * @p _flag expansion, results in either @p _if_1_code or @p
     160              :  * _else_code is expanded.
     161              :  *
     162              :  * To prevent the preprocessor from treating commas as argument
     163              :  * separators, the @p _if_1_code and @p _else_code expressions must be
     164              :  * inside brackets/parentheses: <tt>()</tt>. These are stripped away
     165              :  * during macro expansion.
     166              :  *
     167              :  * Example:
     168              :  *
     169              :  *     COND_CODE_1(CONFIG_FLAG, (uint32_t x;), (there_is_no_flag();))
     170              :  *
     171              :  * If @p CONFIG_FLAG is defined to 1, this expands to:
     172              :  *
     173              :  *     uint32_t x;
     174              :  *
     175              :  * It expands to <tt>there_is_no_flag();</tt> otherwise.
     176              :  *
     177              :  * This could be used as an alternative to:
     178              :  *
     179              :  *     #if defined(CONFIG_FLAG) && (CONFIG_FLAG == 1)
     180              :  *     #define MAYBE_DECLARE(x) uint32_t x
     181              :  *     #else
     182              :  *     #define MAYBE_DECLARE(x) there_is_no_flag()
     183              :  *     #endif
     184              :  *
     185              :  *     MAYBE_DECLARE(x);
     186              :  *
     187              :  * However, the advantage of COND_CODE_1() is that code is resolved in
     188              :  * place where it is used, while the @p \#if method defines @p
     189              :  * MAYBE_DECLARE on two lines and requires it to be invoked again on a
     190              :  * separate line. This makes COND_CODE_1() more concise and also
     191              :  * sometimes more useful when used within another macro's expansion.
     192              :  *
     193              :  * @note @p _flag can be the result of preprocessor expansion, e.g.
     194              :  *       an expression involving <tt>NUM_VA_ARGS_LESS_1(...)</tt>.
     195              :  *       However, @p _if_1_code is only expanded if @p _flag expands
     196              :  *       to the integer literal 1. Integer expressions that evaluate
     197              :  *       to 1, e.g. after doing some arithmetic, will not work.
     198              :  *
     199              :  * @param _flag evaluated flag
     200              :  * @param _if_1_code result if @p _flag expands to 1; must be in parentheses
     201              :  * @param _else_code result otherwise; must be in parentheses
     202              :  */
     203            1 : #define COND_CODE_1(_flag, _if_1_code, _else_code) \
     204              :         Z_COND_CODE_1(_flag, _if_1_code, _else_code)
     205              : 
     206              : /**
     207              :  * @brief Like COND_CODE_1() except tests if @p _flag is 0.
     208              :  *
     209              :  * This is like COND_CODE_1(), except that it tests whether @p _flag
     210              :  * expands to the integer literal 0. It expands to @p _if_0_code if
     211              :  * so, and @p _else_code otherwise; both of these must be enclosed in
     212              :  * parentheses.
     213              :  *
     214              :  * @param _flag evaluated flag
     215              :  * @param _if_0_code result if @p _flag expands to 0; must be in parentheses
     216              :  * @param _else_code result otherwise; must be in parentheses
     217              :  * @see COND_CODE_1()
     218              :  */
     219            1 : #define COND_CODE_0(_flag, _if_0_code, _else_code) \
     220              :         Z_COND_CODE_0(_flag, _if_0_code, _else_code)
     221              : 
     222              : /**
     223              :  * @brief Insert code if @p _flag is defined and equals 1.
     224              :  *
     225              :  * Like COND_CODE_1(), this expands to @p _code if @p _flag is defined to 1;
     226              :  * it expands to nothing otherwise.
     227              :  *
     228              :  * Example:
     229              :  *
     230              :  *     IF_ENABLED(CONFIG_FLAG, (uint32_t foo;))
     231              :  *
     232              :  * If @p CONFIG_FLAG is defined to 1, this expands to:
     233              :  *
     234              :  *     uint32_t foo;
     235              :  *
     236              :  * and to nothing otherwise.
     237              :  *
     238              :  * It can be considered as a more compact alternative to:
     239              :  *
     240              :  *     #if defined(CONFIG_FLAG) && (CONFIG_FLAG == 1)
     241              :  *     uint32_t foo;
     242              :  *     #endif
     243              :  *
     244              :  * @param _flag evaluated flag
     245              :  * @param _code result if @p _flag expands to 1; must be in parentheses
     246              :  */
     247            1 : #define IF_ENABLED(_flag, _code) \
     248              :         COND_CODE_1(_flag, _code, ())
     249              : 
     250              : /**
     251              :  * @brief Insert code if @p _flag is not defined as 1.
     252              :  *
     253              :  * This expands to nothing if @p _flag is defined and equal to 1;
     254              :  * it expands to @p _code otherwise.
     255              :  *
     256              :  * Example:
     257              :  *
     258              :  *     IF_DISABLED(CONFIG_FLAG, (uint32_t foo;))
     259              :  *
     260              :  * If @p CONFIG_FLAG isn't defined or different than 1, this expands to:
     261              :  *
     262              :  *     uint32_t foo;
     263              :  *
     264              :  * and to nothing otherwise.
     265              :  *
     266              :  * IF_DISABLED does the opposite of IF_ENABLED.
     267              :  *
     268              :  * @param _flag evaluated flag
     269              :  * @param _code result if @p _flag does not expand to 1; must be in parentheses
     270              :  */
     271            1 : #define IF_DISABLED(_flag, _code) \
     272              :         COND_CODE_1(_flag, (), _code)
     273              : 
     274              : /**
     275              :  * @brief Check if a macro has a replacement expression
     276              :  *
     277              :  * If @p a is a macro defined to a nonempty value, this will return
     278              :  * true, otherwise it will return false. It only works with defined
     279              :  * macros, so an additional @p \#ifdef test may be needed in some cases.
     280              :  *
     281              :  * This macro may be used with COND_CODE_1() and COND_CODE_0() while
     282              :  * processing `__VA_ARGS__` to avoid processing empty arguments.
     283              :  *
     284              :  * Example:
     285              :  *
     286              :  *      #define EMPTY
     287              :  *      #define NON_EMPTY       1
     288              :  *      #undef  UNDEFINED
     289              :  *      IS_EMPTY(EMPTY)
     290              :  *      IS_EMPTY(NON_EMPTY)
     291              :  *      IS_EMPTY(UNDEFINED)
     292              :  *      #if defined(EMPTY) && IS_EMPTY(EMPTY) == true
     293              :  *      some_conditional_code
     294              :  *      #endif
     295              :  *
     296              :  * In above examples, the invocations of IS_EMPTY(...) return @p true,
     297              :  * @p false, and @p true; @p some_conditional_code is included.
     298              :  *
     299              :  * @param ... macro to check for emptiness (may be `__VA_ARGS__`)
     300              :  */
     301            1 : #define IS_EMPTY(...) Z_IS_EMPTY_(__VA_ARGS__)
     302              : 
     303              : /**
     304              :  * @brief Like <tt>a == b</tt>, but does evaluation and
     305              :  * short-circuiting at C preprocessor time.
     306              :  *
     307              :  * This however only works for integer literal from 0 to 4096 (literals with U suffix,
     308              :  * e.g. 0U are also included).
     309              :  *
     310              :  * Examples:
     311              :  *
     312              :  *   IS_EQ(1, 1)   -> 1
     313              :  *   IS_EQ(1U, 1U) -> 1
     314              :  *   IS_EQ(1U, 1)  -> 1
     315              :  *   IS_EQ(1, 1U)  -> 1
     316              :  *   IS_EQ(1, 0)   -> 0
     317              :  *
     318              :  * @param a Integer literal (can be with U suffix)
     319              :  * @param b Integer literal
     320              :  *
     321              :  */
     322            1 : #define IS_EQ(a, b) Z_IS_EQ(a, b)
     323              : 
     324              : /**
     325              :  * @brief Remove empty arguments from list.
     326              :  *
     327              :  * During macro expansion, `__VA_ARGS__` and other preprocessor
     328              :  * generated lists may contain empty elements, e.g.:
     329              :  *
     330              :  *      #define LIST ,a,b,,d,
     331              :  *
     332              :  * Using EMPTY to show each empty element, LIST contains:
     333              :  *
     334              :  *      EMPTY, a, b, EMPTY, d
     335              :  *
     336              :  * When processing such lists, e.g. using FOR_EACH(), all empty elements
     337              :  * will be processed, and may require filtering out.
     338              :  * To make that process easier, it is enough to invoke LIST_DROP_EMPTY
     339              :  * which will remove all empty elements.
     340              :  *
     341              :  * Example:
     342              :  *
     343              :  *      LIST_DROP_EMPTY(LIST)
     344              :  *
     345              :  * expands to:
     346              :  *
     347              :  *      a, b, d
     348              :  *
     349              :  * @param ... list to be processed
     350              :  */
     351            1 : #define LIST_DROP_EMPTY(...) \
     352              :         Z_LIST_DROP_FIRST(FOR_EACH(Z_LIST_NO_EMPTIES, (), __VA_ARGS__))
     353              : 
     354              : /**
     355              :  * @brief Macro with an empty expansion
     356              :  *
     357              :  * This trivial definition is provided for readability when a macro
     358              :  * should expand to an empty result, which e.g. is sometimes needed to
     359              :  * silence checkpatch.
     360              :  *
     361              :  * Example:
     362              :  *
     363              :  *      #define LIST_ITEM(n) , item##n
     364              :  *
     365              :  * The above would cause checkpatch to complain, but:
     366              :  *
     367              :  *      #define LIST_ITEM(n) EMPTY, item##n
     368              :  *
     369              :  * would not.
     370              :  */
     371            1 : #define EMPTY
     372              : 
     373              : /**
     374              :  * @brief Macro that expands to its argument
     375              :  *
     376              :  * This is useful in macros like @c FOR_EACH() when there is no
     377              :  * transformation required on the list elements.
     378              :  *
     379              :  * @param V any value
     380              :  */
     381            1 : #define IDENTITY(V) V
     382              : 
     383              : /**
     384              :  * @brief Get nth argument from argument list.
     385              :  *
     386              :  * @param N Argument index to fetch. Counter from 1.
     387              :  * @param ... Variable list of arguments from which one argument is returned.
     388              :  *
     389              :  * @return Nth argument.
     390              :  */
     391            1 : #define GET_ARG_N(N, ...) Z_GET_ARG_##N(__VA_ARGS__)
     392              : 
     393              : /**
     394              :  * @brief Strips n first arguments from the argument list.
     395              :  *
     396              :  * @param N Number of arguments to discard.
     397              :  * @param ... Variable list of arguments.
     398              :  *
     399              :  * @return argument list without N first arguments.
     400              :  */
     401            1 : #define GET_ARGS_LESS_N(N, ...) Z_GET_ARGS_LESS_##N(__VA_ARGS__)
     402              : 
     403              : /**
     404              :  * @brief Like <tt>a || b</tt>, but does evaluation and
     405              :  * short-circuiting at C preprocessor time.
     406              :  *
     407              :  * This is not the same as the binary @p || operator; in particular,
     408              :  * @p a should expand to an integer literal 0 or 1. However, @p b
     409              :  * can be any value.
     410              :  *
     411              :  * This can be useful when @p b is an expression that would cause a
     412              :  * build error when @p a is 1.
     413              :  */
     414            1 : #define UTIL_OR(a, b) COND_CODE_1(UTIL_BOOL(a), (a), (b))
     415              : 
     416              : /**
     417              :  * @brief Like <tt>a && b</tt>, but does evaluation and
     418              :  * short-circuiting at C preprocessor time.
     419              :  *
     420              :  * This is not the same as the binary @p &&, however; in particular,
     421              :  * @p a should expand to an integer literal 0 or 1. However, @p b
     422              :  * can be any value.
     423              :  *
     424              :  * This can be useful when @p b is an expression that would cause a
     425              :  * build error when @p a is 0.
     426              :  */
     427            1 : #define UTIL_AND(a, b) COND_CODE_1(UTIL_BOOL(a), (b), (0))
     428              : 
     429              : /**
     430              :  * @brief UTIL_INC(x) for an integer literal x from 0 to 4095 expands to an
     431              :  * integer literal whose value is x+1.
     432              :  *
     433              :  * @see UTIL_DEC(x)
     434              :  */
     435            1 : #define UTIL_INC(x) UTIL_PRIMITIVE_CAT(Z_UTIL_INC_, x)
     436              : 
     437              : /**
     438              :  * @brief UTIL_DEC(x) for an integer literal x from 0 to 4095 expands to an
     439              :  * integer literal whose value is x-1.
     440              :  *
     441              :  * @see UTIL_INC(x)
     442              :  */
     443            1 : #define UTIL_DEC(x) UTIL_PRIMITIVE_CAT(Z_UTIL_DEC_, x)
     444              : 
     445              : /**
     446              :  * @brief UTIL_X2(y) for an integer literal y from 0 to 4095 expands to an
     447              :  * integer literal whose value is 2y.
     448              :  */
     449            1 : #define UTIL_X2(y) UTIL_PRIMITIVE_CAT(Z_UTIL_X2_, y)
     450              : 
     451              : 
     452              : /**
     453              :  * @brief Generates a sequence of code with configurable separator.
     454              :  *
     455              :  * Example:
     456              :  *
     457              :  *     #define FOO(i, _) MY_PWM ## i
     458              :  *     { LISTIFY(PWM_COUNT, FOO, (,)) }
     459              :  *
     460              :  * The above two lines expand to:
     461              :  *
     462              :  *    { MY_PWM0 , MY_PWM1 }
     463              :  *
     464              :  * @param LEN The length of the sequence. Must be an integer literal less
     465              :  *            than 4095.
     466              :  * @param F A macro function that accepts at least two arguments:
     467              :  *          <tt>F(i, ...)</tt>. @p F is called repeatedly in the expansion.
     468              :  *          Its first argument @p i is the index in the sequence, and
     469              :  *          the variable list of arguments passed to LISTIFY are passed
     470              :  *          through to @p F.
     471              :  *
     472              :  * @param sep Separator (e.g. comma or semicolon). Must be in parentheses;
     473              :  *            this is required to enable providing a comma as separator.
     474              :  *
     475              :  * @note Calling LISTIFY with undefined arguments has undefined
     476              :  * behavior.
     477              :  */
     478            1 : #define LISTIFY(LEN, F, sep, ...) UTIL_CAT(Z_UTIL_LISTIFY_, LEN)(F, sep, __VA_ARGS__)
     479              : 
     480              : /**
     481              :  * @brief Call a macro @p F on each provided argument with a given
     482              :  *        separator between each call.
     483              :  *
     484              :  * Example:
     485              :  *
     486              :  *     #define F(x) int a##x
     487              :  *     FOR_EACH(F, (;), 4, 5, 6);
     488              :  *
     489              :  * This expands to:
     490              :  *
     491              :  *     int a4;
     492              :  *     int a5;
     493              :  *     int a6;
     494              :  *
     495              :  * @param F Macro to invoke
     496              :  * @param sep Separator (e.g. comma or semicolon). Must be in parentheses;
     497              :  *            this is required to enable providing a comma as separator.
     498              :  * @param ... Variable argument list. The macro @p F is invoked as
     499              :  *            <tt>F(element)</tt> for each element in the list.
     500              :  */
     501            1 : #define FOR_EACH(F, sep, ...) \
     502              :         Z_FOR_EACH(F, sep, REVERSE_ARGS(__VA_ARGS__))
     503              : 
     504              : /**
     505              :  * @brief Like FOR_EACH(), but with a terminator instead of a separator,
     506              :  *        and drops empty elements from the argument list
     507              :  *
     508              :  * The @p sep argument to <tt>FOR_EACH(F, (sep), a, b)</tt> is a
     509              :  * separator which is placed between calls to @p F, like this:
     510              :  *
     511              :  *     FOR_EACH(F, (sep), a, b) // F(a) sep F(b)
     512              :  *                              //               ^^^ no sep here!
     513              :  *
     514              :  * By contrast, the @p term argument to <tt>FOR_EACH_NONEMPTY_TERM(F, (term),
     515              :  * a, b)</tt> is added after each time @p F appears in the expansion:
     516              :  *
     517              :  *     FOR_EACH_NONEMPTY_TERM(F, (term), a, b) // F(a) term F(b) term
     518              :  *                                             //                ^^^^
     519              :  *
     520              :  * Further, any empty elements are dropped:
     521              :  *
     522              :  *     FOR_EACH_NONEMPTY_TERM(F, (term), a, EMPTY, b) // F(a) term F(b) term
     523              :  *
     524              :  * This is more convenient in some cases, because FOR_EACH_NONEMPTY_TERM()
     525              :  * expands to nothing when given an empty argument list, and it's
     526              :  * often cumbersome to write a macro @p F that does the right thing
     527              :  * even when given an empty argument.
     528              :  *
     529              :  * One example is when `__VA_ARGS__` may or may not be empty,
     530              :  * and the results are embedded in a larger initializer:
     531              :  *
     532              :  *     #define SQUARE(x) ((x)*(x))
     533              :  *
     534              :  *     int my_array[] = {
     535              :  *             FOR_EACH_NONEMPTY_TERM(SQUARE, (,), FOO(...))
     536              :  *             FOR_EACH_NONEMPTY_TERM(SQUARE, (,), BAR(...))
     537              :  *             FOR_EACH_NONEMPTY_TERM(SQUARE, (,), BAZ(...))
     538              :  *     };
     539              :  *
     540              :  * This is more convenient than:
     541              :  *
     542              :  * 1. figuring out whether the @p FOO, @p BAR, and @p BAZ expansions
     543              :  *    are empty and adding a comma manually (or not) between FOR_EACH()
     544              :  *    calls
     545              :  * 2. rewriting SQUARE so it reacts appropriately when "x" is empty
     546              :  *    (which would be necessary if e.g. @p FOO expands to nothing)
     547              :  *
     548              :  * @param F Macro to invoke on each nonempty element of the variable
     549              :  *          arguments
     550              :  * @param term Terminator (e.g. comma or semicolon) placed after each
     551              :  *             invocation of F. Must be in parentheses; this is required
     552              :  *             to enable providing a comma as separator.
     553              :  * @param ... Variable argument list. The macro @p F is invoked as
     554              :  *            <tt>F(element)</tt> for each nonempty element in the list.
     555              :  */
     556            1 : #define FOR_EACH_NONEMPTY_TERM(F, term, ...)                            \
     557              :         COND_CODE_0(                                                    \
     558              :                 /* are there zero non-empty arguments ? */              \
     559              :                 NUM_VA_ARGS_LESS_1(LIST_DROP_EMPTY(__VA_ARGS__, _)),    \
     560              :                 /* if so, expand to nothing */                          \
     561              :                 (),                                                     \
     562              :                 /* otherwise, expand to: */                             \
     563              :                 (/* FOR_EACH() on nonempty elements, */         \
     564              :                         FOR_EACH(F, term, LIST_DROP_EMPTY(__VA_ARGS__)) \
     565              :                         /* plus a final terminator */                   \
     566              :                         __DEBRACKET term                                \
     567              :                 ))
     568              : 
     569              : /**
     570              :  * @brief Call macro @p F on each provided argument, with the argument's index
     571              :  *        as an additional parameter.
     572              :  *
     573              :  * This is like FOR_EACH(), except @p F should be a macro which takes two
     574              :  * arguments: <tt>F(index, variable_arg)</tt>.
     575              :  *
     576              :  * Example:
     577              :  *
     578              :  *     #define F(idx, x) int a##idx = x
     579              :  *     FOR_EACH_IDX(F, (;), 4, 5, 6);
     580              :  *
     581              :  * This expands to:
     582              :  *
     583              :  *     int a0 = 4;
     584              :  *     int a1 = 5;
     585              :  *     int a2 = 6;
     586              :  *
     587              :  * @param F Macro to invoke
     588              :  * @param sep Separator (e.g. comma or semicolon). Must be in parentheses;
     589              :  *            this is required to enable providing a comma as separator.
     590              :  * @param ... Variable argument list. The macro @p F is invoked as
     591              :  *            <tt>F(index, element)</tt> for each element in the list.
     592              :  */
     593            1 : #define FOR_EACH_IDX(F, sep, ...) \
     594              :         Z_FOR_EACH_IDX(F, sep, REVERSE_ARGS(__VA_ARGS__))
     595              : 
     596              : /**
     597              :  * @brief Call macro @p F on each provided argument, with an additional fixed
     598              :  *        argument as a parameter.
     599              :  *
     600              :  * This is like FOR_EACH(), except @p F should be a macro which takes two
     601              :  * arguments: <tt>F(variable_arg, fixed_arg)</tt>.
     602              :  *
     603              :  * Example:
     604              :  *
     605              :  *     static void func(int val, void *dev);
     606              :  *     FOR_EACH_FIXED_ARG(func, (;), dev, 4, 5, 6);
     607              :  *
     608              :  * This expands to:
     609              :  *
     610              :  *     func(4, dev);
     611              :  *     func(5, dev);
     612              :  *     func(6, dev);
     613              :  *
     614              :  * @param F Macro to invoke
     615              :  * @param sep Separator (e.g. comma or semicolon). Must be in parentheses;
     616              :  *            this is required to enable providing a comma as separator.
     617              :  * @param fixed_arg Fixed argument passed to @p F as the second macro parameter.
     618              :  * @param ... Variable argument list. The macro @p F is invoked as
     619              :  *            <tt>F(element, fixed_arg)</tt> for each element in the list.
     620              :  */
     621            1 : #define FOR_EACH_FIXED_ARG(F, sep, fixed_arg, ...) \
     622              :         Z_FOR_EACH_FIXED_ARG(F, sep, fixed_arg, REVERSE_ARGS(__VA_ARGS__))
     623              : 
     624              : /**
     625              :  * @brief Calls macro @p F for each variable argument with an index and fixed
     626              :  *        argument
     627              :  *
     628              :  * This is like the combination of FOR_EACH_IDX() with FOR_EACH_FIXED_ARG().
     629              :  *
     630              :  * Example:
     631              :  *
     632              :  *     #define F(idx, x, fixed_arg) int fixed_arg##idx = x
     633              :  *     FOR_EACH_IDX_FIXED_ARG(F, (;), a, 4, 5, 6);
     634              :  *
     635              :  * This expands to:
     636              :  *
     637              :  *     int a0 = 4;
     638              :  *     int a1 = 5;
     639              :  *     int a2 = 6;
     640              :  *
     641              :  * @param F Macro to invoke
     642              :  * @param sep Separator (e.g. comma or semicolon). Must be in parentheses;
     643              :  *            This is required to enable providing a comma as separator.
     644              :  * @param fixed_arg Fixed argument passed to @p F as the third macro parameter.
     645              :  * @param ... Variable list of arguments. The macro @p F is invoked as
     646              :  *            <tt>F(index, element, fixed_arg)</tt> for each element in
     647              :  *            the list.
     648              :  */
     649            1 : #define FOR_EACH_IDX_FIXED_ARG(F, sep, fixed_arg, ...) \
     650              :         Z_FOR_EACH_IDX_FIXED_ARG(F, sep, fixed_arg, REVERSE_ARGS(__VA_ARGS__))
     651              : 
     652              : /** @brief Reverse arguments order.
     653              :  *
     654              :  * @param ... Variable argument list.
     655              :  */
     656            1 : #define REVERSE_ARGS(...) \
     657              :         Z_FOR_EACH_ENGINE(Z_FOR_EACH_EXEC, (,), Z_BYPASS, _, __VA_ARGS__)
     658              : 
     659              : /**
     660              :  * @brief Number of arguments in the variable arguments list minus one.
     661              :  *
     662              :  * @note Supports up to 64 arguments.
     663              :  *
     664              :  * @param ... List of arguments
     665              :  * @return  Number of variadic arguments in the argument list, minus one
     666              :  */
     667            1 : #define NUM_VA_ARGS_LESS_1(...) \
     668              :         NUM_VA_ARGS_LESS_1_IMPL(__VA_ARGS__, 63, 62, 61, \
     669              :         60, 59, 58, 57, 56, 55, 54, 53, 52, 51,          \
     670              :         50, 49, 48, 47, 46, 45, 44, 43, 42, 41,          \
     671              :         40, 39, 38, 37, 36, 35, 34, 33, 32, 31,          \
     672              :         30, 29, 28, 27, 26, 25, 24, 23, 22, 21,          \
     673              :         20, 19, 18, 17, 16, 15, 14, 13, 12, 11,          \
     674              :         10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, ~)
     675              : 
     676              : /**
     677              :  * @brief Number of arguments in the variable arguments list.
     678              :  *
     679              :  * @note Supports up to 63 arguments.
     680              :  *
     681              :  * @param ... List of arguments
     682              :  * @return  Number of variadic arguments in the argument list
     683              :  */
     684            1 : #define NUM_VA_ARGS(...)                                                                           \
     685              :         COND_CODE_1(IS_EMPTY(__VA_ARGS__), (0), (UTIL_INC(NUM_VA_ARGS_LESS_1(__VA_ARGS__))))
     686              : 
     687              : /**
     688              :  * @brief Mapping macro that pastes results together
     689              :  *
     690              :  * This is similar to FOR_EACH() in that it invokes a macro repeatedly
     691              :  * on each element of `__VA_ARGS__`. However, unlike FOR_EACH(),
     692              :  * MACRO_MAP_CAT() pastes the results together into a single token.
     693              :  *
     694              :  * For example, with this macro FOO:
     695              :  *
     696              :  *     #define FOO(x) item_##x##_
     697              :  *
     698              :  * <tt>MACRO_MAP_CAT(FOO, a, b, c),</tt> expands to the token:
     699              :  *
     700              :  *     item_a_item_b_item_c_
     701              :  *
     702              :  * @param ... Macro to expand on each argument, followed by its
     703              :  *            arguments. (The macro should take exactly one argument.)
     704              :  * @return The results of expanding the macro on each argument, all pasted
     705              :  *         together
     706              :  */
     707            1 : #define MACRO_MAP_CAT(...) MACRO_MAP_CAT_(__VA_ARGS__)
     708              : 
     709              : /**
     710              :  * @brief Mapping macro that pastes a fixed number of results together
     711              :  *
     712              :  * Similar to @ref MACRO_MAP_CAT(), but expects a fixed number of
     713              :  * arguments. If more arguments are given than are expected, the rest
     714              :  * are ignored.
     715              :  *
     716              :  * @param N   Number of arguments to map
     717              :  * @param ... Macro to expand on each argument, followed by its
     718              :  *            arguments. (The macro should take exactly one argument.)
     719              :  * @return The results of expanding the macro on each argument, all pasted
     720              :  *         together
     721              :  */
     722            1 : #define MACRO_MAP_CAT_N(N, ...) MACRO_MAP_CAT_N_(N, __VA_ARGS__)
     723              : 
     724              : /**
     725              :  * @}
     726              :  */
     727              : 
     728              : #ifdef __cplusplus
     729              : }
     730              : #endif
     731              : 
     732              : #endif /* ZEPHYR_INCLUDE_SYS_UTIL_MACROS_H_ */
        

Generated by: LCOV version 2.0-1