C/C++ preprocessor: extract every second variadic parameter -
is there way extract every second parameter list of variadic parameters in c/c++ preprocessor?
i write macro generate boilerplate code interface methods in following way:
#define interface_fn(_name, _x, _y, _n_params, ...) \ void _name(__va_args__) \ { \ processing_function(_x, _y, _n_params, every_second(__va_args__); \ } void processing_function(int x, int y, int count, ...) { va_list params; va_start(params, count); while (count--) { do_something(va_arg(params, parentclass*)); } va_end(params); // else }
which used as:
interface_fn(foo, 1, 2, 0); interface_fn(bar, 3, 4, 1, classx*, x); interface_fn(jar, 5, 6, 2, classy*, y, classz*, z);
the classes classx
, classy
, classz
derivatives of parentclass
;
i'm looking every_second
macro.
here working example of asked for
#define every_second0(...) #define every_second1_(second, ...) , second #define every_second1(first, ...) every_second1_(__va_args__) #define every_second2_(second, ...) , second every_second1(__va_args__) #define every_second2(first, ...) every_second2_(__va_args__) #define every_second3_(second, ...) , second every_second2(__va_args__) #define every_second3(first, ...) every_second3_(__va_args__) #define every_second4_(second, ...) , second every_second3(__va_args__) #define every_second4(first, ...) every_second4_(__va_args__) #define every_second5_(second, ...) , second every_second4(__va_args__) #define every_second5(first, ...) every_second5_(__va_args__) #define count_every_second(_1,__1,_2,__2,_3,__3,_4,__4,_5,__5,num,...) every_second ## num #define every_second(...) count_every_second(__va_args__,5,5,4,4,3,3,2,2,1,0)(__va_args__) #define interface_fn(_name, _x, _y, _n_params, ...) \ void _name(__va_args__) \ { \ processing_function(_x, _y, _n_params every_second(__va_args__)); \ } class parentclass {}; class classx {}; class classy {}; class classz {}; void processing_function(int x, int y, int count, ...) { va_list params; va_start(params, count); while (count--) { do_something(va_arg(params, parentclass*)); } va_end(params); // else } interface_fn(foo, 1, 2, 0); interface_fn(bar, 3, 4, 1, classx*, x); interface_fn(jar, 5, 6, 2, classy*, y, classz*, z);
the preprocessor output looks this
class parentclass {}; class classx {}; class classy {}; class classz {}; void processing_function(int x, int y, int count, ...) { va_list params; va_start(params, count); while (count--) { do_something(va_arg(params, parentclass*)); } va_end(params); } void foo() { processing_function(1, 2, 0 ); }; void bar(classx*, x) { processing_function(3, 4, 1 , x); }; void jar(classy*, y, classz*, z) { processing_function(5, 6, 2 , y , z); };
though give obligatory warning there easier way without macros.
this have comma @ end if put odd number of arguments, though shouldn't happen use case. allows 5 pairs (10 total arguments) think can see pattern how add support more. there no way without explicitly defining each number of args due preprocessors limitations
have fun!
edit:
i note can improved never have specify _n_params , let macros count you, add macro
#define count_every_second_(_1,__1,_2,__2,_3,__3,_4,__4,_5,__5,num,...) num
and replace interface_fn
s definition
#define interface_fn(_name, _x, _y, ...) \ void _name(__va_args__) \ { \ processing_function(_x, _y, count_every_second_(__va_args__,5,error,4,4,3,3,2,2,1,0) every_second(__va_args__)); \ }
Comments
Post a Comment