#pragma once #include #include template class reflection { private: template using Field = T Object::*; public: reflection(); template static bool exists( std::string const & name ) { return s_reflector.count( name ); } template static Field get_pointer( std::string const & name ) { auto it = s_reflector.find( name ); if ( it == s_reflector.end() ) { return nullptr; } return it->second; } template static void bind( Field field, std::string const & name, std::string const & /*discard*/ = "" ) { s_reflector.reserve( s_reflector.size() + 1 ); s_reflector.emplace( name, field ); } private: template static std::unordered_map> s_reflector; }; #define REFLECT_MEMBER_PP_IMPL2( type, field, ... ) bind( &type::field, ##__VA_ARGS__, #field ) #define REFLECT_MEMBER_PP_IMPL( type, field, ... ) REFLECT_MEMBER_PP_IMPL2( type, field, ##__VA_ARGS__ ) #define UNWRAP( ... ) __VA_ARGS__ #define REFLECT_MEMBER_PP2( data, elem ) REFLECT_MEMBER_PP_IMPL( data, UNWRAP elem ) #define REFLECT_MEMBER_PP( r, data, elem ) REFLECT_MEMBER_PP2( data, elem ); #include #include #define CONCAT2( A, B ) A##B #define CONCAT( A, B ) CONCAT2( A, B ) #define CREATE_REFLECTION( type, ... ) \ template <> reflection::reflection() { \ BOOST_PP_SEQ_FOR_EACH( REFLECT_MEMBER_PP, type, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__) ) \ } \ static reflection CONCAT( reflector_, __LINE__ ) {} template template std::unordered_map reflection::s_reflector;