Browse Source

removed raw view + added extended each member function to all the other views

Michele Caini 7 years ago
parent
commit
c91f9beddb

+ 7 - 69
docs/entity.md

@@ -30,7 +30,6 @@
     * [Single component standard view](#single-component-standard-view)
     * [Single component standard view](#single-component-standard-view)
     * [Multi component standard view](#multi-component-standard-view)
     * [Multi component standard view](#multi-component-standard-view)
   * [Persistent View](#persistent-view)
   * [Persistent View](#persistent-view)
-  * [Raw View](#raw-view)
   * [Runtime View](#runtime-view)
   * [Runtime View](#runtime-view)
   * [Types: const, non-const and all in between](#types-const-non-const-and-all-in-between)
   * [Types: const, non-const and all in between](#types-const-non-const-and-all-in-between)
   * [Give me everything](#give-me-everything)
   * [Give me everything](#give-me-everything)
@@ -810,9 +809,9 @@ view can only iterate entities and their components, then read or update the
 data members of the latter.<br/>
 data members of the latter.<br/>
 It is a subtle difference that can help designing a better software sometimes.
 It is a subtle difference that can help designing a better software sometimes.
 
 
-There are mainly four kinds of views: standard (also known as `view`),
-persistent (also known as `persistent_view`), raw (also known as `raw_view`) and
-runtime (also known as `runtime_view`).<br/>
+There are mainly three kinds of views: standard (also known as `view`),
+persistent (also known as `persistent_view`), and runtime (also known as
+`runtime_view`).<br/>
 All of them have pros and cons to take in consideration. In particular:
 All of them have pros and cons to take in consideration. In particular:
 
 
 * Standard views:
 * Standard views:
@@ -854,22 +853,6 @@ All of them have pros and cons to take in consideration. In particular:
     persistent views there will be, the less performing will be creating and
     persistent views there will be, the less performing will be creating and
     destroying entities and components or sorting a pool.
     destroying entities and components or sorting a pool.
 
 
-* Raw views:
-
-  Pros:
-
-  * They work out-of-the-box and don't require any dedicated data structure.
-  * Creating and destroying them isn't expensive at all because they don't have
-    any type of initialization.
-  * They are the best tool for iterating components when it is not necessary to
-    know which entities they belong to.
-  * They don't affect any other operations of the registry.
-
-  Cons:
-
-  * They can be used to iterate only one type of component at a time.
-  * They don't return the entity to which a component belongs to the caller.
-
 * Runtime views:
 * Runtime views:
 
 
   Pros:
   Pros:
@@ -887,7 +870,6 @@ All of them have pros and cons to take in consideration. In particular:
 
 
 To sum up and as a rule of thumb:
 To sum up and as a rule of thumb:
 
 
-* Use a raw view to iterate components only (no entities) for a given type.
 * Use a standard view to iterate entities and components for a single type.
 * Use a standard view to iterate entities and components for a single type.
 * Use a standard view to iterate entities and components for multiple types when
 * Use a standard view to iterate entities and components for multiple types when
   a significantly low number of entities have one of the components, persistent
   a significantly low number of entities have one of the components, persistent
@@ -1096,48 +1078,6 @@ only entities, using `each` should be the preferred approach.
 function template of a registry during iterations, if possible. However, keep in
 function template of a registry during iterations, if possible. However, keep in
 mind that it works only with the components of the view itself.
 mind that it works only with the components of the view itself.
 
 
-## Raw View
-
-Raw views return all the components of a given type. This kind of views can
-access components directly and avoid extra indirections like when components are
-accessed via an entity identifier.<br/>
-They offer a bunch of functionalities to get the number of instances they are
-going to return and a raw access to the entity list as well as to the component
-list.<br/>
-Refer to the inline documentation for all the details.
-
-Raw views can be used only to iterate components for a single type:
-
-```cpp
-auto view = registry.raw_view<renderable>();
-```
-
-There is no need to store views around for they are extremely cheap to
-construct, even though they can be copied without problems and reused freely. In
-fact, they return newly created and correctly initialized iterators whenever
-`begin` or `end` are invoked.<br/>
-To iterate a raw view, use it in a range-for loop:
-
-```cpp
-auto view = registry.raw_view<renderable>();
-
-for(auto &&component: raw) {
-    // ...
-}
-```
-
-Or rely on the `each` member function:
-
-```cpp
-registry.raw_view<renderable>().each([](auto &renderable) {
-    // ...
-});
-```
-
-Performance are exactly the same in both cases.
-
-**Note**: raw views don't have a `get` member function for obvious reasons.
-
 ## Runtime View
 ## Runtime View
 
 
 Runtime views iterate entities that have at least all the given components in
 Runtime views iterate entities that have at least all the given components in
@@ -1334,13 +1274,11 @@ assigned.
 
 
 The drawback is that the `raw` member function will no longer be able to return
 The drawback is that the `raw` member function will no longer be able to return
 a valid pointer to the list of components in the pool. This is because there is
 a valid pointer to the list of components in the pool. This is because there is
-no list of components at all. Therefore, `raw` will always return `nullptr` for
-this type of components.<br/>
+no list of components at all. Only one instance of the given type exists in this
+case. Therefore, `raw` will always return a pointer to that instance.<br/>
 Nonetheless, the iterators returned by the `begin` and `end` member functions
 Nonetheless, the iterators returned by the `begin` and `end` member functions
-are still valid and can be used safely. Similarly, raw views can still be built
-for this type of components if required.<br/>
-More in general, all the features offered by the library aren't affected, but
-for the `raw` member function that is no longer available instead.
+are still valid and can be used safely. More in general, all the features
+offered by the library aren't affected, but for the `raw` member function.
 
 
 # Multithreading
 # Multithreading
 
 

+ 0 - 10
src/entt/entity/helper.hpp

@@ -47,16 +47,6 @@ struct as_view final {
         return reg.template persistent_view<Component...>();
         return reg.template persistent_view<Component...>();
     }
     }
 
 
-    /**
-     * @brief Conversion function from a registry to a raw view.
-     * @tparam Component Type of component used to construct the view.
-     * @return A newly created raw view.
-     */
-    template<typename Component>
-    inline operator entt::raw_view<Entity, Component>() const {
-        return reg.template raw_view<Component>();
-    }
-
 private:
 private:
     registry_type &reg;
     registry_type &reg;
 };
 };

+ 0 - 39
src/entt/entity/registry.hpp

@@ -1124,7 +1124,6 @@ public:
      * @sa view
      * @sa view
      * @sa view<Entity, Component>
      * @sa view<Entity, Component>
      * @sa persistent_view
      * @sa persistent_view
-     * @sa raw_view
      * @sa runtime_view
      * @sa runtime_view
      *
      *
      * @tparam Component Type of components used to construct the view.
      * @tparam Component Type of components used to construct the view.
@@ -1174,7 +1173,6 @@ public:
      * @sa view
      * @sa view
      * @sa view<Entity, Component>
      * @sa view<Entity, Component>
      * @sa persistent_view
      * @sa persistent_view
-     * @sa raw_view
      * @sa runtime_view
      * @sa runtime_view
      *
      *
      * @tparam Component Types of components used to construct the view.
      * @tparam Component Types of components used to construct the view.
@@ -1222,42 +1220,6 @@ public:
         return const_cast<registry *>(this)->persistent_view<Component...>(type_list<Exclude...>{});
         return const_cast<registry *>(this)->persistent_view<Component...>(type_list<Exclude...>{});
     }
     }
 
 
-    /**
-     * @brief Returns a raw view for the given component.
-     *
-     * This kind of views are created on the fly and share with the registry its
-     * internal data structures.<br/>
-     * Feel free to discard a view after the use. Creating and destroying a view
-     * is an incredibly cheap operation because they do not require any type of
-     * initialization.<br/>
-     * As a rule of thumb, storing a view should never be an option.
-     *
-     * Raw views are incredibly fast and must be considered the best tool to
-     * iterate components whenever knowing the entities to which they belong
-     * isn't required.
-     *
-     * @sa view
-     * @sa view<Entity, Component>
-     * @sa persistent_view
-     * @sa raw_view
-     * @sa runtime_view
-     *
-     * @tparam Component Type of component used to construct the view.
-     * @return A newly created raw view.
-     */
-    template<typename Component>
-    entt::raw_view<Entity, Component> raw_view() {
-        assure<Component>();
-        return { &pool<Component>() };
-    }
-
-    /*! @copydoc raw_view */
-    template<typename Component>
-    inline entt::raw_view<Entity, Component> raw_view() const {
-        static_assert(std::is_const_v<Component>);
-        return const_cast<registry *>(this)->raw_view<Component>();
-    }
-
     /**
     /**
      * @brief Returns a runtime view for the given components.
      * @brief Returns a runtime view for the given components.
      *
      *
@@ -1276,7 +1238,6 @@ public:
      * @sa view
      * @sa view
      * @sa view<Entity, Component>
      * @sa view<Entity, Component>
      * @sa persistent_view
      * @sa persistent_view
-     * @sa raw_view
      * @sa runtime_view
      * @sa runtime_view
      *
      *
      * @tparam It Type of forward iterator.
      * @tparam It Type of forward iterator.

+ 4 - 3
src/entt/entity/sparse_set.hpp

@@ -774,14 +774,15 @@ public:
      * to iterate the sparse set in the expected order.
      * to iterate the sparse set in the expected order.
      *
      *
      * @warning
      * @warning
-     * Empty components aren't explicitly instantiated. Therefore, this function
-     * always returns `nullptr` for them.
+     * Empty components aren't explicitly instantiated. Only one instance of the
+     * given type is created. Therefore, this function always returns a pointer
+     * to that instance.
      *
      *
      * @return A pointer to the array of objects.
      * @return A pointer to the array of objects.
      */
      */
     const object_type * raw() const ENTT_NOEXCEPT {
     const object_type * raw() const ENTT_NOEXCEPT {
         if constexpr(std::is_empty_v<object_type>) {
         if constexpr(std::is_empty_v<object_type>) {
-            return nullptr;
+            return &instances;
         } else {
         } else {
             return instances.data();
             return instances.data();
         }
         }

+ 48 - 215
src/entt/entity/view.hpp

@@ -62,7 +62,6 @@ class registry;
  *
  *
  * @sa view
  * @sa view
  * @sa view<Entity, Component>
  * @sa view<Entity, Component>
- * @sa raw_view
  * @sa runtime_view
  * @sa runtime_view
  *
  *
  * @tparam Entity A valid entity type (see entt_traits for more details).
  * @tparam Entity A valid entity type (see entt_traits for more details).
@@ -101,10 +100,9 @@ class persistent_view final {
     }
     }
 
 
     template<typename Comp>
     template<typename Comp>
-    inline decltype(auto) get([[maybe_unused]] typename persistent_type::object_type::value_type index, [[maybe_unused]] const Entity entity) const {
+    inline decltype(auto) instance([[maybe_unused]] typename persistent_type::object_type::value_type index) const {
         if constexpr(std::is_empty_v<Comp>) {
         if constexpr(std::is_empty_v<Comp>) {
-            // raw returns nullptr for empty components
-            return pool<Comp>()->get(entity);
+            return *pool<Comp>()->raw();
         } else {
         } else {
             return pool<Comp>()->raw()[index];
             return pool<Comp>()->raw()[index];
         }
         }
@@ -112,10 +110,17 @@ class persistent_view final {
 
 
     template<typename Func, std::size_t... Indexes>
     template<typename Func, std::size_t... Indexes>
     void each(Func func, std::index_sequence<Indexes...>) const {
     void each(Func func, std::index_sequence<Indexes...>) const {
-        std::for_each(handler->view_type::begin(), handler->view_type::end(), [func = std::move(func), raw = handler->cbegin(), this](const auto entity) mutable {
-            func(entity, get<Component>((*raw)[Indexes], entity)...);
-            ++raw;
-        });
+        if constexpr(std::is_invocable_v<Func, std::add_lvalue_reference_t<Component>...>) {
+            std::for_each(handler->cbegin(), handler->cend(), [func = std::move(func), this](const auto &indexes) mutable {
+                // we can safely use the first entity each and every time, b
+                func(instance<Component>(indexes[Indexes])...);
+            });
+        } else {
+            std::for_each(handler->view_type::begin(), handler->view_type::end(), [func = std::move(func), raw = handler->cbegin(), this](const auto entity) mutable {
+                func(entity, instance<Component>((*raw)[Indexes])...);
+                ++raw;
+            });
+        }
     }
     }
 
 
 public:
 public:
@@ -268,12 +273,14 @@ public:
      * object to them.
      * object to them.
      *
      *
      * The function object is invoked for each entity. It is provided with the
      * The function object is invoked for each entity. It is provided with the
-     * entity itself and a set of const references to all the components of the
-     * view.<br/>
-     * The signature of the function should be equivalent to the following:
+     * entity itself and a set of references to all its components. The
+     * _constness_ of the components is as requested.<br/>
+     * The signature of the function must be equivalent to one of the following
+     * forms:
      *
      *
      * @code{.cpp}
      * @code{.cpp}
      * void(const entity_type, Component &...);
      * void(const entity_type, Component &...);
+     * void(Component &...);
      * @endcode
      * @endcode
      *
      *
      * @tparam Func Type of the function object to invoke.
      * @tparam Func Type of the function object to invoke.
@@ -346,7 +353,6 @@ private:
  *
  *
  * @sa view<Entity, Component>
  * @sa view<Entity, Component>
  * @sa persistent_view
  * @sa persistent_view
- * @sa raw_view
  * @sa runtime_view
  * @sa runtime_view
  *
  *
  * @tparam Entity A valid entity type (see entt_traits for more details).
  * @tparam Entity A valid entity type (see entt_traits for more details).
@@ -488,8 +494,14 @@ class view final {
         auto begin = cpool->view_type::begin();
         auto begin = cpool->view_type::begin();
 
 
         // we can directly use the raw iterators if pools are ordered
         // we can directly use the raw iterators if pools are ordered
-        while(((begin != end) && ... && (*begin == *(std::get<Indexes>(data)++)))) {
-            func(*(begin++), *(std::get<component_iterator_type<Component>>(raw)++)...);
+        if constexpr(std::is_invocable_v<Func, std::add_lvalue_reference_t<Component>...>) {
+            for(; ((begin != end) && ... && (*begin == *(std::get<Indexes>(data)++))); ++begin) {
+                func(*(std::get<component_iterator_type<Component>>(raw)++)...);
+            }
+        } else {
+            while(((begin != end) && ... && (*begin == *(std::get<Indexes>(data)++)))) {
+                func(*(begin++), *(std::get<component_iterator_type<Component>>(raw)++)...);
+            }
         }
         }
 
 
         // fallback to visit what remains using indirections
         // fallback to visit what remains using indirections
@@ -500,7 +512,11 @@ class view final {
 
 
             if(((sz < extent) && ... && std::get<Indexes>(other)->fast(entity))) {
             if(((sz < extent) && ... && std::get<Indexes>(other)->fast(entity))) {
                 // avoided at least the indirection due to the sparse set for the pivot type (see get for more details)
                 // avoided at least the indirection due to the sparse set for the pivot type (see get for more details)
-                func(entity, get<Comp, Component>(it, entity)...);
+                if constexpr(std::is_invocable_v<Func, std::add_lvalue_reference_t<Component>...>) {
+                    func(get<Comp, Component>(it, entity)...);
+                } else {
+                    func(entity, get<Comp, Component>(it, entity)...);
+                }
             }
             }
         }
         }
     }
     }
@@ -636,12 +652,14 @@ public:
      * object to them.
      * object to them.
      *
      *
      * The function object is invoked for each entity. It is provided with the
      * The function object is invoked for each entity. It is provided with the
-     * entity itself and a set of const references to all the components of the
-     * view.<br/>
-     * The signature of the function should be equivalent to the following:
+     * entity itself and a set of references to all its components. The
+     * _constness_ of the components is as requested.<br/>
+     * The signature of the function must be equivalent to one of the following
+     * forms:
      *
      *
      * @code{.cpp}
      * @code{.cpp}
      * void(const entity_type, Component &...);
      * void(const entity_type, Component &...);
+     * void(Component &...);
      * @endcode
      * @endcode
      *
      *
      * @tparam Func Type of the function object to invoke.
      * @tparam Func Type of the function object to invoke.
@@ -690,7 +708,6 @@ private:
  *
  *
  * @sa view
  * @sa view
  * @sa persistent_view
  * @sa persistent_view
- * @sa raw_view
  * @sa runtime_view
  * @sa runtime_view
  *
  *
  * @tparam Entity A valid entity type (see entt_traits for more details).
  * @tparam Entity A valid entity type (see entt_traits for more details).
@@ -870,202 +887,13 @@ public:
      * object to them.
      * object to them.
      *
      *
      * The function object is invoked for each entity. It is provided with the
      * The function object is invoked for each entity. It is provided with the
-     * entity itself and a const reference to the component of the view.<br/>
-     * The signature of the function should be equivalent to the following:
-     *
-     * @code{.cpp}
-     * void(const entity_type, const Component &);
-     * @endcode
-     *
-     * @tparam Func Type of the function object to invoke.
-     * @param func A valid function object.
-     */
-    template<typename Func>
-    void each(Func func) const {
-        std::for_each(pool->view_type::begin(), pool->view_type::end(), [func = std::move(func), raw = pool->begin()](const auto entity) mutable {
-            func(entity, *(raw++));
-        });
-    }
-
-private:
-    pool_type *pool;
-};
-
-
-/**
- * @brief Raw view.
- *
- * Raw views are meant to easily iterate components without having to resort to
- * using any other member function, so as to further increase the performance.
- * Whenever knowing the entity to which a component belongs isn't required, this
- * should be the preferred tool.<br/>
- * Order of elements during iterations are highly dependent on the order of the
- * underlying data structure. See sparse_set and its specializations for more
- * details.
- *
- * @b Important
- *
- * Iterators aren't invalidated if:
- *
- * * New instances of the given component are created and assigned to entities.
- * * The entity to which the component belongs is modified (as an example, the
- *   given component is destroyed).
- *
- * In all the other cases, modifying the pool of the given component in any way
- * invalidates all the iterators and using them results in undefined behavior.
- *
- * @note
- * Views share a reference to the underlying data structure with the registry
- * that generated them. Therefore any change to the entities and to the
- * components made by means of the registry are immediately reflected by views.
- *
- * @warning
- * Lifetime of a view must overcome the one of the registry that generated it.
- * In any other case, attempting to use a view results in undefined behavior.
- *
- * @sa view
- * @sa view<Entity, Component>
- * @sa persistent_view
- * @sa runtime_view
- *
- * @tparam Entity A valid entity type (see entt_traits for more details).
- * @tparam Component Type of component iterated by the view.
- */
-template<typename Entity, typename Component>
-class raw_view final {
-    /*! @brief A registry is allowed to create views. */
-    friend class registry<Entity>;
-
-    using pool_type = std::conditional_t<std::is_const_v<Component>, const sparse_set<Entity, std::remove_const_t<Component>>, sparse_set<Entity, Component>>;
-
-    raw_view(pool_type *pool) ENTT_NOEXCEPT
-        : pool{pool}
-    {}
-
-public:
-    /*! @brief Type of component iterated by the view. */
-    using raw_type = std::remove_reference_t<decltype(std::declval<pool_type>().get(0))>;
-    /*! @brief Underlying entity identifier. */
-    using entity_type = typename pool_type::entity_type;
-    /*! @brief Unsigned integer type. */
-    using size_type = typename pool_type::size_type;
-    /*! @brief Input iterator type. */
-    using iterator_type = decltype(std::declval<pool_type>().begin());
-
-    /*! @brief Default copy constructor. */
-    raw_view(const raw_view &) = default;
-    /*! @brief Default move constructor. */
-    raw_view(raw_view &&) = default;
-
-    /*! @brief Default copy assignment operator. @return This view. */
-    raw_view & operator=(const raw_view &) = default;
-    /*! @brief Default move assignment operator. @return This view. */
-    raw_view & operator=(raw_view &&) = default;
-
-    /**
-     * @brief Returns the number of instances of the given type.
-     * @return Number of instances of the given component.
-     */
-    size_type size() const ENTT_NOEXCEPT {
-        return pool->size();
-    }
-
-    /**
-     * @brief Checks whether the view is empty.
-     * @return True if the view is empty, false otherwise.
-     */
-    bool empty() const ENTT_NOEXCEPT {
-        return pool->empty();
-    }
-
-    /**
-     * @brief Direct access to the list of components.
-     *
-     * The returned pointer is such that range `[raw(), raw() + size()]` is
-     * always a valid range, even if the container is empty.
-     *
-     * @note
-     * There are no guarantees on the order of the components. Use `begin` and
-     * `end` if you want to iterate the view in the expected order.
-     *
-     * @warning
-     * Empty components aren't explicitly instantiated. Therefore, this function
-     * always returns `nullptr` for them.
-     *
-     * @return A pointer to the array of components.
-     */
-    raw_type * raw() const ENTT_NOEXCEPT {
-        return pool->raw();
-    }
-
-    /**
-     * @brief Direct access to the list of entities.
-     *
-     * The returned pointer is such that range `[data(), data() + size()]` is
-     * always a valid range, even if the container is empty.
-     *
-     * @note
-     * There are no guarantees on the order of the entities. Use `begin` and
-     * `end` if you want to iterate the view in the expected order.
-     *
-     * @return A pointer to the array of entities.
-     */
-    const entity_type * data() const ENTT_NOEXCEPT {
-        return pool->data();
-    }
-
-    /**
-     * @brief Returns an iterator to the first instance of the given type.
-     *
-     * The returned iterator points to the first instance of the given type. If
-     * the view is empty, the returned iterator will be equal to `end()`.
-     *
-     * @note
-     * Input iterators stay true to the order imposed to the underlying data
-     * structures.
-     *
-     * @return An iterator to the first instance of the given type.
-     */
-    iterator_type begin() const ENTT_NOEXCEPT {
-        return pool->begin();
-    }
-
-    /**
-     * @brief Returns an iterator that is past the last instance of the given
-     * type.
-     *
-     * The returned iterator points to the element following the last instance
-     * of the given type. Attempting to dereference the returned iterator
-     * results in undefined behavior.
-     *
-     * @note
-     * Input iterators stay true to the order imposed to the underlying data
-     * structures.
-     *
-     * @return An iterator to the element following the last instance of the
-     * given type.
-     */
-    iterator_type end() const ENTT_NOEXCEPT {
-        return pool->end();
-    }
-
-    /**
-     * @brief Returns a reference to the element at the given position.
-     * @param pos Position of the element to return.
-     * @return A reference to the requested element.
-     */
-    raw_type & operator[](const size_type pos) const ENTT_NOEXCEPT {
-        return pool->begin()[pos];
-    }
-
-    /**
-     * @brief Iterates components and applies the given function object to them.
-     *
-     * The function object is provided with a reference to each component of the
-     * view.<br/>
-     * The signature of the function should be equivalent to the following:
+     * entity itself and a reference to its component. The _constness_ of the
+     * component is as requested.<br/>
+     * The signature of the function must be equivalent to one of the following
+     * forms:
      *
      *
      * @code{.cpp}
      * @code{.cpp}
+     * void(const entity_type, Component &);
      * void(Component &);
      * void(Component &);
      * @endcode
      * @endcode
      *
      *
@@ -1074,7 +902,13 @@ public:
      */
      */
     template<typename Func>
     template<typename Func>
     void each(Func func) const {
     void each(Func func) const {
-        std::for_each(pool->begin(), pool->end(), std::move(func));
+        if constexpr(std::is_invocable_v<Func, std::add_lvalue_reference_t<Component>>) {
+            std::for_each(pool->begin(), pool->end(), std::move(func));
+        } else {
+            std::for_each(pool->view_type::begin(), pool->view_type::end(), [func = std::move(func), raw = pool->begin()](const auto entity) mutable {
+                func(entity, *(raw++));
+            });
+        }
     }
     }
 
 
 private:
 private:
@@ -1120,7 +954,6 @@ private:
  * @sa view
  * @sa view
  * @sa view<Entity, Component>
  * @sa view<Entity, Component>
  * @sa persistent_view
  * @sa persistent_view
- * @sa raw_view
  *
  *
  * @tparam Entity A valid entity type (see entt_traits for more details).
  * @tparam Entity A valid entity type (see entt_traits for more details).
  */
  */

+ 2 - 2
src/entt/signal/emitter.hpp

@@ -23,11 +23,11 @@ namespace entt {
  * The emitter class template follows the CRTP idiom. To create a custom emitter
  * The emitter class template follows the CRTP idiom. To create a custom emitter
  * type, derived classes must inherit directly from the base class as:
  * type, derived classes must inherit directly from the base class as:
  *
  *
- * ```cpp
+ * @code{.cpp}
  * struct my_emitter: emitter<my_emitter> {
  * struct my_emitter: emitter<my_emitter> {
  *     // ...
  *     // ...
  * }
  * }
- * ```
+ * @endcode
  *
  *
  * Handlers for the type of events are created internally on the fly. It's not
  * Handlers for the type of events are created internally on the fly. It's not
  * required to specify in advance the full list of accepted types.<br/>
  * required to specify in advance the full list of accepted types.<br/>

+ 25 - 47
test/benchmark/benchmark.cpp

@@ -115,29 +115,7 @@ TEST(Benchmark, IterateSingleComponent1M) {
         timer.elapsed();
         timer.elapsed();
     };
     };
 
 
-    test([](auto, const auto &) {});
-    test([](auto, auto &... comp) {
-        ((comp.x = {}), ...);
-    });
-}
-
-TEST(Benchmark, IterateSingleComponentRaw1M) {
-    entt::registry<> registry;
-
-    std::cout << "Iterating over 1000000 entities, one component, raw view" << std::endl;
-
-    for(std::uint64_t i = 0; i < 1000000L; i++) {
-        const auto entity = registry.create();
-        registry.assign<position>(entity);
-    }
-
-    auto test = [&registry](auto func) {
-        timer timer;
-        registry.raw_view<position>().each(func);
-        timer.elapsed();
-    };
-
-    test([](const auto &) {});
+    test([](const auto &...) {});
     test([](auto &... comp) {
     test([](auto &... comp) {
         ((comp.x = {}), ...);
         ((comp.x = {}), ...);
     });
     });
@@ -185,8 +163,8 @@ TEST(Benchmark, IterateTwoComponents1M) {
         timer.elapsed();
         timer.elapsed();
     };
     };
 
 
-    test([](auto, const auto &...) {});
-    test([](auto, auto &... comp) {
+    test([](const auto &...) {});
+    test([](auto &... comp) {
         ((comp.x = {}), ...);
         ((comp.x = {}), ...);
     });
     });
 }
 }
@@ -211,8 +189,8 @@ TEST(Benchmark, IterateTwoComponents1MHalf) {
         timer.elapsed();
         timer.elapsed();
     };
     };
 
 
-    test([](auto, const auto &...) {});
-    test([](auto, auto &... comp) {
+    test([](const auto &...) {});
+    test([](auto &... comp) {
         ((comp.x = {}), ...);
         ((comp.x = {}), ...);
     });
     });
 }
 }
@@ -237,8 +215,8 @@ TEST(Benchmark, IterateTwoComponents1MOne) {
         timer.elapsed();
         timer.elapsed();
     };
     };
 
 
-    test([](auto, const auto &...) {});
-    test([](auto, auto &... comp) {
+    test([](const auto &...) {});
+    test([](auto &... comp) {
         ((comp.x = {}), ...);
         ((comp.x = {}), ...);
     });
     });
 }
 }
@@ -261,8 +239,8 @@ TEST(Benchmark, IterateTwoComponentsPersistent1M) {
         timer.elapsed();
         timer.elapsed();
     };
     };
 
 
-    test([](auto, const auto &...) {});
-    test([](auto, auto &... comp) {
+    test([](const auto &...) {});
+    test([](auto &... comp) {
         ((comp.x = {}), ...);
         ((comp.x = {}), ...);
     });
     });
 }
 }
@@ -374,8 +352,8 @@ TEST(Benchmark, IterateFiveComponents1M) {
         timer.elapsed();
         timer.elapsed();
     };
     };
 
 
-    test([](auto, const auto &...) {});
-    test([](auto, auto &... comp) {
+    test([](const auto &...) {});
+    test([](auto &... comp) {
         ((comp.x = {}), ...);
         ((comp.x = {}), ...);
     });
     });
 }
 }
@@ -403,8 +381,8 @@ TEST(Benchmark, IterateFiveComponents1MHalf) {
         timer.elapsed();
         timer.elapsed();
     };
     };
 
 
-    test([](auto, const auto &...) {});
-    test([](auto, auto &... comp) {
+    test([](const auto &...) {});
+    test([](auto &... comp) {
         ((comp.x = {}), ...);
         ((comp.x = {}), ...);
     });
     });
 }
 }
@@ -432,8 +410,8 @@ TEST(Benchmark, IterateFiveComponents1MOne) {
         timer.elapsed();
         timer.elapsed();
     };
     };
 
 
-    test([](auto, const auto &...) {});
-    test([](auto, auto &... comp) {
+    test([](const auto &...) {});
+    test([](auto &... comp) {
         ((comp.x = {}), ...);
         ((comp.x = {}), ...);
     });
     });
 }
 }
@@ -459,8 +437,8 @@ TEST(Benchmark, IterateFiveComponentsPersistent1M) {
         timer.elapsed();
         timer.elapsed();
     };
     };
 
 
-    test([](auto, const auto &...) {});
-    test([](auto, auto &... comp) {
+    test([](const auto &...) {});
+    test([](auto &... comp) {
         ((comp.x = {}), ...);
         ((comp.x = {}), ...);
     });
     });
 }
 }
@@ -613,8 +591,8 @@ TEST(Benchmark, IterateTenComponents1M) {
         timer.elapsed();
         timer.elapsed();
     };
     };
 
 
-    test([](auto, const auto &...) {});
-    test([](auto, auto &... comp) {
+    test([](const auto &...) {});
+    test([](auto &... comp) {
         ((comp.x = {}), ...);
         ((comp.x = {}), ...);
     });
     });
 }
 }
@@ -647,8 +625,8 @@ TEST(Benchmark, IterateTenComponents1MHalf) {
         timer.elapsed();
         timer.elapsed();
     };
     };
 
 
-    test([](auto, auto &...) {});
-    test([](auto, auto &... comp) {
+    test([](auto &...) {});
+    test([](auto &... comp) {
         ((comp.x = {}), ...);
         ((comp.x = {}), ...);
     });
     });
 }
 }
@@ -681,8 +659,8 @@ TEST(Benchmark, IterateTenComponents1MOne) {
         timer.elapsed();
         timer.elapsed();
     };
     };
 
 
-    test([](auto, const auto &...) {});
-    test([](auto, auto &... comp) {
+    test([](const auto &...) {});
+    test([](auto &... comp) {
         ((comp.x = {}), ...);
         ((comp.x = {}), ...);
     });
     });
 }
 }
@@ -713,8 +691,8 @@ TEST(Benchmark, IterateTenComponentsPersistent1M) {
         timer.elapsed();
         timer.elapsed();
     };
     };
 
 
-    test([](auto, const auto &...) {});
-    test([](auto, auto &... comp) {
+    test([](const auto &...) {});
+    test([](auto &... comp) {
         ((comp.x = {}), ...);
         ((comp.x = {}), ...);
     });
     });
 }
 }

+ 0 - 3
test/entt/entity/helper.cpp

@@ -14,9 +14,6 @@ TEST(Helper, AsView) {
 
 
     ([](entt::persistent_view<entity_type, int, char>) {})(entt::as_view{registry});
     ([](entt::persistent_view<entity_type, int, char>) {})(entt::as_view{registry});
     ([](entt::persistent_view<entity_type, const double, const float>) {})(entt::as_view{cregistry});
     ([](entt::persistent_view<entity_type, const double, const float>) {})(entt::as_view{cregistry});
-
-    ([](entt::raw_view<entity_type, int>) {})(entt::as_view{registry});
-    ([](entt::raw_view<entity_type, const double>) {})(entt::as_view{cregistry});
 }
 }
 
 
 TEST(Helper, Dependency) {
 TEST(Helper, Dependency) {

+ 0 - 30
test/entt/entity/registry.cpp

@@ -417,24 +417,6 @@ TEST(Registry, PersistentView) {
     ASSERT_EQ(cnt, decltype(view)::size_type{2});
     ASSERT_EQ(cnt, decltype(view)::size_type{2});
 }
 }
 
 
-TEST(Registry, RawView) {
-    entt::registry<> registry;
-    auto view = registry.raw_view<int>();
-
-    const auto e0 = registry.create();
-    registry.assign<int>(e0, 0);
-    registry.assign<char>(e0, 'c');
-
-    const auto e1 = registry.create();
-    registry.assign<int>(e1, 0);
-    registry.assign<char>(e1, 'c');
-
-    decltype(view)::size_type cnt{0};
-    view.each([&cnt](auto &...) { ++cnt; });
-
-    ASSERT_EQ(cnt, decltype(view)::size_type{2});
-}
-
 TEST(Registry, CleanStandardViewAfterReset) {
 TEST(Registry, CleanStandardViewAfterReset) {
     entt::registry<> registry;
     entt::registry<> registry;
     auto view = registry.view<int>();
     auto view = registry.view<int>();
@@ -462,18 +444,6 @@ TEST(Registry, CleanPersistentViewAfterReset) {
     ASSERT_EQ(view.size(), entt::registry<>::size_type{0});
     ASSERT_EQ(view.size(), entt::registry<>::size_type{0});
 }
 }
 
 
-TEST(Registry, CleanRawViewAfterReset) {
-    entt::registry<> registry;
-    auto view = registry.raw_view<int>();
-    registry.assign<int>(registry.create(), 0);
-
-    ASSERT_EQ(view.size(), entt::registry<>::size_type{1});
-
-    registry.reset();
-
-    ASSERT_EQ(view.size(), entt::registry<>::size_type{0});
-}
-
 TEST(Registry, SortSingle) {
 TEST(Registry, SortSingle) {
     entt::registry<> registry;
     entt::registry<> registry;
 
 

+ 1 - 1
test/entt/entity/snapshot.cpp

@@ -231,7 +231,7 @@ TEST(Snapshot, Iterator) {
 
 
     ASSERT_EQ(registry.view<another_component>().size(), size);
     ASSERT_EQ(registry.view<another_component>().size(), size);
 
 
-    registry.view<another_component>().each([](const auto entity, auto &&...) {
+    registry.view<another_component>().each([](const auto entity, const auto &) {
         ASSERT_TRUE(entity % 2);
         ASSERT_TRUE(entity % 2);
     });
     });
 }
 }

+ 2 - 2
test/entt/entity/sparse_set.cpp

@@ -632,8 +632,8 @@ TEST(SparseSetWithType, RawEmptyType) {
 
 
     set.construct(3);
     set.construct(3);
 
 
-    ASSERT_EQ(set.raw(), nullptr);
-    ASSERT_EQ(cset.raw(), nullptr);
+    ASSERT_EQ(set.raw(), cset.raw());
+    ASSERT_EQ(set.try_get(3), set.raw());
 }
 }
 
 
 TEST(SparseSetWithType, SortOrdered) {
 TEST(SparseSetWithType, SortOrdered) {

+ 13 - 143
test/entt/entity/view.cpp

@@ -131,10 +131,12 @@ TEST(PersistentView, Each) {
     std::size_t cnt = 0;
     std::size_t cnt = 0;
 
 
     view.each([&cnt](auto, int &, char &) { ++cnt; });
     view.each([&cnt](auto, int &, char &) { ++cnt; });
+    view.each([&cnt](int &, char &) { ++cnt; });
 
 
-    ASSERT_EQ(cnt, std::size_t{2});
+    ASSERT_EQ(cnt, std::size_t{4});
 
 
     cview.each([&cnt](auto, const int &, const char &) { --cnt; });
     cview.each([&cnt](auto, const int &, const char &) { --cnt; });
+    cview.each([&cnt](const int &, const char &) { --cnt; });
 
 
     ASSERT_EQ(cnt, std::size_t{0});
     ASSERT_EQ(cnt, std::size_t{0});
 }
 }
@@ -336,6 +338,10 @@ TEST(PersistentView, EmptyAndNonEmptyTypes) {
         ASSERT_TRUE(entity == e0 || entity == e1);
         ASSERT_TRUE(entity == e0 || entity == e1);
     }
     }
 
 
+    view.each([e0, e1](const auto entity, const int &, const empty_type &) {
+        ASSERT_TRUE(entity == e0 || entity == e1);
+    });
+
     ASSERT_EQ(view.size(), typename decltype(view)::size_type{2});
     ASSERT_EQ(view.size(), typename decltype(view)::size_type{2});
     ASSERT_EQ(&view.get<empty_type>(e0), &view.get<empty_type>(e1));
     ASSERT_EQ(&view.get<empty_type>(e0), &view.get<empty_type>(e1));
 }
 }
@@ -450,10 +456,12 @@ TEST(SingleComponentView, Each) {
     std::size_t cnt = 0;
     std::size_t cnt = 0;
 
 
     view.each([&cnt](auto, int &) { ++cnt; });
     view.each([&cnt](auto, int &) { ++cnt; });
+    view.each([&cnt](int &) { ++cnt; });
 
 
-    ASSERT_EQ(cnt, std::size_t{2});
+    ASSERT_EQ(cnt, std::size_t{4});
 
 
     cview.each([&cnt](auto, const int &) { --cnt; });
     cview.each([&cnt](auto, const int &) { --cnt; });
+    cview.each([&cnt](const int &) { --cnt; });
 
 
     ASSERT_EQ(cnt, std::size_t{0});
     ASSERT_EQ(cnt, std::size_t{0});
 }
 }
@@ -629,10 +637,12 @@ TEST(MultipleComponentView, Each) {
     std::size_t cnt = 0;
     std::size_t cnt = 0;
 
 
     view.each([&cnt](auto, int &, char &) { ++cnt; });
     view.each([&cnt](auto, int &, char &) { ++cnt; });
+    view.each([&cnt](int &, char &) { ++cnt; });
 
 
-    ASSERT_EQ(cnt, std::size_t{2});
+    ASSERT_EQ(cnt, std::size_t{4});
 
 
     cview.each([&cnt](auto, const int &, const char &) { --cnt; });
     cview.each([&cnt](auto, const int &, const char &) { --cnt; });
+    cview.each([&cnt](const int &, const char &) { --cnt; });
 
 
     ASSERT_EQ(cnt, std::size_t{0});
     ASSERT_EQ(cnt, std::size_t{0});
 }
 }
@@ -714,146 +724,6 @@ TEST(MultipleComponentView, Find) {
     ASSERT_EQ(++view.find(e0), view.end());
     ASSERT_EQ(++view.find(e0), view.end());
 }
 }
 
 
-TEST(RawView, Functionalities) {
-    entt::registry<> registry;
-    auto view = registry.raw_view<char>();
-    auto cview = std::as_const(registry).raw_view<const char>();
-
-    ASSERT_TRUE(view.empty());
-
-    const auto e0 = registry.create();
-    const auto e1 = registry.create();
-
-    registry.assign<int>(e1);
-    registry.assign<char>(e1);
-
-    ASSERT_FALSE(view.empty());
-    ASSERT_NO_THROW(view.begin()++);
-    ASSERT_NO_THROW(++cview.begin());
-
-    ASSERT_NE(view.begin(), view.end());
-    ASSERT_NE(cview.begin(), cview.end());
-    ASSERT_EQ(view.size(), typename decltype(view)::size_type{1});
-
-    registry.assign<char>(e0);
-
-    ASSERT_EQ(view.size(), typename decltype(view)::size_type{2});
-
-    registry.get<char>(e0) = '1';
-    registry.get<char>(e1) = '2';
-
-    for(auto &&component: view) {
-        ASSERT_TRUE(component == '1' || component == '2');
-    }
-
-    ASSERT_EQ(*(view.data() + 0), e1);
-    ASSERT_EQ(*(view.data() + 1), e0);
-
-    ASSERT_EQ(*(view.raw() + 0), '2');
-    ASSERT_EQ(*(cview.raw() + 1), '1');
-
-    for(auto &&component: view) {
-        // verifies that iterators return references to components
-        component = '0';
-    }
-
-    for(auto &&component: cview) {
-        ASSERT_TRUE(component == '0');
-    }
-
-    registry.remove<char>(e0);
-    registry.remove<char>(e1);
-
-    ASSERT_EQ(view.begin(), view.end());
-    ASSERT_TRUE(view.empty());
-}
-
-TEST(RawView, ElementAccess) {
-    entt::registry<> registry;
-    auto view = registry.raw_view<int>();
-    auto cview = std::as_const(registry).raw_view<const int>();
-
-    const auto e0 = registry.create();
-    registry.assign<int>(e0, 42);
-
-    const auto e1 = registry.create();
-    registry.assign<int>(e1, 3);
-
-    for(typename decltype(view)::size_type i{}; i < view.size(); ++i) {
-        ASSERT_EQ(view[i], i ? 42 : 3);
-        ASSERT_EQ(cview[i], i ? 42 : 3);
-    }
-}
-
-TEST(RawView, Empty) {
-    entt::registry<> registry;
-
-    const auto e0 = registry.create();
-    registry.assign<char>(e0);
-    registry.assign<double>(e0);
-
-    const auto e1 = registry.create();
-    registry.assign<char>(e1);
-
-    auto view = registry.raw_view<int>();
-
-    ASSERT_EQ(view.size(), entt::registry<>::size_type{0});
-
-    for(auto &&component: view) {
-        (void)component;
-        FAIL();
-    }
-}
-
-TEST(RawView, Each) {
-    entt::registry<> registry;
-
-    registry.assign<int>(registry.create(), 1);
-    registry.assign<int>(registry.create(), 3);
-
-    auto view = registry.raw_view<int>();
-    auto cview = std::as_const(registry).raw_view<const int>();
-    std::size_t cnt = 0;
-
-    view.each([&cnt](int &v) { cnt += (v % 2); });
-
-    ASSERT_EQ(cnt, std::size_t{2});
-
-    cview.each([&cnt](const int &v) { cnt -= (v % 2); });
-
-    ASSERT_EQ(cnt, std::size_t{0});
-}
-
-TEST(RawView, ConstNonConstAndAllInBetween) {
-    entt::registry<> registry;
-    auto view = registry.raw_view<int>();
-    auto cview = registry.raw_view<const int>();
-
-    ASSERT_TRUE((std::is_same_v<typename decltype(view)::raw_type, int>));
-    ASSERT_TRUE((std::is_same_v<typename decltype(cview)::raw_type, const int>));
-
-    ASSERT_TRUE((std::is_same_v<decltype(view[0]), int &>));
-    ASSERT_TRUE((std::is_same_v<decltype(view.raw()), int *>));
-    ASSERT_TRUE((std::is_same_v<decltype(cview[0]), const int &>));
-    ASSERT_TRUE((std::is_same_v<decltype(cview.raw()), const int *>));
-
-    view.each([](auto &&i) {
-        ASSERT_TRUE((std::is_same_v<decltype(i), int &>));
-    });
-
-    cview.each([](auto &&i) {
-        ASSERT_TRUE((std::is_same_v<decltype(i), const int &>));
-    });
-
-    for(auto &&i: view) {
-        ASSERT_TRUE((std::is_same_v<decltype(i), int &>));
-    }
-
-    for(auto &&i: cview) {
-        ASSERT_TRUE((std::is_same_v<decltype(i), const int &>));
-    }
-}
-
 TEST(RuntimeView, Functionalities) {
 TEST(RuntimeView, Functionalities) {
     entt::registry<> registry;
     entt::registry<> registry;
     using component_type = typename decltype(registry)::component_type;
     using component_type = typename decltype(registry)::component_type;