Skip to content

Commit

Permalink
sparse_set: update/set head properly accordingly with the policy
Browse files Browse the repository at this point in the history
  • Loading branch information
skypjack committed Sep 5, 2023
1 parent be09b3a commit 9c9a71a
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 8 deletions.
20 changes: 15 additions & 5 deletions src/entt/entity/sparse_set.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,16 @@ class basic_sparse_set {
}
}

underlying_type policy_to_head() {
switch(mode) {
case deletion_policy::swap_and_pop:
case deletion_policy::in_place:
return traits_type::entity_mask;
case deletion_policy::swap_only:
return underlying_type{};
}
}

private:
virtual const void *get_at(const std::size_t) const {
return nullptr;
Expand Down Expand Up @@ -389,7 +399,7 @@ class basic_sparse_set {
packed{allocator},
info{&elem},
mode{pol},
head{traits_type::entity_mask} {}
head{policy_to_head()} {}

/**
* @brief Move constructor.
Expand All @@ -400,7 +410,7 @@ class basic_sparse_set {
packed{std::move(other.packed)},
info{other.info},
mode{other.mode},
head{std::exchange(other.head, traits_type::entity_mask)} {}
head{std::exchange(other.head, policy_to_head())} {}

/**
* @brief Allocator-extended move constructor.
Expand All @@ -412,7 +422,7 @@ class basic_sparse_set {
packed{std::move(other.packed), allocator},
info{other.info},
mode{other.mode},
head{std::exchange(other.head, traits_type::entity_mask)} {
head{std::exchange(other.head, policy_to_head())} {
ENTT_ASSERT(alloc_traits::is_always_equal::value || packed.get_allocator() == other.packed.get_allocator(), "Copying a sparse set is not allowed");
}

Expand All @@ -434,7 +444,7 @@ class basic_sparse_set {
packed = std::move(other.packed);
info = other.info;
mode = other.mode;
head = std::exchange(other.head, traits_type::entity_mask);
head = std::exchange(other.head, policy_to_head());
return *this;
}

Expand Down Expand Up @@ -993,7 +1003,7 @@ class basic_sparse_set {
pop_all();
// sanity check to avoid subtle issues due to storage classes
ENTT_ASSERT((compact(), size()) == 0u, "Non-empty set");
head = traits_type::entity_mask;
head = policy_to_head();
packed.clear();
}

Expand Down
6 changes: 3 additions & 3 deletions test/entt/entity/sparse_set.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -614,21 +614,21 @@ TEST(SparseSet, SwapOnlyErase) {
entt::entity entity[3u]{entt::entity{3}, entt::entity{42}, traits_type::construct(9, 3)};

ASSERT_EQ(set.policy(), entt::deletion_policy::swap_only);
ASSERT_GT(set.free_list(), set.size());
ASSERT_EQ(set.free_list(), set.size());
ASSERT_TRUE(set.empty());

set.push(std::begin(entity), std::end(entity));
set.erase(set.begin(), set.end());

ASSERT_FALSE(set.empty());
ASSERT_EQ(set.size(), 3u);
ASSERT_GT(set.free_list(), set.size());
ASSERT_LT(set.free_list(), set.size());

set.erase(entity[2u]);

ASSERT_FALSE(set.empty());
ASSERT_EQ(set.size(), 3u);
ASSERT_GT(set.free_list(), set.size());
ASSERT_LT(set.free_list(), set.size());

ASSERT_EQ(set.at(0u), entity[0u]);
ASSERT_EQ(set.at(1u), entity[1u]);
Expand Down

0 comments on commit 9c9a71a

Please sign in to comment.