Browse Source

meta: early exit for typed allow_cast

Michele Caini 1 year ago
parent
commit
1650d058f6
2 changed files with 7 additions and 4 deletions
  1. 2 0
      TODO
  2. 5 4
      src/entt/meta/meta.hpp

+ 2 - 0
TODO

@@ -31,3 +31,5 @@ TODO:
 * allow passing arguments to meta setter/getter (we can fallback on meta invoke probably)
 * FetchContent_Populate -> FetchContent_MakeAvailable warnings
 * doc: IMPLICIT_DIR_DOCS for dir docs or \dir
+* meta non-const allow_cast overloads: (const int &) to (int &) is not allowed, but (const int &) to (double &) is allowed
+* improve non-const allow cast with in-place switch

+ 5 - 4
src/entt/meta/meta.hpp

@@ -514,8 +514,8 @@ public:
         if constexpr(std::is_reference_v<Type> && !std::is_const_v<std::remove_reference_t<Type>>) {
             return meta_any{meta_ctx_arg, *ctx};
         } else {
-            auto other = internal::resolve<std::remove_cv_t<std::remove_reference_t<Type>>>(internal::meta_context::from(*ctx));
-            return allow_cast(meta_type{*ctx, other});
+            // also support early return for performance reasons
+            return ((node.info != nullptr) && (*node.info == entt::type_id<Type>())) ? as_ref() : allow_cast(meta_type{*ctx, internal::resolve<std::remove_cv_t<std::remove_reference_t<Type>>>(internal::meta_context::from(*ctx))});
         }
     }
 
@@ -526,8 +526,9 @@ public:
      */
     template<typename Type>
     [[nodiscard]] bool allow_cast() {
-        auto other = internal::resolve<std::remove_cv_t<std::remove_reference_t<Type>>>(internal::meta_context::from(*ctx));
-        return allow_cast(meta_type{*ctx, other}) && (!(std::is_reference_v<Type> && !std::is_const_v<std::remove_reference_t<Type>>) || storage.data() != nullptr);
+        // also support early return for performance reasons
+        return (((node.info != nullptr) && (*node.info == entt::type_id<Type>())) || allow_cast(meta_type{*ctx, internal::resolve<std::remove_cv_t<std::remove_reference_t<Type>>>(internal::meta_context::from(*ctx))}))
+               && (!(std::is_reference_v<Type> && !std::is_const_v<std::remove_reference_t<Type>>) || storage.data() != nullptr);
     }
 
     /*! @copydoc any::emplace */