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

any: use std::array internally

Michele Caini 1 год назад
Родитель
Сommit
514e6e710c
1 измененных файлов с 6 добавлено и 9 удалено
  1. 6 9
      src/entt/core/any.hpp

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

@@ -1,6 +1,7 @@
 #ifndef ENTT_CORE_ANY_HPP
 #define ENTT_CORE_ANY_HPP
 
+#include <array>
 #include <cstddef>
 #include <memory>
 #include <type_traits>
@@ -49,10 +50,6 @@ class basic_any {
     using operation = internal::any_operation;
     using vtable_type = const void *(const operation, const basic_any &, const void *);
 
-    struct storage_type {
-        alignas(Align) std::byte data[Len + !Len];
-    };
-
     template<typename Type>
     static constexpr bool in_situ = Len && alignof(Type) <= Align && sizeof(Type) <= Len && std::is_nothrow_move_constructible_v<Type>;
 
@@ -62,7 +59,7 @@ class basic_any {
         const Type *elem = nullptr;
 
         if constexpr(in_situ<Type>) {
-            elem = (value.mode == any_policy::owner) ? reinterpret_cast<const Type *>(&value.storage) : static_cast<const Type *>(value.instance);
+            elem = (value.mode == any_policy::owner) ? reinterpret_cast<const Type *>(value.storage.data()) : static_cast<const Type *>(value.instance);
         } else {
             elem = static_cast<const Type *>(value.instance);
         }
@@ -76,7 +73,7 @@ class basic_any {
         case operation::move:
             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.data()) Type{std::move(*const_cast<Type *>(elem))};
                 }
             }
 
@@ -128,9 +125,9 @@ class basic_any {
                 instance = (std::addressof(args), ...);
             } else if constexpr(in_situ<std::remove_cv_t<std::remove_reference_t<Type>>>) {
                 if constexpr(std::is_aggregate_v<std::remove_cv_t<std::remove_reference_t<Type>>> && (sizeof...(Args) != 0u || !std::is_default_constructible_v<std::remove_cv_t<std::remove_reference_t<Type>>>)) {
-                    ::new(&storage) std::remove_cv_t<std::remove_reference_t<Type>>{std::forward<Args>(args)...};
+                    ::new(storage.data()) std::remove_cv_t<std::remove_reference_t<Type>>{std::forward<Args>(args)...};
                 } else {
-                    ::new(&storage) std::remove_cv_t<std::remove_reference_t<Type>>(std::forward<Args>(args)...);
+                    ::new(storage.data()) std::remove_cv_t<std::remove_reference_t<Type>>(std::forward<Args>(args)...);
                 }
             } else {
                 if constexpr(std::is_aggregate_v<std::remove_cv_t<std::remove_reference_t<Type>>> && (sizeof...(Args) != 0u || !std::is_default_constructible_v<std::remove_cv_t<std::remove_reference_t<Type>>>)) {
@@ -406,7 +403,7 @@ public:
 private:
     union {
         const void *instance;
-        storage_type storage;
+        alignas(Align) std::array<std::byte, Len> storage;
     };
     const type_info *info;
     vtable_type *vtable;