Quellcode durchsuchen

type_info/type_id:
* type_info is no longer default constructible
* users cannot construct type_info objects anymore
* make type_id refer to an object with static storage duration

Michele Caini vor 4 Jahren
Ursprung
Commit
db44549276

+ 6 - 13
src/entt/core/any.hpp

@@ -86,11 +86,10 @@ class basic_any {
         }
         case operation::get: {
             const type_info &info = *static_cast<const type_info *>(to);
-            return (!info || (info == type_id<Type>())) ? instance : nullptr;
+            return (info == type_id<void>() || info == type_id<Type>()) ? instance : nullptr;
         }
         case operation::type:
-            *static_cast<type_info *>(const_cast<void *>(to)) = type_id<Type>();
-            break;
+            return &type_id<Type>();
         }
 
         return nullptr;
@@ -241,14 +240,8 @@ public:
      * @brief Returns the object type if any, `type_id<void>()` otherwise.
      * @return The object type if any, `type_id<void>()` otherwise.
      */
-    [[nodiscard]] type_info type() const ENTT_NOEXCEPT {
-        if(vtable) {
-            type_info info{};
-            vtable(operation::type, *this, &info);
-            return info;
-        }
-
-        return type_id<void>();
+    [[nodiscard]] const type_info &type() const ENTT_NOEXCEPT {
+        return vtable ? *static_cast<const type_info *>(vtable(operation::type, *this, nullptr)) : type_id<void>();
     }
 
     /**
@@ -256,12 +249,12 @@ public:
      * @param req Optional expected type.
      * @return An opaque pointer the contained instance, if any.
      */
-    [[nodiscard]] const void *data(const type_info &req = type_info{}) const ENTT_NOEXCEPT {
+    [[nodiscard]] const void *data(const type_info &req = type_id<void>()) const ENTT_NOEXCEPT {
         return vtable ? vtable(operation::get, *this, &req) : nullptr;
     }
 
     /*! @copydoc data */
-    [[nodiscard]] void *data(const type_info &req = type_info{}) ENTT_NOEXCEPT {
+    [[nodiscard]] void *data(const type_info &req = type_id<void>()) ENTT_NOEXCEPT {
         return (!vtable || mode == policy::cref) ? nullptr : const_cast<void *>(vtable(operation::get, *this, &req));
     }
 

+ 7 - 37
src/entt/core/type_info.hpp

@@ -138,48 +138,17 @@ struct type_name final {
 };
 
 /*! @brief Implementation specific information about a type. */
-struct type_info final {
-    /*! @brief Default constructor. */
-    constexpr type_info() ENTT_NOEXCEPT
-        : seq{},
-          identifier{},
-          alias{} {}
-
-    /*! @brief Default copy constructor. */
-    constexpr type_info(const type_info &) ENTT_NOEXCEPT = default;
-    /*! @brief Default move constructor. */
-    constexpr type_info(type_info &&) ENTT_NOEXCEPT = default;
+class type_info final {
+    template<typename Type>
+    friend constexpr const type_info &type_id() ENTT_NOEXCEPT;
 
-    /**
-     * @brief Creates a type info object for a given type.
-     * @tparam Type Type for which to generate a type info object.
-     */
     template<typename Type>
     constexpr type_info(std::in_place_type_t<Type>) ENTT_NOEXCEPT
         : seq{type_index<std::remove_reference_t<std::remove_const_t<Type>>>::value()},
           identifier{type_hash<std::remove_reference_t<std::remove_const_t<Type>>>::value()},
           alias{type_name<std::remove_reference_t<std::remove_const_t<Type>>>::value()} {}
 
-    /**
-     * @brief Default copy assignment operator.
-     * @return This type info object.
-     */
-    constexpr type_info &operator=(const type_info &) ENTT_NOEXCEPT = default;
-
-    /**
-     * @brief Default move assignment operator.
-     * @return This type info object.
-     */
-    constexpr type_info &operator=(type_info &&) ENTT_NOEXCEPT = default;
-
-    /**
-     * @brief Checks if a type info object is properly initialized.
-     * @return True if the object is properly initialized, false otherwise.
-     */
-    [[nodiscard]] constexpr explicit operator bool() const ENTT_NOEXCEPT {
-        return alias.data() != nullptr;
-    }
-
+public:
     /**
      * @brief Type index.
      * @return Type index.
@@ -284,8 +253,9 @@ private:
  * @return A properly initialized type info object.
  */
 template<typename Type>
-[[nodiscard]] constexpr type_info type_id() ENTT_NOEXCEPT {
-    return type_info{std::in_place_type<std::remove_cv_t<std::remove_reference_t<Type>>>};
+[[nodiscard]] constexpr const type_info &type_id() ENTT_NOEXCEPT {
+    static type_info instance{std::in_place_type<std::remove_cv_t<std::remove_reference_t<Type>>>};
+    return instance;
 }
 
 } // namespace entt

+ 14 - 14
src/entt/entity/organizer.hpp

@@ -110,7 +110,7 @@ template<typename Entity>
 class basic_organizer final {
     using callback_type = void(const void *, basic_registry<Entity> &);
     using prepare_type = void(basic_registry<Entity> &);
-    using dependency_type = std::size_t(const bool, type_info *, const std::size_t);
+    using dependency_type = std::size_t(const bool, const type_info **, const std::size_t);
 
     struct vertex_data final {
         std::size_t ro_count{};
@@ -120,7 +120,7 @@ class basic_organizer final {
         callback_type *callback{};
         dependency_type *dependency;
         prepare_type *prepare{};
-        type_info info{};
+        const type_info *info{};
     };
 
     template<typename Type>
@@ -140,11 +140,11 @@ class basic_organizer final {
     }
 
     template<typename... Type>
-    static std::size_t fill_dependencies(type_list<Type...>, [[maybe_unused]] type_info *buffer, [[maybe_unused]] const std::size_t count) {
+    static std::size_t fill_dependencies(type_list<Type...>, [[maybe_unused]] const type_info **buffer, [[maybe_unused]] const std::size_t count) {
         if constexpr(sizeof...(Type) == 0u) {
             return {};
         } else {
-            type_info info[sizeof...(Type)]{type_id<Type>()...};
+            const type_info *info[sizeof...(Type)]{&type_id<Type>()...};
             const auto length = (std::min)(count, sizeof...(Type));
             std::copy_n(info, length, buffer);
             return length;
@@ -256,7 +256,7 @@ public:
          * @param length The length of the user-supplied buffer.
          * @return The number of type info objects written to the buffer.
          */
-        size_type ro_dependency(type_info *buffer, const std::size_t length) const ENTT_NOEXCEPT {
+        size_type ro_dependency(const type_info **buffer, const std::size_t length) const ENTT_NOEXCEPT {
             return node.dependency(false, buffer, length);
         }
 
@@ -267,7 +267,7 @@ public:
          * @param length The length of the user-supplied buffer.
          * @return The number of type info objects written to the buffer.
          */
-        size_type rw_dependency(type_info *buffer, const std::size_t length) const ENTT_NOEXCEPT {
+        size_type rw_dependency(const type_info **buffer, const std::size_t length) const ENTT_NOEXCEPT {
             return node.dependency(true, buffer, length);
         }
 
@@ -299,8 +299,8 @@ public:
          * @brief Returns a type info object associated with a vertex.
          * @return A properly initialized type info object.
          */
-        type_info info() const ENTT_NOEXCEPT {
-            return node.info;
+        const type_info &info() const ENTT_NOEXCEPT {
+            return *node.info;
         }
 
         /**
@@ -371,9 +371,9 @@ public:
             name,
             nullptr,
             callback,
-            +[](const bool rw, type_info *buffer, const std::size_t length) { return rw ? fill_dependencies(typename resource_type::rw{}, buffer, length) : fill_dependencies(typename resource_type::ro{}, buffer, length); },
+            +[](const bool rw, const type_info **buffer, const std::size_t length) { return rw ? fill_dependencies(typename resource_type::rw{}, buffer, length) : fill_dependencies(typename resource_type::ro{}, buffer, length); },
             +[](basic_registry<entity_type> &reg) { void(to_args(reg, typename resource_type::args{})); },
-            type_id<std::integral_constant<decltype(Candidate), Candidate>>()};
+            &type_id<std::integral_constant<decltype(Candidate), Candidate>>()};
 
         track_dependencies(vertices.size(), requires_registry, typename resource_type::ro{}, typename resource_type::rw{});
         vertices.push_back(std::move(vdata));
@@ -404,9 +404,9 @@ public:
             name,
             &value_or_instance,
             callback,
-            +[](const bool rw, type_info *buffer, const std::size_t length) { return rw ? fill_dependencies(typename resource_type::rw{}, buffer, length) : fill_dependencies(typename resource_type::ro{}, buffer, length); },
+            +[](const bool rw, const type_info **buffer, const std::size_t length) { return rw ? fill_dependencies(typename resource_type::rw{}, buffer, length) : fill_dependencies(typename resource_type::ro{}, buffer, length); },
             +[](basic_registry<entity_type> &reg) { void(to_args(reg, typename resource_type::args{})); },
-            type_id<std::integral_constant<decltype(Candidate), Candidate>>()};
+            &type_id<std::integral_constant<decltype(Candidate), Candidate>>()};
 
         track_dependencies(vertices.size(), requires_registry, typename resource_type::ro{}, typename resource_type::rw{});
         vertices.push_back(std::move(vdata));
@@ -431,9 +431,9 @@ public:
             name,
             payload,
             func,
-            +[](const bool rw, type_info *buffer, const std::size_t length) { return rw ? fill_dependencies(typename resource_type::rw{}, buffer, length) : fill_dependencies(typename resource_type::ro{}, buffer, length); },
+            +[](const bool rw, const type_info **buffer, const std::size_t length) { return rw ? fill_dependencies(typename resource_type::rw{}, buffer, length) : fill_dependencies(typename resource_type::ro{}, buffer, length); },
             nullptr,
-            type_info{}};
+            &type_id<void>()};
 
         vertices.push_back(std::move(vdata));
     }

+ 2 - 2
src/entt/entity/poly_storage.hpp

@@ -15,7 +15,7 @@ namespace entt {
  * @tparam Entity A valid entity type (see entt_traits for more details).
  */
 template<typename Entity>
-struct Storage: type_list<type_info() const ENTT_NOEXCEPT> {
+struct Storage: type_list<const type_info &() const ENTT_NOEXCEPT> {
     /**
      * @brief Concept definition.
      * @tparam Base Opaque base class from which to inherit.
@@ -26,7 +26,7 @@ struct Storage: type_list<type_info() const ENTT_NOEXCEPT> {
          * @brief Returns a type info for the contained objects.
          * @return The type info for the contained objects.
          */
-        type_info value_type() const ENTT_NOEXCEPT {
+        const type_info &value_type() const ENTT_NOEXCEPT {
             return poly_call<0>(*this);
         }
     };

+ 7 - 7
src/entt/entity/registry.hpp

@@ -179,13 +179,13 @@ public:
      * @return A valid poly storage if a pool for the given type exists, an
      * empty and thus invalid element otherwise.
      */
-    poly_storage &storage(const type_info info) {
+    poly_storage &storage(const type_info &info) {
         ENTT_ASSERT(info.index() < pools.size() && pools[info.index()].poly, "Storage not available");
         return pools[info.index()].poly;
     }
 
     /*! @copydoc storage */
-    const poly_storage &storage(const type_info info) const {
+    const poly_storage &storage(const type_info &info) const {
         ENTT_ASSERT(info.index() < pools.size() && pools[info.index()].poly, "Storage not available");
         return pools[info.index()].poly;
     }
@@ -1469,7 +1469,7 @@ public:
      * The signature of the function should be equivalent to the following:
      *
      * @code{.cpp}
-     * void(const type_info);
+     * void(const type_info &);
      * @endcode
      *
      * Returned identifiers are those of the components owned by the entity.
@@ -1499,7 +1499,7 @@ public:
      * The signature of the function should be equivalent to the following:
      *
      * @code{.cpp}
-     * void(const type_info);
+     * void(const type_info &);
      * @endcode
      *
      * Returned identifiers are those of the components managed by the registry.
@@ -1574,7 +1574,7 @@ public:
      */
     template<typename Type>
     [[nodiscard]] std::add_const_t<Type> *try_ctx() const {
-        const auto info = type_id<Type>();
+        const auto &info = type_id<Type>();
 
         for(const auto &curr: vars) {
             if(auto *value = curr.data(info); value) {
@@ -1591,7 +1591,7 @@ public:
         if constexpr(std::is_const_v<Type>) {
             return std::as_const(*this).template try_ctx<Type>();
         } else {
-            const auto info = type_id<Type>();
+            const auto &info = type_id<Type>();
 
             for(auto &curr: vars) {
                 if(auto *value = curr.data(info); value) {
@@ -1635,7 +1635,7 @@ public:
      * The signature of the function should be equivalent to the following:
      *
      * @code{.cpp}
-     * void(const type_info);
+     * void(const type_info &);
      * @endcode
      *
      * Returned identifiers are those of the context variables currently set.

+ 10 - 10
src/entt/meta/meta.hpp

@@ -348,9 +348,9 @@ public:
      */
     template<typename Type>
     [[nodiscard]] const Type *try_cast() const {
-        if(const auto info = type_id<Type>(); node && node->info == info) {
+        if(const auto &info = type_id<Type>(); node && *node->info == info) {
             return any_cast<Type>(&storage);
-        } else if(const auto *base = internal::visit<&internal::meta_type_node::base>([info](const auto *curr) { return curr->type->info == info; }, node); base) {
+        } else if(const auto *base = internal::visit<&internal::meta_type_node::base>([info](const auto *curr) { return *curr->type->info == info; }, node); base) {
             return static_cast<const Type *>(base->cast(storage.data()));
         }
 
@@ -360,9 +360,9 @@ public:
     /*! @copydoc try_cast */
     template<typename Type>
     [[nodiscard]] Type *try_cast() {
-        if(const auto info = type_id<Type>(); node && node->info == info) {
+        if(const auto &info = type_id<Type>(); node && *node->info == info) {
             return any_cast<Type>(&storage);
-        } else if(const auto *base = internal::visit<&internal::meta_type_node::base>([info](const auto *curr) { return curr->type->info == info; }, node); base) {
+        } else if(const auto *base = internal::visit<&internal::meta_type_node::base>([info](const auto *curr) { return *curr->type->info == info; }, node); base) {
             return static_cast<Type *>(const_cast<constness_as_t<void, Type> *>(base->cast(static_cast<constness_as_t<any, Type> &>(storage).data())));
         }
 
@@ -542,7 +542,7 @@ public:
      * @return False if the two objects differ in their content, true otherwise.
      */
     [[nodiscard]] bool operator==(const meta_any &other) const {
-        return (!node && !other.node) || (node && other.node && node->info == other.node->info && storage == other.storage);
+        return (!node && !other.node) || (node && other.node && *node->info == *other.node->info && storage == other.storage);
     }
 
     /**
@@ -1000,8 +1000,8 @@ public:
      * @brief Returns the type info object of the underlying type.
      * @return The type info object of the underlying type.
      */
-    [[nodiscard]] type_info info() const ENTT_NOEXCEPT {
-        return node->info;
+    [[nodiscard]] const type_info &info() const ENTT_NOEXCEPT {
+        return *node->info;
     }
 
     /**
@@ -1321,7 +1321,7 @@ public:
      * @return True if the objects refer to the same type, false otherwise.
      */
     [[nodiscard]] bool operator==(const meta_type &other) const ENTT_NOEXCEPT {
-        return (!node && !other.node) || (node && other.node && node->info == other.node->info);
+        return (!node && !other.node) || (node && other.node && *node->info == *other.node->info);
     }
 
 private:
@@ -1366,9 +1366,9 @@ bool meta_any::set(const id_type id, Type &&value) {
 }
 
 [[nodiscard]] inline meta_any meta_any::allow_cast(const meta_type &type) const {
-    if(const auto info = type.info(); (node && node->info == info) || internal::visit<&internal::meta_type_node::base>([info](const auto *curr) { return curr->type->info == info; }, node)) {
+    if(const auto info = type.info(); (node && *node->info == info) || internal::visit<&internal::meta_type_node::base>([info](const auto *curr) { return *curr->type->info == info; }, node)) {
         return as_ref();
-    } else if(const auto *const conv = internal::visit<&internal::meta_type_node::conv>([info](const auto *curr) { return curr->type->info == info; }, node); conv) {
+    } else if(const auto *const conv = internal::visit<&internal::meta_type_node::conv>([info](const auto *curr) { return *curr->type->info == info; }, node); conv) {
         return conv->conv(storage.data());
     } else if(node && node->conversion_helper && (type.is_arithmetic() || type.is_enum())) {
         // exploits the fact that arithmetic types and enums are also default constructible

+ 2 - 2
src/entt/meta/node.hpp

@@ -102,7 +102,7 @@ struct meta_template_node {
 
 struct meta_type_node {
     using size_type = std::size_t;
-    const type_info info;
+    const type_info *info;
     id_type id;
     meta_type_node *next;
     meta_prop_node *prop;
@@ -166,7 +166,7 @@ class ENTT_API meta_node {
 public:
     [[nodiscard]] static meta_type_node *resolve() ENTT_NOEXCEPT {
         static meta_type_node node{
-            type_id<Type>(),
+            &type_id<Type>(),
             {},
             nullptr,
             nullptr,

+ 2 - 3
src/entt/meta/resolve.hpp

@@ -44,12 +44,11 @@ template<typename Type>
 }
 
 /**
- * @brief Returns the meta type associated with a given type info object, if
- * any.
+ * @brief Returns the meta type associated with a given type info object.
  * @param info The type info object of the requested type.
  * @return The meta type associated with the given type info object, if any.
  */
-[[nodiscard]] inline meta_type resolve(const type_info info) ENTT_NOEXCEPT {
+[[nodiscard]] inline meta_type resolve(const type_info &info) ENTT_NOEXCEPT {
     for(auto &&curr: resolve()) {
         if(curr.info() == info) {
             return curr;

+ 1 - 1
src/entt/poly/poly.hpp

@@ -228,7 +228,7 @@ public:
      * @brief Returns the object type if any, `type_id<void>()` otherwise.
      * @return The object type if any, `type_id<void>()` otherwise.
      */
-    [[nodiscard]] type_info type() const ENTT_NOEXCEPT {
+    [[nodiscard]] const type_info &type() const ENTT_NOEXCEPT {
         return storage.type();
     }
 

+ 22 - 21
test/entt/core/type_info.cpp

@@ -42,23 +42,23 @@ TEST(TypeName, Functionalities) {
 }
 
 TEST(TypeInfo, Functionalities) {
-    static_assert(std::is_default_constructible_v<entt::type_info>);
     static_assert(std::is_copy_constructible_v<entt::type_info>);
     static_assert(std::is_move_constructible_v<entt::type_info>);
     static_assert(std::is_copy_assignable_v<entt::type_info>);
     static_assert(std::is_move_assignable_v<entt::type_info>);
 
-    ASSERT_EQ(entt::type_info{}, entt::type_info{});
-    ASSERT_NE(entt::type_id<int>(), entt::type_info{});
-    ASSERT_NE(entt::type_id<int>(), entt::type_id<char>());
+    ASSERT_EQ(entt::type_id<int>(), entt::type_id<int>());
     ASSERT_EQ(entt::type_id<int &>(), entt::type_id<int &&>());
     ASSERT_EQ(entt::type_id<int &>(), entt::type_id<int>());
+    ASSERT_NE(entt::type_id<int>(), entt::type_id<char>());
+
+    ASSERT_EQ(&entt::type_id<int>(), &entt::type_id<int>());
+    ASSERT_NE(&entt::type_id<int>(), &entt::type_id<void>());
 
     auto info = entt::type_id<const int &>();
-    const auto unnamed = entt::type_id<float>();
-    entt::type_info empty{};
+    auto other = entt::type_id<void>();
 
-    ASSERT_NE(info, empty);
+    ASSERT_NE(info, other);
     ASSERT_TRUE(info == info);
     ASSERT_FALSE(info != info);
 
@@ -66,29 +66,30 @@ TEST(TypeInfo, Functionalities) {
     ASSERT_EQ(info.hash(), entt::type_hash<int>::value());
     ASSERT_EQ(info.name(), entt::type_name<int>::value());
 
-    ASSERT_TRUE(info);
-    ASSERT_TRUE(unnamed);
-    ASSERT_FALSE(empty);
+    other = info;
 
-    empty = info;
+    ASSERT_EQ(other.index(), entt::type_index<int>::value());
+    ASSERT_EQ(other.hash(), entt::type_hash<int>::value());
+    ASSERT_EQ(other.name(), entt::type_name<int>::value());
 
-    ASSERT_TRUE(empty);
-    ASSERT_EQ(empty.hash(), info.hash());
+    ASSERT_EQ(other.index(), info.index());
+    ASSERT_EQ(other.hash(), info.hash());
+    ASSERT_EQ(other.name(), info.name());
 
-    empty = {};
+    other = std::move(info);
 
-    ASSERT_FALSE(empty);
-    ASSERT_NE(empty.hash(), info.hash());
+    ASSERT_EQ(other.index(), entt::type_index<int>::value());
+    ASSERT_EQ(other.hash(), entt::type_hash<int>::value());
+    ASSERT_EQ(other.name(), entt::type_name<int>::value());
 
-    empty = std::move(info);
-
-    ASSERT_TRUE(empty);
-    ASSERT_EQ(empty.hash(), info.hash());
+    ASSERT_EQ(other.index(), info.index());
+    ASSERT_EQ(other.hash(), info.hash());
+    ASSERT_EQ(other.name(), info.name());
 }
 
 TEST(TypeInfo, Order) {
-    entt::type_info lhs = entt::type_id<char>();
     entt::type_info rhs = entt::type_id<int>();
+    entt::type_info lhs = entt::type_id<char>();
 
     // let's adjust the two objects since values are generated at runtime
     (rhs < lhs) || (std::swap(lhs, rhs), true);

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

@@ -168,7 +168,7 @@ TEST(BasicHandle, Component) {
     ASSERT_TRUE((registry.empty<char, double>()));
     ASSERT_EQ(0u, (handle.remove<char, double>()));
 
-    handle.visit([](auto info) { ASSERT_EQ(entt::type_id<int>(), info); });
+    handle.visit([](const auto &info) { ASSERT_EQ(entt::type_id<int>(), info); });
 
     ASSERT_TRUE((handle.any_of<int, char, double>()));
     ASSERT_FALSE((handle.all_of<int, char, double>()));

+ 11 - 11
test/entt/entity/organizer.cpp

@@ -244,10 +244,10 @@ TEST(Organizer, EmplaceDirectFunction) {
     ASSERT_EQ(graph[2u].data(), nullptr);
     ASSERT_EQ(graph[3u].data(), &instance);
 
-    ASSERT_EQ(graph[0u].info(), entt::type_info{});
-    ASSERT_EQ(graph[1u].info(), entt::type_info{});
-    ASSERT_EQ(graph[2u].info(), entt::type_info{});
-    ASSERT_EQ(graph[3u].info(), entt::type_info{});
+    ASSERT_EQ(graph[0u].info(), entt::type_id<void>());
+    ASSERT_EQ(graph[1u].info(), entt::type_id<void>());
+    ASSERT_EQ(graph[2u].info(), entt::type_id<void>());
+    ASSERT_EQ(graph[3u].info(), entt::type_id<void>());
 
     ASSERT_TRUE(graph[0u].top_level());
     ASSERT_FALSE(graph[1u].top_level());
@@ -380,7 +380,7 @@ TEST(Organizer, Dependencies) {
     organizer.emplace<char, const double>(+[](const void *, entt::registry &) {});
 
     const auto graph = organizer.graph();
-    entt::type_info buffer[5u]{};
+    const entt::type_info *buffer[5u]{};
 
     ASSERT_EQ(graph.size(), 3u);
 
@@ -391,8 +391,8 @@ TEST(Organizer, Dependencies) {
     ASSERT_EQ(graph[0u].rw_dependency(buffer, 2u), 0u);
 
     ASSERT_EQ(graph[0u].ro_dependency(buffer, 5u), 2u);
-    ASSERT_EQ(buffer[0u], entt::type_id<int>());
-    ASSERT_EQ(buffer[1u], entt::type_id<double>());
+    ASSERT_EQ(*buffer[0u], entt::type_id<int>());
+    ASSERT_EQ(*buffer[1u], entt::type_id<double>());
 
     ASSERT_EQ(graph[1u].ro_count(), 0u);
     ASSERT_EQ(graph[1u].rw_count(), 2u);
@@ -401,8 +401,8 @@ TEST(Organizer, Dependencies) {
     ASSERT_EQ(graph[1u].rw_dependency(buffer, 0u), 0u);
 
     ASSERT_EQ(graph[1u].rw_dependency(buffer, 5u), 2u);
-    ASSERT_EQ(buffer[0u], entt::type_id<int>());
-    ASSERT_EQ(buffer[1u], entt::type_id<char>());
+    ASSERT_EQ(*buffer[0u], entt::type_id<int>());
+    ASSERT_EQ(*buffer[1u], entt::type_id<char>());
 
     ASSERT_EQ(graph[2u].ro_count(), 1u);
     ASSERT_EQ(graph[2u].rw_count(), 1u);
@@ -411,10 +411,10 @@ TEST(Organizer, Dependencies) {
     ASSERT_EQ(graph[2u].rw_dependency(buffer, 0u), 0u);
 
     ASSERT_EQ(graph[2u].ro_dependency(buffer, 5u), 1u);
-    ASSERT_EQ(buffer[0u], entt::type_id<double>());
+    ASSERT_EQ(*buffer[0u], entt::type_id<double>());
 
     ASSERT_EQ(graph[2u].rw_dependency(buffer, 5u), 1u);
-    ASSERT_EQ(buffer[0u], entt::type_id<char>());
+    ASSERT_EQ(*buffer[0u], entt::type_id<char>());
 }
 
 TEST(Organizer, ToArgsIntegrity) {

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

@@ -82,7 +82,7 @@ TEST(PolyStorage, CopyEntity) {
     ASSERT_TRUE((registry.all_of<int, char>(entity)));
     ASSERT_FALSE((registry.any_of<int, char>(other)));
 
-    registry.visit(entity, [&](const auto info) {
+    registry.visit(entity, [&](const auto &info) {
         auto &&storage = registry.storage(info);
         storage->emplace(registry, other, storage->get(entity));
     });
@@ -107,7 +107,7 @@ TEST(PolyStorage, CopyRegistry) {
     ASSERT_EQ(other.size(), 0u);
 
     other.assign(registry.data(), registry.data() + registry.size(), registry.released());
-    registry.visit([&](const auto info) { std::as_const(registry).storage(info)->copy_to(other); });
+    registry.visit([&](const auto &info) { std::as_const(registry).storage(info)->copy_to(other); });
 
     ASSERT_EQ(registry.size(), other.size());
     ASSERT_EQ((registry.view<int, char>().size_hint()), (other.view<int, char>().size_hint()));

+ 4 - 4
test/entt/entity/registry.cpp

@@ -83,7 +83,7 @@ TEST(Registry, Context) {
 
     auto count = 0;
 
-    registry.ctx([&count](auto info) {
+    registry.ctx([&count](const auto &info) {
         ASSERT_EQ(info.hash(), entt::type_hash<char>::value());
         ++count;
     });
@@ -1884,7 +1884,7 @@ TEST(Registry, Visit) {
 
     bool hasType[3]{};
 
-    registry.visit([&hasType](auto info) {
+    registry.visit([&hasType](const auto &info) {
         hasType[0] = hasType[0] || (info.hash() == entt::type_hash<int>::value());
         hasType[1] = hasType[1] || (info.hash() == entt::type_hash<double>::value());
         hasType[2] = hasType[2] || (info.hash() == entt::type_hash<char>::value());
@@ -1894,7 +1894,7 @@ TEST(Registry, Visit) {
 
     hasType[0] = hasType[1] = hasType[2] = false;
 
-    registry.visit(entity, [&hasType](auto info) {
+    registry.visit(entity, [&hasType](const auto &info) {
         hasType[0] = hasType[0] || (info.hash() == entt::type_hash<int>::value());
         hasType[1] = hasType[1] || (info.hash() == entt::type_hash<double>::value());
         hasType[2] = hasType[2] || (info.hash() == entt::type_hash<char>::value());
@@ -1904,7 +1904,7 @@ TEST(Registry, Visit) {
 
     hasType[0] = hasType[2] = false;
 
-    registry.visit(other, [&hasType](auto info) {
+    registry.visit(other, [&hasType](const auto &info) {
         hasType[0] = hasType[0] || (info.hash() == entt::type_hash<int>::value());
         hasType[1] = hasType[1] || (info.hash() == entt::type_hash<double>::value());
         hasType[2] = hasType[2] || (info.hash() == entt::type_hash<char>::value());

+ 0 - 1
test/entt/meta/meta_type.cpp

@@ -170,7 +170,6 @@ struct MetaType: ::testing::Test {
 TEST_F(MetaType, Resolve) {
     using namespace entt::literals;
 
-    ASSERT_EQ(entt::resolve(entt::type_info{}), entt::meta_type{});
     ASSERT_EQ(entt::resolve<double>(), entt::resolve("double"_hs));
     ASSERT_EQ(entt::resolve<double>(), entt::resolve(entt::type_id<double>()));