test: storage::sort for ranges
This commit is contained in:
1
TODO
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
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user