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

any: take in consideration alignment requirements for in_situ test (see #676)

Michele Caini 5 лет назад
Родитель
Сommit
e996d3398f
2 измененных файлов с 10 добавлено и 1 удалено
  1. 1 1
      src/entt/core/any.hpp
  2. 9 0
      test/entt/core/any.cpp

+ 1 - 1
src/entt/core/any.hpp

@@ -28,7 +28,7 @@ class basic_any {
     using vtable_type = const void *(const operation, const basic_any &, const void *);
 
     template<typename Type>
-    static constexpr bool in_situ = Len && sizeof(Type) <= sizeof(storage_type) && std::is_nothrow_move_constructible_v<Type>;
+    static constexpr bool in_situ = Len && alignof(Type) <= alignof(storage_type) && sizeof(Type) <= sizeof(storage_type) && std::is_nothrow_move_constructible_v<Type>;
 
     template<typename Type>
     [[nodiscard]] static bool compare(const void *lhs, const void *rhs) {

+ 9 - 0
test/entt/core/any.cpp

@@ -34,6 +34,8 @@ struct not_copyable {
     double payload[Sz];
 };
 
+struct alignas(64u) over_aligned {};
+
 TEST(Any, SBO) {
     entt::any any{'c'};
 
@@ -884,3 +886,10 @@ TEST(Any, SBOVsZeroedSBOSize) {
 
     ASSERT_EQ(valid, same.data());
 }
+
+TEST(Any, Alignment) {
+    static constexpr auto alignment = alignof(over_aligned);
+    entt::basic_any<alignment> target[2] = { over_aligned{}, over_aligned{} };
+    ASSERT_TRUE((reinterpret_cast<std::uintptr_t>(entt::any_cast<over_aligned>(&target[0u])) % alignment) == 0u);
+    ASSERT_TRUE((reinterpret_cast<std::uintptr_t>(entt::any_cast<over_aligned>(&target[1u])) % alignment) == 0u);
+}