Arvid Gerstmann - Building A Reflection System - CPP On Sea
Arvid Gerstmann - Building A Reflection System - CPP On Sea
User user;
user.id = 42;
user.name = "John";
user.pets.push_back("Buddy");
user.pets.push_back("Cooper");
Name: name
Type: System.String
Name: pets
Type: System.Collections.Generic.List`1[System.String]
struct Function {
Field returnValue;
Field parameters[N];
char const *name;
};
struct Field {
Type *type;
char const *name;
size_t offset;
};
struct Function {
Field returnValue;
Field parameters[N];
char const *name;
};
template<class T>
Type const *
GetTypeImpl(TypeTag<vector<T>>)
{
/* ... */
}
28 — C++ On Sea 2019 / @ArvidGerstmann
Class const *
GetClassImpl(ClassTag<User>)
{
static Class clazz;
clazz.fields[0].type = GetType<uint64_t>();
clazz.fields[0].name = "id";
clazz.fields[0].offset = offsetof(User, id);
clazz.fields[1].type = GetType<string>();
clazz.fields[1].name = "name";
clazz.fields[1].offset = offsetof(User, name);
clazz.fields[2].type = GetType<vector<user>>();
clazz.fields[2].name = "pets";
clazz.fields[2].offset = offsetof(User, pets);
return &clazz;
}
29 — C++ On Sea 2019 / @ArvidGerstmann
Class const *c = GetClass<User>();
Name: name
Type: std::string
Name: pets
Type: std::vector<std::string>
struct User
{
uint64_t id;
std::string name;
std::vector<std::string> pets;
};
CLASS() User
{
public:
PROPERTY()
uint64_t id;
PROPERTY()
string name;
PROPERTY()
vector<string> pets;
};
DeclarationMatcher classMatcher =
cxxRecordDecl(decl().bind("id"), hasAttr(attr::Annotate));
DeclarationMatcher propertyMatcher =
fieldDecl(decl().bind("id"), hasAttr(attr::Annotate));
DeclarationMatcher functionMatcher =
functionDecl(decl().bind("id"), hasAttr(attr::Annotate));
finder.addMatcher(classMatcher, &classFinder);
finder.addMatcher(propertyMatcher, &classFinder);
finder.addMatcher(functionMatcher, &classFinder);
void
ClassFinder::FoundField(FieldDecl const *field)
{
field->dump();
}
void
ClassFinder::FoundFunction(FunctionDecl const *function)
{
function->dump();
}
52 — C++ On Sea 2019 / @ArvidGerstmann
int main(int argc char **argv)
{
/* ... */
return tool.run(newFrontendActionFactory(&finder).get());
}
void
ClassFinder::FoundField(FieldDecl const *field)
{
m_classes.back().AddField(field);
}
void
ClassFinder::FoundFunction(FunctionDecl const *function)
{
m_classes.back().AddFunction(function);
}
os << "}\n";
}
CLASS(Serialized) User
{
PROPERTY(Serialized)
uint64_t id;
PROPERTY(Serialized)
string name;
PROPERTY(Serialized)
vector<string> pets;
};