2010-03-02 2 views
3

Je cherche une méthode ou un moyen de générer une liste de typedefs et une liste d'instanciations d'objets à partir d'une liste des macro-invocations, en définissant les types de classe et les paramètres constructeurs de ces objets.Macro C/C++: Comment générer deux sections séparées de code avec une seule macro (bibliothèque de préprocesseur booster?)

Cela devrait ressembler au code (ne fonctionne pas) ci-dessous. Le problème à résoudre est un moyen de générer deux listes différentes sur une liste d'invocations de macros. Je suppose que c'est un problème à résoudre avec la partie bibliothèque de préprocesseur boost mais j'ai maintenant de la colle comment faire.

///////////////////////////////////////////////////////////////////////////////// 
// MACRO-Definitions 
#define DEF_OBJECT_TYPE(name, class, contructor_params) \ 
    typedef class name ## type; 
    name ## type* name; 

#define DEF_OBJECT_RUN(name, class, contructor_params) \ 
    name ## type* name = new name ## type contructor_params; \ 

#define DEF_OBJECTS(definitions) \ 
    /* Type-Header */ \ 
    definitions \ 
    /* Type-Footer */ \ 
    /* Run-Header */ \ 
    definitions \ 
    /* Run-Footer */ 

#define OBJECT(name) (dynamic_cast<name ## type*>(name)) 

///////////////////////////////////////////////////////////////////////////////// 
// Object-Definitions 
DEF_OBJECTS(
    DEF_OBJECT(Object1, CClass1, ("par1")) 
    DEF_OBJECT(Object2, CClass2, ("par1", "par1")) 
) 

///////////////////////////////////////////////////////////////////////////////// 
// This shall be the result of the macro expansion 
// shall expand to: 
struct MyClass { 

    typedef class Object1type; 
    Object1type* Object1; 

    typedef class Object2type; 
    Object2type* Object2; 

    void Run(); 
} 

void MyClass::Init() { 
    Object1type* Object1 = new Object1type("par1"); 
    Object2type* Object2 = new Object2type("par1", "par2"); 
} 
// end of expansion 
///////////////////////////////////////////////////////////////////////////////// 

// I want to use these automatic created objects in this way: 
void MyClass::Run() { 
    OBJECT(Object1)->method_class1(1); 
    OBJECT(Object2)->method_class2(1,2); 
} 

Répondre

2

astuces Macro ...

Si vous souhaitez développer une boucle dans une macro C, vous devez avoir autant de MACROES que l'itération (avec le préprocesseur, vous pouvez aussi jouer d'autres tours avec notamment fichiers de manière récursive, mais vous n'avez pas d'interface de type macro).

J'ai ajouté et marqueur de fin, je ne sais pas si c'est vraiment nécessaire ou non.

Je distribue vers une macro de fin vide ou une macro en cours en créant des noms de macro.

Voici donc quelque chose qui fait ce que vous voulez - avec une interface modifiée et avec au plus 4 objets. Ajoutez simplement des macros similaires pour plus d'objets.

#define TYPE_DEF_OBJECT(name, class, constructor_params) \ 
    typedef class name ## type; \ 
    name ## type* name; 

#define TYPE_DEF_END(name, class, constructor_params) 

#define TYPE4_OBJECT(name, class, constructor_params) \ 
    TYPE_DEF_OBJECT(name, class, constructor_params) TYPE5 
#define TYPE4_END(name, class, constructor_params) \ 
    TYPE_DEF_END(name, class, constructor_params) 
#define TYPE4(kind, name, class, constr) \ 
    TYPE4_##kind(name, class, constr) 

#define TYPE3_OBJECT(name, class, constructor_params) \ 
    TYPE_DEF_OBJECT(name, class, constructor_params) TYPE4 
#define TYPE3_END(name, class, constructor_params) \ 
    TYPE_DEF_END(name, class, constructor_params) 
#define TYPE3(kind, name, class, constr) \ 
    TYPE3_##kind(name, class, constr) 

#define TYPE2_OBJECT(name, class, constructor_params) \ 
    TYPE_DEF_OBJECT(name, class, constructor_params) TYPE3 
#define TYPE2_END(name, class, constructor_params) \ 
    TYPE_DEF_END(name, class, constructor_params) 
#define TYPE2(kind, name, class, constr) \ 
    TYPE2_##kind(name, class, constr) 

#define TYPE1_OBJECT(name, class, constructor_params) \ 
    TYPE_DEF_OBJECT(name, class, constructor_params) TYPE2 
#define TYPE1_END(name, class, constructor_params) \ 
    TYPE_DEF_END(name, class, constructor_params) 
#define TYPE1(kind, name, class, constr) \ 
    TYPE1_##kind(name, class, constr) 

#define TYPE0_OBJECT(name, class, constructor_params) \ 
    TYPE_DEF_OBJECT(name, class, constructor_params) TYPE1 
#define TYPE0_END(name, class, constructor_params) \ 
    TYPE_DEF_END(name, class, constructor_params) 
#define TYPE(kind, name, class, constr) \ 
    TYPE0_##kind(name, class, constr) 


#define RUN_DEF_OBJECT(name, class, constructor_params) \ 
    name ## type* name = new name##type constructor_params; 

#define RUN_DEF_END(name, class, constructor_params) 

#define RUN4_OBJECT(name, class, constructor_params) \ 
    RUN_DEF_OBJECT(name, class, constructor_params) RUN5 
#define RUN4_END(name, class, constructor_params) \ 
    RUN_DEF_END(name, class, constructor_params) 
#define RUN4(kind, name, class, constr) \ 
    RUN4_##kind(name, class, constr) 

#define RUN3_OBJECT(name, class, constructor_params) \ 
    RUN_DEF_OBJECT(name, class, constructor_params) RUN4 
#define RUN3_END(name, class, constructor_params) \ 
    RUN_DEF_END(name, class, constructor_params) 
#define RUN3(kind, name, class, constr) \ 
    RUN3_##kind(name, class, constr) 

#define RUN2_OBJECT(name, class, constructor_params) \ 
    RUN_DEF_OBJECT(name, class, constructor_params) RUN3 
#define RUN2_END(name, class, constructor_params) \ 
    RUN_DEF_END(name, class, constructor_params) 
#define RUN2(kind, name, class, constr) \ 
    RUN2_##kind(name, class, constr) 

#define RUN1_OBJECT(name, class, constructor_params) \ 
    RUN_DEF_OBJECT(name, class, constructor_params) RUN2 
#define RUN1_END(name, class, constructor_params) \ 
    RUN_DEF_END(name, class, constructor_params) 
#define RUN1(kind, name, class, constr) \ 
    RUN1_##kind(name, class, constr) 

#define RUN0_OBJECT(name, class, constructor_params) \ 
    RUN_DEF_OBJECT(name, class, constructor_params) RUN1 
#define RUN0_END(name, class, constructor_params) \ 
    RUN_DEF_END(name, class, constructor_params) 
#define RUN(kind, name, class, constr) \ 
    RUN0_##kind(name, class, constr) 

#define DEF_OBJECTS(definitions) \ 
    TYPE definitions \ 
    RUN definitions \ 

DEF_OBJECTS(
    (OBJECT, Object1, CClass1, ("par1")) 
    (END, , ,) 
) 
+0

Merci pour la solution rapide - cela fonctionne! La génération de TYPE0_DEF, TYPE1_DEF etc.pp. macros coutures d'être un candidat pour la bibliothèque boost-preprocessor. Je vais essayer cela dès que possible. Merci encore! – Marcel

Questions connexes