test: storage::sort for ranges

This commit is contained in:
Michele Caini
2019-07-10 15:00:00 +02:00
parent 6340423b32
commit 3996ce8ce5
3 changed files with 73 additions and 7 deletions

1
TODO
View File

@@ -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

View File

@@ -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];

View File

@@ -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;