Nested macro iteration with C preprocessor

我是研究僧i 提交于 2019-12-10 13:14:29

问题


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:


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)


来源:https://stackoverflow.com/questions/42157399/nested-macro-iteration-with-c-preprocessor

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!