view: path towards further reducing istantiations

This commit is contained in:
Michele Caini
2024-06-13 15:43:17 +02:00
parent f931687ff0
commit c9e48c0a14

View File

@@ -41,8 +41,7 @@ template<typename Result, typename View, typename Other, std::size_t... VGet, st
[[nodiscard]] Result view_pack(const View &view, const Other &other, std::index_sequence<VGet...>, std::index_sequence<VExclude...>, std::index_sequence<OGet...>, std::index_sequence<OExclude...>) {
Result elem{};
// friend-initialization, avoid multiple calls to refresh
elem.pools = {view.template storage<VGet>()..., other.template storage<OGet>()...};
elem.filter = {view.template storage<sizeof...(VGet) + VExclude>()..., other.template storage<sizeof...(OGet) + OExclude>()...};
elem.pools = {view.template storage<VGet>()..., other.template storage<OGet>()..., view.template storage<sizeof...(VGet) + VExclude>()..., other.template storage<sizeof...(OGet) + OExclude>()...};
elem.refresh();
return elem;
}
@@ -50,15 +49,15 @@ template<typename Result, typename View, typename Other, std::size_t... VGet, st
template<typename Type, std::size_t Get, std::size_t Exclude>
class view_iterator final {
template<typename, typename...>
friend struct extended_view_iterator;
friend class extended_view_iterator;
using iterator_type = typename Type::const_iterator;
using iterator_traits = std::iterator_traits<iterator_type>;
[[nodiscard]] bool valid(const typename iterator_traits::value_type entt) const noexcept {
return ((Get != 1u) || (entt != tombstone))
&& internal::all_of(pools.begin(), pools.begin() + index, entt) && internal::all_of(pools.begin() + index + 1, pools.end(), entt)
&& internal::none_of(filter.begin(), filter.end(), entt);
&& internal::all_of(pools.begin(), pools.begin() + index, entt) && internal::all_of(pools.begin() + index + 1, pools.begin() + Get, entt)
&& internal::none_of(pools.begin() + Get, pools.end(), entt);
}
public:
@@ -72,14 +71,12 @@ public:
: it{},
last{},
pools{},
filter{},
index{} {}
view_iterator(iterator_type first, std::array<const Type *, Get> value, std::array<const Type *, Exclude> excl, const std::size_t idx) noexcept
view_iterator(iterator_type first, std::array<const Type *, Get + Exclude> value, const std::size_t idx) noexcept
: it{first},
last{value[idx]->end()},
pools{value},
filter{excl},
index{idx} {
while(it != last && !valid(*it)) {
++it;
@@ -110,8 +107,7 @@ public:
private:
iterator_type it;
iterator_type last;
std::array<const Type *, Get> pools;
std::array<const Type *, Exclude> filter;
std::array<const Type *, Get + Exclude> pools;
std::size_t index;
};
@@ -126,7 +122,13 @@ template<typename LhsType, auto... LhsArgs, typename RhsType, auto... RhsArgs>
}
template<typename It, typename... Type>
struct extended_view_iterator final {
class extended_view_iterator final {
template<std::size_t... Index>
auto dereference(std::index_sequence<Index...>) const noexcept {
return std::tuple_cat(std::make_tuple(*it), static_cast<Type *>(const_cast<constness_as_t<typename Type::base_type, Type> *>(std::get<Index>(it.pools)))->get_as_tuple(*it)...);
}
public:
using iterator_type = It;
using value_type = decltype(std::tuple_cat(std::make_tuple(*std::declval<It>()), std::declval<Type>().get_as_tuple({})...));
using pointer = input_iterator_pointer<value_type>;
@@ -151,7 +153,7 @@ struct extended_view_iterator final {
}
[[nodiscard]] reference operator*() const noexcept {
return std::apply([entt = *it](auto *...curr) { return std::tuple_cat(std::make_tuple(entt), static_cast<Type *>(const_cast<constness_as_t<typename Type::base_type, Type> *>(curr))->get_as_tuple(entt)...); }, it.pools);
return dereference(std::index_sequence_for<Type...>{});
}
[[nodiscard]] pointer operator->() const noexcept {
@@ -238,9 +240,8 @@ protected:
/*! @cond TURN_OFF_DOXYGEN */
basic_common_view() noexcept = default;
basic_common_view(std::array<const Type *, Get> value, std::array<const Type *, Exclude> excl) noexcept
basic_common_view(std::array<const Type *, Get + Exclude> value) noexcept
: pools{value},
filter{excl},
index{Get} {
unchecked_refresh();
}
@@ -294,7 +295,7 @@ public:
* @return An iterator to the first entity of the view.
*/
[[nodiscard]] iterator begin() const noexcept {
return (index != Get) ? iterator{pools[index]->end() - static_cast<typename iterator::difference_type>(offset()), pools, filter, index} : iterator{};
return (index != Get) ? iterator{pools[index]->end() - static_cast<typename iterator::difference_type>(offset()), pools, index} : iterator{};
}
/**
@@ -302,7 +303,7 @@ public:
* @return An iterator to the entity following the last entity of the view.
*/
[[nodiscard]] iterator end() const noexcept {
return (index != Get) ? iterator{pools[index]->end(), pools, filter, index} : iterator{};
return (index != Get) ? iterator{pools[index]->end(), pools, index} : iterator{};
}
/**
@@ -338,7 +339,7 @@ public:
* iterator otherwise.
*/
[[nodiscard]] iterator find(const entity_type entt) const noexcept {
return contains(entt) ? iterator{pools[index]->find(entt), pools, filter, index} : end();
return contains(entt) ? iterator{pools[index]->find(entt), pools, index} : end();
}
/**
@@ -346,7 +347,7 @@ public:
* @return True if the view is fully initialized, false otherwise.
*/
[[nodiscard]] explicit operator bool() const noexcept {
return (index != Get) && internal::fully_initialized(filter.begin(), filter.end());
return (index != Get) && internal::fully_initialized(pools.begin() + Get, pools.end());
}
/**
@@ -356,15 +357,14 @@ public:
*/
[[nodiscard]] bool contains(const entity_type entt) const noexcept {
return (index != Get)
&& internal::all_of(pools.begin(), pools.end(), entt)
&& internal::none_of(filter.begin(), filter.end(), entt)
&& internal::all_of(pools.begin(), pools.begin() + Get, entt)
&& internal::none_of(pools.begin() + Get, pools.end(), entt)
&& pools[index]->index(entt) < offset();
}
protected:
/*! @cond TURN_OFF_DOXYGEN */
std::array<const common_type *, Get> pools{};
std::array<const common_type *, Exclude> filter{};
std::array<const common_type *, Get + Exclude> pools{};
size_type index{Get};
/*! @endcond */
};
@@ -407,7 +407,7 @@ class basic_view<get_t<Get...>, exclude_t<Exclude...>>: public basic_common_view
template<std::size_t Curr, typename Func, std::size_t... Index>
void each(Func &func, std::index_sequence<Index...>) const {
for(const auto curr: storage<Curr>()->each()) {
if(const auto entt = std::get<0>(curr); (!tombstone_check_required || (entt != tombstone)) && ((Curr == Index || this->pools[Index]->contains(entt)) && ...) && internal::none_of(this->filter.begin(), this->filter.end(), entt)) {
if(const auto entt = std::get<0>(curr); (!tombstone_check_required || (entt != tombstone)) && ((Curr == Index || this->pools[Index]->contains(entt)) && ...) && internal::none_of(this->pools.begin() + sizeof...(Get), this->pools.end(), entt)) {
if constexpr(is_applicable_v<Func, decltype(std::tuple_cat(std::tuple<entity_type>{}, std::declval<basic_view>().get({})))>) {
std::apply(func, std::tuple_cat(std::make_tuple(entt), dispatch_get<Curr, Index>(curr)...));
} else {
@@ -444,7 +444,7 @@ public:
* @param excl The storage for the types used to filter the view.
*/
basic_view(Get &...value, Exclude &...excl) noexcept
: base_type{{&value...}, {&excl...}} {
: base_type{{&value..., &excl...}} {
}
/**
@@ -491,12 +491,7 @@ public:
template<std::size_t Index>
[[nodiscard]] auto *storage() const noexcept {
using type = type_list_element_t<Index, type_list<Get..., Exclude...>>;
if constexpr(Index < sizeof...(Get)) {
return static_cast<type *>(const_cast<constness_as_t<common_type, type> *>(this->pools[Index]));
} else {
return static_cast<type *>(const_cast<constness_as_t<common_type, type> *>(this->filter[Index - sizeof...(Get)]));
}
return static_cast<type *>(const_cast<constness_as_t<common_type, type> *>(this->pools[Index]));
}
/**
@@ -518,12 +513,10 @@ public:
template<std::size_t Index, typename Type>
void storage(Type &elem) noexcept {
static_assert(std::is_convertible_v<Type &, type_list_element_t<Index, type_list<Get..., Exclude...>> &>, "Unexpected type");
this->pools[Index] = &elem;
if constexpr(Index < sizeof...(Get)) {
this->pools[Index] = &elem;
base_type::refresh();
} else {
this->filter[Index - sizeof...(Get)] = &elem;
}
}