Skip to content

Instantly share code, notes, and snippets.

@evandrix
Created January 2, 2013 14:01
Show Gist options
  • Save evandrix/4434795 to your computer and use it in GitHub Desktop.
Save evandrix/4434795 to your computer and use it in GitHub Desktop.
#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