sparse_set/storage: cleanup
This commit is contained in:
@@ -197,44 +197,38 @@ class basic_sparse_set {
|
||||
}
|
||||
|
||||
void resize_packed(const std::size_t req) {
|
||||
auto &allocator = reserved.first();
|
||||
auto &len = reserved.second();
|
||||
ENTT_ASSERT((req != len) && !(req < count), "Invalid request");
|
||||
const auto mem = alloc_traits::allocate(allocator, req);
|
||||
ENTT_ASSERT((req != reserved.second()) && !(req < count), "Invalid request");
|
||||
const auto mem = alloc_traits::allocate(reserved.first(), req);
|
||||
|
||||
std::uninitialized_fill(mem + count, mem + req, tombstone);
|
||||
|
||||
if(packed) {
|
||||
std::uninitialized_copy(packed, packed + count, mem);
|
||||
std::destroy(packed, packed + len);
|
||||
alloc_traits::deallocate(allocator, packed, len);
|
||||
std::destroy(packed, packed + reserved.second());
|
||||
alloc_traits::deallocate(reserved.first(), packed, reserved.second());
|
||||
}
|
||||
|
||||
packed = mem;
|
||||
len = req;
|
||||
reserved.second() = req;
|
||||
}
|
||||
|
||||
void release_memory() {
|
||||
auto &allocator = reserved.first();
|
||||
auto &len = reserved.second();
|
||||
|
||||
if(packed) {
|
||||
std::destroy(packed, packed + len);
|
||||
alloc_traits::deallocate(allocator, packed, len);
|
||||
std::destroy(packed, packed + reserved.second());
|
||||
alloc_traits::deallocate(reserved.first(), packed, reserved.second());
|
||||
}
|
||||
|
||||
if(sparse) {
|
||||
alloc_ptr allocator_ptr{allocator};
|
||||
|
||||
for(size_type pos{}; pos < bucket; ++pos) {
|
||||
if(sparse[pos]) {
|
||||
std::destroy(sparse[pos], sparse[pos] + sparse_page_v);
|
||||
alloc_traits::deallocate(allocator, sparse[pos], sparse_page_v);
|
||||
alloc_traits::deallocate(reserved.first(), sparse[pos], sparse_page_v);
|
||||
}
|
||||
|
||||
alloc_ptr_traits::destroy(allocator_ptr, std::addressof(sparse[pos]));
|
||||
std::destroy_at(std::addressof(sparse[pos]));
|
||||
}
|
||||
|
||||
alloc_ptr allocator_ptr{reserved.first()};
|
||||
alloc_ptr_traits::deallocate(allocator_ptr, sparse, bucket);
|
||||
}
|
||||
}
|
||||
@@ -316,9 +310,9 @@ protected:
|
||||
ENTT_ASSERT(entity_traits::to_version(elem) == entity_traits::to_version(tombstone), "Slot not available");
|
||||
|
||||
if(free_list == null) {
|
||||
if(const auto len = reserved.second(); count == len) {
|
||||
const size_type sz = static_cast<size_type>(len * growth_factor_v);
|
||||
resize_packed(sz + !(sz > len));
|
||||
if(count == reserved.second()) {
|
||||
const size_type sz = static_cast<size_type>(reserved.second() * growth_factor_v);
|
||||
resize_packed(sz + !(sz > reserved.second()));
|
||||
}
|
||||
|
||||
elem = entity_traits::combine(static_cast<typename entity_traits::entity_type>(count), entity_traits::to_integral(entt));
|
||||
|
||||
@@ -199,36 +199,33 @@ class basic_storage: public basic_sparse_set<Entity, typename std::allocator_tra
|
||||
const auto idx = pos / packed_page_v;
|
||||
|
||||
if(!(idx < bucket.second())) {
|
||||
auto &allocator = bucket.first();
|
||||
auto &len = bucket.second();
|
||||
alloc_ptr allocator_ptr{allocator};
|
||||
|
||||
const size_type sz = idx + 1u;
|
||||
alloc_ptr allocator_ptr{bucket.first()};
|
||||
const auto mem = alloc_ptr_traits::allocate(allocator_ptr, sz);
|
||||
std::uninitialized_value_construct(mem + len, mem + sz);
|
||||
std::uninitialized_value_construct(mem + bucket.second(), mem + sz);
|
||||
|
||||
ENTT_TRY {
|
||||
for(auto next = len; next < sz; ++next) {
|
||||
mem[next] = alloc_traits::allocate(allocator, packed_page_v);
|
||||
for(auto next = bucket.second(); next < sz; ++next) {
|
||||
mem[next] = alloc_traits::allocate(bucket.first(), packed_page_v);
|
||||
}
|
||||
} ENTT_CATCH {
|
||||
for(auto next = len; next < sz && mem[next]; ++next) {
|
||||
alloc_traits::deallocate(allocator, mem[next], packed_page_v);
|
||||
for(auto next = bucket.second(); next < sz && mem[next]; ++next) {
|
||||
alloc_traits::deallocate(bucket.first(), mem[next], packed_page_v);
|
||||
}
|
||||
|
||||
std::destroy(mem + len, mem + sz);
|
||||
std::destroy(mem + bucket.second(), mem + sz);
|
||||
alloc_ptr_traits::deallocate(allocator_ptr, mem, sz);
|
||||
ENTT_THROW;
|
||||
}
|
||||
|
||||
if(packed) {
|
||||
std::uninitialized_copy(packed, packed + len, mem);
|
||||
std::destroy(packed, packed + len);
|
||||
alloc_ptr_traits::deallocate(allocator_ptr, packed, len);
|
||||
std::uninitialized_copy(packed, packed + bucket.second(), mem);
|
||||
std::destroy(packed, packed + bucket.second());
|
||||
alloc_ptr_traits::deallocate(allocator_ptr, packed, bucket.second());
|
||||
}
|
||||
|
||||
packed = mem;
|
||||
len = sz;
|
||||
bucket.second() = sz;
|
||||
}
|
||||
|
||||
return packed[idx] + fast_mod<packed_page_v>(pos);
|
||||
@@ -236,22 +233,19 @@ class basic_storage: public basic_sparse_set<Entity, typename std::allocator_tra
|
||||
|
||||
void release_unused_pages() {
|
||||
if(const auto length = base_type::size() / packed_page_v; length < bucket.second()) {
|
||||
auto &allocator = bucket.first();
|
||||
auto &len = bucket.second();
|
||||
alloc_ptr allocator_ptr{allocator};
|
||||
|
||||
alloc_ptr allocator_ptr{bucket.first()};
|
||||
const auto mem = alloc_ptr_traits::allocate(allocator_ptr, length);
|
||||
std::uninitialized_copy(packed, packed + length, mem);
|
||||
|
||||
for(auto pos = length; pos < len; ++pos) {
|
||||
alloc_traits::deallocate(allocator, packed[pos], packed_page_v);
|
||||
for(auto pos = length, last = bucket.second(); pos < last; ++pos) {
|
||||
alloc_traits::deallocate(bucket.first(), packed[pos], packed_page_v);
|
||||
}
|
||||
|
||||
std::destroy(packed, packed + len);
|
||||
alloc_ptr_traits::deallocate(allocator_ptr, packed, len);
|
||||
std::destroy(packed, packed + bucket.second());
|
||||
alloc_ptr_traits::deallocate(allocator_ptr, packed, bucket.second());
|
||||
|
||||
packed = mem;
|
||||
len = length;
|
||||
bucket.second() = length;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -262,20 +256,17 @@ class basic_storage: public basic_sparse_set<Entity, typename std::allocator_tra
|
||||
base_type::clear();
|
||||
} else {
|
||||
for(size_type pos{}, last = base_type::size(); pos < last; ++pos) {
|
||||
destroy(element_at(pos));
|
||||
std::destroy_at(std::addressof(element_at(pos)));
|
||||
}
|
||||
}
|
||||
|
||||
auto &allocator = bucket.first();
|
||||
auto &len = bucket.second();
|
||||
alloc_ptr allocator_ptr{allocator};
|
||||
|
||||
for(size_type pos{}; pos < len; ++pos) {
|
||||
alloc_traits::deallocate(allocator, packed[pos], packed_page_v);
|
||||
alloc_ptr_traits::destroy(allocator_ptr, std::addressof(packed[pos]));
|
||||
for(size_type pos{}, last = bucket.second(); pos < last; ++pos) {
|
||||
alloc_traits::deallocate(bucket.first(), packed[pos], packed_page_v);
|
||||
std::destroy_at(std::addressof(packed[pos]));
|
||||
}
|
||||
|
||||
alloc_ptr_traits::deallocate(allocator_ptr, packed, len);
|
||||
alloc_ptr allocator_ptr{bucket.first()};
|
||||
alloc_ptr_traits::deallocate(allocator_ptr, packed, bucket.second());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -288,10 +279,6 @@ class basic_storage: public basic_sparse_set<Entity, typename std::allocator_tra
|
||||
}
|
||||
}
|
||||
|
||||
void destroy(Type &elem) {
|
||||
alloc_traits::destroy(bucket.first(), std::addressof(elem));
|
||||
}
|
||||
|
||||
template<typename It, typename Generator>
|
||||
void consume_range(It first, It last, Generator generator) {
|
||||
for(const auto sz = base_type::size(); first != last && base_type::slot() != sz; ++first) {
|
||||
@@ -337,7 +324,7 @@ protected:
|
||||
void move_and_pop(const std::size_t from, const std::size_t to) final {
|
||||
auto &elem = element_at(from);
|
||||
construct(assure_at_least(to), std::move(elem));
|
||||
destroy(elem);
|
||||
std::destroy_at(std::addressof(elem));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -355,7 +342,7 @@ protected:
|
||||
// support for nosy destructors
|
||||
[[maybe_unused]] auto unused = std::move(target);
|
||||
target = std::move(elem);
|
||||
destroy(elem);
|
||||
std::destroy_at(std::addressof(elem));
|
||||
|
||||
base_type::swap_and_pop(entt, ud);
|
||||
}
|
||||
@@ -369,7 +356,7 @@ protected:
|
||||
const auto pos = base_type::index(entt);
|
||||
base_type::in_place_pop(entt, ud);
|
||||
// support for nosy destructors
|
||||
destroy(element_at(pos));
|
||||
std::destroy_at(std::addressof(element_at(pos)));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -386,7 +373,7 @@ protected:
|
||||
base_type::try_emplace(entt, nullptr);
|
||||
ENTT_ASSERT(pos == base_type::index(entt), "Misplaced component");
|
||||
} ENTT_CATCH {
|
||||
destroy(element_at(pos));
|
||||
std::destroy_at(std::addressof(element_at(pos)));
|
||||
ENTT_THROW;
|
||||
}
|
||||
}
|
||||
@@ -684,7 +671,7 @@ public:
|
||||
base_type::try_emplace(entt, nullptr);
|
||||
ENTT_ASSERT(pos == base_type::index(entt), "Misplaced component");
|
||||
} ENTT_CATCH {
|
||||
destroy(element_at(pos));
|
||||
std::destroy_at(std::addressof(element_at(pos)));
|
||||
ENTT_THROW;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user