En mi búsqueda épica de hacer C++ hacer cosas que no debería, estoy tratando de armar una clase generada en tiempo de compilación.C++ Code Generation
Sobre la base de una definición de preprocesador, tales como (concepto bruto)
CLASS_BEGIN(Name)
RECORD(xyz)
RECORD(abc)
RECORD_GROUP(GroupName)
RECORD_GROUP_RECORD(foo)
RECORD_GROUP_RECORD(bar)
END_RECORDGROUP
END_CLASS
Aunque estoy bastante seguro de que genero una clase que lee los datos del sistema de archivos que utiliza este tipo de estructura (tal vez incluso hacerlo utilizando la metaprogramación de plantillas), no veo cómo puedo generar tanto las funciones para acceder a los datos como la función para leer los datos.
me gustaría terminar con una clase algo como esto
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
}
};
¿Alguien tiene alguna idea de si esto es posible?
--EDIT--
Para aclarar el uso previsto para ello. Tengo archivos en un formato estándar que quiero leer. El formato ya está definido, por lo que no está abierto a cambios. Cada archivo puede contener cualquier número de registros, cada uno de los cuales puede contener cualquier número de registros secundarios.
Los numerosos tipos de registros contienen un conjunto diferente de registros secundarios, pero se pueden definir. Entonces, por ejemplo, el registro de mapa de altura debe contener un mapa de altura, pero puede contener opcionalmente normales.
Así que me gustaría definir un registro para que de este modo:
CLASS_BEGIN(Heightmap)
RECORD(VHDT, Heightmap, std::string) //Subrecord Name, Readable Name, Type
RECORD_OPTIONAL(VNML, Normals, std::string)
END_CLASS
Por lo que yo quiero mostrar algo, con la funcionalidad de una clase como esta:
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;
}
La cuestión Lo que estoy teniendo es que necesito cada definición de preprocesador dos veces. Una vez para definir la definición de función dentro de la clase, y una vez para crear la función de lectura. Como el preprocesador es puramente funcional, no puedo enviar los datos a una cola y generar la clase en la definición de marco END_CLASS.
No veo una forma de solucionar este problema, pero me pregunto si alguien que tenga una mayor comprensión de C++ lo hizo.
Es posible, sospecho. ¿Puedes ser más preciso sobre exactamente dónde estás golpeando la pared? –
No es obvio qué ventajas obtienes al hacer esto, por favor explica. –