Parcourir la source

view: tuple constructor

Michele Caini il y a 3 ans
Parent
commit
8d86816d8d
3 fichiers modifiés avec 59 ajouts et 14 suppressions
  1. 12 6
      src/entt/entity/registry.hpp
  2. 28 5
      src/entt/entity/view.hpp
  3. 19 3
      test/entt/entity/view.cpp

+ 12 - 6
src/entt/entity/registry.hpp

@@ -221,8 +221,8 @@ class basic_registry {
     using entity_traits = entt_traits<Entity>;
     using entity_traits = entt_traits<Entity>;
     using basic_common_type = basic_sparse_set<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...>
     template<typename...>
     struct group_handler;
     struct group_handler;
@@ -1220,14 +1220,20 @@ public:
      * @return A newly created view.
      * @return A newly created view.
      */
      */
     template<typename Component, typename... Other, typename... Exclude>
     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 */
     /*! @copydoc view */
     template<typename Component, typename... Other, typename... Exclude>
     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>>())...)};
     }
     }
 
 
     /**
     /**

+ 28 - 5
src/entt/entity/view.hpp

@@ -255,9 +255,17 @@ public:
      * @param epool The storage for the types used to filter the view.
      * @param epool The storage for the types used to filter the view.
      */
      */
     basic_view(storage_type<Component> &...component, storage_type<Exclude> &...epool) ENTT_NOEXCEPT
     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.
      * @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.
      * @param ref The storage for the type to iterate.
      */
      */
     basic_view(storage_type &ref) ENTT_NOEXCEPT
     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{},
           filter{},
-          view{&ref} {}
+          view{&std::get<0>(ref)} {}
 
 
     /**
     /**
      * @brief Returns the leading storage of a view.
      * @brief Returns the leading storage of a view.
@@ -831,6 +846,14 @@ private:
 template<typename... Type>
 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<>>;
 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
 } // namespace entt
 
 
 #endif
 #endif

+ 19 - 3
test/entt/entity/view.cpp

@@ -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<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<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<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) {
 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<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<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, 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) {
 TEST(MultiComponentView, IterableViewAlgorithmCompatibility) {
@@ -1197,13 +1213,13 @@ TEST(View, Pipe) {
     registry.emplace<char>(other);
     registry.emplace<char>(other);
     registry.emplace<stable_type>(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 view2 = registry.view<const char>(entt::exclude<float>);
     const auto view3 = registry.view<empty_type>();
     const auto view3 = registry.view<empty_type>();
     const auto view4 = registry.view<stable_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))>);
     static_assert(std::is_same_v<decltype((view3 | view2) | view1), decltype(view3 | (view2 | view1))>);
 
 
     ASSERT_FALSE((view1 | view2).contains(entity));
     ASSERT_FALSE((view1 | view2).contains(entity));