Bläddra i källkod

meta: make it work also with VS2017

Michele Caini 4 år sedan
förälder
incheckning
5228739c87
1 ändrade filer med 41 tillägg och 22 borttagningar
  1. 41 22
      src/entt/meta/factory.hpp

+ 41 - 22
src/entt/meta/factory.hpp

@@ -235,23 +235,49 @@ struct meta_factory<Type> {
     /**
      * @brief Assigns a meta conversion function to a meta type.
      *
-     * The given type must be such that an instance of the reflected type can be
-     * converted to it.
+     * Conversion functions can be either free functions or member
+     * functions.<br/>
+     * In case of free functions, they must accept a const reference to an
+     * instance of the parent type as an argument. In case of member functions,
+     * they should have no arguments at all.
      *
-     * @tparam To Type of the conversion function to assign to the meta type.
+     * @tparam Candidate The actual function to use for the conversion.
      * @return A meta factory for the parent type.
      */
-    template<typename To>
-    auto conv() ENTT_NOEXCEPT {
-        static_assert(std::is_convertible_v<Type, To>, "Could not convert to the required type");
+    template<auto Candidate>
+    std::enable_if_t<std::is_member_function_pointer_v<decltype(Candidate)>, meta_factory<Type>> conv() ENTT_NOEXCEPT {
+        using conv_type = std::invoke_result_t<decltype(Candidate), Type &>;
         auto * const type = internal::meta_info<Type>::resolve();
 
         static internal::meta_conv_node node{
             type,
             nullptr,
-            &internal::meta_info<To>::resolve,
+            &internal::meta_info<conv_type>::resolve,
             [](const void *instance) -> meta_any {
-                return static_cast<To>(*static_cast<const Type *>(instance));
+                return (static_cast<const Type *>(instance)->*Candidate)();
+            }
+        };
+
+        if(!internal::find_if(&node, type->conv)) {
+            node.next = type->conv;
+            type->conv = &node;
+        }
+
+        return meta_factory<Type>{};
+    }
+
+    /*! @copydoc conv */
+    template<auto Candidate>
+    std::enable_if_t<!std::is_member_function_pointer_v<decltype(Candidate)>, meta_factory<Type>> conv() ENTT_NOEXCEPT {
+        using conv_type = std::invoke_result_t<decltype(Candidate), Type &>;
+        auto * const type = internal::meta_info<Type>::resolve();
+
+        static internal::meta_conv_node node{
+            type,
+            nullptr,
+            &internal::meta_info<conv_type>::resolve,
+            [](const void *instance) -> meta_any {
+                return Candidate(*static_cast<const Type *>(instance));
             }
         };
 
@@ -266,30 +292,23 @@ struct meta_factory<Type> {
     /**
      * @brief Assigns a meta conversion function to a meta type.
      *
-     * Conversion functions can be either free functions or member
-     * functions.<br/>
-     * In case of free functions, they must accept a const reference to an
-     * instance of the parent type as an argument. In case of member functions,
-     * they should have no arguments at all.
+     * The given type must be such that an instance of the reflected type can be
+     * converted to it.
      *
-     * @tparam Candidate The actual function to use for the conversion.
+     * @tparam To Type of the conversion function to assign to the meta type.
      * @return A meta factory for the parent type.
      */
-    template<auto Candidate>
+    template<typename To>
     auto conv() ENTT_NOEXCEPT {
-        using conv_type = std::invoke_result_t<decltype(Candidate), Type &>;
+        static_assert(std::is_convertible_v<Type, To>, "Could not convert to the required type");
         auto * const type = internal::meta_info<Type>::resolve();
 
         static internal::meta_conv_node node{
             type,
             nullptr,
-            &internal::meta_info<conv_type>::resolve,
+            &internal::meta_info<To>::resolve,
             [](const void *instance) -> meta_any {
-                if constexpr(std::is_member_function_pointer_v<decltype(Candidate)>) {
-                    return (static_cast<const Type *>(instance)->*Candidate)();
-                } else {
-                    return Candidate(*static_cast<const Type *>(instance));
-                }
+                return static_cast<To>(*static_cast<const Type *>(instance));
             }
         };