fixed: sort functionalities

This commit is contained in:
Michele Caini
2017-09-07 14:05:58 +02:00
parent 2011defb1e
commit ed98ae3e70
3 changed files with 209 additions and 20 deletions

View File

@@ -378,11 +378,11 @@ public:
std::get<ident<Component...>.template get<Comp>()>(pool).sort(std::move(compare));
}
template<typename To, typename From, typename Compare>
template<typename To, typename From>
void sort() {
auto &&to = std::get<ident<Component...>.template get<To>()>(pool);
auto &&from = std::get<ident<Component...>.template get<From>()>(pool);
to.sort(from);
to.respect(from);
}
template<typename Comp>

View File

@@ -4,6 +4,7 @@
#include <algorithm>
#include <utility>
#include <numeric>
#include <vector>
#include <cstddef>
#include <cassert>
@@ -159,17 +160,21 @@ class SparseSet<Index, Type> final: public SparseSet<Index> {
const auto *data = SparseSet<Index>::data();
const auto size = SparseSet<Index>::size();
std::vector<pos_type> 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<Index>::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<Index>::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<typename Idx>
void sort(const SparseSet<Index> &other) {
void respect(const SparseSet<Idx> &other) {
const auto *data = SparseSet<Index>::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;
});
}

View File

@@ -165,34 +165,218 @@ TEST(SparseSetWithType, Swap) {
set.reset();
}
TEST(SparseSetWithType, SortBasic) {
TEST(SparseSetWithType, SortOrdered) {
using SparseSet = entt::SparseSet<unsigned int, int>;
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<unsigned int, int>;
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<unsigned int, int>;
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<unsigned int, int>;
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<unsigned int, int>;
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<unsigned int, int>;
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();
}