Просмотр исходного кода

type_info:
* reserve a seq identifier for empty type_info objects
* require type_index to return non-zero values
* make type_info default constructible
* add type_info::operator bool()

Michele Caini 3 лет назад
Родитель
Сommit
6b9d346b8b
2 измененных файлов с 31 добавлено и 3 удалено
  1. 21 3
      src/entt/core/type_info.hpp
  2. 10 0
      test/entt/core/type_info.cpp

+ 21 - 3
src/entt/core/type_info.hpp

@@ -21,7 +21,8 @@ namespace internal {
 struct ENTT_API type_index final {
     [[nodiscard]] static id_type next() ENTT_NOEXCEPT {
         static ENTT_MAYBE_ATOMIC(id_type) value{};
-        return value++;
+        // 0u is reserved for empty type_info objects
+        return ++value;
     }
 };
 
@@ -146,9 +147,17 @@ class type_info final {
     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()} {}
+          alias{type_name<std::remove_reference_t<std::remove_const_t<Type>>>::value()} {
+        ENTT_ASSERT(seq != 0u, "Invalid type index");
+    }
 
 public:
+    /*! @brief Default constructor. */
+    constexpr type_info() ENTT_NOEXCEPT
+        : seq{},
+          identifier{},
+          alias{} {}
+
     /**
      * @brief Type index.
      * @return Type index.
@@ -173,6 +182,14 @@ public:
         return alias;
     }
 
+    /**
+     * @brief Returns true if properly initialized, false otherwise.
+     * @return True if properly initialized, false otherwise.
+     */
+    [[nodiscard]] explicit constexpr operator bool() const ENTT_NOEXCEPT {
+        return (seq != 0u);
+    }
+
 private:
     id_type seq;
     id_type identifier;
@@ -245,12 +262,13 @@ private:
 /**
  * @brief Returns the type info object associated to a given type.
  *
+ * The returned element refers to an object with static storage duration.<br/>
  * The type doesn't need to be a complete type. If the type is a reference, the
  * result refers to the referenced type. In all cases, top-level cv-qualifiers
  * are ignored.
  *
  * @tparam Type Type for which to generate a type info object.
- * @return A properly initialized type info object.
+ * @return A reference to a properly initialized type info object.
  */
 template<typename Type>
 [[nodiscard]] const type_info &type_id() ENTT_NOEXCEPT {

+ 10 - 0
test/entt/core/type_info.cpp

@@ -93,6 +93,16 @@ TEST(TypeInfo, Functionalities) {
     ASSERT_EQ(other.name(), info.name());
 }
 
+TEST(TypeInfo, Validity) {
+    entt::type_info info{};
+    entt::type_info other = entt::type_id<int>();
+
+    ASSERT_FALSE(info);
+    ASSERT_TRUE(other);
+    ASSERT_EQ(info.index(), 0u);
+    ASSERT_NE(other.index(), 0u);
+}
+
 TEST(TypeInfo, Order) {
     entt::type_info rhs = entt::type_id<int>();
     entt::type_info lhs = entt::type_id<char>();