sparse_set: added the ::bump function

This commit is contained in:
Michele Caini
2022-03-01 13:47:11 +01:00
parent 3156dd1321
commit efbb32a498
2 changed files with 44 additions and 2 deletions

View File

@@ -172,10 +172,9 @@ template<typename Entity, typename Allocator>
class basic_sparse_set {
using alloc_traits = std::allocator_traits<Allocator>;
static_assert(std::is_same_v<typename alloc_traits::value_type, Entity>);
using entity_traits = entt_traits<Entity>;
using sparse_container_type = std::vector<typename alloc_traits::pointer, typename alloc_traits::template rebind_alloc<typename alloc_traits::pointer>>;
using packed_container_type = std::vector<Entity, Allocator>;
using entity_traits = entt_traits<Entity>;
[[nodiscard]] auto sparse_ptr(const Entity entt) const {
const auto pos = static_cast<size_type>(entity_traits::to_entity(entt));
@@ -660,6 +659,21 @@ public:
return try_emplace(entt, false, value);
}
/**
* @brief Bump the version number of an entity.
*
* @warning
* Attempting to bump the version of an entity that doesn't belong to the
* sparse set results in undefined behavior.
*
* @param entt A valid identifier.
*/
void bump(const entity_type entt) {
auto &entity = sparse_ref(entt);
entity = entity_traits::combine(entity_traits::to_integral(entity), entity_traits::to_integral(entt));
packed[static_cast<size_type>(entity_traits::to_entity(entity))] = entt;
}
/**
* @brief Assigns one or more entities to a sparse set.
*

View File

@@ -310,6 +310,34 @@ TEST(SparseSet, EmplaceOutOfBounds) {
ASSERT_EQ(set.index(entities[1u]), 0u);
}
TEST(SparseSet, Bump) {
using traits_type = entt::entt_traits<entt::entity>;
entt::sparse_set set;
entt::entity entities[3u]{entt::entity{3}, entt::entity{42}, traits_type::construct(9, 3)};
set.insert(std::begin(entities), std::end(entities));
ASSERT_EQ(set.current(entities[0u]), 0u);
ASSERT_EQ(set.current(entities[1u]), 0u);
ASSERT_EQ(set.current(entities[2u]), 3u);
set.bump(entities[0u]);
set.bump(traits_type::construct(traits_type::to_entity(entities[1u]), 1));
set.bump(traits_type::construct(traits_type::to_entity(entities[2u]), 0));
ASSERT_EQ(set.current(entities[0u]), 0u);
ASSERT_EQ(set.current(entities[1u]), 1u);
ASSERT_EQ(set.current(entities[2u]), 0u);
}
TEST(SparseSetDeathTest, Bump) {
entt::sparse_set set{entt::deletion_policy::in_place};
ASSERT_DEATH(set.bump(entt::null), "");
ASSERT_DEATH(set.bump(entt::tombstone), "");
ASSERT_DEATH(set.bump(entt::entity{42}), "");
}
TEST(SparseSet, Insert) {
entt::sparse_set set{entt::deletion_policy::in_place};
entt::entity entities[2u]{entt::entity{3}, entt::entity{42}};