sparse_set/storage: value type from base, if any
This commit is contained in:
@@ -11,6 +11,7 @@
|
||||
#include "../core/algorithm.hpp"
|
||||
#include "../core/any.hpp"
|
||||
#include "../core/memory.hpp"
|
||||
#include "../core/type_info.hpp"
|
||||
#include "entity.hpp"
|
||||
#include "fwd.hpp"
|
||||
|
||||
@@ -282,14 +283,14 @@ public:
|
||||
|
||||
/*! @brief Default constructor. */
|
||||
basic_sparse_set()
|
||||
: basic_sparse_set{allocator_type{}} {}
|
||||
: basic_sparse_set{type_id<void>()} {}
|
||||
|
||||
/**
|
||||
* @brief Constructs an empty container with a given allocator.
|
||||
* @param allocator The allocator to use.
|
||||
*/
|
||||
explicit basic_sparse_set(const allocator_type &allocator)
|
||||
: basic_sparse_set{deletion_policy::swap_and_pop, allocator} {}
|
||||
: basic_sparse_set{type_id<void>(), deletion_policy::swap_and_pop, allocator} {}
|
||||
|
||||
/**
|
||||
* @brief Constructs an empty container with the given policy and allocator.
|
||||
@@ -297,8 +298,18 @@ public:
|
||||
* @param allocator The allocator to use (possibly default-constructed).
|
||||
*/
|
||||
explicit basic_sparse_set(deletion_policy pol, const allocator_type &allocator = {})
|
||||
: basic_sparse_set{type_id<void>(), pol, allocator} {}
|
||||
|
||||
/**
|
||||
* @brief Constructs an empty container with the given policy and allocator.
|
||||
* @param value Returned value type, if any.
|
||||
* @param pol Type of deletion policy.
|
||||
* @param allocator The allocator to use (possibly default-constructed).
|
||||
*/
|
||||
explicit basic_sparse_set(const type_info &value, deletion_policy pol = deletion_policy::swap_and_pop, const allocator_type &allocator = {})
|
||||
: sparse{allocator},
|
||||
packed{allocator},
|
||||
info{&value},
|
||||
free_list{tombstone},
|
||||
mode{pol} {}
|
||||
|
||||
@@ -309,6 +320,7 @@ public:
|
||||
basic_sparse_set(basic_sparse_set &&other) ENTT_NOEXCEPT
|
||||
: sparse{std::move(other.sparse)},
|
||||
packed{std::move(other.packed)},
|
||||
info{other.info},
|
||||
free_list{std::exchange(other.free_list, tombstone)},
|
||||
mode{other.mode} {}
|
||||
|
||||
@@ -320,6 +332,7 @@ public:
|
||||
basic_sparse_set(basic_sparse_set &&other, const allocator_type &allocator) ENTT_NOEXCEPT
|
||||
: sparse{std::move(other.sparse), allocator},
|
||||
packed{std::move(other.packed), allocator},
|
||||
info{other.info},
|
||||
free_list{std::exchange(other.free_list, tombstone)},
|
||||
mode{other.mode} {
|
||||
ENTT_ASSERT(alloc_traits::is_always_equal::value || packed.get_allocator() == other.packed.get_allocator(), "Copying a sparse set is not allowed");
|
||||
@@ -341,6 +354,7 @@ public:
|
||||
release_sparse_pages();
|
||||
sparse = std::move(other.sparse);
|
||||
packed = std::move(other.packed);
|
||||
info = other.info;
|
||||
free_list = std::exchange(other.free_list, tombstone);
|
||||
mode = other.mode;
|
||||
return *this;
|
||||
@@ -354,6 +368,7 @@ public:
|
||||
using std::swap;
|
||||
swap(sparse, other.sparse);
|
||||
swap(packed, other.packed);
|
||||
swap(info, other.info);
|
||||
swap(free_list, other.free_list);
|
||||
swap(mode, other.mode);
|
||||
}
|
||||
@@ -835,12 +850,21 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returned value type, if any.
|
||||
* @return Returned value type, if any.
|
||||
*/
|
||||
const type_info &type() const ENTT_NOEXCEPT {
|
||||
return *info;
|
||||
}
|
||||
|
||||
/*! @brief Forwards variables to mixins, if any. */
|
||||
virtual void bind(any) ENTT_NOEXCEPT {}
|
||||
|
||||
private:
|
||||
sparse_container_type sparse;
|
||||
packed_container_type packed;
|
||||
const type_info *info;
|
||||
entity_type free_list;
|
||||
deletion_policy mode;
|
||||
};
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "../core/any.hpp"
|
||||
#include "../core/compressed_pair.hpp"
|
||||
#include "../core/memory.hpp"
|
||||
#include "../core/type_info.hpp"
|
||||
#include "../core/type_traits.hpp"
|
||||
#include "../signal/sigh.hpp"
|
||||
#include "component.hpp"
|
||||
@@ -390,15 +391,14 @@ public:
|
||||
|
||||
/*! @brief Default constructor. */
|
||||
basic_storage()
|
||||
: base_type{deletion_policy{comp_traits::in_place_delete::value}},
|
||||
packed{} {}
|
||||
: basic_storage{allocator_type{}} {}
|
||||
|
||||
/**
|
||||
* @brief Constructs an empty storage with a given allocator.
|
||||
* @param allocator The allocator to use.
|
||||
*/
|
||||
explicit basic_storage(const allocator_type &allocator)
|
||||
: base_type{deletion_policy{comp_traits::in_place_delete::value}, allocator},
|
||||
: base_type{type_id<value_type>(), deletion_policy{comp_traits::in_place_delete::value}, allocator},
|
||||
packed{container_type{allocator}, allocator} {}
|
||||
|
||||
/**
|
||||
@@ -743,14 +743,14 @@ public:
|
||||
|
||||
/*! @brief Default constructor. */
|
||||
basic_storage()
|
||||
: base_type{deletion_policy{comp_traits::in_place_delete::value}} {}
|
||||
: basic_storage{allocator_type{}} {}
|
||||
|
||||
/**
|
||||
* @brief Constructs an empty container with a given allocator.
|
||||
* @param allocator The allocator to use.
|
||||
*/
|
||||
explicit basic_storage(const allocator_type &allocator)
|
||||
: base_type{deletion_policy{comp_traits::in_place_delete::value}, allocator} {}
|
||||
: base_type{type_id<value_type>(), deletion_policy{comp_traits::in_place_delete::value}, allocator} {}
|
||||
|
||||
/**
|
||||
* @brief Move constructor.
|
||||
|
||||
@@ -19,6 +19,7 @@ TEST(SparseSet, Functionalities) {
|
||||
entt::sparse_set set;
|
||||
|
||||
ASSERT_NO_THROW([[maybe_unused]] auto alloc = set.get_allocator());
|
||||
ASSERT_EQ(set.type(), entt::type_id<void>());
|
||||
|
||||
set.reserve(42);
|
||||
|
||||
|
||||
@@ -73,6 +73,7 @@ TEST(Storage, Functionalities) {
|
||||
entt::storage<int> pool;
|
||||
|
||||
ASSERT_NO_THROW([[maybe_unused]] auto alloc = pool.get_allocator());
|
||||
ASSERT_EQ(pool.type(), entt::type_id<int>());
|
||||
|
||||
pool.reserve(42);
|
||||
|
||||
@@ -141,11 +142,13 @@ TEST(Storage, Move) {
|
||||
|
||||
ASSERT_TRUE(std::is_move_constructible_v<decltype(pool)>);
|
||||
ASSERT_TRUE(std::is_move_assignable_v<decltype(pool)>);
|
||||
ASSERT_EQ(pool.type(), entt::type_id<int>());
|
||||
|
||||
entt::storage<int> other{std::move(pool)};
|
||||
|
||||
ASSERT_TRUE(pool.empty());
|
||||
ASSERT_FALSE(other.empty());
|
||||
ASSERT_EQ(other.type(), entt::type_id<int>());
|
||||
ASSERT_EQ(pool.at(0u), static_cast<entt::entity>(entt::null));
|
||||
ASSERT_EQ(other.at(0u), entt::entity{3});
|
||||
ASSERT_EQ(other.get(entt::entity{3}), 3);
|
||||
@@ -184,6 +187,9 @@ TEST(Storage, Swap) {
|
||||
|
||||
pool.swap(other);
|
||||
|
||||
ASSERT_EQ(pool.type(), entt::type_id<int>());
|
||||
ASSERT_EQ(other.type(), entt::type_id<int>());
|
||||
|
||||
ASSERT_EQ(pool.size(), 1u);
|
||||
ASSERT_EQ(other.size(), 1u);
|
||||
|
||||
@@ -209,6 +215,9 @@ TEST(Storage, StableSwap) {
|
||||
|
||||
pool.swap(other);
|
||||
|
||||
ASSERT_EQ(pool.type(), entt::type_id<stable_type>());
|
||||
ASSERT_EQ(other.type(), entt::type_id<stable_type>());
|
||||
|
||||
ASSERT_EQ(pool.size(), 2u);
|
||||
ASSERT_EQ(other.size(), 1u);
|
||||
|
||||
@@ -224,6 +233,8 @@ TEST(Storage, EmptyType) {
|
||||
pool.emplace(entt::entity{99});
|
||||
|
||||
ASSERT_NO_THROW([[maybe_unused]] auto alloc = pool.get_allocator());
|
||||
ASSERT_EQ(pool.type(), entt::type_id<empty_stable_type>());
|
||||
|
||||
ASSERT_TRUE(pool.contains(entt::entity{99}));
|
||||
ASSERT_DEATH(pool.get(entt::entity{}), "");
|
||||
|
||||
@@ -574,6 +585,9 @@ TEST(Storage, TypeFromBase) {
|
||||
entt::sparse_set &base = pool;
|
||||
entt::entity entities[2u]{entt::entity{3}, entt::entity{42}};
|
||||
|
||||
ASSERT_EQ(pool.type(), entt::type_id<int>());
|
||||
ASSERT_EQ(pool.type(), base.type());
|
||||
|
||||
ASSERT_FALSE(pool.contains(entities[0u]));
|
||||
ASSERT_FALSE(pool.contains(entities[1u]));
|
||||
|
||||
@@ -602,6 +616,9 @@ TEST(Storage, EmptyTypeFromBase) {
|
||||
entt::sparse_set &base = pool;
|
||||
entt::entity entities[2u]{entt::entity{3}, entt::entity{42}};
|
||||
|
||||
ASSERT_EQ(pool.type(), entt::type_id<empty_stable_type>());
|
||||
ASSERT_EQ(pool.type(), base.type());
|
||||
|
||||
ASSERT_FALSE(pool.contains(entities[0u]));
|
||||
ASSERT_FALSE(pool.contains(entities[1u]));
|
||||
|
||||
@@ -630,6 +647,9 @@ TEST(Storage, NonDefaultConstructibleTypeFromBase) {
|
||||
entt::sparse_set &base = pool;
|
||||
entt::entity entities[2u]{entt::entity{3}, entt::entity{42}};
|
||||
|
||||
ASSERT_EQ(pool.type(), entt::type_id<non_default_constructible>());
|
||||
ASSERT_EQ(pool.type(), base.type());
|
||||
|
||||
ASSERT_FALSE(pool.contains(entities[0u]));
|
||||
ASSERT_FALSE(pool.contains(entities[1u]));
|
||||
|
||||
@@ -665,6 +685,9 @@ TEST(Storage, NonCopyConstructibleTypeFromBase) {
|
||||
entt::sparse_set &base = pool;
|
||||
entt::entity entities[2u]{entt::entity{3}, entt::entity{42}};
|
||||
|
||||
ASSERT_EQ(pool.type(), entt::type_id<std::unique_ptr<int>>());
|
||||
ASSERT_EQ(pool.type(), base.type());
|
||||
|
||||
ASSERT_FALSE(pool.contains(entities[0u]));
|
||||
ASSERT_FALSE(pool.contains(entities[1u]));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user