Explorar el Código

sparse_set: make sort_as return an iterator past the last shared element

Michele Caini hace 2 años
padre
commit
b96631c486
Se han modificado 3 ficheros con 27 adiciones y 13 borrados
  1. 1 1
      TODO
  2. 6 2
      src/entt/entity/sparse_set.hpp
  3. 20 10
      test/entt/entity/sparse_set.cpp

+ 1 - 1
TODO

@@ -27,5 +27,5 @@ TODO:
 * review assure conflicts check, hash doesn't fit the purpose maybe
 * allow to zero-sized versions (with non-regression tests)
 * auto type info data from types if present
-* sparse set sort_as should return the length to be a proper drop-in replacement for pack (then review registry destroy)
 * group review: use handler as base with protected members and arrays of common type (see view for further details)
+* swap sets in swap-only mode, return scoped iterators by default, make ::free_list return an iterator if possible

+ 6 - 2
src/entt/entity/sparse_set.hpp

@@ -1039,12 +1039,14 @@ public:
      * @tparam It Type of input iterator.
      * @param first An iterator to the first element of the range of entities.
      * @param last An iterator past the last element of the range of entities.
+     * @return An iterator past the last of the elements actually shared.
      */
     template<typename It>
-    void sort_as(It first, It last) {
+    iterator sort_as(It first, It last) {
         ENTT_ASSERT((mode != deletion_policy::in_place) || (head == traits_type::to_entity(null)), "Sorting with tombstones not allowed");
+        auto it = begin(0);
 
-        for(auto it = begin(0); it.index() && first != last; ++first) {
+        for(const auto other = end(0); (it != other) && (first != last); ++first) {
             if(const auto curr = *first; contains(curr)) {
                 if(const auto entt = *it; entt != curr) {
                     // basic no-leak guarantee (with invalid state) if swapping throws
@@ -1054,6 +1056,8 @@ public:
                 ++it;
             }
         }
+
+        return it;
     }
 
     /*! @brief Clears a sparse set. */

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

@@ -1847,8 +1847,9 @@ TYPED_TEST(SparseSet, SortAsDisjoint) {
 
         ASSERT_TRUE(std::equal(entity.rbegin(), entity.rend(), lhs.begin(), lhs.end()));
 
-        lhs.sort_as(rhs.begin(), rhs.end());
+        const auto it = lhs.sort_as(rhs.begin(), rhs.end());
 
+        ASSERT_EQ(it, lhs.begin(0));
         ASSERT_TRUE(std::equal(entity.rbegin(), entity.rend(), lhs.begin(), lhs.end()));
     }
 }
@@ -1870,10 +1871,12 @@ TYPED_TEST(SparseSet, SortAsOverlap) {
         ASSERT_TRUE(std::equal(lhs_entity.rbegin(), lhs_entity.rend(), lhs.begin(), lhs.end()));
         ASSERT_TRUE(std::equal(rhs_entity.rbegin(), rhs_entity.rend(), rhs.begin(), rhs.end()));
 
-        lhs.sort_as(rhs.begin(), rhs.end());
+        const auto it = lhs.sort_as(rhs.begin(), rhs.end());
+
+        ASSERT_EQ(it, lhs.begin(0) + rhs_entity.size());
 
         auto begin = lhs.begin();
-        auto end = lhs.end();
+        const auto end = lhs.end();
 
         ASSERT_EQ(*(begin++), lhs_entity[1u]);
         ASSERT_EQ(*(begin++), lhs_entity[2u]);
@@ -1899,8 +1902,9 @@ TYPED_TEST(SparseSet, SortAsOrdered) {
         ASSERT_TRUE(std::equal(lhs_entity.rbegin(), lhs_entity.rend(), lhs.begin(), lhs.end()));
         ASSERT_TRUE(std::equal(rhs_entity.rbegin(), rhs_entity.rend(), rhs.begin(), rhs.end()));
 
-        rhs.sort_as(lhs.begin(), lhs.end());
+        const auto it = rhs.sort_as(lhs.begin(), lhs.end());
 
+        ASSERT_EQ(it, rhs.begin(0) + lhs_entity.size());
         ASSERT_TRUE(std::equal(rhs_entity.rbegin(), rhs_entity.rend(), rhs.begin(), rhs.end()));
     }
 }
@@ -1922,10 +1926,12 @@ TYPED_TEST(SparseSet, SortAsReverse) {
         ASSERT_TRUE(std::equal(lhs_entity.rbegin(), lhs_entity.rend(), lhs.begin(), lhs.end()));
         ASSERT_TRUE(std::equal(rhs_entity.rbegin(), rhs_entity.rend(), rhs.begin(), rhs.end()));
 
-        rhs.sort_as(lhs.begin(), lhs.end());
+        const auto it = rhs.sort_as(lhs.begin(), lhs.end());
+
+        ASSERT_EQ(it, rhs.begin(0) + lhs_entity.size());
 
         auto begin = rhs.begin();
-        auto end = rhs.end();
+        const auto end = rhs.end();
 
         ASSERT_EQ(*(begin++), rhs_entity[0u]);
         ASSERT_EQ(*(begin++), rhs_entity[1u]);
@@ -1954,10 +1960,12 @@ TYPED_TEST(SparseSet, SortAsUnordered) {
         ASSERT_TRUE(std::equal(lhs_entity.rbegin(), lhs_entity.rend(), lhs.begin(), lhs.end()));
         ASSERT_TRUE(std::equal(rhs_entity.rbegin(), rhs_entity.rend(), rhs.begin(), rhs.end()));
 
-        rhs.sort_as(lhs.begin(), lhs.end());
+        const auto it = rhs.sort_as(lhs.begin(), lhs.end());
+
+        ASSERT_EQ(it, rhs.begin(0) + lhs_entity.size());
 
         auto begin = rhs.begin();
-        auto end = rhs.end();
+        const auto end = rhs.end();
 
         ASSERT_EQ(*(begin++), rhs_entity[5u]);
         ASSERT_EQ(*(begin++), rhs_entity[4u]);
@@ -1987,10 +1995,12 @@ TYPED_TEST(SparseSet, SortAsInvalid) {
         ASSERT_TRUE(std::equal(lhs_entity.rbegin(), lhs_entity.rend(), lhs.begin(), lhs.end()));
         ASSERT_TRUE(std::equal(rhs_entity.rbegin(), rhs_entity.rend(), rhs.begin(), rhs.end()));
 
-        rhs.sort_as(lhs.begin(), lhs.end());
+        const auto it = rhs.sort_as(lhs.begin(), lhs.end());
+
+        ASSERT_EQ(it, rhs.begin(0) + lhs_entity.size() - 1u);
 
         auto begin = rhs.begin();
-        auto end = rhs.end();
+        const auto end = rhs.end();
 
         ASSERT_EQ(*(begin++), rhs_entity[0u]);
         ASSERT_EQ(*(begin++), rhs_entity[1u]);