Просмотр исходного кода

any: plugin-friendly, faster quick check

skypjack 3 месяцев назад
Родитель
Сommit
fe8320c66f
2 измененных файлов с 10 добавлено и 11 удалено
  1. 0 2
      TODO
  2. 10 9
      src/entt/core/any.hpp

+ 0 - 2
TODO

@@ -32,8 +32,6 @@ TODO:
 * paged vector as a standalone class
 * resource: shared_from_this?
 * finish the imgui viewer/editor!
-* introduce compile-time flag to skip dll-only checks in basic_any
 * archetype-like a-là EnTT support (see my own notes)
-* meta_any refine allow_cast implementations
 * meta: conversion_helper machinery has lot of room for improvements
 * meta_factory: add a replace flag to traits to get around the |-only mechanism

+ 10 - 9
src/entt/core/any.hpp

@@ -130,6 +130,7 @@ class basic_any: private internal::basic_any_storage<Len, Align> {
         using plain_type = std::remove_const_t<std::remove_reference_t<Type>>;
 
         vtable = basic_vtable<plain_type>;
+        underlying_type = type_hash<plain_type>::value();
 
         if constexpr(std::is_void_v<Type>) {
             deleter = nullptr;
@@ -243,6 +244,7 @@ public:
     basic_any(basic_any &&other) noexcept
         : base_type{},
           vtable{other.vtable},
+          underlying_type{other.underlying_type},
           deleter{other.deleter},
           mode{other.mode} {
         if(other.mode == any_policy::embedded) {
@@ -292,6 +294,7 @@ public:
             }
 
             vtable = other.vtable;
+            underlying_type = other.underlying_type;
             deleter = other.deleter;
             mode = other.mode;
         }
@@ -327,7 +330,7 @@ public:
      * otherwise.
      */
     [[nodiscard]] bool has_value(const type_info &req) const noexcept {
-        return (info() == req);
+        return (underlying_type == req.hash());
     }
 
     /**
@@ -340,8 +343,7 @@ public:
     template<typename Type>
     [[nodiscard]] bool has_value() const noexcept {
         static_assert(std::is_same_v<std::remove_const_t<Type>, Type>, "Invalid type");
-        // it could be a call across boundaries, but still for the same type
-        return (vtable == &basic_vtable<Type>) || has_value(type_id<Type>());
+        return (underlying_type == type_hash<Type>::value());
     }
 
     /**
@@ -437,8 +439,7 @@ public:
      * @return True in case of success, false otherwise.
      */
     bool assign(const basic_any &other) {
-        // it could be a call across boundaries, but still for the same type
-        if(other && (mode != any_policy::cref) && ((vtable == other.vtable) || has_value(other.info()))) {
+        if(other && (mode != any_policy::cref) && (underlying_type == other.underlying_type)) {
             return (vtable(request::assign, *this, other.data()) != nullptr);
         }
 
@@ -448,8 +449,7 @@ public:
     /*! @copydoc assign */
     // NOLINTNEXTLINE(cppcoreguidelines-rvalue-reference-param-not-moved)
     bool assign(basic_any &&other) {
-        // it could be a call across boundaries, but still for the same type
-        if(other && (mode != any_policy::cref) && ((vtable == other.vtable) || has_value(other.info()))) {
+        if(other && (mode != any_policy::cref) && (underlying_type == other.underlying_type)) {
             return (other.mode == any_policy::cref) ? (vtable(request::assign, *this, std::as_const(other).data()) != nullptr) : (vtable(request::transfer, *this, other.data()) != nullptr);
         }
 
@@ -476,8 +476,7 @@ public:
      * @return False if the two objects differ in their content, true otherwise.
      */
     [[nodiscard]] bool operator==(const basic_any &other) const noexcept {
-        // it could be a call across boundaries, but still for the same type
-        if(other && ((vtable == other.vtable) || has_value(other.info()))) {
+        if(other && (underlying_type == other.underlying_type)) {
             return (vtable(request::compare, *this, other.data()) != nullptr);
         }
 
@@ -508,6 +507,7 @@ public:
         basic_any other{};
         other.instance = data();
         other.vtable = vtable;
+        other.underlying_type = underlying_type;
         other.mode = any_policy::cref;
         return other;
     }
@@ -531,6 +531,7 @@ public:
 private:
     vtable_type *vtable{};
     deleter_type *deleter{};
+    id_type underlying_type{};
     any_policy mode{};
 };