Jelajahi Sumber

entity: added sfinae-friendly utility for component-to-pool conversions

Michele Caini 5 tahun lalu
induk
melakukan
6ebc39e038
4 mengubah file dengan 64 tambahan dan 37 penghapusan
  1. 5 23
      src/entt/entity/group.hpp
  2. 53 0
      src/entt/entity/pool.hpp
  3. 5 14
      src/entt/entity/view.hpp
  4. 1 0
      src/entt/entt.hpp

+ 5 - 23
src/entt/entity/group.hpp

@@ -7,11 +7,11 @@
 #include <type_traits>
 #include "../config/config.h"
 #include "../core/type_traits.hpp"
-#include "sparse_set.hpp"
-#include "storage.hpp"
-#include "utility.hpp"
 #include "entity.hpp"
 #include "fwd.hpp"
+#include "pool.hpp"
+#include "sparse_set.hpp"
+#include "utility.hpp"
 
 
 namespace entt {
@@ -68,17 +68,8 @@ class basic_group<Entity, exclude_t<Exclude...>, get_t<Get...>> {
     /*! @brief A registry is allowed to create groups. */
     friend class basic_registry<Entity>;
 
-    // I could have used std::conditional_t ...
-    template<typename Component>
-    struct pool { using type = storage<Entity, Component>; };
-
-    // ... if only MSVC didn't have a bug ...
     template<typename Component>
-    struct pool<const Component> { using type = const storage<Entity, std::remove_const_t<Component>>; };
-
-    // ... that forces me to do the same in a worse way! :(
-    template<typename Component>
-    using pool_type = typename pool<Component>::type;
+    using pool_type = pool_t<Entity, Component>;
 
     class group_range {
         friend class basic_group<Entity, exclude_t<Exclude...>, get_t<Get...>>;
@@ -579,17 +570,8 @@ class basic_group<Entity, exclude_t<Exclude...>, get_t<Get...>, Owned...> {
     /*! @brief A registry is allowed to create groups. */
     friend class basic_registry<Entity>;
 
-    // I could have used std::conditional_t ...
-    template<typename Component>
-    struct pool { using type = storage<Entity, Component>; };
-
-    // ... if only MSVC didn't have a bug ...
-    template<typename Component>
-    struct pool<const Component> { using type = const storage<Entity, std::remove_const_t<Component>>; };
-
-    // ... that forces me to do the same in a worse way! :(
     template<typename Component>
-    using pool_type = typename pool<Component>::type;
+    using pool_type = pool_t<Entity, Component>;
 
     template<typename Component>
     using component_iterator = decltype(std::declval<pool_type<Component>>().begin());

+ 53 - 0
src/entt/entity/pool.hpp

@@ -0,0 +1,53 @@
+#ifndef ENTT_ENTITY_POOL_HPP
+#define ENTT_ENTITY_POOL_HPP
+
+
+#include <type_traits>
+#include "storage.hpp"
+
+
+namespace entt {
+
+
+/**
+ * @brief Applies component-to-pool conversion and defines the resulting type as
+ * the member typedef type.
+ *
+ * Formally:
+ *
+ * * If the component type is a non-const one, the member typedef type is the
+ *   declared storage type.
+ * * If the component type is a const one, the member typedef type is the
+ *   declared storage type, except it has a const-qualifier added.
+ *
+ * @tparam Entity A valid entity type (see entt_traits for more details).
+ * @tparam Type Type of objects assigned to the entities.
+ */
+template<typename Entity, typename Type, typename = void>
+struct pool {
+    /*! @brief Resulting type after component-to-pool conversion. */
+    using type = storage<Entity, Type>;
+};
+
+
+/*! @copydoc pool */
+template<typename Entity, typename Type>
+struct pool<Entity, const Type> {
+    /*! @brief Resulting type after component-to-pool conversion. */
+    using type = std::add_const_t<typename pool<Entity, std::remove_const_t<Type>>::type>;
+};
+
+
+/**
+ * @brief Alias declaration to use to make component-to-pool conversions.
+ * @tparam Entity A valid entity type (see entt_traits for more details).
+ * @tparam Type Type of objects assigned to the entities.
+ */
+template<typename Entity, typename Type>
+using pool_t = typename pool<Entity, Type>::type;
+
+
+}
+
+
+#endif

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

@@ -10,11 +10,11 @@
 #include <type_traits>
 #include "../config/config.h"
 #include "../core/type_traits.hpp"
-#include "sparse_set.hpp"
-#include "storage.hpp"
-#include "utility.hpp"
 #include "entity.hpp"
 #include "fwd.hpp"
+#include "pool.hpp"
+#include "sparse_set.hpp"
+#include "utility.hpp"
 
 
 namespace entt {
@@ -68,17 +68,8 @@ class basic_view<Entity, exclude_t<Exclude...>, Component...> {
     /*! @brief A registry is allowed to create views. */
     friend class basic_registry<Entity>;
 
-    // I could have used std::conditional_t ...
-    template<typename Comp>
-    struct pool { using type = storage<Entity, Comp>; };
-
-    // ... if only MSVC didn't have a bug ...
-    template<typename Comp>
-    struct pool<const Comp> { using type = const storage<Entity, std::remove_const_t<Comp>>; };
-
-    // ... that forces me to do the same in a worse way! :(
     template<typename Comp>
-    using pool_type = typename pool<Comp>::type;
+    using pool_type = pool_t<Entity, Comp>;
 
     template<typename Comp>
     using component_iterator = decltype(std::declval<pool_type<Comp>>().begin());
@@ -628,7 +619,7 @@ class basic_view<Entity, exclude_t<>, Component> {
     /*! @brief A registry is allowed to create views. */
     friend class basic_registry<Entity>;
 
-    using pool_type = std::conditional_t<std::is_const_v<Component>, const storage<Entity, std::remove_const_t<Component>>, storage<Entity, Component>>;
+    using pool_type = pool_t<Entity, Component>;
 
     class view_range {
         friend class basic_view<Entity, exclude_t<>, Component>;

+ 1 - 0
src/entt/entt.hpp

@@ -13,6 +13,7 @@
 #include "entity/handle.hpp"
 #include "entity/helper.hpp"
 #include "entity/observer.hpp"
+#include "entity/pool.hpp"
 #include "entity/registry.hpp"
 #include "entity/runtime_view.hpp"
 #include "entity/snapshot.hpp"