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

any: make vtable void-friendly

skypjack 5 месяцев назад
Родитель
Сommit
ab1d7d0126
1 измененных файлов с 51 добавлено и 53 удалено
  1. 51 53
      src/entt/core/any.hpp

+ 51 - 53
src/entt/core/any.hpp

@@ -68,63 +68,61 @@ class basic_any: private internal::basic_any_storage<Len, Align> {
         static_assert(std::is_same_v<std::remove_const_t<std::remove_reference_t<Type>>, Type>, "Invalid type");
         static constexpr auto in_situ = internal::in_situ<Type, Len, Align>::value;
 
-        if constexpr(!std::is_void_v<Type>) {
-            const Type *elem = nullptr;
+        const Type *elem = nullptr;
+
+        if constexpr(in_situ_v<Type>) {
+            elem = (value.mode == any_policy::embedded) ? reinterpret_cast<const Type *>(&value.buffer) : static_cast<const Type *>(value.instance);
+        } else {
+            elem = static_cast<const Type *>(value.instance);
+        }
 
+        switch(req) {
+        case request::transfer:
+            if constexpr(std::is_move_assignable_v<Type>) {
+                // NOLINTNEXTLINE(bugprone-casting-through-void)
+                *const_cast<Type *>(elem) = std::move(*static_cast<Type *>(const_cast<void *>(other)));
+                return other;
+            }
+            [[fallthrough]];
+        case request::assign:
+            if constexpr(std::is_copy_assignable_v<Type>) {
+                *const_cast<Type *>(elem) = *static_cast<const Type *>(other);
+                return other;
+            }
+            break;
+        case request::destroy:
             if constexpr(in_situ_v<Type>) {
-                elem = (value.mode == any_policy::embedded) ? reinterpret_cast<const Type *>(&value.buffer) : static_cast<const Type *>(value.instance);
+                (value.mode == any_policy::embedded) ? elem->~Type() : (delete elem);
+            } else if constexpr(std::is_array_v<Type>) {
+                delete[] elem;
             } else {
-                elem = static_cast<const Type *>(value.instance);
+                delete elem;
             }
-
-            switch(req) {
-            case request::transfer:
-                if constexpr(std::is_move_assignable_v<Type>) {
-                    // NOLINTNEXTLINE(bugprone-casting-through-void)
-                    *const_cast<Type *>(elem) = std::move(*static_cast<Type *>(const_cast<void *>(other)));
-                    return other;
-                }
-                [[fallthrough]];
-            case request::assign:
-                if constexpr(std::is_copy_assignable_v<Type>) {
-                    *const_cast<Type *>(elem) = *static_cast<const Type *>(other);
-                    return other;
-                }
-                break;
-            case request::destroy:
-                if constexpr(in_situ_v<Type>) {
-                    (value.mode == any_policy::embedded) ? elem->~Type() : (delete elem);
-                } else if constexpr(std::is_array_v<Type>) {
-                    delete[] elem;
-                } else {
-                    delete elem;
-                }
-                break;
-            case request::compare:
-                if constexpr(!std::is_function_v<Type> && !std::is_array_v<Type> && is_equality_comparable_v<Type>) {
-                    return (*elem == *static_cast<const Type *>(other)) ? other : nullptr;
-                } else {
-                    return (elem == other) ? other : nullptr;
-                }
-            case request::copy:
-                if constexpr(std::is_copy_constructible_v<Type>) {
-                    // NOLINTNEXTLINE(bugprone-casting-through-void)
-                    static_cast<basic_any *>(const_cast<void *>(other))->initialize<Type>(*elem);
-                }
-                break;
-            case request::move:
-                ENTT_ASSERT(value.mode == any_policy::embedded, "Unexpected policy");
-                if constexpr(in_situ_v<Type>) {
-                    // NOLINTNEXTLINE(bugprone-casting-through-void, bugprone-multi-level-implicit-pointer-conversion)
-                    return ::new(&static_cast<basic_any *>(const_cast<void *>(other))->buffer) Type{std::move(*const_cast<Type *>(elem))};
-                }
-                [[fallthrough]];
-            case request::get:
-                ENTT_ASSERT(value.mode == any_policy::embedded, "Unexpected policy");
-                if constexpr(in_situ_v<Type>) {
-                    // NOLINTNEXTLINE(bugprone-multi-level-implicit-pointer-conversion)
-                    return elem;
-                }
+            break;
+        case request::compare:
+            if constexpr(!std::is_function_v<Type> && !std::is_array_v<Type> && is_equality_comparable_v<Type>) {
+                return (*elem == *static_cast<const Type *>(other)) ? other : nullptr;
+            } else {
+                return (elem == other) ? other : nullptr;
+            }
+        case request::copy:
+            if constexpr(std::is_copy_constructible_v<Type>) {
+                // NOLINTNEXTLINE(bugprone-casting-through-void)
+                static_cast<basic_any *>(const_cast<void *>(other))->initialize<Type>(*elem);
+            }
+            break;
+        case request::move:
+            ENTT_ASSERT(value.mode == any_policy::embedded, "Unexpected policy");
+            if constexpr(in_situ_v<Type>) {
+                // NOLINTNEXTLINE(bugprone-casting-through-void, bugprone-multi-level-implicit-pointer-conversion)
+                return ::new(&static_cast<basic_any *>(const_cast<void *>(other))->buffer) Type{std::move(*const_cast<Type *>(elem))};
+            }
+            [[fallthrough]];
+        case request::get:
+            ENTT_ASSERT(value.mode == any_policy::embedded, "Unexpected policy");
+            if constexpr(in_situ_v<Type>) {
+                // NOLINTNEXTLINE(bugprone-multi-level-implicit-pointer-conversion)
+                return elem;
             }
         }