Browse Source

view: public constructors and deduction guides

Michele Caini 5 years ago
parent
commit
b7ef1607dc
2 changed files with 48 additions and 16 deletions
  1. 29 16
      src/entt/entity/view.hpp
  2. 19 0
      test/entt/entity/view.cpp

+ 29 - 16
src/entt/entity/view.hpp

@@ -65,9 +65,6 @@ class basic_view;
  */
 template<typename Entity, typename... Exclude, typename... Component>
 class basic_view<Entity, exclude_t<Exclude...>, Component...> final {
-    /*! @brief A registry is allowed to create views. */
-    friend class basic_registry<Entity>;
-
     template<typename Comp>
     using storage_type = constness_as_t<typename storage_traits<Entity, std::remove_const_t<Comp>>::storage_type, Comp>;
 
@@ -222,12 +219,6 @@ class basic_view<Entity, exclude_t<Exclude...>, Component...> final {
         const basic_view view;
     };
 
-    basic_view(storage_type<Component> &... component, const storage_type<Exclude> &... epool) ENTT_NOEXCEPT
-        : pools{&component...},
-          filter{&epool...},
-          view{candidate()}
-    {}
-
     [[nodiscard]] const basic_sparse_set<Entity> * candidate() const ENTT_NOEXCEPT {
         return (std::min)({ static_cast<const basic_sparse_set<entity_type> *>(std::get<storage_type<Component> *>(pools))... }, [](const auto *lhs, const auto *rhs) {
             return lhs->size() < rhs->size();
@@ -293,6 +284,17 @@ public:
     /*! @brief Reverse iterator type. */
     using reverse_iterator = view_iterator<typename basic_sparse_set<entity_type>::reverse_iterator>;
 
+    /**
+     * @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(storage_type<Component> &... component, const storage_type<Exclude> &... epool) ENTT_NOEXCEPT
+        : pools{&component...},
+          filter{&epool...},
+          view{candidate()}
+    {}
+
     /**
      * @brief Forces the type to use to drive iterations.
      * @tparam Comp Type of component to use to drive the iteration.
@@ -555,9 +557,6 @@ private:
  */
 template<typename Entity, typename Component>
 class basic_view<Entity, exclude_t<>, Component> final {
-    /*! @brief A registry is allowed to create views. */
-    friend class basic_registry<Entity>;
-
     using storage_type = constness_as_t<typename storage_traits<Entity, std::remove_const_t<Component>>::storage_type, Component>;
 
     class iterable_view {
@@ -640,10 +639,6 @@ class basic_view<Entity, exclude_t<>, Component> final {
         storage_type *pool;
     };
 
-    basic_view(storage_type &ref) ENTT_NOEXCEPT
-        : pool{&ref}
-    {}
-
 public:
     /*! @brief Type of component iterated by the view. */
     using raw_type = Component;
@@ -656,6 +651,14 @@ public:
     /*! @brief Reversed iterator type. */
     using reverse_iterator = typename basic_sparse_set<Entity>::reverse_iterator;
 
+    /**
+     * @brief Constructs a single-type view from a storage class.
+     * @param ref The storage for the type to iterate.
+     */
+    basic_view(storage_type &ref) ENTT_NOEXCEPT
+        : pool{&ref}
+    {}
+
     /**
      * @brief Returns the number of entities that have the given component.
      * @return Number of entities that have the given component.
@@ -903,6 +906,16 @@ private:
 };
 
 
+/**
+ * @brief Deduction guide.
+ * @tparam Storage Type of storage classes used to create the view.
+ * @param storage The storage for the types to iterate.
+ */
+template<typename... Storage>
+basic_view(Storage &... storage) ENTT_NOEXCEPT
+-> basic_view<std::common_type_t<typename Storage::entity_type...>, entt::exclude_t<>, constness_as_t<typename Storage::value_type, Storage>...>;
+
+
 }
 
 

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

@@ -308,6 +308,14 @@ TEST(SingleComponentView, FrontBack) {
     ASSERT_EQ(view.back(), e0);
 }
 
+TEST(SingleComponentView, DeductionGuide) {
+    entt::registry registry;
+    typename entt::storage_traits<entt::entity, int>::storage_type storage;
+
+    static_assert(std::is_same_v<decltype(entt::basic_view{storage}), entt::basic_view<entt::entity, entt::exclude_t<>, int>>);
+    static_assert(std::is_same_v<decltype(entt::basic_view{std::as_const(storage)}), entt::basic_view<entt::entity, entt::exclude_t<>, const int>>);
+}
+
 TEST(MultiComponentView, Functionalities) {
     entt::registry registry;
     auto view = registry.view<int, char>();
@@ -780,3 +788,14 @@ TEST(MultiComponentView, ExtendedGet) {
     static_assert(std::is_same_v<std::tuple_element_t<0, type>, int &>);
     static_assert(std::is_same_v<std::tuple_element_t<1, type>, char &>);
 }
+
+TEST(MultiComponentView, DeductionGuide) {
+    entt::registry registry;
+    typename entt::storage_traits<entt::entity, int>::storage_type istorage;
+    typename entt::storage_traits<entt::entity, double>::storage_type dstorage;
+
+    static_assert(std::is_same_v<decltype(entt::basic_view{istorage, dstorage}), entt::basic_view<entt::entity, entt::exclude_t<>, int, double>>);
+    static_assert(std::is_same_v<decltype(entt::basic_view{std::as_const(istorage), dstorage}), entt::basic_view<entt::entity, entt::exclude_t<>, const int, double>>);
+    static_assert(std::is_same_v<decltype(entt::basic_view{istorage, std::as_const(dstorage)}), entt::basic_view<entt::entity, entt::exclude_t<>, int, const double>>);
+    static_assert(std::is_same_v<decltype(entt::basic_view{std::as_const(istorage), std::as_const(dstorage)}), entt::basic_view<entt::entity, entt::exclude_t<>, const int, const double>>);
+}