sparse_set: ::emplace no longer returns the position

This commit is contained in:
Michele Caini
2021-08-26 16:13:26 +02:00
parent de6b660b12
commit 23d162e9e4
3 changed files with 27 additions and 28 deletions

View File

@@ -242,20 +242,17 @@ class basic_sparse_set {
}
}
std::size_t append(const Entity entt) {
void append(const Entity entt) {
ENTT_ASSERT(count != reserved.second(), "Not enough space left");
ENTT_ASSERT(current(entt) == entity_traits::to_version(tombstone), "Slot not available");
assure_page(page(entt))[offset(entt)] = entity_traits::combine(static_cast<typename entity_traits::entity_type>(count), entity_traits::to_integral(entt));
packed_array[count] = entt;
return count++;
packed_array[count++] = entt;
}
std::size_t recycle(const Entity entt) ENTT_NOEXCEPT {
void recycle(const Entity entt) {
ENTT_ASSERT(current(entt) == entity_traits::to_version(tombstone), "Slot not available");
const auto pos = static_cast<size_type>(entity_traits::to_entity(free_list));
assure_page(page(entt))[offset(entt)] = entity_traits::combine(entity_traits::to_integral(free_list), entity_traits::to_integral(entt));
free_list = std::exchange(packed_array[pos], entt);
return pos;
free_list = std::exchange(packed_array[static_cast<size_type>(entity_traits::to_entity(free_list))], entt);
}
protected:
@@ -651,18 +648,17 @@ public:
* results in undefined behavior.
*
* @param entt A valid identifier.
* @return The slot used for insertion.
*/
size_type emplace(const entity_type entt) {
void emplace(const entity_type entt) {
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_array(sz + !(sz > len));
}
return append(entt);
append(entt);
} else {
return recycle(entt);
recycle(entt);
}
}

View File

@@ -271,7 +271,7 @@ class basic_storage: public basic_sparse_set<Entity, typename std::allocator_tra
}
template<typename It, typename Generator>
void recycle_or_append(It first, It last, Generator generator) {
void consume_range(It first, It last, Generator generator) {
if constexpr(comp_traits::in_place_delete::value) {
for(const auto sz = base_type::size(); first != last && base_type::slot() != sz; ++first) {
emplace(*first, generator());
@@ -642,8 +642,8 @@ public:
construct(elem, std::forward<Args>(args)...);
ENTT_TRY {
[[maybe_unused]] const auto curr = base_type::emplace(entt);
ENTT_ASSERT(pos == curr, "Misplaced component");
base_type::emplace(entt);
ENTT_ASSERT(pos == base_type::index(entt), "Misplaced component");
} ENTT_CATCH {
destroy(packed[page(pos)][offset(pos)]);
ENTT_THROW;
@@ -682,7 +682,7 @@ public:
*/
template<typename It>
void insert(It first, It last, const value_type &value = {}) {
recycle_or_append(std::move(first), std::move(last), [&value]() -> decltype(auto) { return value; });
consume_range(std::move(first), std::move(last), [&value]() -> decltype(auto) { return value; });
}
/**
@@ -699,7 +699,7 @@ public:
*/
template<typename EIt, typename CIt, typename = std::enable_if_t<std::is_same_v<std::decay_t<typename std::iterator_traits<CIt>::value_type>, value_type>>>
void insert(EIt first, EIt last, CIt from) {
recycle_or_append(std::move(first), std::move(last), [&from]() -> decltype(auto) { return *(from++); });
consume_range(std::move(first), std::move(last), [&from]() -> decltype(auto) { return *(from++); });
}
private:

View File

@@ -32,7 +32,7 @@ TEST(SparseSet, Functionalities) {
ASSERT_EQ(set.capacity(), 42u);
ASSERT_TRUE(set.empty());
ASSERT_EQ(set.emplace(entt::entity{42}), 0u);
set.emplace(entt::entity{42});
ASSERT_FALSE(set.empty());
ASSERT_EQ(set.size(), 1u);
@@ -56,7 +56,7 @@ TEST(SparseSet, Functionalities) {
ASSERT_EQ(set.at(0u), static_cast<entt::entity>(entt::null));
ASSERT_EQ(set.at(1u), static_cast<entt::entity>(entt::null));
ASSERT_EQ(set.emplace(entt::entity{42}), 0u);
set.emplace(entt::entity{42});
ASSERT_FALSE(set.empty());
ASSERT_EQ(set.index(entt::entity{42}), 0u);
@@ -279,13 +279,14 @@ TEST(SparseSet, EmplaceOutOfBounds) {
entt::sparse_set set{entt::deletion_policy::in_place};
entt::entity entities[2u]{entt::entity{0}, entt::entity{ENTT_SPARSE_PAGE}};
ASSERT_EQ(set.emplace(entities[0u]), 0u);
set.emplace(entities[0u]);
ASSERT_EQ(set.extent(), ENTT_SPARSE_PAGE);
ASSERT_EQ(set.index(entities[0u]), 0u);
set.erase(entities[0u]);
set.emplace(entities[1u]);
ASSERT_EQ(set.emplace(entities[1u]), 0u);
ASSERT_EQ(set.extent(), 2u * ENTT_SPARSE_PAGE);
ASSERT_EQ(set.index(entities[1u]), 0u);
}
@@ -481,12 +482,13 @@ TEST(SparseSet, StableErase) {
ASSERT_TRUE(*set.begin() == entt::tombstone);
ASSERT_EQ(set.slot(), 1u);
ASSERT_EQ(set.emplace(entities[0u]), 1u);
set.emplace(entities[0u]);
ASSERT_EQ(*++set.begin(), entities[0u]);
ASSERT_EQ(set.emplace(entities[1u]), 0u);
ASSERT_EQ(set.emplace(entities[2u]), 2u);
ASSERT_EQ(set.emplace(entt::entity{0}), 3u);
set.emplace(entities[1u]);
set.emplace(entities[2u]);
set.emplace(entt::entity{0});
ASSERT_EQ(set.size(), 4u);
ASSERT_EQ(*set.begin(), entt::entity{0});
@@ -671,12 +673,13 @@ TEST(SparseSet, StableRemove) {
ASSERT_TRUE(*set.begin() == entt::tombstone);
ASSERT_EQ(set.slot(), 1u);
ASSERT_EQ(set.emplace(entities[0u]), 1u);
set.emplace(entities[0u]);
ASSERT_EQ(*++set.begin(), entities[0u]);
ASSERT_EQ(set.emplace(entities[1u]), 0u);
ASSERT_EQ(set.emplace(entities[2u]), 2u);
ASSERT_EQ(set.emplace(entt::entity{0}), 3u);
set.emplace(entities[1u]);
set.emplace(entities[2u]);
set.emplace(entt::entity{0});
ASSERT_EQ(set.size(), 4u);
ASSERT_EQ(*set.begin(), entt::entity{0});