|
|
@@ -5,50 +5,84 @@
|
|
|
|
|
|
template <typename Object>
|
|
|
class reflection {
|
|
|
- private:
|
|
|
- template <typename T>
|
|
|
- using Field = T Object::*;
|
|
|
- public:
|
|
|
- reflection();
|
|
|
+private:
|
|
|
+ template <typename T> using Field = T Object::*;
|
|
|
+ template <typename K, typename V> using map = std::unordered_map<K, V>;
|
|
|
|
|
|
- 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;
|
|
|
+private:
|
|
|
+ template <typename T> static map<std::string, Field<T>> s_reflector;
|
|
|
+ static map<std::ptrdiff_t, std::string> s_fieldname;
|
|
|
+
|
|
|
+private:
|
|
|
+ template <typename T>
|
|
|
+ static std::ptrdiff_t offset(Field<T> field) {
|
|
|
+ return std::ptrdiff_t(&(reinterpret_cast<Object const*>(NULL)->*field));
|
|
|
+ }
|
|
|
+
|
|
|
+ static std::string_view name(std::ptrdiff_t offset) {
|
|
|
+ auto it = s_fieldname.find(offset);
|
|
|
+ if (it == s_fieldname.end()) { return ""; }
|
|
|
+ return it->second;
|
|
|
+ }
|
|
|
+
|
|
|
+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 std::string_view name(Object const * ptr, T const & data) {
|
|
|
+ return name(std::ptrdiff_t(&data) - std::ptrdiff_t(ptr));
|
|
|
+ }
|
|
|
+
|
|
|
+ template <typename T>
|
|
|
+ static std::string_view name(Object const & obj, T const & data) {
|
|
|
+ return name(&obj, data);
|
|
|
+ }
|
|
|
+
|
|
|
+ template <typename T>
|
|
|
+ static std::string_view name(Field<T> field) {
|
|
|
+ return name(offset(field));
|
|
|
+ }
|
|
|
+
|
|
|
+ template <typename T>
|
|
|
+ static void bind(Field<T> field, std::string const & name,
|
|
|
+ std::string const & /*discard*/ = "") {
|
|
|
+ s_fieldname.emplace(offset(field), name);
|
|
|
+ s_reflector<T>.emplace(name, field);
|
|
|
+ }
|
|
|
};
|
|
|
|
|
|
-#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 );
|
|
|
+#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>
|
|
|
+#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;
|
|
|
+template <typename Object>
|
|
|
+std::unordered_map<std::ptrdiff_t, std::string> reflection<Object>::s_fieldname;
|