6

With the C preprocessor you can have some kind of high-order macros. Something like this:

#define ABC(f) f(a) f(b) f(c)
#define XY(f) f(x) f(y)

#define CODE(x) foo_ ## x
ABC(CODE)
#undef CODE

#define CODE(x) bar_ ## x
XY(CODE)
#undef CODE

The output is:

 foo_a foo_b foo_c
 bar_x bar_y

Is there some trick to nest such iterations, to do something like this?

#define CODE(x) foo_ ## x
NEST(ABC, XY, CODE)
#undef CODE

So the output would be:

foo_ax foo_ay foo_bx foo_by foo_cx foo_cy

In particular, I'd like to have the definitions of ABC and XY independent from each other, so that I can still use ABC stand-alone or maybe do even something like this:

#define CODE(x) foo_ ## x
NEST(XY, KLMN, ABC, CODE)
#undef CODE

For the record, here the solution:

#include <boost/preprocessor/seq.hpp>

#define ABC (a) (b) (c)
#define XY (x) (y)

#define CODE(r, prod) BOOST_PP_CAT(foo_, BOOST_PP_SEQ_CAT(prod))
BOOST_PP_SEQ_FOR_EACH_PRODUCT(CODE, (ABC) (XY))

Yields:

foo_ax foo_ay foo_bx foo_by foo_cx foo_cy
1
  • 1
    Out of experience, I can tell that whenever you are deep down in meta-programming with macros, you are almost certainly creating a poor program design, and it is almost certainly the incorrect solution to the problem. "X macros" and their various spin-offs are to be regarded as the very last resort. What's the actual problem you are trying to solve? Commented Feb 10, 2017 at 12:33

1 Answer 1

3

The Boost Preprocessor Library offers several macros that can do this out of the box.

BOOST_PP_SEQ_FOR_EACH_PRODUCT will iterate over the cartesian products of two or more lists encoded in the form (x) (y) (z) (which are known as sequences is the library's parlance).

BOOST_PP_LIST_FOR_EACH_PRODUCT will do the same for lists encoded as (x, (y, (z, NIL))).

It's trivial to convert the X macro iteration to a "sequence" like this:

#define LIST_TO_SEQ(X) (X)
ABC(LIST_TO_SEQ)
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.