Reputation: 2448
I would like to expand a variadic macro to another macro that takes a single argument, which is formed by joining the variadic arguments with a delimiter/separator (e.g. "_"). Something like this:
#define FOO(...)
FOO(a, b, c, d);
which expands into
#define BAR(X)
BAR(a_b_c_d);
I know there is __VA_ARGS__
for working with the variadic parameters, and ##
for concatenation. How do I use them together to achieve what I want (preferably using C++17 and older language features, without libraries such as Boost)?
Upvotes: 1
Views: 771
Reputation: 6637
First, there are no language feature that directly tackles the question you are trying to solve. (there might be complier specific ones, but I don't know).
However, if you know the upper limit of the amount of argument that macro can take(preferably not too many), you can use this answer as a guide to iterate through the __VA_ARGS__
: Is it possible to iterate over arguments in variadic macros?
On the other hand, Boost.Preprocessor is a header only library. While it is a pretty heavy macro-only library that could bring a lot of ugliness behind the scene, it does offer simple ways to handle macros that take up to thousands of parameter.
Here's a quick one that should work for you:
#define CAT_OP(index, state, elem) BOOST_PP_CAT(state, BOOST_PP_CAT(_, elem))
#define CAT_SEQ(seq) BOOST_PP_SEQ_FOLD_LEFT(CAT_OP, BOOST_PP_SEQ_HEAD(seq), BOOST_PP_SEQ_TAIL(seq))
#define CAT_VA_ARGS(...) CAT_SEQ(BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__))
Demo.
It treats the variadic as a Sequence, then performs a left fold over the sequence with concat operation.
Upvotes: 1