Bladeren bron

any: skip vtable on move for reference types

Michele Caini 1 jaar geleden
bovenliggende
commit
e13c87a447
2 gewijzigde bestanden met toevoegingen van 18 en 10 verwijderingen
  1. 1 0
      TODO
  2. 17 10
      src/entt/core/any.hpp

+ 1 - 0
TODO

@@ -42,3 +42,4 @@ TODO:
 * sigh_mixin: change cb signature from reg/entt to storage/entt (breaking for the good)
 * sigh_mixin: change cb signature from reg/entt to storage/entt (breaking for the good)
 * don't pass reactive storage by default to callback
 * don't pass reactive storage by default to callback
 * runtime types support for meta for types that aren't backed by C++ types
 * runtime types support for meta for types that aren't backed by C++ types
+* bypass vtable in any (improvements available for move/get, add more policy types)

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

@@ -75,13 +75,13 @@ class basic_any {
             }
             }
             break;
             break;
         case operation::move:
         case operation::move:
+            ENTT_ASSERT(value.mode == any_policy::owner, "Unexpected mode");
+
             if constexpr(in_situ<Type>) {
             if constexpr(in_situ<Type>) {
-                if(value.mode == any_policy::owner) {
-                    return ::new(&static_cast<basic_any *>(const_cast<void *>(other))->storage) Type{std::move(*const_cast<Type *>(elem))};
-                }
+                return ::new(&static_cast<basic_any *>(const_cast<void *>(other))->storage) Type{std::move(*const_cast<Type *>(elem))};
+            } else {
+                return (static_cast<basic_any *>(const_cast<void *>(other))->instance = std::exchange(const_cast<basic_any &>(value).instance, nullptr));
             }
             }
-
-            return (static_cast<basic_any *>(const_cast<void *>(other))->instance = std::exchange(const_cast<basic_any &>(value).instance, nullptr));
         case operation::transfer:
         case operation::transfer:
             if constexpr(std::is_move_assignable_v<Type>) {
             if constexpr(std::is_move_assignable_v<Type>) {
                 *const_cast<Type *>(elem) = std::move(*static_cast<Type *>(const_cast<void *>(other)));
                 *const_cast<Type *>(elem) = std::move(*static_cast<Type *>(const_cast<void *>(other)));
@@ -208,7 +208,10 @@ public:
           info{other.info},
           info{other.info},
           vtable{other.vtable},
           vtable{other.vtable},
           mode{other.mode} {
           mode{other.mode} {
-        if(other.vtable) {
+        if(other.mode != any_policy::owner) {
+            ENTT_ASSERT(other.mode == any_policy::ref || other.mode == any_policy::cref, "Unexpected mode");
+            instance = std::exchange(other.instance, nullptr);
+        } else if(other.vtable) {
             other.vtable(operation::move, other, this);
             other.vtable(operation::move, other, this);
         }
         }
     }
     }
@@ -247,13 +250,17 @@ public:
 
 
         reset();
         reset();
 
 
-        if(other.vtable) {
+        if(other.mode != any_policy::owner) {
+            ENTT_ASSERT(other.mode == any_policy::ref || other.mode == any_policy::cref, "Unexpected mode");
+            instance = std::exchange(other.instance, nullptr);
+        } else if(other.vtable) {
             other.vtable(operation::move, other, this);
             other.vtable(operation::move, other, this);
-            info = other.info;
-            vtable = other.vtable;
-            mode = other.mode;
         }
         }
 
 
+        info = other.info;
+        vtable = other.vtable;
+        mode = other.mode;
+
         return *this;
         return *this;
     }
     }