sparse_set: fixed a throwing case that could leave the set in an inconsistent state

This commit is contained in:
Michele Caini
2021-12-26 16:36:30 +01:00
parent 9d304cb35c
commit 40aabe76c7
2 changed files with 9 additions and 1 deletions

View File

@@ -274,8 +274,8 @@ protected:
ENTT_ASSERT(entity_traits::to_version(elem) == entity_traits::to_version(tombstone), "Slot not available");
if(free_list == null) {
elem = entity_traits::combine(static_cast<typename entity_traits::entity_type>(packed.size()), entity_traits::to_integral(entt));
packed.push_back(entt);
elem = entity_traits::combine(static_cast<typename entity_traits::entity_type>(packed.size() - 1u), entity_traits::to_integral(entt));
} else {
elem = entity_traits::combine(entity_traits::to_integral(free_list), entity_traits::to_integral(entt));
free_list = std::exchange(packed[static_cast<size_type>(entity_traits::to_entity(free_list))], entt);

View File

@@ -1246,6 +1246,14 @@ TEST(SparseSet, ThrowingAllocator) {
ASSERT_TRUE(set.contains(entt::entity{0}));
ASSERT_EQ(set.capacity(), 1u);
test::throwing_allocator<entt::entity>::trigger_on_allocate = true;
ASSERT_THROW(set.emplace(entt::entity{1}), test::throwing_allocator<entt::entity>::exception_type);
ASSERT_EQ(set.extent(), ENTT_SPARSE_PAGE);
ASSERT_TRUE(set.contains(entt::entity{0}));
ASSERT_FALSE(set.contains(entt::entity{1}));
ASSERT_EQ(set.capacity(), 1u);
entt::entity entities[2u]{entt::entity{1}, entt::entity{ENTT_SPARSE_PAGE}};
test::throwing_allocator<entt::entity>::trigger_after_allocate = true;