В своем эпическом стремлении заставить C++ делать то, чего он не должен, я пытаюсь собрать класс, сгенерированный во время компиляции.
На основе определения препроцессора, такого как (грубая концепция)
CLASS_BEGIN(Name)
RECORD(xyz)
RECORD(abc)
RECORD_GROUP(GroupName)
RECORD_GROUP_RECORD(foo)
RECORD_GROUP_RECORD(bar)
END_RECORDGROUP
END_CLASS
Хотя я совершенно уверен, что сгенерирую класс, который считывает данные из файловой системы, используя такую структуру (возможно, даже делая это с помощью метапрограммирования шаблонов), я не понимаю, как я могу сгенерировать как функции для доступа к данным, так и функция чтения данных.
Я хотел бы закончить с классом что-то вроде этого
class Name{
public:
xyz_type getxyz();
void setxyz(xyz_type v);
//etc
list<group_type> getGroupName();
//etc
void readData(filesystem){
//read xyz
//read abc
//etc
}
};
Кто-нибудь знает, возможно ли это вообще?
--РЕДАКТИРОВАТЬ--
Чтобы уточнить предполагаемое использование для этого. У меня есть файлы в стандартном формате, которые я хочу прочитать. Формат уже определен, поэтому его нельзя изменить. Каждый файл может содержать любое количество записей, каждая из которых может содержать любое количество подзаписей.
Каждый из многочисленных типов записей содержит различный набор вложенных записей, но их можно определить. Так, например, запись карты высот должна содержать карту высот, но может содержать нормали.
Поэтому я хотел бы определить запись для этого так:
CLASS_BEGIN(Heightmap)
RECORD(VHDT, Heightmap, std::string) //Subrecord Name, Readable Name, Type
RECORD_OPTIONAL(VNML, Normals, std::string)
END_CLASS
Для чего я хотел бы вывести что-то с функциональностью класса, например:
class Heightmap{
public:
std::string getHeightmap(){
return mHeightmap->get<std::string>();
}
void setHeightmap(std::string v){
mHeight->set<std::string>(v);
}
bool hasNormal(){
return mNormal != 0;
}
//getter and setter functions for normals go here
private:
void read(Record* r){
mHeightmap = r->getFirst(VHDT);
mNormal = r->getFirst(VNML);
}
SubRecord* mHeightmap, mNormal;
}
Проблема, с которой я сталкиваюсь, заключается в том, что мне нужно каждое определение препроцессора дважды. Один раз для определения определения функции в классе и один раз для создания функции чтения. Поскольку препроцессор является чисто функциональным, я не могу помещать данные в очередь и генерировать класс в определении маркировки END_CLASS.
Я не вижу способа обойти эту проблему, но задавался вопросом, знает ли кто-нибудь, кто лучше разбирается в С++.