diff --git a/docs/md/entity.md b/docs/md/entity.md
index 1aae64f94..7d26a66e6 100644
--- a/docs/md/entity.md
+++ b/docs/md/entity.md
@@ -10,6 +10,7 @@
* [Type-less and bitset-free](#type-less-and-bitset-free)
* [Build your own](#build-your-own)
* [Pay per use](#pay-per-use)
+ * [All or nothing](#all-or-nothing)
* [Vademecum](#vademecum)
* [Pools](#pools)
* [The Registry, the Entity and the Component](#the-registry-the-entity-and-the-component)
@@ -118,6 +119,19 @@ performance where needed.
So far, this choice has proven to be a good one and I really hope it can be for
many others besides me.
+## All or nothing
+
+`EnTT` is such that a `T**` pointer (or whatever a custom pool returns) is
+always available to directly access all the instances of a given component type
+`T`.
+I cannot say whether it will be useful or not to the reader, but it's worth to
+mention it since it's one of the corner stones of this library.
+
+Many of the tools described below give the possibility to get this information
+and have been designed around this need.
+The rest is experimentation and the desire to invent something new, hoping to
+have succeeded.
+
# Vademecum
The registry to store, the views and the groups to iterate. That's all.
@@ -1237,11 +1251,12 @@ different in the two cases.
Single component views are specialized in order to give a boost in terms of
performance in all the situations. This kind of views can access the underlying
data structures directly and avoid superfluous checks. There is nothing as fast
-as a single component view. In fact, they walk through a packed array of
-components and return them one at a time.
-Single component views offer a bunch of functionalities to get the number of
-entities they are going to return and a raw access to the entity list. It's also
-possible to ask a view if it contains a given entity.
+as a single component view. In fact, they walk through a packed (actually paged)
+array of components and return them one at a time.
+Single component views also offer a bunch of functionalities to get the number
+of entities they are going to return and a raw access to the entity list as well
+as to the component list. It's also possible to ask a view if it contains a
+given entity.
Refer to the inline documentation for all the details.
Multi component views iterate entities that have at least all the given
@@ -1435,8 +1450,9 @@ However, it's unlikely that users will be able to appreciate the impact of
groups on the other functionalities of a registry.
Groups offer a bunch of functionalities to get the number of entities they are
-going to return and a raw access to the entity list. It's also possible to ask a
-group if it contains a given entity.
+going to return and a raw access to the entity list as well as to the component
+list for owned components. It's also possible to ask a group if it contains a
+given entity.
Refer to the inline documentation for all the details.
There is no need to store groups aside for they are extremely cheap to
@@ -1846,9 +1862,9 @@ When an empty type is detected, it's not instantiated in any case. Therefore,
only the entities to which it's assigned are made available.
There doesn't exist a way to _get_ empty types from a registry, views and groups
will never return instances for them (for example, during a call to `each`) and
-some functions such as `try_get` aren't available for empty types. Finally, the
-`sort` functionality will only accepts callbacks that require to return entities
-rather than components:
+some functions such as `try_get` or the raw access to the list of components
+aren't available for empty types. Finally, the `sort` functionality will only
+accepts callbacks that require to return entities rather than components:
```cpp
registry.sort([](const entt::entity lhs, const entt::entity rhs) {
diff --git a/src/entt/entity/group.hpp b/src/entt/entity/group.hpp
index dc143a745..f0ace4448 100644
--- a/src/entt/entity/group.hpp
+++ b/src/entt/entity/group.hpp
@@ -680,6 +680,22 @@ public:
return !*this || !*length;
}
+ /**
+ * @brief Direct access to the raw representation offered by the storage.
+ *
+ * @warning
+ * This function is only available for owned types.
+ *
+ * @tparam Component Type of component in which one is interested.
+ * @return A pointer to the array of components.
+ */
+ template
+ [[nodiscard]] auto raw() const ENTT_NOEXCEPT {
+ static_assert((std::is_same_v || ...), "Non-owned type");
+ auto *cpool = std::get *>(pools);
+ return cpool ? cpool->raw() : decltype(cpool->raw()){};
+ }
+
/**
* @brief Direct access to the list of entities.
*
diff --git a/src/entt/entity/storage.hpp b/src/entt/entity/storage.hpp
index 037aac224..9d5be1230 100644
--- a/src/entt/entity/storage.hpp
+++ b/src/entt/entity/storage.hpp
@@ -59,11 +59,12 @@ class basic_storage: public basic_sparse_set::template rebind_alloc;
using alloc_traits = std::allocator_traits;
using alloc_pointer = typename alloc_traits::pointer;
+ using alloc_const_pointer = typename alloc_traits::const_pointer;
using bucket_alloc_type = typename std::allocator_traits::template rebind_alloc;
using bucket_alloc_traits = std::allocator_traits;
using bucket_alloc_pointer = typename bucket_alloc_traits::pointer;
- using bucket_alloc_const_pointer = typename bucket_alloc_traits::const_pointer;
+ using bucket_alloc_const_pointer = typename std::allocator_traits::template rebind_alloc::const_pointer;
using entity_alloc_type = typename std::allocator_traits::template rebind_alloc;
@@ -74,7 +75,7 @@ class basic_storage: public basic_sparse_set;
- storage_iterator(const bucket_alloc_const_pointer *ref, const typename traits_type::difference_type idx) ENTT_NOEXCEPT
+ storage_iterator(bucket_alloc_pointer const *ref, const typename traits_type::difference_type idx) ENTT_NOEXCEPT
: packed{ref}, index{idx}
{}
@@ -166,7 +167,7 @@ class basic_storage: public basic_sparse_set;
/*! @brief Constant random access iterator type. */
@@ -354,6 +359,19 @@ public:
count ? maybe_resize_packed(count) : reset_to_empty();
}
+ /**
+ * @brief Direct access to the array of objects.
+ * @return A pointer to the array of objects.
+ */
+ [[nodiscard]] const_pointer raw() const ENTT_NOEXCEPT {
+ return packed;
+ }
+
+ /*! @copydoc raw */
+ [[nodiscard]] pointer raw() ENTT_NOEXCEPT {
+ return packed;
+ }
+
/**
* @brief Returns an iterator to the beginning.
*
diff --git a/src/entt/entity/view.hpp b/src/entt/entity/view.hpp
index 6b44ba78e..bd8de4cf8 100644
--- a/src/entt/entity/view.hpp
+++ b/src/entt/entity/view.hpp
@@ -708,6 +708,14 @@ public:
return std::get<0>(pools)->empty();
}
+ /**
+ * @brief Direct access to the raw representation offered by the storage.
+ * @return A pointer to the array of components.
+ */
+ [[nodiscard]] auto raw() const ENTT_NOEXCEPT {
+ return std::get<0>(pools)->raw();
+ }
+
/**
* @brief Direct access to the list of entities.
*
diff --git a/test/entt/entity/group.cpp b/test/entt/entity/group.cpp
index 97991ab9a..a24a600e0 100644
--- a/test/entt/entity/group.cpp
+++ b/test/entt/entity/group.cpp
@@ -53,7 +53,7 @@ TEST(NonOwningGroup, Functionalities) {
ASSERT_EQ(cgroup.get(entity), '2');
}
- ASSERT_EQ(*(group.data() + 0), e1);
+ ASSERT_EQ(group.data()[0u], e1);
registry.erase(e0);
registry.erase(e1);
@@ -221,17 +221,17 @@ TEST(NonOwningGroup, Sort) {
registry.emplace(e1, 1);
registry.emplace(e2, 2);
- ASSERT_EQ(*(group.data() + 0u), e0);
- ASSERT_EQ(*(group.data() + 1u), e1);
- ASSERT_EQ(*(group.data() + 2u), e2);
+ ASSERT_EQ(group.data()[0u], e0);
+ ASSERT_EQ(group.data()[1u], e1);
+ ASSERT_EQ(group.data()[2u], e2);
group.sort([](const entt::entity lhs, const entt::entity rhs) {
return entt::to_integral(lhs) < entt::to_integral(rhs);
});
- ASSERT_EQ(*(group.data() + 0u), e2);
- ASSERT_EQ(*(group.data() + 1u), e1);
- ASSERT_EQ(*(group.data() + 2u), e0);
+ ASSERT_EQ(group.data()[0u], e2);
+ ASSERT_EQ(group.data()[1u], e1);
+ ASSERT_EQ(group.data()[2u], e0);
ASSERT_EQ((group.get(e0)), (std::make_tuple(0, 0u)));
ASSERT_EQ((group.get(e1)), (std::make_tuple(1, 1u)));
@@ -243,9 +243,9 @@ TEST(NonOwningGroup, Sort) {
return lhs > rhs;
});
- ASSERT_EQ(*(group.data() + 0u), e0);
- ASSERT_EQ(*(group.data() + 1u), e1);
- ASSERT_EQ(*(group.data() + 2u), e2);
+ ASSERT_EQ(group.data()[0u], e0);
+ ASSERT_EQ(group.data()[1u], e1);
+ ASSERT_EQ(group.data()[2u], e2);
ASSERT_EQ((group.get(e0)), (std::make_tuple(0, 0u)));
ASSERT_EQ((group.get(e1)), (std::make_tuple(1, 1u)));
@@ -259,9 +259,9 @@ TEST(NonOwningGroup, Sort) {
return std::get<0>(lhs) < std::get<0>(rhs);
});
- ASSERT_EQ(*(group.data() + 0u), e2);
- ASSERT_EQ(*(group.data() + 1u), e1);
- ASSERT_EQ(*(group.data() + 2u), e0);
+ ASSERT_EQ(group.data()[0u], e2);
+ ASSERT_EQ(group.data()[1u], e1);
+ ASSERT_EQ(group.data()[2u], e0);
ASSERT_EQ((group.get(e0)), (std::make_tuple(0, 0u)));
ASSERT_EQ((group.get(e1)), (std::make_tuple(1, 1u)));
@@ -665,8 +665,8 @@ TEST(OwningGroup, Functionalities) {
ASSERT_EQ(group.size(), 1u);
- ASSERT_EQ(*(cgroup.rbegin() + 0), e1);
- ASSERT_EQ(*(group.rbegin() + 0), e1);
+ ASSERT_EQ(cgroup.raw()[0u][0u], 42);
+ ASSERT_EQ(group.raw()[0u][0u], 42);
for(auto entity: group) {
ASSERT_EQ(std::get<0>(cgroup.get(entity)), 42);
@@ -674,7 +674,8 @@ TEST(OwningGroup, Functionalities) {
ASSERT_EQ(cgroup.get(entity), '2');
}
- ASSERT_EQ(*(group.data() + 0), e1);
+ ASSERT_EQ(group.data()[0u], e1);
+ ASSERT_EQ(group.raw()[0u][0u], 42);
registry.erase(e0);
registry.erase(e1);
@@ -705,6 +706,7 @@ TEST(OwningGroup, Invalid) {
ASSERT_TRUE(group.empty());
ASSERT_EQ(group.size(), 0u);
+ ASSERT_EQ(group.raw(), nullptr);
ASSERT_EQ(group.data(), nullptr);
ASSERT_EQ(group.begin(), group.end());
@@ -839,17 +841,21 @@ TEST(OwningGroup, SortOrdered) {
return group.get(lhs).value < group.get(rhs).value;
});
- ASSERT_EQ(*(group.data() + 0u), entities[0]);
- ASSERT_EQ(*(group.data() + 1u), entities[1]);
- ASSERT_EQ(*(group.data() + 2u), entities[2]);
+ ASSERT_EQ(group.data()[0u], entities[0]);
+ ASSERT_EQ(group.data()[1u], entities[1]);
+ ASSERT_EQ(group.data()[2u], entities[2]);
+ ASSERT_EQ(group.data()[3u], entities[3]);
+ ASSERT_EQ(group.data()[4u], entities[4]);
- ASSERT_EQ(group.get(*(group.data() + 0u)).value, 12);
- ASSERT_EQ(group.get(*(group.data() + 1u)).value, 9);
- ASSERT_EQ(group.get(*(group.data() + 2u)).value, 6);
+ ASSERT_EQ(group.raw()[0u][0u].value, 12);
+ ASSERT_EQ(group.raw()[0u][1u].value, 9);
+ ASSERT_EQ(group.raw()[0u][2u].value, 6);
+ ASSERT_EQ(group.raw()[0u][3u].value, 1);
+ ASSERT_EQ(group.raw()[0u][4u].value, 2);
- ASSERT_EQ(group.get(*(group.data() + 0u)), 'a');
- ASSERT_EQ(group.get(*(group.data() + 1u)), 'b');
- ASSERT_EQ(group.get(*(group.data() + 2u)), 'c');
+ ASSERT_EQ(group.raw()[0u][0u], 'a');
+ ASSERT_EQ(group.raw()[0u][1u], 'b');
+ ASSERT_EQ(group.raw()[0u][2u], 'c');
ASSERT_EQ((group.get(entities[0])), (std::make_tuple(boxed_int{12}, 'a')));
ASSERT_EQ((group.get(entities[1])), (std::make_tuple(boxed_int{9}, 'b')));
@@ -882,17 +888,21 @@ TEST(OwningGroup, SortReverse) {
return lhs.value < rhs.value;
});
- ASSERT_EQ(*(group.data() + 0u), entities[2]);
- ASSERT_EQ(*(group.data() + 1u), entities[1]);
- ASSERT_EQ(*(group.data() + 2u), entities[0]);
+ ASSERT_EQ(group.data()[0u], entities[2]);
+ ASSERT_EQ(group.data()[1u], entities[1]);
+ ASSERT_EQ(group.data()[2u], entities[0]);
+ ASSERT_EQ(group.data()[3u], entities[3]);
+ ASSERT_EQ(group.data()[4u], entities[4]);
- ASSERT_EQ(group.get(*(group.data() + 0u)).value, 12);
- ASSERT_EQ(group.get(*(group.data() + 1u)).value, 9);
- ASSERT_EQ(group.get(*(group.data() + 2u)).value, 6);
+ ASSERT_EQ(group.raw()[0u][0u].value, 12);
+ ASSERT_EQ(group.raw()[0u][1u].value, 9);
+ ASSERT_EQ(group.raw()[0u][2u].value, 6);
+ ASSERT_EQ(group.raw()[0u][3u].value, 1);
+ ASSERT_EQ(group.raw()[0u][4u].value, 2);
- ASSERT_EQ(group.get(*(group.data() + 0u)), 'c');
- ASSERT_EQ(group.get(*(group.data() + 1u)), 'b');
- ASSERT_EQ(group.get(*(group.data() + 2u)), 'a');
+ ASSERT_EQ(group.raw()[0u][0u], 'c');
+ ASSERT_EQ(group.raw()[0u][1u], 'b');
+ ASSERT_EQ(group.raw()[0u][2u], 'a');
ASSERT_EQ((group.get(entities[0])), (std::make_tuple(boxed_int{6}, 'a')));
ASSERT_EQ((group.get(entities[1])), (std::make_tuple(boxed_int{9}, 'b')));
@@ -933,29 +943,27 @@ TEST(OwningGroup, SortUnordered) {
return std::get<1>(lhs) < std::get<1>(rhs);
});
- ASSERT_EQ(*(group.data() + 0u), entities[4]);
- ASSERT_EQ(*(group.data() + 1u), entities[3]);
- ASSERT_EQ(*(group.data() + 2u), entities[0]);
- ASSERT_EQ(*(group.data() + 3u), entities[1]);
- ASSERT_EQ(*(group.data() + 4u), entities[2]);
+ ASSERT_EQ(group.data()[0u], entities[4]);
+ ASSERT_EQ(group.data()[1u], entities[3]);
+ ASSERT_EQ(group.data()[2u], entities[0]);
+ ASSERT_EQ(group.data()[3u], entities[1]);
+ ASSERT_EQ(group.data()[4u], entities[2]);
+ ASSERT_EQ(group.data()[5u], entities[5]);
+ ASSERT_EQ(group.data()[6u], entities[6]);
- ASSERT_EQ(group.get(*(group.data() + 0u)).value, 12);
- ASSERT_EQ(group.get(*(group.data() + 1u)).value, 9);
- ASSERT_EQ(group.get(*(group.data() + 2u)).value, 6);
- ASSERT_EQ(group.get(*(group.data() + 3u)).value, 3);
- ASSERT_EQ(group.get(*(group.data() + 4u)).value, 1);
+ ASSERT_EQ(group.raw()[0u][0u].value, 12);
+ ASSERT_EQ(group.raw()[0u][1u].value, 9);
+ ASSERT_EQ(group.raw()[0u][2u].value, 6);
+ ASSERT_EQ(group.raw()[0u][3u].value, 3);
+ ASSERT_EQ(group.raw()[0u][4u].value, 1);
+ ASSERT_EQ(group.raw()[0u][5u].value, 4);
+ ASSERT_EQ(group.raw()[0u][6u].value, 5);
- ASSERT_EQ(group.get(*(group.data() + 0u)), 'e');
- ASSERT_EQ(group.get(*(group.data() + 1u)), 'd');
- ASSERT_EQ(group.get(*(group.data() + 2u)), 'c');
- ASSERT_EQ(group.get(*(group.data() + 3u)), 'b');
- ASSERT_EQ(group.get(*(group.data() + 4u)), 'a');
-
- ASSERT_EQ((group.get(entities[0])), (std::make_tuple(boxed_int{6}, 'c')));
- ASSERT_EQ((group.get(entities[1])), (std::make_tuple(boxed_int{3}, 'b')));
- ASSERT_EQ((group.get(entities[2])), (std::make_tuple(boxed_int{1}, 'a')));
- ASSERT_EQ((group.get(entities[3])), (std::make_tuple(boxed_int{9}, 'd')));
- ASSERT_EQ((group.get(entities[4])), (std::make_tuple(boxed_int{12}, 'e')));
+ ASSERT_EQ(group.get(group.data()[0u]), 'e');
+ ASSERT_EQ(group.get(group.data()[1u]), 'd');
+ ASSERT_EQ(group.get(group.data()[2u]), 'c');
+ ASSERT_EQ(group.get(group.data()[3u]), 'b');
+ ASSERT_EQ(group.get(group.data()[4u]), 'a');
ASSERT_FALSE(group.contains(entities[5]));
ASSERT_FALSE(group.contains(entities[6]));
@@ -980,15 +988,20 @@ TEST(OwningGroup, SortWithExclusionList) {
return lhs < rhs;
});
- ASSERT_EQ(*(group.data() + 0u), entities[4]);
- ASSERT_EQ(*(group.data() + 1u), entities[3]);
- ASSERT_EQ(*(group.data() + 2u), entities[1]);
- ASSERT_EQ(*(group.data() + 3u), entities[0]);
+ ASSERT_EQ(group.data()[0u], entities[4]);
+ ASSERT_EQ(group.data()[1u], entities[3]);
+ ASSERT_EQ(group.data()[2u], entities[1]);
+ ASSERT_EQ(group.data()[3u], entities[0]);
- ASSERT_EQ(group.get(*(group.data() + 0u)).value, 4);
- ASSERT_EQ(group.get(*(group.data() + 1u)).value, 3);
- ASSERT_EQ(group.get(*(group.data() + 2u)).value, 1);
- ASSERT_EQ(group.get(*(group.data() + 3u)).value, 0);
+ ASSERT_EQ(group.raw()[0u][0u].value, 4);
+ ASSERT_EQ(group.raw()[0u][1u].value, 3);
+ ASSERT_EQ(group.raw()[0u][2u].value, 1);
+ ASSERT_EQ(group.raw()[0u][3u].value, 0);
+
+ ASSERT_EQ(group.get(entities[0]).value, 0);
+ ASSERT_EQ(group.get(entities[1]).value, 1);
+ ASSERT_EQ(group.get(entities[3]).value, 3);
+ ASSERT_EQ(group.get(entities[4]).value, 4);
ASSERT_FALSE(group.contains(entities[2]));
}
@@ -1049,6 +1062,8 @@ TEST(OwningGroup, ConstNonConstAndAllInBetween) {
static_assert(std::is_same_v({})), std::tuple>);
static_assert(std::is_same_v>);
static_assert(std::is_same_v);
+ static_assert(std::is_same_v()), const char * const *>);
+ static_assert(std::is_same_v()), int **>);
group.each([](auto &&i, auto &&c, auto &&d, auto &&f) {
static_assert(std::is_same_v);
diff --git a/test/entt/entity/registry_no_eto.cpp b/test/entt/entity/registry_no_eto.cpp
index 63224b9ec..a6a917a49 100644
--- a/test/entt/entity/registry_no_eto.cpp
+++ b/test/entt/entity/registry_no_eto.cpp
@@ -14,6 +14,7 @@ TEST(Registry, NoEto) {
registry.emplace(entity);
registry.emplace(entity, 42);
+ ASSERT_NE(registry.view().raw(), nullptr);
ASSERT_NE(registry.try_get(entity), nullptr);
ASSERT_EQ(registry.view().get(entity), std::as_const(registry).view().get(entity));
diff --git a/test/entt/entity/storage.cpp b/test/entt/entity/storage.cpp
index b2e75170d..33344791f 100644
--- a/test/entt/entity/storage.cpp
+++ b/test/entt/entity/storage.cpp
@@ -418,6 +418,22 @@ TEST(Storage, ConstReverseIterator) {
ASSERT_GE(cend, pool.crend());
}
+TEST(Storage, Raw) {
+ entt::storage pool;
+
+ pool.emplace(entt::entity{3}, 3);
+ pool.emplace(entt::entity{12}, 6);
+ pool.emplace(entt::entity{42}, 9);
+
+ ASSERT_EQ(pool.get(entt::entity{3}), 3);
+ ASSERT_EQ(std::as_const(pool).get(entt::entity{12}), 6);
+ ASSERT_EQ(pool.get(entt::entity{42}), 9);
+
+ ASSERT_EQ(pool.raw()[0u][0u], 3);
+ ASSERT_EQ(std::as_const(pool).raw()[0u][1u], 6);
+ ASSERT_EQ(pool.raw()[0u][2u], 9);
+}
+
TEST(Storage, SortOrdered) {
entt::storage pool;
entt::entity entities[5u]{entt::entity{12}, entt::entity{42}, entt::entity{7}, entt::entity{3}, entt::entity{9}};
@@ -480,9 +496,9 @@ TEST(Storage, SortRange) {
pool.sort_n(2u, [](auto lhs, auto rhs) { return lhs.value < rhs.value; });
- ASSERT_EQ(pool.rbegin()[0u], boxed_int{6});
- ASSERT_EQ(pool.rbegin()[1u], boxed_int{3});
- ASSERT_EQ(pool.rbegin()[2u], boxed_int{1});
+ ASSERT_EQ(pool.raw()[0u][0u], boxed_int{6});
+ ASSERT_EQ(pool.raw()[0u][1u], boxed_int{3});
+ ASSERT_EQ(pool.raw()[0u][2u], boxed_int{1});
ASSERT_EQ(pool.data()[0u], entt::entity{42});
ASSERT_EQ(pool.data()[1u], entt::entity{12});
diff --git a/test/entt/entity/view.cpp b/test/entt/entity/view.cpp
index 967140dd9..24914ba67 100644
--- a/test/entt/entity/view.cpp
+++ b/test/entt/entity/view.cpp
@@ -44,8 +44,11 @@ TEST(SingleComponentView, Functionalities) {
ASSERT_TRUE(cview.get(entity) == '1' || std::get(cview.get(entity)) == '2');
}
- ASSERT_EQ(*(view.data() + 0), e1);
- ASSERT_EQ(*(view.data() + 1), e0);
+ ASSERT_EQ(view.data()[0u], e1);
+ ASSERT_EQ(view.data()[1u], e0);
+
+ ASSERT_EQ(view.raw()[0u][0u], '2');
+ ASSERT_EQ(cview.raw()[0u][1u], '1');
registry.erase(e0);
registry.erase(e1);
@@ -61,7 +64,7 @@ TEST(SingleComponentView, Functionalities) {
ASSERT_FALSE(invalid);
}
-TEST(SingleComponentView, Data) {
+TEST(SingleComponentView, RawData) {
entt::registry registry;
auto view = registry.view();
auto cview = std::as_const(registry).view();
@@ -70,6 +73,8 @@ TEST(SingleComponentView, Data) {
ASSERT_EQ(view.size(), 0u);
ASSERT_EQ(cview.size(), 0u);
+ ASSERT_EQ(view.raw(), nullptr);
+ ASSERT_EQ(cview.raw(), nullptr);
ASSERT_EQ(view.data(), nullptr);
ASSERT_EQ(cview.data(), nullptr);
@@ -77,8 +82,10 @@ TEST(SingleComponentView, Data) {
ASSERT_NE(view.size(), 0u);
ASSERT_NE(cview.size(), 0u);
- ASSERT_EQ(*view.data(), entity);
- ASSERT_EQ(*cview.data(), entity);
+ ASSERT_EQ(view.raw()[0u][0u], 42);
+ ASSERT_EQ(cview.raw()[0u][0u], 42);
+ ASSERT_EQ(view.data()[0u], entity);
+ ASSERT_EQ(cview.data()[0u], entity);
registry.destroy(entity);
@@ -98,6 +105,7 @@ TEST(SingleComponentView, LazyTypeFromConstRegistry) {
ASSERT_TRUE(cview);
ASSERT_TRUE(eview);
+ ASSERT_NE(cview.raw(), nullptr);
ASSERT_NE(eview.data(), nullptr);
ASSERT_FALSE(cview.empty());
@@ -218,10 +226,15 @@ TEST(SingleComponentView, ConstNonConstAndAllInBetween) {
ASSERT_EQ(view.size(), 1u);
ASSERT_EQ(cview.size(), 1u);
+ static_assert(std::is_same_v);
+ static_assert(std::is_same_v);
+
static_assert(std::is_same_v({})), int &>);
static_assert(std::is_same_v>);
+ static_assert(std::is_same_v);
static_assert(std::is_same_v({})), const int &>);
static_assert(std::is_same_v>);
+ static_assert(std::is_same_v);
view.each([](auto &&i) {
static_assert(std::is_same_v);