Browse Source

view: path towards further reducing istantiations

Michele Caini 1 year ago
parent
commit
c9e48c0a14
1 changed files with 26 additions and 33 deletions
  1. 26 33
      src/entt/entity/view.hpp

+ 26 - 33
src/entt/entity/view.hpp

@@ -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;
         }
     }