Created
September 26, 2017 09:31
-
-
Save eliasdaler/213d42051958ae21185adbc7edbff915 to your computer and use it in GitHub Desktop.
Simple meta info class for this article: https://eliasdaler.github.io/meta-stuff
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <memory> | |
#include <string> | |
#include <unordered_map> | |
#include <json.hpp> | |
using json = nlohmann::json; | |
template <typename Class> | |
class IMember { | |
public: | |
virtual ~IMember() = default; | |
virtual void fromJson(Class& obj, const json& j) const = 0; | |
virtual json toJson(const Class& obj) const = 0; | |
}; | |
template <typename Class, typename T> | |
class Member : public IMember<Class> { | |
public: | |
Member(T Class::* ptr) : ptr(ptr) {} | |
void fromJson(Class& obj, const json& j) const override | |
{ | |
obj.*ptr = j; | |
} | |
json toJson(const Class& obj) const override | |
{ | |
return json(obj.*ptr); | |
} | |
private: | |
T Class::* ptr; | |
}; | |
namespace ImGui | |
{ | |
void Input(int anim); | |
} | |
template <typename Class> | |
class ClassMetaInfo { | |
public: | |
static void serialize(Class& obj, const json& j) | |
{ | |
for (const auto& pair : members) { | |
const auto& memberName = pair.first; | |
const auto& memberPtr = pair.second; | |
memberPtr->fromJson(obj, j[memberName]); | |
} | |
} | |
static json deserialize(const Class& obj) | |
{ | |
json j; | |
for (const auto& pair : members) { | |
const auto& memberName = pair.first; | |
const auto& memberPtr = pair.second; | |
j[memberName] = memberPtr->toJson(obj); | |
} | |
return j; | |
} | |
template <typename T> | |
static void registerMember(const char* name, T Class::* ptr) | |
{ | |
members.emplace(name, std::make_unique<Member<Class, T>>(ptr)); | |
} | |
using MemberPtrType = std::unique_ptr<IMember<Class>>; | |
using MemberMapType = std::unordered_map<std::string, MemberPtrType>; | |
private: | |
static MemberMapType members; | |
}; | |
template <typename Class> | |
typename ClassMetaInfo<Class>::MemberMapType ClassMetaInfo<Class>::members; | |
struct Person { | |
std::string name; | |
int age; | |
static void registerClass() | |
{ | |
ClassMetaInfo<Person>::registerMember("name", &Person::name); | |
ClassMetaInfo<Person>::registerMember("age", &Person::age); | |
} | |
}; | |
int main() | |
{ | |
std::tuple<Member<Person, std::string>, Member<Person, int>> members; | |
Person::registerClass(); | |
Person p{ "John", 30 }; | |
json j = ClassMetaInfo<Person>::deserialize(p); | |
std::cout << std::setw(4) << j << std::endl; | |
Person p2; | |
ClassMetaInfo<Person>::serialize(p2, j); | |
std::cout << "Name = " << p2.name << ", age = " << p2.age << "\n"; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment