Browse Source

meta: review

Michele Caini 6 years ago
parent
commit
442c7f1f09
2 changed files with 42 additions and 50 deletions
  1. 2 1
      TODO
  2. 40 49
      src/entt/meta/meta.hpp

+ 2 - 1
TODO

@@ -38,4 +38,5 @@
 * is it possible to make named type constraints namespace-free?
 * is it possible to make named type constraints namespace-free?
 * stomp -> merge (naming is hard as heck, it's known thing)
 * stomp -> merge (naming is hard as heck, it's known thing)
 * observer: user defined filters (eg .replace<T, &function> or .group<T, U, &func>)
 * observer: user defined filters (eg .replace<T, &function> or .group<T, U, &func>)
-* get rid of meta_handle, it's no longer required
+* review noexcept policy (there are some errores here and there)
+* use meta_handle for inputs to invoke/ctor/...

+ 40 - 49
src/entt/meta/meta.hpp

@@ -3,7 +3,6 @@
 
 
 
 
 #include <array>
 #include <array>
-#include <memory>
 #include <cstddef>
 #include <cstddef>
 #include <utility>
 #include <utility>
 #include <type_traits>
 #include <type_traits>
@@ -308,63 +307,58 @@ class meta_any {
     friend class meta_handle;
     friend class meta_handle;
 
 
     using storage_type = std::aligned_storage_t<sizeof(void *), alignof(void *)>;
     using storage_type = std::aligned_storage_t<sizeof(void *), alignof(void *)>;
-    using copy_fn_type = void *(storage_type &, const void *);
-    using destroy_fn_type = void(void *);
-    using steal_fn_type = void *(storage_type &, void *, destroy_fn_type *);
-
-    template<typename Type>
-    static Type * release(Type *instance) {
-        const auto * const node = internal::meta_info<Type>::resolve();
-        [[maybe_unused]] const bool destroyed = (!node->dtor || node->dtor->invoke(*instance));
-        ENTT_ASSERT(destroyed);
-        return instance;
-    }
+    using copy_fn_type = void(meta_any &, const meta_any &);
+    using steal_fn_type = void(meta_any &, meta_any &);
+    using destroy_fn_type = void(meta_any &);
 
 
     template<typename Type, typename = std::void_t<>>
     template<typename Type, typename = std::void_t<>>
     struct type_traits {
     struct type_traits {
         template<typename... Args>
         template<typename... Args>
-        static void * instance(storage_type &storage, Args &&... args) {
-            auto instance = std::make_unique<Type>(std::forward<Args>(args)...);
-            new (&storage) Type *{instance.get()};
-            return instance.release();
+        static void instance(meta_any &any, Args &&... args) {
+            any.instance = new Type{std::forward<Args>(args)...};
+            new (&any.storage) Type *{static_cast<Type *>(any.instance)};
         }
         }
 
 
-        static void destroy(void *instance) {
-            delete release<Type>(static_cast<Type *>(instance));
+        static void destroy(meta_any &any) {
+            const auto * const node = internal::meta_info<Type>::resolve();
+            [[maybe_unused]] const bool destroyed = (!node->dtor || node->dtor->invoke(any));
+            delete static_cast<Type *>(any.instance);
+            ENTT_ASSERT(destroyed);
         }
         }
 
 
-        static void * copy(storage_type &storage, const void *other) {
-            auto instance = std::make_unique<Type>(*static_cast<const Type *>(other));
-            new (&storage) Type *{instance.get()};
-            return instance.release();
+        static void copy(meta_any &to, const meta_any &from) {
+            auto *instance = new Type{*static_cast<const Type *>(from.instance)};
+            new (&to.storage) Type *{instance};
+            to.instance = instance;
         }
         }
 
 
-        static void * steal(storage_type &to, void *from, destroy_fn_type *) {
-            auto * const instance = static_cast<Type *>(from);
-            new (&to) Type *{instance};
-            return instance;
+        static void steal(meta_any &to, meta_any &from) {
+            new (&to.storage) Type *{static_cast<Type *>(from.instance)};
+            to.instance = from.instance;
         }
         }
     };
     };
 
 
     template<typename Type>
     template<typename Type>
     struct type_traits<Type, std::enable_if_t<sizeof(Type) <= sizeof(void *) && std::is_nothrow_move_constructible_v<Type>>> {
     struct type_traits<Type, std::enable_if_t<sizeof(Type) <= sizeof(void *) && std::is_nothrow_move_constructible_v<Type>>> {
         template<typename... Args>
         template<typename... Args>
-        static void * instance(storage_type &storage, Args &&... args) {
-            return new (&storage) Type{std::forward<Args>(args)...};
+        static void instance(meta_any &any, Args &&... args) {
+            any.instance = new (&any.storage) Type{std::forward<Args>(args)...};
         }
         }
 
 
-        static void destroy(void *instance) {
-            release<Type>(static_cast<Type *>(instance))->~Type();
+        static void destroy(meta_any &any) {
+            const auto * const node = internal::meta_info<Type>::resolve();
+            [[maybe_unused]] const bool destroyed = (!node->dtor || node->dtor->invoke(any));
+            static_cast<Type *>(any.instance)->~Type();
+            ENTT_ASSERT(destroyed);
         }
         }
 
 
-        static void * copy(storage_type &storage, const void *instance) {
-            return new (&storage) Type{*static_cast<const Type *>(instance)};
+        static void copy(meta_any &to, const meta_any &from) {
+            to.instance = new (&to.storage) Type{*static_cast<const Type *>(from.instance)};
         }
         }
 
 
-        static void * steal(storage_type &to, void *from, destroy_fn_type *destroy_fn) {
-            void * const instance = new (&to) Type{std::move(*static_cast<Type *>(from))};
-            destroy_fn(from);
-            return instance;
+        static void steal(meta_any &to, meta_any &from) {
+            to.instance = new (&to.storage) Type{std::move(*static_cast<Type *>(from.instance))};
+            destroy(from);
         }
         }
     };
     };
 
 
@@ -385,10 +379,9 @@ public:
         node = internal::meta_info<Type>::resolve();
         node = internal::meta_info<Type>::resolve();
 
 
         if constexpr(!std::is_void_v<Type>) {
         if constexpr(!std::is_void_v<Type>) {
-            using traits_type = type_traits<std::remove_cv_t<std::remove_reference_t<Type>>>;
             static_assert(std::is_copy_constructible_v<Type>);
             static_assert(std::is_copy_constructible_v<Type>);
-
-            instance = traits_type::instance(storage, std::forward<Args>(args)...);
+            using traits_type = type_traits<std::remove_cv_t<std::remove_reference_t<Type>>>;
+            traits_type::instance(*this, std::forward<Args>(args)...);
             destroy_fn = &traits_type::destroy;
             destroy_fn = &traits_type::destroy;
             copy_fn = &traits_type::copy;
             copy_fn = &traits_type::copy;
             steal_fn = &traits_type::steal;
             steal_fn = &traits_type::steal;
@@ -432,7 +425,7 @@ public:
         : meta_any{}
         : meta_any{}
     {
     {
         node = other.node;
         node = other.node;
-        instance = other.copy_fn ? other.copy_fn(storage, other.instance) : other.instance;
+        (other.copy_fn ? other.copy_fn : [](meta_any &to, const meta_any &from) { to.instance = from.instance; })(*this, other);
         destroy_fn = other.destroy_fn;
         destroy_fn = other.destroy_fn;
         copy_fn = other.copy_fn;
         copy_fn = other.copy_fn;
         steal_fn = other.steal_fn;
         steal_fn = other.steal_fn;
@@ -455,7 +448,7 @@ public:
     /*! @brief Frees the internal storage, whatever it means. */
     /*! @brief Frees the internal storage, whatever it means. */
     ~meta_any() {
     ~meta_any() {
         if(destroy_fn) {
         if(destroy_fn) {
-            destroy_fn(instance);
+            destroy_fn(*this);
         }
         }
     }
     }
 
 
@@ -634,16 +627,14 @@ public:
      */
      */
     friend void swap(meta_any &lhs, meta_any &rhs) ENTT_NOEXCEPT {
     friend void swap(meta_any &lhs, meta_any &rhs) ENTT_NOEXCEPT {
         if(lhs.steal_fn && rhs.steal_fn) {
         if(lhs.steal_fn && rhs.steal_fn) {
-            storage_type buffer;
-            auto * const temp = lhs.steal_fn(buffer, lhs.instance, lhs.destroy_fn);
-            lhs.instance = rhs.steal_fn(lhs.storage, rhs.instance, rhs.destroy_fn);
-            rhs.instance = lhs.steal_fn(rhs.storage, temp, lhs.destroy_fn);
+            meta_any buffer{};
+            lhs.steal_fn(buffer, lhs);
+            rhs.steal_fn(lhs, rhs);
+            lhs.steal_fn(rhs, buffer);
         } else if(lhs.steal_fn) {
         } else if(lhs.steal_fn) {
-            lhs.instance = lhs.steal_fn(rhs.storage, lhs.instance, lhs.destroy_fn);
-            std::swap(rhs.instance, lhs.instance);
+            lhs.steal_fn(rhs, lhs);
         } else if(rhs.steal_fn) {
         } else if(rhs.steal_fn) {
-            rhs.instance = rhs.steal_fn(lhs.storage, rhs.instance, rhs.destroy_fn);
-            std::swap(rhs.instance, lhs.instance);
+            rhs.steal_fn(lhs, rhs);
         } else {
         } else {
             std::swap(lhs.instance, rhs.instance);
             std::swap(lhs.instance, rhs.instance);
         }
         }