Jelajahi Sumber

sparse_set/storage: minor changes, more tests

Michele Caini 4 tahun lalu
induk
melakukan
588c056205
3 mengubah file dengan 34 tambahan dan 16 penghapusan
  1. 1 3
      src/entt/entity/sparse_set.hpp
  2. 6 10
      src/entt/entity/storage.hpp
  3. 27 3
      test/entt/entity/storage.cpp

+ 1 - 3
src/entt/entity/sparse_set.hpp

@@ -237,9 +237,7 @@ protected:
      * @param entt A valid identifier.
      */
     virtual void try_erase(const Entity entt) {
-        const auto pos = index(entt);
-
-        if(mode == deletion_policy::in_place) {
+        if(const auto pos = index(entt); mode == deletion_policy::in_place) {
             packed[pos] = std::exchange(free_list, entity_traits::combine(static_cast<typename entity_traits::entity_type>(pos), entity_traits::reserved));
         } else {
             packed[pos] = packed.back();

+ 6 - 10
src/entt/entity/storage.hpp

@@ -327,16 +327,12 @@ protected:
      * @param entt A valid identifier.
      */
     void try_erase(const Entity entt) override {
-        if constexpr(comp_traits::in_place_delete) {
-            std::destroy_at(std::addressof(element_at(base_type::index(entt))));
-            base_type::try_erase(entt);
-        } else {
-            auto &elem = element_at(base_type::size() - 1u);
-            // support chained destructors i.e. parent-to-child propagation
-            [[maybe_unused]] auto unused = std::exchange(element_at(base_type::index(entt)), std::move(elem));
-            std::destroy_at(std::addressof(elem));
-            base_type::try_erase(entt);
-        }
+        const auto pos = base_type::index(entt);
+        auto &elem = element_at(comp_traits::in_place_delete ? pos : (base_type::size() - 1u));
+        // support chained destructors i.e. parent-to-child propagation
+        [[maybe_unused]] auto unused = std::exchange(element_at(pos), std::move(elem));
+        std::destroy_at(std::addressof(elem));
+        base_type::try_erase(entt);
     }
 
     /**

+ 27 - 3
test/entt/entity/storage.cpp

@@ -65,6 +65,11 @@ struct entt::component_traits<empty_stable_type>: basic_component_traits {
     static constexpr auto in_place_delete = true;
 };
 
+template<>
+struct entt::component_traits<std::unordered_set<char>>: basic_component_traits {
+    static constexpr auto in_place_delete = true;
+};
+
 bool operator==(const boxed_int &lhs, const boxed_int &rhs) {
     return lhs.value == rhs.value;
 }
@@ -810,11 +815,30 @@ TEST(Storage, AggregatesMustWork) {
     entt::storage<aggregate_type>{}.emplace(entt::entity{0}, 42);
 }
 
-TEST(Storage, TypesFromStandardTemplateLibraryMustWork) {
+TEST(Storage, SelfMoveSupport) {
     // see #37 - this test shouldn't crash, that's all
     entt::storage<std::unordered_set<int>> pool;
-    pool.emplace(entt::entity{0}).insert(42);
-    pool.erase(entt::entity{0});
+    entt::entity entity{};
+
+    ASSERT_EQ(pool.policy(), entt::deletion_policy::swap_and_pop);
+
+    pool.emplace(entity).insert(42);
+    pool.erase(entity);
+
+    ASSERT_FALSE(pool.contains(entity));
+}
+
+TEST(Storage, SelfMoveSupportInPlaceDelete) {
+    // see #37 - this test shouldn't crash, that's all
+    entt::storage<std::unordered_set<char>> pool;
+    entt::entity entity{};
+
+    ASSERT_EQ(pool.policy(), entt::deletion_policy::in_place);
+
+    pool.emplace(entity).insert(42);
+    pool.erase(entity);
+
+    ASSERT_FALSE(pool.contains(entity));
 }
 
 TEST(Storage, Iterator) {