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

test: storage::sort for ranges

Michele Caini 6 лет назад
Родитель
Сommit
3996ce8ce5
3 измененных файлов с 73 добавлено и 7 удалено
  1. 0 1
      TODO
  2. 7 6
      src/entt/entity/storage.hpp
  3. 66 0
      test/entt/entity/storage.cpp

+ 0 - 1
TODO

@@ -25,5 +25,4 @@
 TODO
 * registry::sort also for types that are part of a group (untracked items only)
 * add sort by type to the non-owning group
-* add test for range sort to storage
 * custom (decoupled) pools ==> double buffering, shared components, multi-model

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

@@ -444,17 +444,18 @@ public:
         ENTT_ASSERT(!(first > last));
 
         std::vector<size_type> copy(last - first);
-        std::iota(copy.begin(), copy.end(), std::distance(last, end()));
+        const auto offset = std::distance(last, end());
+        std::iota(copy.begin(), copy.end(), size_type{});
 
         if constexpr(std::is_invocable_v<Compare, const object_type &, const object_type &>) {
             static_assert(!std::is_empty_v<object_type>);
 
-            algo(copy.rbegin(), copy.rend(), [this, compare = std::move(compare)](const auto lhs, const auto rhs) {
-                return compare(std::as_const(instances[lhs]), std::as_const(instances[rhs]));
+            algo(copy.rbegin(), copy.rend(), [this, offset, compare = std::move(compare)](const auto lhs, const auto rhs) {
+                return compare(std::as_const(instances[lhs+offset]), std::as_const(instances[rhs+offset]));
             }, std::forward<Args>(args)...);
         } else {
-            algo(copy.rbegin(), copy.rend(), [compare = std::move(compare), data = underlying_type::data()](const auto lhs, const auto rhs) {
-                return compare(std::as_const(data[lhs]), std::as_const(data[rhs]));
+            algo(copy.rbegin(), copy.rend(), [offset, compare = std::move(compare), data = underlying_type::data()](const auto lhs, const auto rhs) {
+                return compare(std::as_const(data[lhs+offset]), std::as_const(data[rhs+offset]));
             }, std::forward<Args>(args)...);
         }
 
@@ -463,7 +464,7 @@ public:
             auto next = copy[curr];
 
             while(curr != next) {
-                swap(copy[curr], copy[next]);
+                swap(copy[curr]+offset, copy[next]+offset);
                 copy[curr] = curr;
                 curr = next;
                 next = copy[curr];

+ 66 - 0
test/entt/entity/storage.cpp

@@ -421,6 +421,72 @@ TEST(Storage, SortUnordered) {
     ASSERT_EQ(begin, end);
 }
 
+TEST(Storage, SortRange) {
+    entt::storage<entt::entity, boxed_int> set;
+
+    set.construct(entt::entity{12}, boxed_int{6});
+    set.construct(entt::entity{42}, boxed_int{3});
+    set.construct(entt::entity{7}, boxed_int{1});
+    set.construct(entt::entity{3}, boxed_int{9});
+    set.construct(entt::entity{9}, boxed_int{12});
+
+    ASSERT_EQ(set.get(entt::entity{12}).value, 6);
+    ASSERT_EQ(set.get(entt::entity{42}).value, 3);
+    ASSERT_EQ(set.get(entt::entity{7}).value, 1);
+    ASSERT_EQ(set.get(entt::entity{3}).value, 9);
+    ASSERT_EQ(set.get(entt::entity{9}).value, 12);
+
+    set.sort(set.end(), set.end(), [](auto lhs, auto rhs) {
+        return lhs.value < rhs.value;
+    });
+
+    ASSERT_EQ(set.get(entt::entity{12}).value, 6);
+    ASSERT_EQ(set.get(entt::entity{42}).value, 3);
+    ASSERT_EQ(set.get(entt::entity{7}).value, 1);
+    ASSERT_EQ(set.get(entt::entity{3}).value, 9);
+    ASSERT_EQ(set.get(entt::entity{9}).value, 12);
+
+    set.sort(set.begin(), set.begin(), [](auto lhs, auto rhs) {
+        return lhs.value < rhs.value;
+    });
+
+    ASSERT_EQ(set.get(entt::entity{12}).value, 6);
+    ASSERT_EQ(set.get(entt::entity{42}).value, 3);
+    ASSERT_EQ(set.get(entt::entity{7}).value, 1);
+    ASSERT_EQ(set.get(entt::entity{3}).value, 9);
+    ASSERT_EQ(set.get(entt::entity{9}).value, 12);
+
+    set.sort(set.begin()+2, set.begin()+3, [](auto lhs, auto rhs) {
+        return lhs.value < rhs.value;
+    });
+
+    ASSERT_EQ(set.get(entt::entity{12}).value, 6);
+    ASSERT_EQ(set.get(entt::entity{42}).value, 3);
+    ASSERT_EQ(set.get(entt::entity{7}).value, 1);
+    ASSERT_EQ(set.get(entt::entity{3}).value, 9);
+    ASSERT_EQ(set.get(entt::entity{9}).value, 12);
+
+    set.sort(++set.begin(), --set.end(), [](auto lhs, auto rhs) {
+        return lhs.value < rhs.value;
+    });
+
+    ASSERT_EQ((set.raw() + 0u)->value, 6);
+    ASSERT_EQ((set.raw() + 1u)->value, 9);
+    ASSERT_EQ((set.raw() + 2u)->value, 3);
+    ASSERT_EQ((set.raw() + 3u)->value, 1);
+    ASSERT_EQ((set.raw() + 4u)->value, 12);
+
+    auto begin = set.begin();
+    auto end = set.end();
+
+    ASSERT_EQ((begin++)->value, 12);
+    ASSERT_EQ((begin++)->value, 1);
+    ASSERT_EQ((begin++)->value, 3);
+    ASSERT_EQ((begin++)->value, 9);
+    ASSERT_EQ((begin++)->value, 6);
+    ASSERT_EQ(begin, end);
+}
+
 TEST(Storage, RespectDisjoint) {
     entt::storage<entt::entity, int> lhs;
     entt::storage<entt::entity, int> rhs;