Prechádzať zdrojové kódy

sparse_set: update/set head properly accordingly with the policy

Michele Caini 2 rokov pred
rodič
commit
9c9a71af74

+ 15 - 5
src/entt/entity/sparse_set.hpp

@@ -231,6 +231,16 @@ class basic_sparse_set {
         }
     }
 
+    underlying_type policy_to_head() {
+        switch(mode) {
+        case deletion_policy::swap_and_pop:
+        case deletion_policy::in_place:
+            return traits_type::entity_mask;
+        case deletion_policy::swap_only:
+            return underlying_type{};
+        }
+    }
+
 private:
     virtual const void *get_at(const std::size_t) const {
         return nullptr;
@@ -389,7 +399,7 @@ public:
           packed{allocator},
           info{&elem},
           mode{pol},
-          head{traits_type::entity_mask} {}
+          head{policy_to_head()} {}
 
     /**
      * @brief Move constructor.
@@ -400,7 +410,7 @@ public:
           packed{std::move(other.packed)},
           info{other.info},
           mode{other.mode},
-          head{std::exchange(other.head, traits_type::entity_mask)} {}
+          head{std::exchange(other.head, policy_to_head())} {}
 
     /**
      * @brief Allocator-extended move constructor.
@@ -412,7 +422,7 @@ public:
           packed{std::move(other.packed), allocator},
           info{other.info},
           mode{other.mode},
-          head{std::exchange(other.head, traits_type::entity_mask)} {
+          head{std::exchange(other.head, policy_to_head())} {
         ENTT_ASSERT(alloc_traits::is_always_equal::value || packed.get_allocator() == other.packed.get_allocator(), "Copying a sparse set is not allowed");
     }
 
@@ -434,7 +444,7 @@ public:
         packed = std::move(other.packed);
         info = other.info;
         mode = other.mode;
-        head = std::exchange(other.head, traits_type::entity_mask);
+        head = std::exchange(other.head, policy_to_head());
         return *this;
     }
 
@@ -993,7 +1003,7 @@ public:
         pop_all();
         // sanity check to avoid subtle issues due to storage classes
         ENTT_ASSERT((compact(), size()) == 0u, "Non-empty set");
-        head = traits_type::entity_mask;
+        head = policy_to_head();
         packed.clear();
     }
 

+ 3 - 3
test/entt/entity/sparse_set.cpp

@@ -614,7 +614,7 @@ TEST(SparseSet, SwapOnlyErase) {
     entt::entity entity[3u]{entt::entity{3}, entt::entity{42}, traits_type::construct(9, 3)};
 
     ASSERT_EQ(set.policy(), entt::deletion_policy::swap_only);
-    ASSERT_GT(set.free_list(), set.size());
+    ASSERT_EQ(set.free_list(), set.size());
     ASSERT_TRUE(set.empty());
 
     set.push(std::begin(entity), std::end(entity));
@@ -622,13 +622,13 @@ TEST(SparseSet, SwapOnlyErase) {
 
     ASSERT_FALSE(set.empty());
     ASSERT_EQ(set.size(), 3u);
-    ASSERT_GT(set.free_list(), set.size());
+    ASSERT_LT(set.free_list(), set.size());
 
     set.erase(entity[2u]);
 
     ASSERT_FALSE(set.empty());
     ASSERT_EQ(set.size(), 3u);
-    ASSERT_GT(set.free_list(), set.size());
+    ASSERT_LT(set.free_list(), set.size());
 
     ASSERT_EQ(set.at(0u), entity[0u]);
     ASSERT_EQ(set.at(1u), entity[1u]);