sparse_set: make sort_as return an iterator past the last shared element

This commit is contained in:
Michele Caini
2024-01-25 08:28:28 +01:00
parent 469a3cd568
commit b96631c486
3 changed files with 27 additions and 13 deletions

2
TODO
View File

@@ -27,5 +27,5 @@ TODO:
* review assure conflicts check, hash doesn't fit the purpose maybe
* allow to zero-sized versions (with non-regression tests)
* auto type info data from types if present
* sparse set sort_as should return the length to be a proper drop-in replacement for pack (then review registry destroy)
* group review: use handler as base with protected members and arrays of common type (see view for further details)
* swap sets in swap-only mode, return scoped iterators by default, make ::free_list return an iterator if possible

View File

@@ -1039,12 +1039,14 @@ public:
* @tparam It Type of input iterator.
* @param first An iterator to the first element of the range of entities.
* @param last An iterator past the last element of the range of entities.
* @return An iterator past the last of the elements actually shared.
*/
template<typename It>
void sort_as(It first, It last) {
iterator sort_as(It first, It last) {
ENTT_ASSERT((mode != deletion_policy::in_place) || (head == traits_type::to_entity(null)), "Sorting with tombstones not allowed");
auto it = begin(0);
for(auto it = begin(0); it.index() && first != last; ++first) {
for(const auto other = end(0); (it != other) && (first != last); ++first) {
if(const auto curr = *first; contains(curr)) {
if(const auto entt = *it; entt != curr) {
// basic no-leak guarantee (with invalid state) if swapping throws
@@ -1054,6 +1056,8 @@ public:
++it;
}
}
return it;
}
/*! @brief Clears a sparse set. */

View File

@@ -1847,8 +1847,9 @@ TYPED_TEST(SparseSet, SortAsDisjoint) {
ASSERT_TRUE(std::equal(entity.rbegin(), entity.rend(), lhs.begin(), lhs.end()));
lhs.sort_as(rhs.begin(), rhs.end());
const auto it = lhs.sort_as(rhs.begin(), rhs.end());
ASSERT_EQ(it, lhs.begin(0));
ASSERT_TRUE(std::equal(entity.rbegin(), entity.rend(), lhs.begin(), lhs.end()));
}
}
@@ -1870,10 +1871,12 @@ TYPED_TEST(SparseSet, SortAsOverlap) {
ASSERT_TRUE(std::equal(lhs_entity.rbegin(), lhs_entity.rend(), lhs.begin(), lhs.end()));
ASSERT_TRUE(std::equal(rhs_entity.rbegin(), rhs_entity.rend(), rhs.begin(), rhs.end()));
lhs.sort_as(rhs.begin(), rhs.end());
const auto it = lhs.sort_as(rhs.begin(), rhs.end());
ASSERT_EQ(it, lhs.begin(0) + rhs_entity.size());
auto begin = lhs.begin();
auto end = lhs.end();
const auto end = lhs.end();
ASSERT_EQ(*(begin++), lhs_entity[1u]);
ASSERT_EQ(*(begin++), lhs_entity[2u]);
@@ -1899,8 +1902,9 @@ TYPED_TEST(SparseSet, SortAsOrdered) {
ASSERT_TRUE(std::equal(lhs_entity.rbegin(), lhs_entity.rend(), lhs.begin(), lhs.end()));
ASSERT_TRUE(std::equal(rhs_entity.rbegin(), rhs_entity.rend(), rhs.begin(), rhs.end()));
rhs.sort_as(lhs.begin(), lhs.end());
const auto it = rhs.sort_as(lhs.begin(), lhs.end());
ASSERT_EQ(it, rhs.begin(0) + lhs_entity.size());
ASSERT_TRUE(std::equal(rhs_entity.rbegin(), rhs_entity.rend(), rhs.begin(), rhs.end()));
}
}
@@ -1922,10 +1926,12 @@ TYPED_TEST(SparseSet, SortAsReverse) {
ASSERT_TRUE(std::equal(lhs_entity.rbegin(), lhs_entity.rend(), lhs.begin(), lhs.end()));
ASSERT_TRUE(std::equal(rhs_entity.rbegin(), rhs_entity.rend(), rhs.begin(), rhs.end()));
rhs.sort_as(lhs.begin(), lhs.end());
const auto it = rhs.sort_as(lhs.begin(), lhs.end());
ASSERT_EQ(it, rhs.begin(0) + lhs_entity.size());
auto begin = rhs.begin();
auto end = rhs.end();
const auto end = rhs.end();
ASSERT_EQ(*(begin++), rhs_entity[0u]);
ASSERT_EQ(*(begin++), rhs_entity[1u]);
@@ -1954,10 +1960,12 @@ TYPED_TEST(SparseSet, SortAsUnordered) {
ASSERT_TRUE(std::equal(lhs_entity.rbegin(), lhs_entity.rend(), lhs.begin(), lhs.end()));
ASSERT_TRUE(std::equal(rhs_entity.rbegin(), rhs_entity.rend(), rhs.begin(), rhs.end()));
rhs.sort_as(lhs.begin(), lhs.end());
const auto it = rhs.sort_as(lhs.begin(), lhs.end());
ASSERT_EQ(it, rhs.begin(0) + lhs_entity.size());
auto begin = rhs.begin();
auto end = rhs.end();
const auto end = rhs.end();
ASSERT_EQ(*(begin++), rhs_entity[5u]);
ASSERT_EQ(*(begin++), rhs_entity[4u]);
@@ -1987,10 +1995,12 @@ TYPED_TEST(SparseSet, SortAsInvalid) {
ASSERT_TRUE(std::equal(lhs_entity.rbegin(), lhs_entity.rend(), lhs.begin(), lhs.end()));
ASSERT_TRUE(std::equal(rhs_entity.rbegin(), rhs_entity.rend(), rhs.begin(), rhs.end()));
rhs.sort_as(lhs.begin(), lhs.end());
const auto it = rhs.sort_as(lhs.begin(), lhs.end());
ASSERT_EQ(it, rhs.begin(0) + lhs_entity.size() - 1u);
auto begin = rhs.begin();
auto end = rhs.end();
const auto end = rhs.end();
ASSERT_EQ(*(begin++), rhs_entity[0u]);
ASSERT_EQ(*(begin++), rhs_entity[1u]);