sigh_mixin: make pop_all use narrow view iterators if any
This commit is contained in:
@@ -48,13 +48,16 @@ class sigh_mixin final: public Type {
|
||||
if(!destruction.empty()) {
|
||||
ENTT_ASSERT(owner != nullptr, "Invalid pointer to registry");
|
||||
|
||||
for(auto &&entt: static_cast<typename Type::base_type &>(*this)) {
|
||||
const auto iterable = Type::each();
|
||||
const auto last = iterable.end().base();
|
||||
|
||||
for(auto first = iterable.begin().base(); first != last; ++first) {
|
||||
if constexpr(Type::traits_type::in_place_delete) {
|
||||
if(entt != tombstone) {
|
||||
if(const auto entt = *first; entt != tombstone) {
|
||||
destruction.publish(*owner, entt);
|
||||
}
|
||||
} else {
|
||||
destruction.publish(*owner, entt);
|
||||
destruction.publish(*owner, *first);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,6 +31,17 @@ void listener(counter &counter, Registry &, typename Registry::entity_type) {
|
||||
++counter.value;
|
||||
}
|
||||
|
||||
struct empty_each_tag final {};
|
||||
|
||||
template<>
|
||||
struct entt::basic_storage<empty_each_tag, entt::entity, std::allocator<empty_each_tag>>: entt::basic_storage<void, entt::entity, std::allocator<void>> {
|
||||
basic_storage(const std::allocator<empty_each_tag> &) {}
|
||||
|
||||
[[nodiscard]] iterable each() noexcept {
|
||||
return {internal::extended_storage_iterator{base_type::end()}, internal::extended_storage_iterator{base_type::end()}};
|
||||
}
|
||||
};
|
||||
|
||||
TEST(SighMixin, GenericType) {
|
||||
entt::entity entities[2u]{entt::entity{3}, entt::entity{42}};
|
||||
entt::sigh_mixin<entt::storage<int>> pool;
|
||||
@@ -423,6 +434,35 @@ TEST(SighMixin, Swap) {
|
||||
ASSERT_EQ(on_destroy.value, 3);
|
||||
}
|
||||
|
||||
TEST(SighMixin, EmptyEachStorage) {
|
||||
entt::sigh_mixin<entt::storage<empty_each_tag>> pool;
|
||||
entt::registry registry;
|
||||
|
||||
counter on_destroy{};
|
||||
|
||||
pool.bind(entt::forward_as_any(registry));
|
||||
pool.on_destroy().connect<&listener<entt::registry>>(on_destroy);
|
||||
|
||||
ASSERT_TRUE(pool.empty());
|
||||
ASSERT_EQ(on_destroy.value, 0);
|
||||
|
||||
pool.push(entt::entity{42});
|
||||
|
||||
ASSERT_FALSE(pool.empty());
|
||||
ASSERT_EQ(on_destroy.value, 0);
|
||||
|
||||
ASSERT_NE(pool.begin(), pool.end());
|
||||
ASSERT_EQ(pool.each().begin(), pool.each().end());
|
||||
ASSERT_EQ(on_destroy.value, 0);
|
||||
|
||||
pool.clear();
|
||||
|
||||
ASSERT_EQ(pool.begin(), pool.end());
|
||||
ASSERT_EQ(pool.each().begin(), pool.each().end());
|
||||
// no signal at all because of the (fake) empty iterable
|
||||
ASSERT_EQ(on_destroy.value, 0);
|
||||
}
|
||||
|
||||
TEST(SighMixin, CustomAllocator) {
|
||||
auto test = [](auto pool, auto alloc) {
|
||||
using registry_type = typename decltype(pool)::registry_type;
|
||||
|
||||
Reference in New Issue
Block a user