Макрос C / C ++: Как создать два отдельных раздела кода с одним макросом (повысить библиотеку препроцессора?) - PullRequest
3 голосов
/ 02 марта 2010

Я ищу метод или способ для генерации списка определений типов и списка экземпляров объектов из списка макро-вызовов, определяющих типы классов и параметры конструктора этих объектов.

Это должно выглядеть как (не работает) код ниже. Проблема, которую нужно решить, - это способ создания двух разных списков из одного списка вызовов макросов. Я полагаю, что это проблема, которую нужно решить с помощью библиотеки препроцессора boost, но теперь я знаю, как это сделать.

/////////////////////////////////////////////////////////////////////////////////
// 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);
}

1 Ответ

2 голосов
/ 02 марта 2010

Макро трюки ...

Если вы хотите расширить цикл в макросе C, вам нужно иметь столько макросов, сколько итераций (с препроцессором вы можете также выполнять другие приемы с включением файлов рекурсивно, но тогда у вас нет такого макроса интерфейс).

Я добавил и завершил маркер, я не знаю, действительно ли он нужен или нет.

Я делаю отправку либо пустому завершающему макросу, либо продолжающемуся макросу, создавая имена макросов.

Итак, здесь происходит то, что вы хотите - с измененным интерфейсом и с максимум 4 объектами. Просто добавьте похожие макросы для большего количества объектов.

#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, , , )
)
...