Nested Macro Iteration with C Preprocessor

With the C preprocessor, you can have some high order macros. Something like that:

#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 

Output:

  foo_a foo_b foo_c bar_x bar_y 

Is there any trick to nesting such iterations to do something like this?

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

Thus, the output will be:

 foo_ax foo_ay foo_bx foo_by foo_cx foo_cy 

In particular, I would like the ABC and XY definitions to be independent of each other, so I can still use ABC autonomously or maybe even something like this:

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

For the record here is 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)) 

Productivity:

 foo_ax foo_ay foo_bx foo_by foo_cx foo_cy 
+6
source share
1 answer

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

BOOST_PP_SEQ_FOR_EACH_PRODUCT will iterate over Cartesian products from two or more lists encoded in the form (x) (y) (z) (which are known as sequences - this is a library language).

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

It is trivial to convert an X macro iteration into a "sequence" like this:

 #define LIST_TO_SEQ(X) (X) ABC(LIST_TO_SEQ) 
+3
source

Source: https://habr.com/ru/post/1014872/


All Articles