Skip to content

Commit 70b738f

Browse files
nordic-krchnashif
authored andcommitted
misc: Extend util.h with conditional code macros
Added macros for conditional code generation based on a flag. Additionally, added macros for getting first and second argument from variable list of arguments and getting all arguments except the first one. Signed-off-by: Krzysztof Chruscinski <[email protected]>
1 parent 880bfb3 commit 70b738f

File tree

1 file changed

+85
-0
lines changed

1 file changed

+85
-0
lines changed

include/misc/util.h

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,91 @@ static inline s64_t arithmetic_shift_right(s64_t value, u8_t shift)
200200
*/
201201
#define _IS_ENABLED3(ignore_this, val, ...) val
202202

203+
/**
204+
* @brief Insert code depending on result of flag evaluation.
205+
*
206+
* This is based on same idea as @ref IS_ENABLED macro but as the result of
207+
* flag evaluation provided code is injected. Because preprocessor interprets
208+
* each comma as argument boundary, code must be provided in the brackets.
209+
* Brackets are stripped away during macro processing.
210+
*
211+
* Usage example:
212+
*
213+
* #define MACRO(x) COND_CODE_1(CONFIG_FLAG, (u32_t x;), ())
214+
*
215+
* It can be considered as alternative to:
216+
*
217+
* #if defined(CONFIG_FLAG) && (CONFIG_FLAG == 1)
218+
* #define MACRO(x) u32_t x;
219+
* #else
220+
* #define MACRO(x)
221+
* #endif
222+
*
223+
* However, the advantage of that approach is that code is resolved in place
224+
* where it is used while \#if method resolves given macro when header is
225+
* included and product is fixed in the given scope.
226+
*
227+
* @note Flag can also be a result of preprocessor output e.g.
228+
* product of NUM_VA_ARGS_LESS_1(...).
229+
*
230+
* @param _flag Evaluated flag
231+
* @param _if_1_code Code used if flag exists and equal 1. Argument must be
232+
* in brackets.
233+
* @param _else_code Code used if flag doesn't exists or isn't equal 1.
234+
*
235+
*/
236+
#define COND_CODE_1(_flag, _if_1_code, _else_code) \
237+
_COND_CODE_1(_flag, _if_1_code, _else_code)
238+
239+
#define _COND_CODE_1(_flag, _if_1_code, _else_code) \
240+
__COND_CODE(_XXXX##_flag, _if_1_code, _else_code)
241+
242+
/**
243+
* @brief Insert code depending on result of flag evaluation.
244+
*
245+
* See @ref COND_CODE_1 for details.
246+
*
247+
* @param _flag Evaluated flag
248+
* @param _if_0_code Code used if flag exists and equal 0. Argument must be
249+
* in brackets.
250+
* @param _else_code Code used if flag doesn't exists or isn't equal 0.
251+
*
252+
*/
253+
#define COND_CODE_0(_flag, _if_0_code, _else_code) \
254+
_COND_CODE_0(_flag, _if_0_code, _else_code)
255+
256+
#define _COND_CODE_0(_flag, _if_0_code, _else_code) \
257+
__COND_CODE(_ZZZZ##_flag, _if_0_code, _else_code)
258+
259+
#define _ZZZZ0 _YYYY,
260+
261+
/* Macro used internally by @ref COND_CODE_1 and @ref COND_CODE_0. */
262+
#define __COND_CODE(one_or_two_args, _if_code, _else_code) \
263+
__GET_ARG2_DEBRACKET(one_or_two_args _if_code, _else_code)
264+
265+
/* Macro used internally to remove brackets from argument. */
266+
#define __DEBRACKET(...) __VA_ARGS__
267+
268+
/* Macro used internally for getting second argument and removing brackets
269+
* around that argument. It is expected that parameter is provided in brackets
270+
*/
271+
#define __GET_ARG2_DEBRACKET(ignore_this, val, ...) __DEBRACKET val
272+
273+
/**
274+
* @brief Get first argument from variable list of arguments
275+
*/
276+
#define GET_ARG1(arg1, ...) arg1
277+
278+
/**
279+
* @brief Get second argument from variable list of arguments
280+
*/
281+
#define GET_ARG2(arg1, arg2, ...) arg2
282+
283+
/**
284+
* @brief Get all arguments except the first one.
285+
*/
286+
#define GET_ARGS_LESS_1(val, ...) __VA_ARGS__
287+
203288
/**
204289
* Macros for doing code-generation with the preprocessor.
205290
*

0 commit comments

Comments
 (0)