registry: assert when emplacing invalid entities - close #1095

This commit is contained in:
Michele Caini
2024-02-02 09:47:06 +01:00
parent 61f4ad8837
commit 83aabf7cfc
2 changed files with 20 additions and 0 deletions

View File

@@ -583,6 +583,7 @@ public:
*/
template<typename Type, typename... Args>
decltype(auto) emplace(const entity_type entt, Args &&...args) {
ENTT_ASSERT(valid(entt), "Invalid entity");
return assure<Type>().emplace(entt, std::forward<Args>(args)...);
}
@@ -599,6 +600,7 @@ public:
*/
template<typename Type, typename It>
void insert(It first, It last, const Type &value = {}) {
ENTT_ASSERT(std::all_of(first, last, [this](const auto entt) { return valid(entt); }), "Invalid entity");
assure<Type>().insert(std::move(first), std::move(last), value);
}
@@ -616,6 +618,7 @@ public:
*/
template<typename Type, typename EIt, typename CIt, typename = std::enable_if_t<std::is_same_v<typename std::iterator_traits<CIt>::value_type, Type>>>
void insert(EIt first, EIt last, CIt from) {
ENTT_ASSERT(std::all_of(first, last, [this](const auto entt) { return valid(entt); }), "Invalid entity");
assure<Type>().insert(first, last, from);
}
@@ -636,6 +639,7 @@ public:
if(auto &cpool = assure<Type>(); cpool.contains(entt)) {
return cpool.patch(entt, [&args...](auto &...curr) { ((curr = Type{std::forward<Args>(args)...}), ...); });
} else {
ENTT_ASSERT(valid(entt), "Invalid entity");
return cpool.emplace(entt, std::forward<Args>(args)...);
}
}
@@ -899,6 +903,7 @@ public:
if(auto &cpool = assure<Type>(); cpool.contains(entt)) {
return cpool.get(entt);
} else {
ENTT_ASSERT(valid(entt), "Invalid entity");
return cpool.emplace(entt, std::forward<Args>(args)...);
}
}

View File

@@ -446,6 +446,20 @@ TEST(Registry, Swap) {
ASSERT_EQ(test.parent, &registry);
}
TEST(RegistryDeathTest, EmplaceInvalidEntity) {
entt::registry registry;
const std::array entity{registry.create()};
const std::array value{0};
registry.destroy(entity[0]);
ASSERT_DEATH(registry.emplace<int>(entity[0u]), "");
ASSERT_DEATH(registry.insert<int>(entity.begin(), entity.end(), value[0]), "");
ASSERT_DEATH(registry.insert<int>(entity.begin(), entity.end(), value.begin()), "");
ASSERT_DEATH(registry.emplace_or_replace<int>(entity[0u]), "");
ASSERT_DEATH([[maybe_unused]] const auto value = registry.get_or_emplace<int>(entity[0u]), "");
}
TEST(Registry, ReplaceAggregate) {
entt::registry registry;
const auto entity = registry.create();
@@ -1894,6 +1908,7 @@ TEST(Registry, GetOrEmplace) {
entt::registry registry;
const auto entity = registry.create();
const auto value = registry.get_or_emplace<int>(entity, 3);
// get_or_emplace must work for empty types
static_cast<void>(registry.get_or_emplace<test::empty>(entity));