From 40aabe76c7211e503290a44a6ea6407df5c81fec Mon Sep 17 00:00:00 2001 From: Michele Caini Date: Sun, 26 Dec 2021 16:36:30 +0100 Subject: [PATCH] sparse_set: fixed a throwing case that could leave the set in an inconsistent state --- src/entt/entity/sparse_set.hpp | 2 +- test/entt/entity/sparse_set.cpp | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/entt/entity/sparse_set.hpp b/src/entt/entity/sparse_set.hpp index 6face2a49..17155e805 100644 --- a/src/entt/entity/sparse_set.hpp +++ b/src/entt/entity/sparse_set.hpp @@ -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(packed.size()), entity_traits::to_integral(entt)); packed.push_back(entt); + elem = entity_traits::combine(static_cast(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(entity_traits::to_entity(free_list))], entt); diff --git a/test/entt/entity/sparse_set.cpp b/test/entt/entity/sparse_set.cpp index c36aee458..f1732c4d4 100644 --- a/test/entt/entity/sparse_set.cpp +++ b/test/entt/entity/sparse_set.cpp @@ -1246,6 +1246,14 @@ TEST(SparseSet, ThrowingAllocator) { ASSERT_TRUE(set.contains(entt::entity{0})); ASSERT_EQ(set.capacity(), 1u); + test::throwing_allocator::trigger_on_allocate = true; + + ASSERT_THROW(set.emplace(entt::entity{1}), test::throwing_allocator::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::trigger_after_allocate = true;