Loading...
Searching...
No Matches
macro_util.h
Go to the documentation of this file.
1#ifndef _BBM_MACRO_UTIL_H_
2#define _BBM_MACRO_UTIL_H_
3
4/***********************************************************************/
5/*! \file macro_util.h
6 \brief General macro utilities.
7************************************************************************/
8
9#define BBM_PARENS ()
10
11/***********************************************************************/
12/*! \brief Just pass the arguments
13************************************************************************/
14#define BBM_PASS(...) __VA_ARGS__
15
16/***********************************************************************/
17/*! \brief Expand the args, then call the macro
18************************************************************************/
19#define BBM_CALL(macro, ...) macro (__VA_ARGS__)
20
21/***********************************************************************/
22/*! \brief A comma
23************************************************************************/
24#define BBM_COMMA() ,
25
26/***********************************************************************/
27/*! \brief Re-scan __VA_ARGS__ 342 times. Part of BBM_FOREACH.
28************************************************************************/
29#define BBM_EXPAND(...) _BBM_EXPAND4(_BBM_EXPAND4(_BBM_EXPAND4(_BBM_EXPAND4(__VA_ARGS__))))
30#define _BBM_EXPAND4(...) _BBM_EXPAND3(_BBM_EXPAND3(_BBM_EXPAND3(_BBM_EXPAND3(__VA_ARGS__))))
31#define _BBM_EXPAND3(...) _BBM_EXPAND2(_BBM_EXPAND2(_BBM_EXPAND2(_BBM_EXPAND2(__VA_ARGS__))))
32#define _BBM_EXPAND2(...) _BBM_EXPAND1(_BBM_EXPAND1(_BBM_EXPAND1(_BBM_EXPAND1(__VA_ARGS__))))
33#define _BBM_EXPAND1(...) __VA_ARGS__
34
35
36/***********************************************************************/
37/*! \brief A macro that applies a macro (MACRO) on every argument in
38 __VA_ARGS__ followed by an (OPT) macro (without arguments) except following
39 the last argument in __VA_ARGS__.
40
41 This code is based on https://www.scs.stanford.edu/~dm/blog/va-opt.html
42
43 \param MACRO = macro to apply to each argument in __VA_ARGS__ (takes one argument)
44 \param OPT = macro to apply between each argument in __VA_ARGS__ (takes no arguments)
45 \param ... = list of __VA_ARGS__
46*************************************************************************/
47#define BBM_FOREACH_OPT(MACRO, OPT, ...) \
48 __VA_OPT__(BBM_EXPAND(_BBM_FOREACH_OPT(MACRO, OPT, __VA_ARGS__)))
49#define _BBM_FOREACH_OPT(MACRO, OPT, ARG, ...) \
50 MACRO(ARG) \
51 __VA_OPT__(OPT() _BBM_CALL_FOREACH_OPT BBM_PARENS (MACRO, OPT, __VA_ARGS__))
52#define _BBM_CALL_FOREACH_OPT() _BBM_FOREACH_OPT
53
54/***********************************************************************/
55/*! \brief A macro that applies another macro (MACRO) on every argument in
56 __VA_ARGS__ (i.e., BBM_FOREACH_OPT with empty OPT-macro)
57
58 \param MACRO = macro to apply to each
59 \param ... = list of __VA_ARGS__
60*************************************************************************/
61#define BBM_FOR_EACH(MACRO, ...) BBM_FOREACH_OPT(MACRO, , __VA_ARGS__)
62
63
64/***********************************************************************/
65/*! \brief __VA_ARGS__ => "__VA_ARGS__"
66************************************************************************/
67#define BBM_TO_STRING(...) #__VA_ARGS__
68
69/***********************************************************************/
70/*! \brief Expand __VA_ARGS__ before converting to a string of comma separated elements
71
72 BBM_STRINGIFY(a,b,c) => "a, b, c"
73************************************************************************/
74#define BBM_STRINGIFY(...) BBM_TO_STRING(__VA_ARGS__)
75
76/***********************************************************************/
77/*! \brief Expand __VA_ARGS__ before converting to a comma separated series strings of elements
78
79 BBM_STRINGIFY_EACH(a,b,c) => "a", "b", "c"
80************************************************************************/
81#define BBM_STRINGIFY_EACH(...) BBM_FOREACH_OPT(BBM_TO_STRING, BBM_COMMA, __VA_ARGS__)
82
83#endif /* _BBM_MACRO_UTIL_H_ */