Pages

Re

#pragma once
// \ 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)};}; \


No comments:

Post a Comment