| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354 |
- #pragma once
- #include <string>
- #include <unordered_map>
- template <typename Object>
- class reflection {
- private:
- template <typename T>
- using Field = T Object::*;
- public:
- reflection();
-
- template <typename T>
- static bool exists( std::string const & name ) {
- return s_reflector<T>.count( name );
- }
- template <typename T>
- static Field<T> get_pointer( std::string const & name ) {
- auto it = s_reflector<T>.find( name );
- if ( it == s_reflector<T>.end() ) { return nullptr; }
- return it->second;
- }
- template <typename T>
- static void bind( Field<T> field, std::string const & name, std::string const & /*discard*/ = "" ) {
- s_reflector<T>.reserve( s_reflector<T>.size() + 1 );
- s_reflector<T>.emplace( name, field );
- }
- private:
- template <typename T>
- static std::unordered_map<std::string, Field<T>> 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 <boost/preprocessor/variadic/to_seq.hpp>
- #include <boost/preprocessor/seq/for_each.hpp>
- #define CONCAT2( A, B ) A##B
- #define CONCAT( A, B ) CONCAT2( A, B )
- #define CREATE_REFLECTION( type, ... ) \
- template <> reflection<type>::reflection() { \
- BOOST_PP_SEQ_FOR_EACH( REFLECT_MEMBER_PP, type, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__) ) \
- } \
- static reflection<type> CONCAT( reflector_, __LINE__ ) {}
- template <typename Object>
- template <typename T>
- std::unordered_map<std::string, T Object::*> reflection<Object>::s_reflector;
|