view: tuple constructor

This commit is contained in:
Michele Caini
2022-04-30 11:56:04 +02:00
parent 12cf3fd8e7
commit 8d86816d8d
3 changed files with 59 additions and 14 deletions

View File

@@ -221,8 +221,8 @@ class basic_registry {
using entity_traits = entt_traits<Entity>;
using basic_common_type = basic_sparse_set<Entity>;
template<typename Component>
using storage_type = typename storage_traits<Entity, Component>::storage_type;
template<typename Comp>
using storage_type = constness_as_t<typename storage_traits<Entity, std::remove_const_t<Comp>>::storage_type, Comp>;
template<typename...>
struct group_handler;
@@ -1220,14 +1220,20 @@ public:
* @return A newly created view.
*/
template<typename Component, typename... Other, typename... Exclude>
[[nodiscard]] basic_view<entity_type, get_t<const Component, const Other...>, exclude_t<const Exclude...>> view(exclude_t<Exclude...> = {}) const {
return {assure<std::remove_const_t<Component>>(), assure<std::remove_const_t<Other>>()..., assure<std::remove_const_t<Exclude>>()...};
[[nodiscard]] auto view(exclude_t<Exclude...> = {}) const {
return basic_view{std::forward_as_tuple(
assure<std::remove_const_t<Component>>(),
assure<std::remove_const_t<Other>>()...),
std::forward_as_tuple(assure<std::remove_const_t<Exclude>>()...)};
}
/*! @copydoc view */
template<typename Component, typename... Other, typename... Exclude>
[[nodiscard]] basic_view<entity_type, get_t<Component, Other...>, exclude_t<Exclude...>> view(exclude_t<Exclude...> = {}) {
return {assure<std::remove_const_t<Component>>(), assure<std::remove_const_t<Other>>()..., assure<std::remove_const_t<Exclude>>()...};
[[nodiscard]] auto view(exclude_t<Exclude...> = {}) {
return basic_view{std::forward_as_tuple(
static_cast<storage_type<Component> &>(assure<std::remove_const_t<Component>>()),
static_cast<storage_type<Other> &>(assure<std::remove_const_t<Other>>())...),
std::forward_as_tuple(static_cast<storage_type<Exclude> &>(assure<std::remove_const_t<Exclude>>())...)};
}
/**

View File

@@ -255,9 +255,17 @@ public:
* @param epool The storage for the types used to filter the view.
*/
basic_view(storage_type<Component> &...component, storage_type<Exclude> &...epool) ENTT_NOEXCEPT
: pools{&component...},
filter{&epool...},
view{(std::min)({&static_cast<const base_type &>(component)...}, [](auto *lhs, auto *rhs) { return lhs->size() < rhs->size(); })} {}
: basic_view{std::forward_as_tuple(component...), std::forward_as_tuple(epool...)} {}
/**
* @brief Constructs a multi-type view from a set of storage classes.
* @param component The storage for the types to iterate.
* @param epool The storage for the types used to filter the view.
*/
basic_view(std::tuple<storage_type<Component> &...> component, std::tuple<storage_type<Exclude> &...> epool = {}) ENTT_NOEXCEPT
: pools{std::apply([](auto &...curr) { return std::make_tuple(&curr...); }, component)},
filter{std::apply([](auto &...curr) { return std::make_tuple(&curr...); }, epool)},
view{std::apply([](const auto &...curr) { return (std::min)({&static_cast<const base_type &>(curr)...}, [](auto *lhs, auto *rhs) { return lhs->size() < rhs->size(); }); }, component)} {}
/**
* @brief Creates a new view driven by a given component in its iterations.
@@ -558,9 +566,16 @@ public:
* @param ref The storage for the type to iterate.
*/
basic_view(storage_type &ref) ENTT_NOEXCEPT
: pools{&ref},
: basic_view{std::forward_as_tuple(ref)} {}
/**
* @brief Constructs a single-type view from a storage class.
* @param ref The storage for the type to iterate.
*/
basic_view(std::tuple<storage_type &> ref, std::tuple<> = {}) ENTT_NOEXCEPT
: pools{&std::get<0>(ref)},
filter{},
view{&ref} {}
view{&std::get<0>(ref)} {}
/**
* @brief Returns the leading storage of a view.
@@ -831,6 +846,14 @@ private:
template<typename... Type>
basic_view(Type &...storage) -> basic_view<std::common_type_t<typename Type::entity_type...>, get_t<constness_as_t<typename Type::value_type, Type>...>, exclude_t<>>;
/**
* @brief Deduction guide.
* @tparam Component Types of components iterated by the view.
* @tparam Exclude Types of components used to filter the view.
*/
template<typename... Component, typename... Exclude>
basic_view(std::tuple<Component &...>, std::tuple<Exclude &...> = {}) -> basic_view<std::common_type_t<typename Component::entity_type..., typename Exclude::entity_type...>, get_t<constness_as_t<typename Component::value_type, Component>...>, exclude_t<constness_as_t<typename Exclude::value_type, Exclude>...>>;
} // namespace entt
#endif

View File

@@ -382,6 +382,10 @@ TEST(SingleComponentView, DeductionGuide) {
static_assert(std::is_same_v<entt::basic_view<entt::entity, entt::get_t<int>, entt::exclude_t<>>, decltype(entt::basic_view{istorage})>);
static_assert(std::is_same_v<entt::basic_view<entt::entity, entt::get_t<const int>, entt::exclude_t<>>, decltype(entt::basic_view{std::as_const(istorage)})>);
static_assert(std::is_same_v<entt::basic_view<entt::entity, entt::get_t<stable_type>, entt::exclude_t<>>, decltype(entt::basic_view{sstorage})>);
static_assert(std::is_same_v<entt::basic_view<entt::entity, entt::get_t<int>, entt::exclude_t<>>, decltype(entt::basic_view{std::forward_as_tuple(istorage), std::make_tuple()})>);
static_assert(std::is_same_v<entt::basic_view<entt::entity, entt::get_t<const int>, entt::exclude_t<>>, decltype(entt::basic_view{std::forward_as_tuple(std::as_const(istorage))})>);
static_assert(std::is_same_v<entt::basic_view<entt::entity, entt::get_t<stable_type>, entt::exclude_t<>>, decltype(entt::basic_view{std::forward_as_tuple(sstorage)})>);
}
TEST(SingleComponentView, IterableViewAlgorithmCompatibility) {
@@ -1036,6 +1040,18 @@ TEST(MultiComponentView, DeductionGuide) {
static_assert(std::is_same_v<entt::basic_view<entt::entity, entt::get_t<int, const double>, entt::exclude_t<>>, decltype(entt::basic_view{istorage, std::as_const(dstorage)})>);
static_assert(std::is_same_v<entt::basic_view<entt::entity, entt::get_t<const int, const double>, entt::exclude_t<>>, decltype(entt::basic_view{std::as_const(istorage), std::as_const(dstorage)})>);
static_assert(std::is_same_v<entt::basic_view<entt::entity, entt::get_t<int, stable_type>, entt::exclude_t<>>, decltype(entt::basic_view{istorage, sstorage})>);
static_assert(std::is_same_v<entt::basic_view<entt::entity, entt::get_t<int, double>, entt::exclude_t<>>, decltype(entt::basic_view{std::forward_as_tuple(istorage, dstorage), std::make_tuple()})>);
static_assert(std::is_same_v<entt::basic_view<entt::entity, entt::get_t<const int, double>, entt::exclude_t<>>, decltype(entt::basic_view{std::forward_as_tuple(std::as_const(istorage), dstorage)})>);
static_assert(std::is_same_v<entt::basic_view<entt::entity, entt::get_t<int, const double>, entt::exclude_t<>>, decltype(entt::basic_view{std::forward_as_tuple(istorage, std::as_const(dstorage))})>);
static_assert(std::is_same_v<entt::basic_view<entt::entity, entt::get_t<const int, const double>, entt::exclude_t<>>, decltype(entt::basic_view{std::forward_as_tuple(std::as_const(istorage), std::as_const(dstorage))})>);
static_assert(std::is_same_v<entt::basic_view<entt::entity, entt::get_t<int, stable_type>, entt::exclude_t<>>, decltype(entt::basic_view{std::forward_as_tuple(istorage, sstorage)})>);
static_assert(std::is_same_v<entt::basic_view<entt::entity, entt::get_t<int>, entt::exclude_t<double>>, decltype(entt::basic_view{std::forward_as_tuple(istorage), std::forward_as_tuple(dstorage)})>);
static_assert(std::is_same_v<entt::basic_view<entt::entity, entt::get_t<const int>, entt::exclude_t<double>>, decltype(entt::basic_view{std::forward_as_tuple(std::as_const(istorage)), std::forward_as_tuple(dstorage)})>);
static_assert(std::is_same_v<entt::basic_view<entt::entity, entt::get_t<int>, entt::exclude_t<const double>>, decltype(entt::basic_view{std::forward_as_tuple(istorage), std::forward_as_tuple(std::as_const(dstorage))})>);
static_assert(std::is_same_v<entt::basic_view<entt::entity, entt::get_t<const int>, entt::exclude_t<const double>>, decltype(entt::basic_view{std::forward_as_tuple(std::as_const(istorage)), std::forward_as_tuple(std::as_const(dstorage))})>);
static_assert(std::is_same_v<entt::basic_view<entt::entity, entt::get_t<int>, entt::exclude_t<stable_type>>, decltype(entt::basic_view{std::forward_as_tuple(istorage), std::forward_as_tuple(sstorage)})>);
}
TEST(MultiComponentView, IterableViewAlgorithmCompatibility) {
@@ -1197,13 +1213,13 @@ TEST(View, Pipe) {
registry.emplace<char>(other);
registry.emplace<stable_type>(other);
const auto view1 = registry.view<int>(entt::exclude<double>);
const auto view1 = registry.view<int>(entt::exclude<const double>);
const auto view2 = registry.view<const char>(entt::exclude<float>);
const auto view3 = registry.view<empty_type>();
const auto view4 = registry.view<stable_type>();
static_assert(std::is_same_v<entt::basic_view<entt::entity, entt::get_t<int, const char>, entt::exclude_t<double, float>>, decltype(view1 | view2)>);
static_assert(std::is_same_v<entt::basic_view<entt::entity, entt::get_t<const char, int>, entt::exclude_t<float, double>>, decltype(view2 | view1)>);
static_assert(std::is_same_v<entt::basic_view<entt::entity, entt::get_t<int, const char>, entt::exclude_t<const double, float>>, decltype(view1 | view2)>);
static_assert(std::is_same_v<entt::basic_view<entt::entity, entt::get_t<const char, int>, entt::exclude_t<float, const double>>, decltype(view2 | view1)>);
static_assert(std::is_same_v<decltype((view3 | view2) | view1), decltype(view3 | (view2 | view1))>);
ASSERT_FALSE((view1 | view2).contains(entity));