소스 검색

registry: decouple ::storage/::assure

Michele Caini 4 년 전
부모
커밋
e4d36e4982
2개의 변경된 파일73개의 추가작업 그리고 55개의 파일을 삭제
  1. 65 55
      src/entt/entity/registry.hpp
  2. 8 0
      test/entt/entity/registry.cpp

+ 65 - 55
src/entt/entity/registry.hpp

@@ -58,11 +58,11 @@ class basic_registry {
 
 
         template<typename Component>
         template<typename Component>
         void maybe_valid_if(basic_registry &owner, const Entity entt) {
         void maybe_valid_if(basic_registry &owner, const Entity entt) {
-            [[maybe_unused]] const auto cpools = std::forward_as_tuple(owner.storage<Owned>()...);
+            [[maybe_unused]] const auto cpools = std::forward_as_tuple(owner.assure<Owned>()...);
 
 
             const auto is_valid = ((std::is_same_v<Component, Owned> || std::get<storage_type<Owned> &>(cpools).contains(entt)) && ...)
             const auto is_valid = ((std::is_same_v<Component, Owned> || std::get<storage_type<Owned> &>(cpools).contains(entt)) && ...)
-                                  && ((std::is_same_v<Component, Get> || owner.storage<Get>().contains(entt)) && ...)
-                                  && ((std::is_same_v<Component, Exclude> || !owner.storage<Exclude>().contains(entt)) && ...);
+                                  && ((std::is_same_v<Component, Get> || owner.assure<Get>().contains(entt)) && ...)
+                                  && ((std::is_same_v<Component, Exclude> || !owner.assure<Exclude>().contains(entt)) && ...);
 
 
             if constexpr(sizeof...(Owned) == 0) {
             if constexpr(sizeof...(Owned) == 0) {
                 if(is_valid && !current.contains(entt)) {
                 if(is_valid && !current.contains(entt)) {
@@ -80,7 +80,7 @@ class basic_registry {
             if constexpr(sizeof...(Owned) == 0) {
             if constexpr(sizeof...(Owned) == 0) {
                 current.remove(entt);
                 current.remove(entt);
             } else {
             } else {
-                if(const auto cpools = std::forward_as_tuple(owner.storage<Owned>()...); std::get<0>(cpools).contains(entt) && (std::get<0>(cpools).index(entt) < current)) {
+                if(const auto cpools = std::forward_as_tuple(owner.assure<Owned>()...); std::get<0>(cpools).contains(entt) && (std::get<0>(cpools).index(entt) < current)) {
                     const auto pos = --current;
                     const auto pos = --current;
                     (std::get<storage_type<Owned> &>(cpools).swap_elements(std::get<storage_type<Owned> &>(cpools).data()[pos], entt), ...);
                     (std::get<storage_type<Owned> &>(cpools).swap_elements(std::get<storage_type<Owned> &>(cpools).data()[pos], entt), ...);
                 }
                 }
@@ -96,6 +96,31 @@ class basic_registry {
         bool (*exclude)(const id_type) ENTT_NOEXCEPT;
         bool (*exclude)(const id_type) ENTT_NOEXCEPT;
     };
     };
 
 
+    template<typename Component>
+    [[nodiscard]] storage_type<Component> &assure(const id_type id = type_hash<Component>::value()) {
+        static_assert(std::is_same_v<Component, std::decay_t<Component>>, "Non-decayed types not allowed");
+        auto &&cpool = pools[id];
+
+        if(!cpool) {
+            cpool.reset(new storage_type<Component>{});
+            cpool->bind(forward_as_any(*this));
+        }
+
+        return static_cast<storage_type<Component> &>(*cpool);
+    }
+
+    template<typename Component>
+    [[nodiscard]] const storage_type<Component> &assure(const id_type id = type_hash<Component>::value()) const {
+        static_assert(std::is_same_v<Component, std::decay_t<Component>>, "Non-decayed types not allowed");
+
+        if(const auto it = pools.find(id); it != pools.cend()) {
+            return static_cast<storage_type<Component> &>(*it->second);
+        }
+
+        static storage_type<Component> placeholder{};
+        return placeholder;
+    }
+
     auto generate_identifier(const std::size_t pos) ENTT_NOEXCEPT {
     auto generate_identifier(const std::size_t pos) ENTT_NOEXCEPT {
         ENTT_ASSERT(pos < entity_traits::to_integral(null), "No entities available");
         ENTT_ASSERT(pos < entity_traits::to_integral(null), "No entities available");
         return entity_traits::combine(static_cast<typename entity_traits::entity_type>(pos), {});
         return entity_traits::combine(static_cast<typename entity_traits::entity_type>(pos), {});
@@ -167,16 +192,8 @@ public:
      * @return The container for the given component type.
      * @return The container for the given component type.
      */
      */
     template<typename Component>
     template<typename Component>
-    [[nodiscard]] storage_type<Component> &storage(const id_type id = type_hash<Component>::value()) {
-        static_assert(std::is_same_v<Component, std::decay_t<Component>>, "Non-decayed types not allowed");
-        auto &&cpool = pools[id];
-
-        if(!cpool) {
-            cpool.reset(new storage_type<Component>{});
-            cpool->bind(forward_as_any(*this));
-        }
-
-        return static_cast<storage_type<Component> &>(*cpool);
+    [[nodiscard]] storage_type<Component> &storage(const id_type id = type_hash<std::remove_const_t<Component>>::value()) {
+        return assure<std::remove_const_t<Component>>(id);
     }
     }
 
 
     /**
     /**
@@ -191,15 +208,8 @@ public:
      * @return The container for the given component type.
      * @return The container for the given component type.
      */
      */
     template<typename Component>
     template<typename Component>
-    [[nodiscard]] const storage_type<Component> &storage(const id_type id = type_hash<Component>::value()) const {
-        static_assert(std::is_same_v<Component, std::decay_t<Component>>, "Non-decayed types not allowed");
-
-        if(const auto it = pools.find(id); it != pools.cend()) {
-            return static_cast<storage_type<Component> &>(*it->second);
-        }
-
-        static storage_type<Component> placeholder{};
-        return placeholder;
+    [[nodiscard]] storage_type<const Component> &storage(const id_type id = type_hash<std::remove_const_t<Component>>::value()) const {
+        return assure<std::remove_const_t<Component>>(id);
     }
     }
 
 
     /**
     /**
@@ -209,7 +219,7 @@ public:
      */
      */
     template<typename Component>
     template<typename Component>
     [[nodiscard]] size_type size() const {
     [[nodiscard]] size_type size() const {
-        return storage<std::remove_const_t<Component>>().size();
+        return assure<std::remove_const_t<Component>>().size();
     }
     }
 
 
     /**
     /**
@@ -252,7 +262,7 @@ public:
         if constexpr(sizeof...(Component) == 0) {
         if constexpr(sizeof...(Component) == 0) {
             entities.reserve(cap);
             entities.reserve(cap);
         } else {
         } else {
-            (storage<Component>().reserve(cap), ...);
+            (assure<Component>().reserve(cap), ...);
         }
         }
     }
     }
 
 
@@ -263,7 +273,7 @@ public:
      */
      */
     template<typename Component>
     template<typename Component>
     [[nodiscard]] size_type capacity() const {
     [[nodiscard]] size_type capacity() const {
-        return storage<std::remove_const_t<Component>>().capacity();
+        return assure<std::remove_const_t<Component>>().capacity();
     }
     }
 
 
     /**
     /**
@@ -282,7 +292,7 @@ public:
      */
      */
     template<typename... Component>
     template<typename... Component>
     void shrink_to_fit() {
     void shrink_to_fit() {
-        (storage<Component>().shrink_to_fit(), ...);
+        (assure<Component>().shrink_to_fit(), ...);
     }
     }
 
 
     /**
     /**
@@ -301,7 +311,7 @@ public:
         if constexpr(sizeof...(Component) == 0) {
         if constexpr(sizeof...(Component) == 0) {
             return !alive();
             return !alive();
         } else {
         } else {
-            return (storage<std::remove_const_t<Component>>().empty() && ...);
+            return (assure<std::remove_const_t<Component>>().empty() && ...);
         }
         }
     }
     }
 
 
@@ -580,7 +590,7 @@ public:
     template<typename Component, typename... Args>
     template<typename Component, typename... Args>
     decltype(auto) emplace(const entity_type entity, Args &&...args) {
     decltype(auto) emplace(const entity_type entity, Args &&...args) {
         ENTT_ASSERT(valid(entity), "Invalid entity");
         ENTT_ASSERT(valid(entity), "Invalid entity");
-        return storage<Component>().emplace(entity, std::forward<Args>(args)...);
+        return assure<Component>().emplace(entity, std::forward<Args>(args)...);
     }
     }
 
 
     /**
     /**
@@ -597,7 +607,7 @@ public:
     template<typename Component, typename It>
     template<typename Component, typename It>
     void insert(It first, It last, const Component &value = {}) {
     void insert(It first, It last, const Component &value = {}) {
         ENTT_ASSERT(std::all_of(first, last, [this](const auto entity) { return valid(entity); }), "Invalid entity");
         ENTT_ASSERT(std::all_of(first, last, [this](const auto entity) { return valid(entity); }), "Invalid entity");
-        storage<Component>().insert(first, last, value);
+        assure<Component>().insert(first, last, value);
     }
     }
 
 
     /**
     /**
@@ -616,7 +626,7 @@ public:
     void insert(EIt first, EIt last, CIt from) {
     void insert(EIt first, EIt last, CIt from) {
         static_assert(std::is_constructible_v<Component, typename std::iterator_traits<CIt>::value_type>, "Invalid value type");
         static_assert(std::is_constructible_v<Component, typename std::iterator_traits<CIt>::value_type>, "Invalid value type");
         ENTT_ASSERT(std::all_of(first, last, [this](const auto entity) { return valid(entity); }), "Invalid entity");
         ENTT_ASSERT(std::all_of(first, last, [this](const auto entity) { return valid(entity); }), "Invalid entity");
-        storage<Component>().insert(first, last, from);
+        assure<Component>().insert(first, last, from);
     }
     }
 
 
     /**
     /**
@@ -634,7 +644,7 @@ public:
     template<typename Component, typename... Args>
     template<typename Component, typename... Args>
     decltype(auto) emplace_or_replace(const entity_type entity, Args &&...args) {
     decltype(auto) emplace_or_replace(const entity_type entity, Args &&...args) {
         ENTT_ASSERT(valid(entity), "Invalid entity");
         ENTT_ASSERT(valid(entity), "Invalid entity");
-        auto &cpool = storage<Component>();
+        auto &cpool = assure<Component>();
 
 
         return cpool.contains(entity)
         return cpool.contains(entity)
                    ? cpool.patch(entity, [&args...](auto &...curr) { ((curr = Component{std::forward<Args>(args)...}), ...); })
                    ? cpool.patch(entity, [&args...](auto &...curr) { ((curr = Component{std::forward<Args>(args)...}), ...); })
@@ -668,7 +678,7 @@ public:
     template<typename Component, typename... Func>
     template<typename Component, typename... Func>
     decltype(auto) patch(const entity_type entity, Func &&...func) {
     decltype(auto) patch(const entity_type entity, Func &&...func) {
         ENTT_ASSERT(valid(entity), "Invalid entity");
         ENTT_ASSERT(valid(entity), "Invalid entity");
-        return storage<Component>().patch(entity, std::forward<Func>(func)...);
+        return assure<Component>().patch(entity, std::forward<Func>(func)...);
     }
     }
 
 
     /**
     /**
@@ -691,7 +701,7 @@ public:
     template<typename Component, typename... Args>
     template<typename Component, typename... Args>
     decltype(auto) replace(const entity_type entity, Args &&...args) {
     decltype(auto) replace(const entity_type entity, Args &&...args) {
         ENTT_ASSERT(valid(entity), "Invalid entity");
         ENTT_ASSERT(valid(entity), "Invalid entity");
-        return storage<Component>().patch(entity, [&args...](auto &...curr) { ((curr = Component{std::forward<Args>(args)...}), ...); });
+        return assure<Component>().patch(entity, [&args...](auto &...curr) { ((curr = Component{std::forward<Args>(args)...}), ...); });
     }
     }
 
 
     /**
     /**
@@ -708,7 +718,7 @@ public:
     size_type remove(const entity_type entity) {
     size_type remove(const entity_type entity) {
         ENTT_ASSERT(valid(entity), "Invalid entity");
         ENTT_ASSERT(valid(entity), "Invalid entity");
         static_assert(sizeof...(Component) > 0, "Provide one or more component types");
         static_assert(sizeof...(Component) > 0, "Provide one or more component types");
-        return (storage<Component>().remove(entity) + ... + size_type{});
+        return (assure<Component>().remove(entity) + ... + size_type{});
     }
     }
 
 
     /**
     /**
@@ -725,7 +735,7 @@ public:
     template<typename... Component, typename It>
     template<typename... Component, typename It>
     size_type remove(It first, It last) {
     size_type remove(It first, It last) {
         static_assert(sizeof...(Component) > 0, "Provide one or more component types");
         static_assert(sizeof...(Component) > 0, "Provide one or more component types");
-        const auto cpools = std::forward_as_tuple(storage<Component>()...);
+        const auto cpools = std::forward_as_tuple(assure<Component>()...);
         size_type count{};
         size_type count{};
 
 
         for(; first != last; ++first) {
         for(; first != last; ++first) {
@@ -751,7 +761,7 @@ public:
     void erase(const entity_type entity) {
     void erase(const entity_type entity) {
         ENTT_ASSERT(valid(entity), "Invalid entity");
         ENTT_ASSERT(valid(entity), "Invalid entity");
         static_assert(sizeof...(Component) > 0, "Provide one or more component types");
         static_assert(sizeof...(Component) > 0, "Provide one or more component types");
-        (storage<Component>().erase(entity), ...);
+        (assure<Component>().erase(entity), ...);
     }
     }
 
 
     /**
     /**
@@ -767,7 +777,7 @@ public:
     template<typename... Component, typename It>
     template<typename... Component, typename It>
     void erase(It first, It last) {
     void erase(It first, It last) {
         static_assert(sizeof...(Component) > 0, "Provide one or more component types");
         static_assert(sizeof...(Component) > 0, "Provide one or more component types");
-        const auto cpools = std::forward_as_tuple(storage<Component>()...);
+        const auto cpools = std::forward_as_tuple(assure<Component>()...);
 
 
         for(; first != last; ++first) {
         for(; first != last; ++first) {
             const auto entity = *first;
             const auto entity = *first;
@@ -788,7 +798,7 @@ public:
                 curr.second->compact();
                 curr.second->compact();
             }
             }
         } else {
         } else {
-            (storage<Component>().compact(), ...);
+            (assure<Component>().compact(), ...);
         }
         }
     }
     }
 
 
@@ -805,7 +815,7 @@ public:
     template<typename... Component>
     template<typename... Component>
     [[nodiscard]] bool all_of(const entity_type entity) const {
     [[nodiscard]] bool all_of(const entity_type entity) const {
         ENTT_ASSERT(valid(entity), "Invalid entity");
         ENTT_ASSERT(valid(entity), "Invalid entity");
-        return (storage<std::remove_const_t<Component>>().contains(entity) && ...);
+        return (assure<std::remove_const_t<Component>>().contains(entity) && ...);
     }
     }
 
 
     /**
     /**
@@ -822,7 +832,7 @@ public:
     template<typename... Component>
     template<typename... Component>
     [[nodiscard]] bool any_of(const entity_type entity) const {
     [[nodiscard]] bool any_of(const entity_type entity) const {
         ENTT_ASSERT(valid(entity), "Invalid entity");
         ENTT_ASSERT(valid(entity), "Invalid entity");
-        return (storage<std::remove_const_t<Component>>().contains(entity) || ...);
+        return (assure<std::remove_const_t<Component>>().contains(entity) || ...);
     }
     }
 
 
     /**
     /**
@@ -841,7 +851,7 @@ public:
         ENTT_ASSERT(valid(entity), "Invalid entity");
         ENTT_ASSERT(valid(entity), "Invalid entity");
 
 
         if constexpr(sizeof...(Component) == 1) {
         if constexpr(sizeof...(Component) == 1) {
-            return storage<std::remove_const_t<Component>...>().get(entity);
+            return assure<std::remove_const_t<Component>...>().get(entity);
         } else {
         } else {
             return std::forward_as_tuple(get<Component>(entity)...);
             return std::forward_as_tuple(get<Component>(entity)...);
         }
         }
@@ -853,7 +863,7 @@ public:
         ENTT_ASSERT(valid(entity), "Invalid entity");
         ENTT_ASSERT(valid(entity), "Invalid entity");
 
 
         if constexpr(sizeof...(Component) == 1) {
         if constexpr(sizeof...(Component) == 1) {
-            return (const_cast<Component &>(storage<std::remove_const_t<Component>>().get(entity)), ...);
+            return (const_cast<Component &>(assure<std::remove_const_t<Component>>().get(entity)), ...);
         } else {
         } else {
             return std::forward_as_tuple(get<Component>(entity)...);
             return std::forward_as_tuple(get<Component>(entity)...);
         }
         }
@@ -877,7 +887,7 @@ public:
     template<typename Component, typename... Args>
     template<typename Component, typename... Args>
     [[nodiscard]] decltype(auto) get_or_emplace(const entity_type entity, Args &&...args) {
     [[nodiscard]] decltype(auto) get_or_emplace(const entity_type entity, Args &&...args) {
         ENTT_ASSERT(valid(entity), "Invalid entity");
         ENTT_ASSERT(valid(entity), "Invalid entity");
-        auto &cpool = storage<Component>();
+        auto &cpool = assure<Component>();
         return cpool.contains(entity) ? cpool.get(entity) : cpool.emplace(entity, std::forward<Args>(args)...);
         return cpool.contains(entity) ? cpool.get(entity) : cpool.emplace(entity, std::forward<Args>(args)...);
     }
     }
 
 
@@ -899,7 +909,7 @@ public:
         ENTT_ASSERT(valid(entity), "Invalid entity");
         ENTT_ASSERT(valid(entity), "Invalid entity");
 
 
         if constexpr(sizeof...(Component) == 1) {
         if constexpr(sizeof...(Component) == 1) {
-            const auto &cpool = storage<std::remove_const_t<Component>...>();
+            const auto &cpool = assure<std::remove_const_t<Component>...>();
             return cpool.contains(entity) ? std::addressof(cpool.get(entity)) : nullptr;
             return cpool.contains(entity) ? std::addressof(cpool.get(entity)) : nullptr;
         } else {
         } else {
             return std::make_tuple(try_get<Component>(entity)...);
             return std::make_tuple(try_get<Component>(entity)...);
@@ -929,7 +939,7 @@ public:
 
 
             each([this](const auto entity) { release_entity(entity, entity_traits::to_version(entity) + 1u); });
             each([this](const auto entity) { release_entity(entity, entity_traits::to_version(entity) + 1u); });
         } else {
         } else {
-            (storage<Component>().clear(), ...);
+            (assure<Component>().clear(), ...);
         }
         }
     }
     }
 
 
@@ -1022,7 +1032,7 @@ public:
      */
      */
     template<typename Component>
     template<typename Component>
     [[nodiscard]] auto on_construct() {
     [[nodiscard]] auto on_construct() {
-        return storage<Component>().on_construct();
+        return assure<Component>().on_construct();
     }
     }
 
 
     /**
     /**
@@ -1045,7 +1055,7 @@ public:
      */
      */
     template<typename Component>
     template<typename Component>
     [[nodiscard]] auto on_update() {
     [[nodiscard]] auto on_update() {
-        return storage<Component>().on_update();
+        return assure<Component>().on_update();
     }
     }
 
 
     /**
     /**
@@ -1070,7 +1080,7 @@ public:
      */
      */
     template<typename Component>
     template<typename Component>
     [[nodiscard]] auto on_destroy() {
     [[nodiscard]] auto on_destroy() {
-        return storage<Component>().on_destroy();
+        return assure<Component>().on_destroy();
     }
     }
 
 
     /**
     /**
@@ -1108,14 +1118,14 @@ public:
     template<typename... Component, typename... Exclude>
     template<typename... Component, typename... Exclude>
     [[nodiscard]] basic_view<Entity, get_t<std::add_const_t<Component>...>, exclude_t<Exclude...>> view(exclude_t<Exclude...> = {}) const {
     [[nodiscard]] basic_view<Entity, get_t<std::add_const_t<Component>...>, exclude_t<Exclude...>> view(exclude_t<Exclude...> = {}) const {
         static_assert(sizeof...(Component) > 0, "Exclusion-only views are not supported");
         static_assert(sizeof...(Component) > 0, "Exclusion-only views are not supported");
-        return {storage<std::remove_const_t<Component>>()..., storage<Exclude>()...};
+        return {assure<std::remove_const_t<Component>>()..., assure<Exclude>()...};
     }
     }
 
 
     /*! @copydoc view */
     /*! @copydoc view */
     template<typename... Component, typename... Exclude>
     template<typename... Component, typename... Exclude>
     [[nodiscard]] basic_view<Entity, get_t<Component...>, exclude_t<Exclude...>> view(exclude_t<Exclude...> = {}) {
     [[nodiscard]] basic_view<Entity, get_t<Component...>, exclude_t<Exclude...>> view(exclude_t<Exclude...> = {}) {
         static_assert(sizeof...(Component) > 0, "Exclusion-only views are not supported");
         static_assert(sizeof...(Component) > 0, "Exclusion-only views are not supported");
-        return {storage<std::remove_const_t<Component>>()..., storage<Exclude>()...};
+        return {assure<std::remove_const_t<Component>>()..., assure<Exclude>()...};
     }
     }
 
 
     /**
     /**
@@ -1201,7 +1211,7 @@ public:
 
 
         using handler_type = group_handler<exclude_t<Exclude...>, get_t<std::remove_const_t<Get>...>, std::remove_const_t<Owned>...>;
         using handler_type = group_handler<exclude_t<Exclude...>, get_t<std::remove_const_t<Get>...>, std::remove_const_t<Owned>...>;
 
 
-        const auto cpools = std::forward_as_tuple(storage<std::remove_const_t<Owned>>()..., storage<std::remove_const_t<Get>>()...);
+        const auto cpools = std::forward_as_tuple(assure<std::remove_const_t<Owned>>()..., assure<std::remove_const_t<Get>>()...);
         constexpr auto size = sizeof...(Owned) + sizeof...(Get) + sizeof...(Exclude);
         constexpr auto size = sizeof...(Owned) + sizeof...(Get) + sizeof...(Exclude);
         handler_type *handler = nullptr;
         handler_type *handler = nullptr;
 
 
@@ -1289,7 +1299,7 @@ public:
             return {};
             return {};
         } else {
         } else {
             using handler_type = group_handler<exclude_t<Exclude...>, get_t<std::remove_const_t<Get>...>, std::remove_const_t<Owned>...>;
             using handler_type = group_handler<exclude_t<Exclude...>, get_t<std::remove_const_t<Get>...>, std::remove_const_t<Owned>...>;
-            return {static_cast<handler_type *>(it->group.get())->current, storage<std::remove_const_t<Owned>>()..., storage<std::remove_const_t<Get>>()...};
+            return {static_cast<handler_type *>(it->group.get())->current, assure<std::remove_const_t<Owned>>()..., assure<std::remove_const_t<Get>>()...};
         }
         }
     }
     }
 
 
@@ -1371,7 +1381,7 @@ public:
     template<typename Component, typename Compare, typename Sort = std_sort, typename... Args>
     template<typename Component, typename Compare, typename Sort = std_sort, typename... Args>
     void sort(Compare compare, Sort algo = Sort{}, Args &&...args) {
     void sort(Compare compare, Sort algo = Sort{}, Args &&...args) {
         ENTT_ASSERT(sortable<Component>(), "Cannot sort owned storage");
         ENTT_ASSERT(sortable<Component>(), "Cannot sort owned storage");
-        auto &cpool = storage<Component>();
+        auto &cpool = assure<Component>();
 
 
         if constexpr(std::is_invocable_v<Compare, decltype(cpool.get({})), decltype(cpool.get({}))>) {
         if constexpr(std::is_invocable_v<Compare, decltype(cpool.get({})), decltype(cpool.get({}))>) {
             auto comp = [&cpool, compare = std::move(compare)](const auto lhs, const auto rhs) { return compare(std::as_const(cpool.get(lhs)), std::as_const(cpool.get(rhs))); };
             auto comp = [&cpool, compare = std::move(compare)](const auto lhs, const auto rhs) { return compare(std::as_const(cpool.get(lhs)), std::as_const(cpool.get(rhs))); };
@@ -1408,7 +1418,7 @@ public:
     template<typename To, typename From>
     template<typename To, typename From>
     void sort() {
     void sort() {
         ENTT_ASSERT(sortable<To>(), "Cannot sort owned storage");
         ENTT_ASSERT(sortable<To>(), "Cannot sort owned storage");
-        storage<To>().respect(storage<From>());
+        assure<To>().respect(assure<From>());
     }
     }
 
 
     /**
     /**

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

@@ -1939,6 +1939,14 @@ TEST(Registry, RuntimePools) {
     auto &storage = registry.storage<empty_type>("other"_hs);
     auto &storage = registry.storage<empty_type>("other"_hs);
     const auto entity = registry.create();
     const auto entity = registry.create();
 
 
+    static_assert(std::is_same_v<decltype(registry.storage<empty_type>()), typename entt::storage_traits<entt::entity, empty_type>::storage_type &>);
+    static_assert(std::is_same_v<decltype(registry.storage<const empty_type>()), const typename entt::storage_traits<entt::entity, empty_type>::storage_type &>);
+    static_assert(std::is_same_v<decltype(std::as_const(registry).storage<empty_type>()), const typename entt::storage_traits<entt::entity, empty_type>::storage_type &>);
+    static_assert(std::is_same_v<decltype(std::as_const(registry).storage<const empty_type>()), const typename entt::storage_traits<entt::entity, empty_type>::storage_type &>);
+
+    ASSERT_EQ(&storage, &registry.storage<const empty_type>("other"_hs));
+    ASSERT_EQ(&registry.storage<empty_type>(), &registry.storage<const empty_type>());
+
     ASSERT_FALSE(registry.any_of<empty_type>(entity));
     ASSERT_FALSE(registry.any_of<empty_type>(entity));
     ASSERT_FALSE(storage.contains(entity));
     ASSERT_FALSE(storage.contains(entity));