sparse_set: added ::emplace_back
This commit is contained in:
@@ -555,6 +555,29 @@ public:
|
||||
return packed[pos];
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Appends an entity to a sparse set.
|
||||
*
|
||||
* @warning
|
||||
* Attempting to assign an entity that already belongs to the sparse set
|
||||
* results in undefined behavior.
|
||||
*
|
||||
* @param entt A valid entity identifier.
|
||||
* @return The slot used for insertion.
|
||||
*/
|
||||
size_type emplace_back(const entity_type entt) {
|
||||
ENTT_ASSERT(!contains(entt), "Set already contains entity");
|
||||
|
||||
if(count == reserved) {
|
||||
const size_type sz = static_cast<size_type>(reserved * growth_factor);
|
||||
resize_packed(sz + !(sz > reserved));
|
||||
}
|
||||
|
||||
assure_page(page(entt))[offset(entt)] = traits_type::construct(static_cast<typename traits_type::entity_type>(count));
|
||||
packed[count] = entt;
|
||||
return count++;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Assigns an entity to a sparse set.
|
||||
*
|
||||
@@ -566,22 +589,11 @@ public:
|
||||
* @return The slot used for insertion.
|
||||
*/
|
||||
size_type emplace(const entity_type entt) {
|
||||
ENTT_ASSERT(!contains(entt), "Set already contains entity");
|
||||
|
||||
if(free_list == null) {
|
||||
if(count == reserved) {
|
||||
const size_type sz = static_cast<size_type>(reserved * growth_factor);
|
||||
resize_packed(sz + !(sz > reserved));
|
||||
}
|
||||
|
||||
assure_page(page(entt))[offset(entt)] = traits_type::construct(static_cast<typename traits_type::entity_type>(count));
|
||||
packed[count] = entt;
|
||||
|
||||
return count++;
|
||||
return emplace_back(entt);
|
||||
} else {
|
||||
ENTT_ASSERT(!contains(entt), "Set already contains entity");
|
||||
const auto pos = size_type{traits_type::to_entity(free_list)};
|
||||
move_and_pop(count, pos);
|
||||
// TODO no guarantees
|
||||
sparse[page(entt)][offset(entt)] = traits_type::construct(static_cast<typename traits_type::entity_type>(pos));
|
||||
free_list = std::exchange(packed[pos], entt);
|
||||
return pos;
|
||||
|
||||
@@ -175,8 +175,42 @@ TEST(SparseSet, Pagination) {
|
||||
ASSERT_EQ(set.extent(), 2 * ENTT_SPARSE_PAGE);
|
||||
}
|
||||
|
||||
TEST(SparseSet, Emplace) {
|
||||
entt::sparse_set set{entt::deletion_policy::in_place};
|
||||
entt::entity entities[2u];
|
||||
|
||||
entities[0u] = entt::entity{3};
|
||||
entities[1u] = entt::entity{42};
|
||||
|
||||
ASSERT_TRUE(set.empty());
|
||||
|
||||
set.emplace(entities[0u]);
|
||||
set.erase(entities[0u]);
|
||||
|
||||
set.emplace_back(entities[0u]);
|
||||
set.emplace(entities[1u]);
|
||||
|
||||
ASSERT_DEATH(set.emplace_back(entities[1u]), "");
|
||||
ASSERT_DEATH(set.emplace(entities[0u]), "");
|
||||
|
||||
ASSERT_EQ(set.at(0u), entities[1u]);
|
||||
ASSERT_EQ(set.at(1u), entities[0u]);
|
||||
ASSERT_EQ(set.index(entities[0u]), 1u);
|
||||
ASSERT_EQ(set.index(entities[1u]), 0u);
|
||||
|
||||
set.erase(std::begin(entities), std::end(entities));
|
||||
set.emplace(entities[1u]);
|
||||
set.emplace_back(entities[0u]);
|
||||
|
||||
ASSERT_EQ(set.at(0u), entities[1u]);
|
||||
ASSERT_EQ(set.at(1u), static_cast<entt::entity>(entt::null));
|
||||
ASSERT_EQ(set.at(2u), entities[0u]);
|
||||
ASSERT_EQ(set.index(entities[0u]), 2u);
|
||||
ASSERT_EQ(set.index(entities[1u]), 0u);
|
||||
}
|
||||
|
||||
TEST(SparseSet, Insert) {
|
||||
entt::sparse_set set;
|
||||
entt::sparse_set set{entt::deletion_policy::in_place};
|
||||
entt::entity entities[2u];
|
||||
|
||||
entities[0u] = entt::entity{3};
|
||||
@@ -204,6 +238,17 @@ TEST(SparseSet, Insert) {
|
||||
ASSERT_EQ(set.data()[set.index(entities[0u])], entities[0u]);
|
||||
ASSERT_EQ(set.data()[set.index(entities[1u])], entities[1u]);
|
||||
ASSERT_EQ(set.data()[set.index(entt::entity{24})], entt::entity{24});
|
||||
|
||||
set.erase(std::begin(entities), std::end(entities));
|
||||
set.insert(std::rbegin(entities), std::rend(entities));
|
||||
|
||||
ASSERT_EQ(set.size(), 6u);
|
||||
ASSERT_TRUE(set.at(1u) == entt::tombstone);
|
||||
ASSERT_TRUE(set.at(2u) == entt::tombstone);
|
||||
ASSERT_EQ(set.at(4u), entities[1u]);
|
||||
ASSERT_EQ(set.at(5u), entities[0u]);
|
||||
ASSERT_EQ(set.index(entities[0u]), 5u);
|
||||
ASSERT_EQ(set.index(entities[1u]), 4u);
|
||||
}
|
||||
|
||||
TEST(SparseSet, Erase) {
|
||||
|
||||
Reference in New Issue
Block a user