I have this macro:
#define DO_SOMETHING(N, a,b,c,...)
my goal is to write such macro with listsd (eg without ...
) that expands to:
DO_SOMETHING(1, a,b,c,...) DO_SOMETHING(2, a,b,c,...) DO_SOMETHING(3, a,b,c,...)
Here's my approach:
#define REP_3(D, A) D(1, A) D(2, A) D(3, A)
#define GENERATE(a,b,c, ...) REP_3(DO_SOMETHING, (a,b,c,__VA_ARGS__))
however, this expands to:
DO_SOMETHING(1, (a,b,c,...)) DO_SOMETHING(2, (a,b,c,...)) DO_SOMETHING(3, (a,b,c,...))
Perhaps, I need something like:
REP_3(DO_SOMETHING2, (a,b,c,__VA_ARGS__))
#define DO_SOMETHING2(N, A) DO_SOMETHING(N, unroll(A)) //??
How can I unroll that list of args represented by A? In other words, what's DO_SOMETHING2
should be defined to translate N, A
, where A
is a list of args (a,b,c,...)
to N, a,b,c, ...
I could define unroll:
#define unroll(...) __VA_ARGS__
#define DO_SOMETHING2(N, A) DO_SOMETHING(N, unroll A)
but this doesn't work, or works with some changes in msvc, but not with gcc
Sorry, if the question wasn't worded clearly, but the goal was to:
#define REP_3(D, A)
using lists (eg without ...
) so that it wouldDO_SOMETHING
macro prepending them with N
that is:
#define REP_3(D, A) D(1, A) D(2, A) D(3, A)
#define DO_SOMETHING(N, a,b,c,...)
#define GENERATE(a,b,c, ...) REP_3(DO_SOMETHING, (a,b,c,__VA_ARGS__))
calling GENERATE(a,b,c,d,e)
should expand to:
DO_SOMETHING(1, a,b,c,d,e) DO_SOMETHING(2, a,b,c,d,e) DO_SOMETHING(3, a,b,c,d,e)
In other words, what GENERATE(a,b,c, ...)
should be defined to, without making changes to REP_3
and DO_SOMETHING
?
At first, DO_SOMETHING
should be passed as a list arg:
#define GENERATE(a,b,c, ...) REP_3(CALLFUNC, (DO_SOMETHING,a,b,c,__VA_ARGS__))
Then:
#define EXPAND(x) x
#define UNROLL(...) __VA_ARGS__
#define CALLFUNC2(N, F, ...) EXPAND(F(N, __VA_ARGS__))
#define CALLFUNC1(...) EXPAND(CALLFUNC2(__VA_ARGS__))
#define CALLFUNC(N, A) CALLFUNC1(N, UNROLL A)
these multiple hoops through EXPAND
are required to get msvc and gcc produce identical results: https://godbolt.org/z/cMxWsox74