Created
February 3, 2018 23:20
-
-
Save dwilliamson/2d0a9692430749a91d03cc52961a7a61 to your computer and use it in GitHub Desktop.
Basic compile-time reflection for C++11
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
#pragma once | |
#include <typestring/typestring.hh> | |
namespace rfl | |
{ | |
// Compile-time data member description | |
template <typename ClassType, typename MemberType, MemberType ClassType::*MemberPtr, typename NameType> | |
struct DataMember | |
{ | |
using Class = ClassType; | |
using Type = MemberType; | |
using Name = NameType; | |
static Type& Get(Class& object) | |
{ | |
return object.*MemberPtr; | |
} | |
}; | |
// Forward declaration of data members list | |
template <typename... Types> | |
struct DataMembers; | |
// A typed linked list for all data members of a class | |
// Repeatedly split a type list into (i, i+1...N) pairs, recursively inheriting | |
// from the second half until there's nothing left; similar to Lisp's car/cdr. | |
template <typename First, typename... Rest> | |
struct DataMembers<First, Rest...> : public DataMembers<Rest...> | |
{ | |
// Links within the list | |
using Type = First; | |
using Next = DataMembers<Rest...>; | |
}; | |
// Terminate a data members list | |
template <> | |
struct DataMembers<> | |
{ | |
}; | |
// So that reflection lists don't require terminating commas | |
struct EndType | |
{ | |
int end; | |
}; | |
// Class reflectors for all types in the system | |
template <typename Class> | |
struct ClassReflector | |
{ | |
}; | |
#define ReflectClass(cls) \ | |
template <> \ | |
struct rfl::ClassReflector<cls> \ | |
{ \ | |
using Class = cls; \ | |
using DataMembers = rfl::DataMembers< | |
#define Reflect(member) \ | |
rfl::DataMember<Class, decltype(member), &member, typestring_is(#member)>, | |
#define EndReflect() \ | |
rfl::DataMember<rfl::EndType, decltype(rfl::EndType::end), &rfl::EndType::end, typestring_is("end")> \ | |
>; \ | |
}; | |
} |
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
ReflectClass(Rect) | |
Reflect(Rect::top) | |
Reflect(Rect::left) | |
Reflect(Rect::bottom) | |
Reflect(Rect::right) | |
EndReflect() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment