Created
January 2, 2013 14:01
-
-
Save evandrix/4434795 to your computer and use it in GitHub Desktop.
Compile time reflection in C++ @ http://lugtug.blogspot.co.uk/2012/12/compile-time-reflection-in-c.html
This file contains hidden or 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 | |
//by dain bray 12/25/2012 | |
//use however you want. | |
#include <type_traits> | |
#include <boost/preprocessor/seq/size.hpp> | |
#include <boost/preprocessor/seq/enum.hpp> | |
#include <boost/preprocessor/seq/pop_front.hpp> | |
#include <boost/preprocessor/seq/for_each_i.hpp> | |
#include <boost/preprocessor/seq/push_back.hpp> | |
#include <boost/preprocessor/seq/elem.hpp> | |
namespace ptl | |
{ | |
namespace member_classes | |
{ | |
struct Variable{}; | |
struct StaticVariable{}; | |
struct Function{}; | |
struct StaticFunction{}; | |
template<bool IsMemberPtr, bool IsMemberFxnPtr, bool IsFunction> | |
struct get_member_class{ struct Something_horrible_happened{}; typedef Something_horrible_happened type;}; | |
template<> | |
struct get_member_class<true, false, false>{ typedef Variable type;}; | |
template<> | |
struct get_member_class<true, true, false>{ typedef Function type;}; | |
template<> | |
struct get_member_class< false, false, false>{ typedef StaticVariable type;}; | |
template<> | |
struct get_member_class< false, false, true>{ typedef StaticFunction type;}; | |
} | |
struct no_meta_data{}; | |
//add more meta tags as required | |
template<class T0 = no_meta_data, class T1 = no_meta_data, class T2 = no_meta_data> | |
struct MetaData | |
{ | |
typedef T0 meta0; | |
typedef T1 meta1; | |
typedef T2 meta2; | |
}; | |
} | |
#define PP__PROCESS_META_DATA(seq) typedef ptl::MetaData<seq> meta; | |
#define PP_MAKE_GET_MEMBER_PTR(TheName) static auto GetMemberPtr() -> decltype(&self_type:: ## TheName) { return &self_type:: ## TheName;} | |
#define PP_MAKE_MEMBER_CLASS(TheName) typedef ptl::member_classes::get_member_class<std::is_member_pointer<decltype(&self_type:: ## TheName)>::value, \ | |
std::is_member_function_pointer<decltype(&self_type:: ## TheName)>::value, std::is_function<decltype(self_type:: ## TheName)>::value>::type member_class; | |
#define PP_MAKE_GET_NAME(TheName) static const char* GetName(){return # TheName;} | |
#define PP_MAKE_VARIABLE_TYPE(TheName, index) typedef decltype(TheName) type; PP_MAKE_GET_MEMBER_PTR(TheName) \ | |
PP_MAKE_GET_NAME(TheName) PP_MAKE_MEMBER_CLASS(TheName) | |
#define PP_REFLECT_SINGLE_MEMBER(r, data, index, seq) public: struct Member ## index{ PP_MAKE_VARIABLE_TYPE(BOOST_PP_SEQ_HEAD(seq), index) \ | |
PP__PROCESS_META_DATA(BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_POP_FRONT(BOOST_PP_SEQ_PUSH_BACK (seq, ptl::no_meta_data)))) }; | |
#define PP_Reflect(className, seq) struct Reflection{ \ | |
typedef className self_type; \ | |
BOOST_PP_SEQ_FOR_EACH_I(PP_REFLECT_SINGLE_MEMBER, _, seq) \ | |
enum{NumClassMembers = BOOST_PP_SEQ_SIZE(seq)};}; \ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment