6 votes

Itération de macros imbriquées avec le préprocesseur C

Avec le préprocesseur C, vous pouvez avoir des sortes de macros d'ordre supérieur. 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

Existe-t-il une astuce pour imbriquer ces itérations, pour faire quelque chose comme ça ?

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

Donc la sortie serait :

foo_ax foo_ay foo_bx foo_by foo_cx foo_cy

En particulier, j'aimerais avoir les définitions de ABC y XY indépendants les uns des autres, de sorte que je puisse toujours utiliser ABC autonome 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 <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))

Rendement :

foo_ax foo_ay foo_bx foo_by foo_cx foo_cy

3voto

Hazy Joe Aardvark Points 1389

En Bibliothèque du préprocesseur Boost propose plusieurs macros qui peuvent faire cela dès le départ.

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) (que l'on appelle des séquences dans le jargon de la bibliothèque).

BOOST_PP_LIST_POUR_CHAQUE_PRODUIT fera de même pour les listes codées en tant que (x, (y, (z, NIL))) .

Il est trivial de convertir le X macro l'itération à une "séquence" comme ceci :

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X