Search code examples
cfunctionmacrosvariadicvariadic-macros

Passing an arbitrary number of args to a function


So basically, I would like to redefine this part of code using macros,

switch(count) {
case 0:
 variadic();
case 1:
 variadic(array[0]);
case 2;
 variadic(array[0], array[1]);
case 3:
 variadic(array[0], array[1], array[2]);
...
}

My constraint is that variadic is a function that CANNOT be passed a count, so I cannot pass the array by reference. This way works just fine, but I want to know if I can do this using a macro, or in a better way, I don't mind if the number of arguments is limited, since right now, I only handle 6 anyways.

Thank you.


Solution

  • something like variadic_(8, array), expanding to variadic(array[0], array[1], array[2], array[3], array[4], array[5], array[6], array[7], array[8]);

    Using boost preprocessor, you can simply do this:

    #include <boost/preprocessor/repetition/repeat.hpp>
    #include <boost/preprocessor/tuple/pop_front.hpp>
    
    #define TO_ARRAY(_,N,V) ,V[N]
    #define variadic_(C,A) \
       variadic BOOST_PP_TUPLE_POP_FRONT((BOOST_PP_REPEAT(C,TO_ARRAY,A)));
    

    (Dropping BOOST_PP_ for discussion)

    REPEAT(3,TO_ARRAY,array) generates a count list, expanding to:

    TO_ARRAY(#,0,array) TO_ARRAY(#,1,array) TO_ARRAY(#,2,array)

    ...where each # is some number you should just ignore (having to do with nested macros, but you really don't care about it).

    With the defined TO_ARRAY, this expands to ,array[0],array[1],array[2]; surrounding that with parentheses makes a tuple. This has an extra leading comma that TUPLE_POP_FRONT strips off.

    As a corner case, if you pass 0 in, this builds the tuple (), which TUPLE_POP_FRONT just maps back to ().