Reputation: 16949
Is it possible to write a preprocessor macro such that would transform a variable number of arguments into successive function calls, such as
MAP(f, 1, 2, 3, ..., n)
into
f(1); f(2); f(3); ... f(n);
So far, I've got following, which seems to work:
#define MAP(f, t, ...) \
{\
t __varlist[] = {__VA_ARGS__};\
for(int i = 0; i < sizeof(__varlist) / sizeof(t); i++)\
f(__varlist[i]);\
}
Note that this macro takes a type parameter so that it can be a bit more useful.
Is there a way to do it without declaring a temporary? Or does it not matter, because the compiler is so smart that it figures out everything? I'm kind of new to C.
Upvotes: 5
Views: 5132
Reputation: 40145
use boost.
note:limit size 256. BOOST_PP_LIMIT_SEQ
#include <stdio.h>
#include <boost/preprocessor/seq/for_each.hpp>
#include <boost/preprocessor/tuple/size.hpp>
#include <boost/preprocessor/tuple/to_seq.hpp>
#define PROC(r, f, elem) f(elem);
//#define MAP(f, ...) BOOST_PP_SEQ_FOR_EACH(PROC, f, BOOST_PP_TUPLE_TO_SEQ(BOOST_PP_TUPLE_SIZE((__VA_ARGS__)),(__VA_ARGS__)))
#define MAP(f, ...) BOOST_PP_SEQ_FOR_EACH(PROC, f, BOOST_PP_TUPLE_TO_SEQ((__VA_ARGS__)))
void f(int data){
printf("%d\n", data);
}
int main(){
MAP(f, 1, 2, 3);
return 0;
}
Upvotes: 2
Reputation: 16441
In gcc, you can avoid the type with typeof
:
#define MAP(f, a1, ...) \
{\
typeof(a1) __varlist[] = {a1, __VA_ARGS__};\
for(int i = 0; i < sizeof(__varlist) / sizeof(t); i++)\
f(__varlist[i]);\
}
Doing it without a temporary, i.e. really building N calls if there are N parameters, is possible, but rather complicated, and will be limited to some maximum (to support up to N, you'll need to define N macros).
To do this, you'll need a macro that counts its arguments (search this site), and use this number, plus concatenation, to choose one of N macros (e.g. MAP1(f, a)
, MAP2(f, a, b)
and so on).
Upvotes: 1