storage:
* increase code coverage * remove a pretty much useless if constexpr
This commit is contained in:
@@ -272,10 +272,8 @@ class basic_storage: public basic_sparse_set<Entity, typename std::allocator_tra
|
||||
|
||||
template<typename It, typename 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());
|
||||
}
|
||||
for(const auto sz = base_type::size(); first != last && base_type::slot() != sz; ++first) {
|
||||
emplace(*first, generator());
|
||||
}
|
||||
|
||||
const auto req = base_type::size() + std::distance(first, last);
|
||||
@@ -848,10 +846,8 @@ public:
|
||||
*/
|
||||
template<typename It, typename... Args>
|
||||
void insert(It first, It last, Args &&...) {
|
||||
if constexpr(comp_traits::in_place_delete::value) {
|
||||
for(const auto sz = base_type::size(); first != last && base_type::slot() != sz; ++first) {
|
||||
emplace(*first);
|
||||
}
|
||||
for(const auto sz = base_type::size(); first != last && base_type::slot() != sz; ++first) {
|
||||
emplace(*first);
|
||||
}
|
||||
|
||||
base_type::reserve(base_type::size() + std::distance(first, last));
|
||||
|
||||
@@ -1224,6 +1224,111 @@ TEST(Storage, UpdateFromDestructor) {
|
||||
test(entt::entity{0u});
|
||||
}
|
||||
|
||||
TEST(Storage, CustomAllocator) {
|
||||
test::throwing_allocator<entt::entity> allocator{};
|
||||
entt::basic_storage<entt::entity, int, test::throwing_allocator<entt::entity>> pool{allocator};
|
||||
|
||||
ASSERT_EQ(pool.get_allocator(), allocator);
|
||||
|
||||
pool.reserve(1u);
|
||||
|
||||
ASSERT_EQ(pool.capacity(), ENTT_PACKED_PAGE);
|
||||
|
||||
pool.emplace(entt::entity{0}, 3);
|
||||
pool.emplace(entt::entity{1}, 42);
|
||||
|
||||
entt::basic_storage<entt::entity, int, test::throwing_allocator<entt::entity>> other{std::move(pool), allocator};
|
||||
|
||||
ASSERT_TRUE(pool.empty());
|
||||
ASSERT_FALSE(other.empty());
|
||||
ASSERT_EQ(pool.capacity(), 0u);
|
||||
ASSERT_EQ(other.capacity(), ENTT_PACKED_PAGE);
|
||||
ASSERT_EQ(other.size(), 2u);
|
||||
|
||||
pool = std::move(other);
|
||||
|
||||
ASSERT_FALSE(pool.empty());
|
||||
ASSERT_TRUE(other.empty());
|
||||
ASSERT_EQ(other.capacity(), 0u);
|
||||
ASSERT_EQ(pool.capacity(), ENTT_PACKED_PAGE);
|
||||
ASSERT_EQ(pool.size(), 2u);
|
||||
|
||||
pool.swap(other);
|
||||
pool = std::move(other);
|
||||
|
||||
ASSERT_FALSE(pool.empty());
|
||||
ASSERT_TRUE(other.empty());
|
||||
ASSERT_EQ(other.capacity(), 0u);
|
||||
ASSERT_EQ(pool.capacity(), ENTT_PACKED_PAGE);
|
||||
ASSERT_EQ(pool.size(), 2u);
|
||||
|
||||
pool.clear();
|
||||
|
||||
ASSERT_EQ(pool.capacity(), ENTT_PACKED_PAGE);
|
||||
ASSERT_EQ(pool.size(), 0u);
|
||||
|
||||
pool.shrink_to_fit();
|
||||
|
||||
ASSERT_EQ(pool.capacity(), 0u);
|
||||
}
|
||||
|
||||
TEST(Storage, ThrowingAllocator) {
|
||||
entt::basic_storage<entt::entity, int, test::throwing_allocator<int>> pool;
|
||||
typename std::decay_t<decltype(pool)>::base_type &base = pool;
|
||||
|
||||
test::throwing_allocator<int>::trigger_on_allocate = true;
|
||||
|
||||
// strong exception safety
|
||||
ASSERT_THROW(pool.reserve(1u), test::throwing_allocator<int>::exception_type);
|
||||
ASSERT_EQ(pool.capacity(), 0u);
|
||||
|
||||
test::throwing_allocator<int>::trigger_after_allocate = true;
|
||||
|
||||
// strong exception safety
|
||||
ASSERT_THROW(pool.reserve(2 * ENTT_PACKED_PAGE), test::throwing_allocator<int>::exception_type);
|
||||
ASSERT_EQ(pool.capacity(), 0u);
|
||||
|
||||
pool.shrink_to_fit();
|
||||
test::throwing_allocator<int>::trigger_on_allocate = true;
|
||||
|
||||
// strong exception safety
|
||||
ASSERT_THROW(pool.emplace(entt::entity{0}, 0), test::throwing_allocator<int>::exception_type);
|
||||
ASSERT_FALSE(pool.contains(entt::entity{0}));
|
||||
ASSERT_TRUE(pool.empty());
|
||||
|
||||
test::throwing_allocator<entt::entity>::trigger_on_allocate = true;
|
||||
|
||||
// strong exception safety
|
||||
ASSERT_THROW(pool.emplace(entt::entity{0}, 0), test::throwing_allocator<entt::entity>::exception_type);
|
||||
ASSERT_FALSE(pool.contains(entt::entity{0}));
|
||||
ASSERT_TRUE(pool.empty());
|
||||
|
||||
test::throwing_allocator<entt::entity>::trigger_on_allocate = true;
|
||||
|
||||
// strong exception safety
|
||||
ASSERT_THROW(base.emplace(entt::entity{0}), test::throwing_allocator<entt::entity>::exception_type);
|
||||
ASSERT_FALSE(base.contains(entt::entity{0}));
|
||||
ASSERT_TRUE(base.empty());
|
||||
|
||||
pool.emplace(entt::entity{0}, 0);
|
||||
const entt::entity entities[2u]{entt::entity{1}, entt::entity{ENTT_SPARSE_PAGE}};
|
||||
test::throwing_allocator<entt::entity>::trigger_after_allocate = true;
|
||||
|
||||
// basic exception safety
|
||||
ASSERT_THROW(pool.insert(std::begin(entities), std::end(entities), 0), test::throwing_allocator<entt::entity>::exception_type);
|
||||
ASSERT_TRUE(pool.contains(entt::entity{1}));
|
||||
ASSERT_FALSE(pool.contains(entt::entity{ENTT_SPARSE_PAGE}));
|
||||
|
||||
pool.erase(entt::entity{1});
|
||||
const int components[2u]{1, ENTT_SPARSE_PAGE};
|
||||
test::throwing_allocator<entt::entity>::trigger_on_allocate = true;
|
||||
|
||||
// basic exception safety
|
||||
ASSERT_THROW(pool.insert(std::begin(entities), std::end(entities), std::begin(components)), test::throwing_allocator<entt::entity>::exception_type);
|
||||
ASSERT_TRUE(pool.contains(entt::entity{1}));
|
||||
ASSERT_FALSE(pool.contains(entt::entity{ENTT_SPARSE_PAGE}));
|
||||
}
|
||||
|
||||
TEST(Storage, ThrowingComponent) {
|
||||
entt::storage<test::throwing_component> pool;
|
||||
test::throwing_component::trigger_on_value = 42;
|
||||
@@ -1275,100 +1380,3 @@ TEST(Storage, ThrowingComponent) {
|
||||
ASSERT_EQ(pool.at(0u), entt::entity{42});
|
||||
ASSERT_EQ(pool.get(entt::entity{42}), 42);
|
||||
}
|
||||
|
||||
TEST(Storage, CustomAllocator) {
|
||||
test::throwing_allocator<entt::entity> allocator{};
|
||||
entt::basic_storage<entt::entity, int, test::throwing_allocator<entt::entity>> pool{allocator};
|
||||
|
||||
ASSERT_EQ(pool.get_allocator(), allocator);
|
||||
|
||||
pool.reserve(1u);
|
||||
|
||||
ASSERT_EQ(pool.capacity(), ENTT_PACKED_PAGE);
|
||||
|
||||
pool.emplace(entt::entity{0}, 3);
|
||||
pool.emplace(entt::entity{1}, 42);
|
||||
|
||||
entt::basic_storage<entt::entity, int, test::throwing_allocator<entt::entity>> other{std::move(pool), allocator};
|
||||
|
||||
ASSERT_TRUE(pool.empty());
|
||||
ASSERT_FALSE(other.empty());
|
||||
ASSERT_EQ(pool.capacity(), 0u);
|
||||
ASSERT_EQ(other.capacity(), ENTT_PACKED_PAGE);
|
||||
ASSERT_EQ(other.size(), 2u);
|
||||
|
||||
pool = std::move(other);
|
||||
|
||||
ASSERT_FALSE(pool.empty());
|
||||
ASSERT_TRUE(other.empty());
|
||||
ASSERT_EQ(other.capacity(), 0u);
|
||||
ASSERT_EQ(pool.capacity(), ENTT_PACKED_PAGE);
|
||||
ASSERT_EQ(pool.size(), 2u);
|
||||
|
||||
pool.swap(other);
|
||||
pool = std::move(other);
|
||||
|
||||
ASSERT_FALSE(pool.empty());
|
||||
ASSERT_TRUE(other.empty());
|
||||
ASSERT_EQ(other.capacity(), 0u);
|
||||
ASSERT_EQ(pool.capacity(), ENTT_PACKED_PAGE);
|
||||
ASSERT_EQ(pool.size(), 2u);
|
||||
|
||||
pool.clear();
|
||||
|
||||
ASSERT_EQ(pool.capacity(), ENTT_PACKED_PAGE);
|
||||
ASSERT_EQ(pool.size(), 0u);
|
||||
|
||||
pool.shrink_to_fit();
|
||||
|
||||
ASSERT_EQ(pool.capacity(), 0u);
|
||||
}
|
||||
|
||||
TEST(Storage, ThrowingAllocator) {
|
||||
entt::basic_storage<entt::entity, int, test::throwing_allocator<int>> pool;
|
||||
|
||||
test::throwing_allocator<int>::trigger_on_allocate = true;
|
||||
|
||||
// strong exception safety
|
||||
ASSERT_THROW(pool.reserve(1u), test::throwing_allocator<int>::exception_type);
|
||||
ASSERT_EQ(pool.capacity(), 0u);
|
||||
|
||||
test::throwing_allocator<int>::trigger_after_allocate = true;
|
||||
|
||||
// strong exception safety
|
||||
ASSERT_THROW(pool.reserve(2 * ENTT_PACKED_PAGE), test::throwing_allocator<int>::exception_type);
|
||||
ASSERT_EQ(pool.capacity(), 0u);
|
||||
|
||||
pool.shrink_to_fit();
|
||||
test::throwing_allocator<int>::trigger_on_allocate = true;
|
||||
|
||||
// strong exception safety
|
||||
ASSERT_THROW(pool.emplace(entt::entity{0}, 0), test::throwing_allocator<int>::exception_type);
|
||||
ASSERT_FALSE(pool.contains(entt::entity{0}));
|
||||
ASSERT_TRUE(pool.empty());
|
||||
|
||||
test::throwing_allocator<entt::entity>::trigger_on_allocate = true;
|
||||
|
||||
// strong exception safety
|
||||
ASSERT_THROW(pool.emplace(entt::entity{0}, 0), test::throwing_allocator<entt::entity>::exception_type);
|
||||
ASSERT_FALSE(pool.contains(entt::entity{0}));
|
||||
ASSERT_TRUE(pool.empty());
|
||||
|
||||
pool.emplace(entt::entity{0}, 0);
|
||||
const entt::entity entities[2u]{entt::entity{1}, entt::entity{ENTT_SPARSE_PAGE}};
|
||||
test::throwing_allocator<entt::entity>::trigger_after_allocate = true;
|
||||
|
||||
// basic exception safety
|
||||
ASSERT_THROW(pool.insert(std::begin(entities), std::end(entities), 0), test::throwing_allocator<entt::entity>::exception_type);
|
||||
ASSERT_TRUE(pool.contains(entt::entity{1}));
|
||||
ASSERT_FALSE(pool.contains(entt::entity{ENTT_SPARSE_PAGE}));
|
||||
|
||||
pool.erase(entt::entity{1});
|
||||
const int components[2u]{1, ENTT_SPARSE_PAGE};
|
||||
test::throwing_allocator<entt::entity>::trigger_on_allocate = true;
|
||||
|
||||
// basic exception safety
|
||||
ASSERT_THROW(pool.insert(std::begin(entities), std::end(entities), std::begin(components)), test::throwing_allocator<entt::entity>::exception_type);
|
||||
ASSERT_TRUE(pool.contains(entt::entity{1}));
|
||||
ASSERT_FALSE(pool.contains(entt::entity{ENTT_SPARSE_PAGE}));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user