From ed98ae3e70b292e6ae4e25e9e41317f95c798263 Mon Sep 17 00:00:00 2001 From: Michele Caini Date: Thu, 7 Sep 2017 14:05:58 +0200 Subject: [PATCH] fixed: sort functionalities --- src/registry.hpp | 4 +- src/sparse_set.hpp | 27 +++--- test/sparse_set.cpp | 198 ++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 209 insertions(+), 20 deletions(-) diff --git a/src/registry.hpp b/src/registry.hpp index ba24df5f9..57f7cb9f0 100644 --- a/src/registry.hpp +++ b/src/registry.hpp @@ -378,11 +378,11 @@ public: std::get.template get()>(pool).sort(std::move(compare)); } - template + template void sort() { auto &&to = std::get.template get()>(pool); auto &&from = std::get.template get()>(pool); - to.sort(from); + to.respect(from); } template diff --git a/src/sparse_set.hpp b/src/sparse_set.hpp index 57f005790..c3a38de1d 100644 --- a/src/sparse_set.hpp +++ b/src/sparse_set.hpp @@ -4,6 +4,7 @@ #include #include +#include #include #include #include @@ -159,17 +160,21 @@ class SparseSet final: public SparseSet { const auto *data = SparseSet::data(); const auto size = SparseSet::size(); std::vector copy(size); - pos_type pos = 0; - std::generate(copy.begin(), copy.end(), [&pos]() { return pos++; }); + std::iota(copy.begin(), copy.end(), pos_type{}); std::sort(copy.begin(), copy.end(), compare); for(pos_type i = 0; i < copy.size(); ++i) { - if(copy[i] != i) { - SparseSet::swap(*(data + copy[i]), *(data + i)); - std::swap(instances[copy[i]], instances[i]); - std::swap(copy[copy[i]], copy[i]); + const auto target = i; + auto curr = i; + + while(copy[curr] != target) { + SparseSet::swap(*(data + copy[curr]), *(data + curr)); + std::swap(instances[copy[curr]], instances[curr]); + std::swap(copy[curr], curr); } + + copy[curr] = curr; } } @@ -230,12 +235,12 @@ public: } template - void sort(const SparseSet &other) { + void respect(const SparseSet &other) { const auto *data = SparseSet::data(); arrange([data, &other](auto lhs, auto rhs) { - auto eLhs = data + lhs; - auto eRhs = data + rhs; + auto eLhs = *(data + lhs); + auto eRhs = *(data + rhs); bool bLhs = other.has(eLhs); bool bRhs = other.has(eRhs); @@ -246,10 +251,10 @@ public: } else if(!bLhs && !bRhs) { compare = eLhs < eRhs; } else { - compare = bLhs; + compare = bRhs; } - return !compare; + return compare; }); } diff --git a/test/sparse_set.cpp b/test/sparse_set.cpp index 324d15ba4..e377e1b54 100644 --- a/test/sparse_set.cpp +++ b/test/sparse_set.cpp @@ -165,34 +165,218 @@ TEST(SparseSetWithType, Swap) { set.reset(); } -TEST(SparseSetWithType, SortBasic) { +TEST(SparseSetWithType, SortOrdered) { using SparseSet = entt::SparseSet; SparseSet set; - ASSERT_EQ(set.construct(12, 6), 6); + ASSERT_EQ(set.construct(12, 12), 12); ASSERT_EQ(set.construct(42, 9), 9); + ASSERT_EQ(set.construct(7, 6), 6); ASSERT_EQ(set.construct(3, 3), 3); + ASSERT_EQ(set.construct(9, 1), 1); set.sort([](auto lhs, auto rhs) { return lhs < rhs; }); - ASSERT_EQ(*(set.raw() + 0u), 9); - ASSERT_EQ(*(set.raw() + 1u), 6); - ASSERT_EQ(*(set.raw() + 2u), 3); + ASSERT_EQ(*(set.raw() + 0u), 12); + ASSERT_EQ(*(set.raw() + 1u), 9); + ASSERT_EQ(*(set.raw() + 2u), 6); + ASSERT_EQ(*(set.raw() + 3u), 3); + ASSERT_EQ(*(set.raw() + 4u), 1); auto begin = set.begin(); auto end = set.end(); + ASSERT_EQ(set.get(*(begin++)), 1); ASSERT_EQ(set.get(*(begin++)), 3); ASSERT_EQ(set.get(*(begin++)), 6); ASSERT_EQ(set.get(*(begin++)), 9); + ASSERT_EQ(set.get(*(begin++)), 12); ASSERT_EQ(begin, end); set.reset(); } -TEST(SparseSetWithType, SortAccordingTo) { - // TODO +TEST(SparseSetWithType, SortReverse) { + using SparseSet = entt::SparseSet; + + SparseSet set; + + ASSERT_EQ(set.construct(12, 1), 1); + ASSERT_EQ(set.construct(42, 3), 3); + ASSERT_EQ(set.construct(7, 6), 6); + ASSERT_EQ(set.construct(3, 9), 9); + ASSERT_EQ(set.construct(9, 12), 12); + + set.sort([](auto lhs, auto rhs) { + return lhs < rhs; + }); + + ASSERT_EQ(*(set.raw() + 0u), 12); + ASSERT_EQ(*(set.raw() + 1u), 9); + ASSERT_EQ(*(set.raw() + 2u), 6); + ASSERT_EQ(*(set.raw() + 3u), 3); + ASSERT_EQ(*(set.raw() + 4u), 1); + + auto begin = set.begin(); + auto end = set.end(); + + ASSERT_EQ(set.get(*(begin++)), 1); + ASSERT_EQ(set.get(*(begin++)), 3); + ASSERT_EQ(set.get(*(begin++)), 6); + ASSERT_EQ(set.get(*(begin++)), 9); + ASSERT_EQ(set.get(*(begin++)), 12); + ASSERT_EQ(begin, end); + + set.reset(); +} + +TEST(SparseSetWithType, SortUnordered) { + using SparseSet = entt::SparseSet; + + SparseSet set; + + ASSERT_EQ(set.construct(12, 6), 6); + ASSERT_EQ(set.construct(42, 3), 3); + ASSERT_EQ(set.construct(7, 1), 1); + ASSERT_EQ(set.construct(3, 9), 9); + ASSERT_EQ(set.construct(9, 12), 12); + + set.sort([](auto lhs, auto rhs) { + return lhs < rhs; + }); + + ASSERT_EQ(*(set.raw() + 0u), 12); + ASSERT_EQ(*(set.raw() + 1u), 9); + ASSERT_EQ(*(set.raw() + 2u), 6); + ASSERT_EQ(*(set.raw() + 3u), 3); + ASSERT_EQ(*(set.raw() + 4u), 1); + + auto begin = set.begin(); + auto end = set.end(); + + ASSERT_EQ(set.get(*(begin++)), 1); + ASSERT_EQ(set.get(*(begin++)), 3); + ASSERT_EQ(set.get(*(begin++)), 6); + ASSERT_EQ(set.get(*(begin++)), 9); + ASSERT_EQ(set.get(*(begin++)), 12); + ASSERT_EQ(begin, end); + + set.reset(); +} + +TEST(SparseSetWithType, RespectOrdered) { + using SparseSet = entt::SparseSet; + + SparseSet lhs; + SparseSet rhs; + + ASSERT_EQ(lhs.construct(1, 0), 0); + ASSERT_EQ(lhs.construct(2, 0), 0); + ASSERT_EQ(lhs.construct(3, 0), 0); + ASSERT_EQ(lhs.construct(4, 0), 0); + ASSERT_EQ(lhs.construct(5, 0), 0); + + ASSERT_EQ(rhs.construct(6, 0), 0); + ASSERT_EQ(rhs.construct(1, 0), 0); + ASSERT_EQ(rhs.construct(2, 0), 0); + ASSERT_EQ(rhs.construct(3, 0), 0); + ASSERT_EQ(rhs.construct(4, 0), 0); + ASSERT_EQ(rhs.construct(5, 0), 0); + + rhs.respect(lhs); + + ASSERT_EQ(*(lhs.data() + 0u), 1u); + ASSERT_EQ(*(lhs.data() + 1u), 2u); + ASSERT_EQ(*(lhs.data() + 2u), 3u); + ASSERT_EQ(*(lhs.data() + 3u), 4u); + ASSERT_EQ(*(lhs.data() + 4u), 5u); + + ASSERT_EQ(*(rhs.data() + 0u), 6u); + ASSERT_EQ(*(rhs.data() + 1u), 1u); + ASSERT_EQ(*(rhs.data() + 2u), 2u); + ASSERT_EQ(*(rhs.data() + 3u), 3u); + ASSERT_EQ(*(rhs.data() + 4u), 4u); + ASSERT_EQ(*(rhs.data() + 5u), 5u); + + lhs.reset(); + rhs.reset(); +} + +TEST(SparseSetWithType, RespectReverse) { + using SparseSet = entt::SparseSet; + + SparseSet lhs; + SparseSet rhs; + + ASSERT_EQ(lhs.construct(1, 0), 0); + ASSERT_EQ(lhs.construct(2, 0), 0); + ASSERT_EQ(lhs.construct(3, 0), 0); + ASSERT_EQ(lhs.construct(4, 0), 0); + ASSERT_EQ(lhs.construct(5, 0), 0); + + ASSERT_EQ(rhs.construct(5, 0), 0); + ASSERT_EQ(rhs.construct(4, 0), 0); + ASSERT_EQ(rhs.construct(3, 0), 0); + ASSERT_EQ(rhs.construct(2, 0), 0); + ASSERT_EQ(rhs.construct(1, 0), 0); + ASSERT_EQ(rhs.construct(6, 0), 0); + + rhs.respect(lhs); + + ASSERT_EQ(*(lhs.data() + 0u), 1u); + ASSERT_EQ(*(lhs.data() + 1u), 2u); + ASSERT_EQ(*(lhs.data() + 2u), 3u); + ASSERT_EQ(*(lhs.data() + 3u), 4u); + ASSERT_EQ(*(lhs.data() + 4u), 5u); + + ASSERT_EQ(*(rhs.data() + 0u), 6u); + ASSERT_EQ(*(rhs.data() + 1u), 1u); + ASSERT_EQ(*(rhs.data() + 2u), 2u); + ASSERT_EQ(*(rhs.data() + 3u), 3u); + ASSERT_EQ(*(rhs.data() + 4u), 4u); + ASSERT_EQ(*(rhs.data() + 5u), 5u); + + lhs.reset(); + rhs.reset(); +} + +TEST(SparseSetWithType, RespectUnordered) { + using SparseSet = entt::SparseSet; + + SparseSet lhs; + SparseSet rhs; + + ASSERT_EQ(lhs.construct(1, 0), 0); + ASSERT_EQ(lhs.construct(2, 0), 0); + ASSERT_EQ(lhs.construct(3, 0), 0); + ASSERT_EQ(lhs.construct(4, 0), 0); + ASSERT_EQ(lhs.construct(5, 0), 0); + + ASSERT_EQ(rhs.construct(3, 0), 0); + ASSERT_EQ(rhs.construct(2, 0), 0); + ASSERT_EQ(rhs.construct(6, 0), 0); + ASSERT_EQ(rhs.construct(1, 0), 0); + ASSERT_EQ(rhs.construct(4, 0), 0); + ASSERT_EQ(rhs.construct(5, 0), 0); + + rhs.respect(lhs); + + ASSERT_EQ(*(lhs.data() + 0u), 1u); + ASSERT_EQ(*(lhs.data() + 1u), 2u); + ASSERT_EQ(*(lhs.data() + 2u), 3u); + ASSERT_EQ(*(lhs.data() + 3u), 4u); + ASSERT_EQ(*(lhs.data() + 4u), 5u); + + ASSERT_EQ(*(rhs.data() + 0u), 6u); + ASSERT_EQ(*(rhs.data() + 1u), 1u); + ASSERT_EQ(*(rhs.data() + 2u), 2u); + ASSERT_EQ(*(rhs.data() + 3u), 3u); + ASSERT_EQ(*(rhs.data() + 4u), 4u); + ASSERT_EQ(*(rhs.data() + 5u), 5u); + + lhs.reset(); + rhs.reset(); }