How to process __VA_ARGS__ in C++ preprocessing?

241 Views Asked by At
#define INITIALIZE_INT_ARRAY(elem_type, array_name,...) \
    elem_type array_name[] = { __VA_ARGS__ }; \ 

INITIALIZE_INT_ARRAY(int, arr, 1, 2, 3, 4, 5)
// will expand to
int arr[] = {1, 2, 3, 4. 5};

Now I want to support tuples in __VA_ARGS__ and will simply take the first element of the tuple if it is a tuple.

INITIALIZE_INT_ARRAY(int, arr, 1, (2, hello), (3, world), (4, X), 5)
// will still expand to
int arr[] = {1, 2, 3, 4, 5}

How can I change my INITIALIZE_INT_ARRAY?

1

There are 1 best solutions below

0
HolyBlackCat On

In general, iterating over comma-separate lists in preprocessor requires writing O(n) boilerplate macros. You can write yourself or get them from Boost.Preprocessor, or...

You can use a different syntax for the list: FOO(int, arr, (1)(2, hello)(3, world)(4, X)(5)).

Then the macro can be written like this, without boilerplate:

#define FOO(type_, name_, seq_) \
    type_ name_[] = { FOO_END( FOO_LOOP_A seq_ ) }; \
    
#define FOO_END(...) FOO_END_(__VA_ARGS__)
#define FOO_END_(...) __VA_ARGS__##_END
    
#define FOO_LOOP_A(...) FOO_LOOP_BODY(__VA_ARGS__,) FOO_LOOP_B
#define FOO_LOOP_B(...) FOO_LOOP_BODY(__VA_ARGS__,) FOO_LOOP_A
#define FOO_LOOP_A_END
#define FOO_LOOP_B_END

#define FOO_LOOP_BODY(x, ...) x,