@@ -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