Forráskód Böngészése

bugfix: mark enum as final reflection
refactor: add more coercive binds

Sam Jaffe 3 éve
szülő
commit
efc8ea5171
1 módosított fájl, 36 hozzáadás és 2 törlés
  1. 36 2
      include/reflection/reflection.h

+ 36 - 2
include/reflection/reflection.h

@@ -21,7 +21,7 @@ namespace reflection {
 
 template <typename T>
 constexpr auto is_final_reflection =
-    std::is_same_v<T, std::string> || std::is_fundamental_v<T>;
+    std::is_same_v<T, std::string> || std::is_fundamental_v<T> || std::is_enum_v<T>;
 
 template <typename Obj, typename> class Reflection {
 public:
@@ -70,13 +70,47 @@ public:
     return *this;
   }
 
+  template <typename F> Reflection & bind(std::string_view id, F func) {
+    if constexpr (!std::is_const_v<decltype(func(std::declval<Obj &>()))>) {
+      members_.emplace(id, REFLECTION(func(obj)));
+    } else {
+      members_.emplace(id, CONST_REFLECTION(func(obj)));
+    }
+    const_members_.emplace(id, CONST_REFLECTION(func(obj)));
+    return *this;
+  }
+
   template <typename R, typename T>
   Reflection & bind(std::string_view id, T Obj::*member) {
-    TypeConversion<R, T> convert;
+    if constexpr (std::is_convertible_v<T, R>) {
+      return bind(id, member, [](T const &v) { return static_cast<R>(v); });
+    } else {
+      return bind(id, member, TypeConversion<R, T>());
+    }
+  }
+  
+  template <typename R, typename T>
+  Reflection & bind(std::string_view id, T (Obj::*get)() const) {
+    if constexpr (std::is_convertible_v<T, R>) {
+      return bind(id, get, [](T const &v) { return static_cast<R>(v); });
+    } else {
+      return bind(id, get, TypeConversion<R, T>());
+    }
+  }
+  
+  template <typename T, typename F>
+  Reflection & bind(std::string_view id, T Obj::*member, F convert) {
     members_.emplace(id, CONST_REFLECTION(convert(obj.*member)));
     const_members_.emplace(id, CONST_REFLECTION(convert(obj.*member)));
     return *this;
   }
+  
+  template <typename T, typename F>
+  Reflection & bind(std::string_view id, T (Obj::*get)() const, F convert) {
+    members_.emplace(id, CONST_REFLECTION(convert((obj.*get)())));
+    const_members_.emplace(id, CONST_REFLECTION(convert((obj.*get)())));
+    return *this;
+  }
 
 private:
   static Cache<Accessor<Obj>> members_;