| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398 |
- #include <iterator>
- #include <memory>
- #include <tuple>
- #include <type_traits>
- #include <utility>
- #include <gtest/gtest.h>
- #include <entt/entity/storage.hpp>
- #include "../common/config.h"
- struct empty_type {};
- template<typename Type>
- struct StorageNoInstance: testing::Test {
- using type = Type;
- };
- template<typename Type>
- using StorageNoInstanceDeathTest = StorageNoInstance<Type>;
- using StorageNoInstanceTypes = ::testing::Types<empty_type, void>;
- TYPED_TEST_SUITE(StorageNoInstance, StorageNoInstanceTypes, );
- TYPED_TEST_SUITE(StorageNoInstanceDeathTest, StorageNoInstanceTypes, );
- TYPED_TEST(StorageNoInstance, Constructors) {
- using value_type = typename TestFixture::type;
- entt::storage<value_type> pool;
- ASSERT_EQ(pool.policy(), entt::deletion_policy::swap_and_pop);
- ASSERT_NO_FATAL_FAILURE([[maybe_unused]] auto alloc = pool.get_allocator());
- ASSERT_EQ(pool.type(), entt::type_id<value_type>());
- pool = entt::storage<value_type>{std::allocator<value_type>{}};
- ASSERT_EQ(pool.policy(), entt::deletion_policy::swap_and_pop);
- ASSERT_NO_FATAL_FAILURE([[maybe_unused]] auto alloc = pool.get_allocator());
- ASSERT_EQ(pool.type(), entt::type_id<value_type>());
- }
- TYPED_TEST(StorageNoInstance, Getters) {
- using value_type = typename TestFixture::type;
- entt::storage<value_type> pool;
- pool.emplace(entt::entity{41}, 3);
- testing::StaticAssertTypeEq<decltype(pool.get({})), void>();
- testing::StaticAssertTypeEq<decltype(std::as_const(pool).get({})), void>();
- testing::StaticAssertTypeEq<decltype(pool.get_as_tuple({})), std::tuple<>>();
- testing::StaticAssertTypeEq<decltype(std::as_const(pool).get_as_tuple({})), std::tuple<>>();
- ASSERT_NO_FATAL_FAILURE(pool.get(entt::entity{41}));
- ASSERT_NO_FATAL_FAILURE(std::as_const(pool).get(entt::entity{41}));
- ASSERT_EQ(pool.get_as_tuple(entt::entity{41}), std::make_tuple());
- ASSERT_EQ(std::as_const(pool).get_as_tuple(entt::entity{41}), std::make_tuple());
- }
- ENTT_DEBUG_TYPED_TEST(StorageNoInstanceDeathTest, Getters) {
- using value_type = typename TestFixture::type;
- entt::storage<value_type> pool;
- ASSERT_DEATH(pool.get(entt::entity{41}), "");
- ASSERT_DEATH(std::as_const(pool).get(entt::entity{41}), "");
- ASSERT_DEATH([[maybe_unused]] const auto value = pool.get_as_tuple(entt::entity{41}), "");
- ASSERT_DEATH([[maybe_unused]] const auto value = std::as_const(pool).get_as_tuple(entt::entity{41}), "");
- }
- TYPED_TEST(StorageNoInstance, Emplace) {
- using value_type = typename TestFixture::type;
- entt::storage<value_type> pool;
- const entt::entity entity[2u]{entt::entity{3}, entt::entity{42}};
- testing::StaticAssertTypeEq<decltype(pool.emplace({})), void>();
- if constexpr(std::is_void_v<value_type>) {
- ASSERT_NO_FATAL_FAILURE(pool.emplace(entity[0u]));
- } else {
- ASSERT_NO_FATAL_FAILURE(pool.emplace(entity[0u]));
- ASSERT_NO_FATAL_FAILURE(pool.emplace(entity[1u], value_type{}));
- }
- }
- ENTT_DEBUG_TYPED_TEST(StorageNoInstanceDeathTest, Emplace) {
- using value_type = typename TestFixture::type;
- entt::storage<value_type> pool;
- const entt::entity entity{42};
- testing::StaticAssertTypeEq<decltype(pool.emplace({})), void>();
- pool.emplace(entity);
- if constexpr(std::is_void_v<value_type>) {
- ASSERT_DEATH(pool.emplace(entity), "");
- } else {
- ASSERT_DEATH(pool.emplace(entity), "");
- ASSERT_DEATH(pool.emplace(entity, value_type{}), "");
- }
- }
- TYPED_TEST(StorageNoInstance, TryEmplace) {
- using value_type = typename TestFixture::type;
- entt::storage<value_type> pool;
- entt::sparse_set &base = pool;
- const entt::entity entity[2u]{entt::entity{3}, entt::entity{42}};
- if constexpr(std::is_void_v<value_type>) {
- ASSERT_NE(base.push(entity[0u], nullptr), base.end());
- } else {
- value_type instance{};
- ASSERT_NE(base.push(entity[0u], &instance), base.end());
- }
- ASSERT_EQ(pool.size(), 1u);
- ASSERT_EQ(base.index(entity[0u]), 0u);
- base.erase(entity[0u]);
- ASSERT_NE(base.push(std::begin(entity), std::end(entity)), base.end());
- ASSERT_EQ(pool.size(), 2u);
- ASSERT_EQ(base.index(entity[0u]), 0u);
- ASSERT_EQ(base.index(entity[1u]), 1u);
- base.erase(std::begin(entity), std::end(entity));
- ASSERT_NE(base.push(std::rbegin(entity), std::rend(entity)), base.end());
- ASSERT_EQ(pool.size(), 2u);
- ASSERT_EQ(base.index(entity[0u]), 1u);
- ASSERT_EQ(base.index(entity[1u]), 0u);
- }
- TYPED_TEST(StorageNoInstance, Patch) {
- using value_type = typename TestFixture::type;
- entt::storage<value_type> pool;
- entt::entity entity{42};
- int counter = 0;
- auto callback = [&counter]() { ++counter; };
- pool.emplace(entity);
- ASSERT_EQ(counter, 0);
- pool.patch(entity);
- pool.patch(entity, callback);
- pool.patch(entity, callback, callback);
- ASSERT_EQ(counter, 3);
- }
- ENTT_DEBUG_TYPED_TEST(StorageNoInstanceDeathTest, Patch) {
- using value_type = typename TestFixture::type;
- entt::storage<value_type> pool;
- ASSERT_DEATH(pool.patch(entt::null), "");
- }
- TYPED_TEST(StorageNoInstance, Insert) {
- using value_type = typename TestFixture::type;
- entt::storage<value_type> pool;
- const entt::entity entity[2u]{entt::entity{3}, entt::entity{42}};
- pool.insert(std::begin(entity), std::end(entity));
- ASSERT_EQ(pool.size(), 2u);
- ASSERT_EQ(pool.index(entity[0u]), 0u);
- ASSERT_EQ(pool.index(entity[1u]), 1u);
- if constexpr(!std::is_void_v<value_type>) {
- const value_type values[2u]{};
- pool.erase(std::begin(entity), std::end(entity));
- pool.insert(std::rbegin(entity), std::rend(entity), std::begin(values));
- ASSERT_EQ(pool.size(), 2u);
- ASSERT_EQ(pool.index(entity[0u]), 1u);
- ASSERT_EQ(pool.index(entity[1u]), 0u);
- }
- }
- ENTT_DEBUG_TYPED_TEST(StorageNoInstanceDeathTest, Insert) {
- using value_type = typename TestFixture::type;
- entt::storage<value_type> pool;
- const entt::entity entity[2u]{entt::entity{3}, entt::entity{42}};
- pool.insert(std::begin(entity), std::end(entity));
- if constexpr(std::is_void_v<value_type>) {
- ASSERT_DEATH(pool.insert(std::begin(entity), std::end(entity)), "");
- } else {
- const value_type values[2u]{};
- ASSERT_DEATH(pool.insert(std::begin(entity), std::end(entity)), "");
- ASSERT_DEATH(pool.insert(std::begin(entity), std::end(entity), std::begin(values)), "");
- }
- }
- TYPED_TEST(StorageNoInstance, Iterable) {
- using value_type = typename TestFixture::type;
- using iterator = typename entt::storage<value_type>::iterable::iterator;
- testing::StaticAssertTypeEq<typename iterator::value_type, std::tuple<entt::entity>>();
- testing::StaticAssertTypeEq<typename iterator::value_type, std::tuple<entt::entity>>();
- testing::StaticAssertTypeEq<typename iterator::pointer, entt::input_iterator_pointer<std::tuple<entt::entity>>>();
- testing::StaticAssertTypeEq<typename iterator::reference, typename iterator::value_type>();
- entt::storage<value_type> pool;
- entt::sparse_set &base = pool;
- pool.emplace(entt::entity{1});
- pool.emplace(entt::entity{3});
- auto iterable = pool.each();
- iterator end{iterable.begin()};
- iterator begin{};
- begin = iterable.end();
- std::swap(begin, end);
- ASSERT_EQ(begin, iterable.begin());
- ASSERT_EQ(end, iterable.end());
- ASSERT_NE(begin, end);
- ASSERT_EQ(begin.base(), base.begin());
- ASSERT_EQ(end.base(), base.end());
- ASSERT_EQ(std::get<0>(*begin.operator->().operator->()), entt::entity{3});
- ASSERT_EQ(std::get<0>(*begin), entt::entity{3});
- ASSERT_EQ(begin++, iterable.begin());
- ASSERT_EQ(begin.base(), ++base.begin());
- ASSERT_EQ(++begin, iterable.end());
- ASSERT_EQ(begin.base(), base.end());
- for(auto [entity]: iterable) {
- testing::StaticAssertTypeEq<decltype(entity), entt::entity>();
- ASSERT_TRUE(entity == entt::entity{1} || entity == entt::entity{3});
- }
- }
- TYPED_TEST(StorageNoInstance, ConstIterable) {
- using value_type = typename TestFixture::type;
- using iterator = typename entt::storage<value_type>::const_iterable::iterator;
- testing::StaticAssertTypeEq<typename iterator::value_type, std::tuple<entt::entity>>();
- testing::StaticAssertTypeEq<typename iterator::value_type, std::tuple<entt::entity>>();
- testing::StaticAssertTypeEq<typename iterator::pointer, entt::input_iterator_pointer<std::tuple<entt::entity>>>();
- testing::StaticAssertTypeEq<typename iterator::reference, typename iterator::value_type>();
- entt::storage<value_type> pool;
- entt::sparse_set &base = pool;
- pool.emplace(entt::entity{1});
- pool.emplace(entt::entity{3});
- auto iterable = std::as_const(pool).each();
- iterator end{iterable.begin()};
- iterator begin{};
- begin = iterable.end();
- std::swap(begin, end);
- ASSERT_EQ(begin, iterable.begin());
- ASSERT_EQ(end, iterable.end());
- ASSERT_NE(begin, end);
- ASSERT_EQ(begin.base(), base.begin());
- ASSERT_EQ(end.base(), base.end());
- ASSERT_EQ(std::get<0>(*begin.operator->().operator->()), entt::entity{3});
- ASSERT_EQ(std::get<0>(*begin), entt::entity{3});
- ASSERT_EQ(begin++, iterable.begin());
- ASSERT_EQ(begin.base(), ++base.begin());
- ASSERT_EQ(++begin, iterable.end());
- ASSERT_EQ(begin.base(), base.end());
- for(auto [entity]: iterable) {
- testing::StaticAssertTypeEq<decltype(entity), entt::entity>();
- ASSERT_TRUE(entity == entt::entity{1} || entity == entt::entity{3});
- }
- }
- TYPED_TEST(StorageNoInstance, ReverseIterable) {
- using value_type = typename TestFixture::type;
- using iterator = typename entt::storage<value_type>::reverse_iterable::iterator;
- testing::StaticAssertTypeEq<typename iterator::value_type, std::tuple<entt::entity>>();
- testing::StaticAssertTypeEq<typename iterator::value_type, std::tuple<entt::entity>>();
- testing::StaticAssertTypeEq<typename iterator::pointer, entt::input_iterator_pointer<std::tuple<entt::entity>>>();
- testing::StaticAssertTypeEq<typename iterator::reference, typename iterator::value_type>();
- entt::storage<value_type> pool;
- entt::sparse_set &base = pool;
- pool.emplace(entt::entity{1});
- pool.emplace(entt::entity{3});
- auto iterable = pool.reach();
- iterator end{iterable.begin()};
- iterator begin{};
- begin = iterable.end();
- std::swap(begin, end);
- ASSERT_EQ(begin, iterable.begin());
- ASSERT_EQ(end, iterable.end());
- ASSERT_NE(begin, end);
- ASSERT_EQ(begin.base(), base.rbegin());
- ASSERT_EQ(end.base(), base.rend());
- ASSERT_EQ(std::get<0>(*begin.operator->().operator->()), entt::entity{1});
- ASSERT_EQ(std::get<0>(*begin), entt::entity{1});
- ASSERT_EQ(begin++, iterable.begin());
- ASSERT_EQ(begin.base(), ++base.rbegin());
- ASSERT_EQ(++begin, iterable.end());
- ASSERT_EQ(begin.base(), base.rend());
- for(auto [entity]: iterable) {
- testing::StaticAssertTypeEq<decltype(entity), entt::entity>();
- ASSERT_TRUE(entity == entt::entity{1} || entity == entt::entity{3});
- }
- }
- TYPED_TEST(StorageNoInstance, ConstReverseIterable) {
- using value_type = typename TestFixture::type;
- using iterator = typename entt::storage<value_type>::const_reverse_iterable::iterator;
- testing::StaticAssertTypeEq<typename iterator::value_type, std::tuple<entt::entity>>();
- testing::StaticAssertTypeEq<typename iterator::value_type, std::tuple<entt::entity>>();
- testing::StaticAssertTypeEq<typename iterator::pointer, entt::input_iterator_pointer<std::tuple<entt::entity>>>();
- testing::StaticAssertTypeEq<typename iterator::reference, typename iterator::value_type>();
- entt::storage<value_type> pool;
- entt::sparse_set &base = pool;
- pool.emplace(entt::entity{1});
- pool.emplace(entt::entity{3});
- auto iterable = std::as_const(pool).reach();
- iterator end{iterable.begin()};
- iterator begin{};
- begin = iterable.end();
- std::swap(begin, end);
- ASSERT_EQ(begin, iterable.begin());
- ASSERT_EQ(end, iterable.end());
- ASSERT_NE(begin, end);
- ASSERT_EQ(begin.base(), base.rbegin());
- ASSERT_EQ(end.base(), base.rend());
- ASSERT_EQ(std::get<0>(*begin.operator->().operator->()), entt::entity{1});
- ASSERT_EQ(std::get<0>(*begin), entt::entity{1});
- ASSERT_EQ(begin++, iterable.begin());
- ASSERT_EQ(begin.base(), ++base.rbegin());
- ASSERT_EQ(++begin, iterable.end());
- ASSERT_EQ(begin.base(), base.rend());
- for(auto [entity]: iterable) {
- testing::StaticAssertTypeEq<decltype(entity), entt::entity>();
- ASSERT_TRUE(entity == entt::entity{1} || entity == entt::entity{3});
- }
- }
- TYPED_TEST(StorageNoInstance, IterableIteratorConversion) {
- using value_type = typename TestFixture::type;
- entt::storage<value_type> pool;
- pool.emplace(entt::entity{3});
- typename entt::storage<value_type>::iterable::iterator it = pool.each().begin();
- typename entt::storage<value_type>::const_iterable::iterator cit = it;
- testing::StaticAssertTypeEq<decltype(*it), std::tuple<entt::entity>>();
- testing::StaticAssertTypeEq<decltype(*cit), std::tuple<entt::entity>>();
- ASSERT_EQ(it, cit);
- ASSERT_NE(++cit, it);
- }
|