Răsfoiți Sursa

sparse_set: emplace returns the slot used for insertion

Michele Caini 4 ani în urmă
părinte
comite
d3df64ef4b
2 a modificat fișierele cu 18 adăugiri și 15 ștergeri
  1. 8 3
      src/entt/entity/sparse_set.hpp
  2. 10 12
      test/entt/entity/sparse_set.cpp

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

@@ -366,7 +366,7 @@ public:
      * @brief Returns the next slot available for insertion.
      * @return The next slot available for insertion.
      */
-    [[nodiscard]] std::size_t slot() const ENTT_NOEXCEPT {
+    [[nodiscard]] size_type slot() const ENTT_NOEXCEPT {
         return free_list == null ? count : size_type{traits_type::to_entity(free_list)};
     }
 
@@ -563,8 +563,9 @@ public:
      * results in undefined behavior.
      *
      * @param entt A valid entity identifier.
+     * @return The slot used for insertion.
      */
-    void emplace(const entity_type entt) {
+    size_type emplace(const entity_type entt) {
         ENTT_ASSERT(!contains(entt), "Set already contains entity");
 
         if(free_list == null) {
@@ -574,12 +575,16 @@ public:
             }
 
             assure_page(page(entt))[offset(entt)] = traits_type::construct(static_cast<typename traits_type::entity_type>(count));
-            packed[count++] = entt;
+            packed[count] = entt;
+
+            return count++;
         } else {
             const auto pos = size_type{traits_type::to_entity(free_list)};
             move_and_pop(count, pos);
+            // TODO no guarantees
             sparse[page(entt)][offset(entt)] = traits_type::construct(static_cast<typename traits_type::entity_type>(pos));
             free_list = std::exchange(packed[pos], entt);
+            return pos;
         }
     }
 

+ 10 - 12
test/entt/entity/sparse_set.cpp

@@ -31,7 +31,7 @@ TEST(SparseSet, Functionalities) {
     ASSERT_EQ(set.capacity(), 42u);
     ASSERT_TRUE(set.empty());
 
-    set.emplace(entt::entity{42});
+    ASSERT_EQ(set.emplace(entt::entity{42}), 0u);
 
     ASSERT_FALSE(set.empty());
     ASSERT_EQ(set.size(), 1u);
@@ -55,7 +55,7 @@ TEST(SparseSet, Functionalities) {
     ASSERT_EQ(set.at(0u), static_cast<entt::entity>(entt::null));
     ASSERT_EQ(set.at(1u), static_cast<entt::entity>(entt::null));
 
-    set.emplace(entt::entity{42});
+    ASSERT_EQ(set.emplace(entt::entity{42}), 0u);
 
     ASSERT_FALSE(set.empty());
     ASSERT_EQ(set.index(entt::entity{42}), 0u);
@@ -329,13 +329,12 @@ TEST(SparseSet, StableErase) {
     ASSERT_TRUE(*set.begin() == entt::tombstone);
     ASSERT_EQ(set.slot(), 1u);
 
-    set.emplace(entities[0u]);
-
+    ASSERT_EQ(set.emplace(entities[0u]), 1u);
     ASSERT_EQ(*++set.begin(), entities[0u]);
 
-    set.emplace(entities[1u]);
-    set.emplace(entities[2u]);
-    set.emplace(entt::entity{0});
+    ASSERT_EQ(set.emplace(entities[1u]), 0u);
+    ASSERT_EQ(set.emplace(entities[2u]), 2u);
+    ASSERT_EQ(set.emplace(entt::entity{0}), 3u);
 
     ASSERT_EQ(set.size(), 4u);
     ASSERT_EQ(*set.begin(), entt::entity{0});
@@ -481,13 +480,12 @@ TEST(SparseSet, StableRemove) {
     ASSERT_TRUE(*set.begin() == entt::tombstone);
     ASSERT_EQ(set.slot(), 1u);
 
-    set.emplace(entities[0u]);
-
+    ASSERT_EQ(set.emplace(entities[0u]), 1u);
     ASSERT_EQ(*++set.begin(), entities[0u]);
 
-    set.emplace(entities[1u]);
-    set.emplace(entities[2u]);
-    set.emplace(entt::entity{0});
+    ASSERT_EQ(set.emplace(entities[1u]), 0u);
+    ASSERT_EQ(set.emplace(entities[2u]), 2u);
+    ASSERT_EQ(set.emplace(entt::entity{0}), 3u);
 
     ASSERT_EQ(set.size(), 4u);
     ASSERT_EQ(*set.begin(), entt::entity{0});