Itération de macro nestede avec le préprocesseur C

Avec le préprocesseur C, vous pouvez avoir une sorte de macros d’ordre élevé. Quelque chose comme ça:

#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 

La sortie est:

  foo_a foo_b foo_c bar_x bar_y 

Y at-il une astuce pour imbriquer de telles itérations, pour faire quelque chose comme ça?

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

Donc, le résultat serait:

 foo_ax foo_ay foo_bx foo_by foo_cx foo_cy 

En particulier, j’aimerais que les définitions de ABC et XY soient indépendantes l’une de l’autre, afin que je puisse toujours utiliser ABC seul ou peut-être même faire quelque chose comme ça:

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

Pour mémoire, voici la solution:

 #include  #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)) 

Rendements:

 foo_ax foo_ay foo_bx foo_by foo_cx foo_cy 

La bibliothèque de préprocesseurs Boost propose plusieurs macros qui peuvent le faire immédiatement.

BOOST_PP_SEQ_FOR_EACH_PRODUCT itérera sur les produits cartésiens de deux ou plusieurs listes codées sous la forme (x) (y) (z) (connues sous le nom de séquences dans le langage de la bibliothèque).

BOOST_PP_LIST_FOR_EACH_PRODUCT fera la même chose pour les listes codées comme (x, (y, (z, NIL))) .

Il est facile de convertir l’itération de macro X en une “séquence” comme celle-ci:

 #define LIST_TO_SEQ(X) (X) ABC(LIST_TO_SEQ)