From 505f4a2b4fa52d94200ec2092b7edd7403949feb Mon Sep 17 00:00:00 2001 From: Michele Caini Date: Thu, 9 Sep 2021 00:20:20 +0200 Subject: [PATCH] type_info: * constexpr support * reduce instantiations * reduce function calls/indirection --- src/entt/core/type_info.hpp | 78 +++++++++++++----------------------- test/entt/core/type_info.cpp | 4 +- 2 files changed, 30 insertions(+), 52 deletions(-) diff --git a/src/entt/core/type_info.hpp b/src/entt/core/type_info.hpp index a43a50e63..f8a1517a2 100644 --- a/src/entt/core/type_info.hpp +++ b/src/entt/core/type_info.hpp @@ -148,98 +148,72 @@ struct type_name final { /*! @brief Implementation specific information about a type. */ -class type_info final { - enum class operation { SEQ, HASH, NAME }; - - using vtable_type = id_type(const operation, void *); - - template - static id_type basic_vtable(const operation op, void *to) { - static_assert(std::is_same_v>, Type>, "Invalid type"); - - switch(op) { - case operation::SEQ: - return type_seq::value(); - break; - case operation::HASH: - return type_hash::value(); - break; - case operation::NAME: - *static_cast(to) = type_name::value(); - break; - } - - return {}; - } - -public: +struct type_info final { /*! @brief Default constructor. */ constexpr type_info() ENTT_NOEXCEPT - : vtable{} + : index{}, + identifier{}, + alias{} {} /*! @brief Default copy constructor. */ - type_info(const type_info &) ENTT_NOEXCEPT = default; + constexpr type_info(const type_info &) ENTT_NOEXCEPT = default; /*! @brief Default move constructor. */ - type_info(type_info &&) ENTT_NOEXCEPT = default; + constexpr type_info(type_info &&) ENTT_NOEXCEPT = default; /** * @brief Creates a type info object for a given type. * @tparam Type Type for which to generate a type info object. */ template - type_info(std::in_place_type_t) ENTT_NOEXCEPT - : vtable{&basic_vtable} + constexpr type_info(std::in_place_type_t) ENTT_NOEXCEPT + : index{&type_seq>>::value}, + identifier{type_hash>>::value()}, + alias{type_name>>::value()} {} /** * @brief Default copy assignment operator. * @return This type info object. */ - type_info & operator=(const type_info &) ENTT_NOEXCEPT = default; + constexpr type_info & operator=(const type_info &) ENTT_NOEXCEPT = default; /** * @brief Default move assignment operator. * @return This type info object. */ - type_info & operator=(type_info &&) ENTT_NOEXCEPT = default; + 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]] explicit operator bool() const ENTT_NOEXCEPT { - return vtable != nullptr; + [[nodiscard]] constexpr explicit operator bool() const ENTT_NOEXCEPT { + return alias.data() != nullptr; } /** * @brief Type sequential identifier. * @return Type sequential identifier. */ - [[nodiscard]] id_type seq() const ENTT_NOEXCEPT { - return vtable ? vtable(operation::SEQ, nullptr) : id_type{}; + [[nodiscard]] constexpr id_type seq() const ENTT_NOEXCEPT { + return index(); } /** * @brief Type hash. * @return Type hash. */ - [[nodiscard]] id_type hash() const ENTT_NOEXCEPT { - return vtable ? vtable(operation::HASH, nullptr) : id_type{}; + [[nodiscard]] constexpr id_type hash() const ENTT_NOEXCEPT { + return identifier; } /** * @brief Type name. * @return Type name. */ - [[nodiscard]] std::string_view name() const ENTT_NOEXCEPT { - std::string_view value{}; - - if(vtable) { - vtable(operation::NAME, &value); - } - - return value; + [[nodiscard]] constexpr std::string_view name() const ENTT_NOEXCEPT { + return alias; } /** @@ -247,12 +221,14 @@ public: * @param other Object with which to compare. * @return False if the two contents differ, true otherwise. */ - [[nodiscard]] bool operator==(const type_info &other) const ENTT_NOEXCEPT { - return hash() == other.hash(); + [[nodiscard]] constexpr bool operator==(const type_info &other) const ENTT_NOEXCEPT { + return identifier == other.identifier; } private: - vtable_type *vtable; + id_type(* index)(); + id_type identifier; + std::string_view alias; }; @@ -262,7 +238,7 @@ private: * @param rhs A type info object. * @return True if the two contents differ, false otherwise. */ -[[nodiscard]] inline bool operator!=(const type_info &lhs, const type_info &rhs) ENTT_NOEXCEPT { +[[nodiscard]] inline constexpr bool operator!=(const type_info &lhs, const type_info &rhs) ENTT_NOEXCEPT { return !(lhs == rhs); } @@ -273,7 +249,7 @@ private: * @return The type info object for the given type. */ template -[[nodiscard]] type_info type_id() ENTT_NOEXCEPT { +[[nodiscard]] constexpr type_info type_id() ENTT_NOEXCEPT { return type_info{std::in_place_type>>}; } diff --git a/test/entt/core/type_info.cpp b/test/entt/core/type_info.cpp index 6a6bb25a9..fbe094a2c 100644 --- a/test/entt/core/type_info.cpp +++ b/test/entt/core/type_info.cpp @@ -51,8 +51,10 @@ TEST(TypeInfo, Functionalities) { ASSERT_EQ(entt::type_info{}, entt::type_info{}); ASSERT_NE(entt::type_id(), entt::type_info{}); ASSERT_NE(entt::type_id(), entt::type_id()); + ASSERT_EQ(entt::type_id(), entt::type_id()); + ASSERT_EQ(entt::type_id(), entt::type_id()); - auto info = entt::type_id(); + constexpr auto info = entt::type_id(); const auto unnamed = entt::type_id(); entt::type_info empty{};