소스 검색

traits: added size_of[_v]

Michele Caini 5 년 전
부모
커밋
7967c6dfc8
4개의 변경된 파일46개의 추가작업 그리고 3개의 파일을 삭제
  1. 13 0
      docs/md/core.md
  2. 25 1
      src/entt/core/type_traits.hpp
  3. 1 2
      src/entt/entity/storage.hpp
  4. 7 0
      test/entt/core/type_traits.cpp

+ 13 - 0
docs/md/core.md

@@ -17,6 +17,7 @@
   * [Type info](#type-info)
   * [Type info](#type-info)
     * [Almost unique identifiers](#almost-unique-identifiers)
     * [Almost unique identifiers](#almost-unique-identifiers)
   * [Type traits](#type-traits)
   * [Type traits](#type-traits)
+    * [Size of](#size-of)
     * [Member class type](#member-class-type)
     * [Member class type](#member-class-type)
     * [Integral constant](#integral-constant)
     * [Integral constant](#integral-constant)
     * [Tag](#tag)
     * [Tag](#tag)
@@ -376,6 +377,18 @@ This list **is not** exhaustive and contains only some of the most useful
 classes. Refer to the inline documentation for more information on the features
 classes. Refer to the inline documentation for more information on the features
 offered by this module.
 offered by this module.
 
 
+### Size of
+
+The standard operator `sizeof` complains when users provide it for example with
+function or incomplete types. On the other hand, it's guaranteed that its result
+is always nonzero, even if applied to an empty class type.<br/>
+This small class combines the two and offers an alternative to `sizeof` that
+works under all circumstances, returning zero if the type isn't supported:
+
+```cpp
+const auto size = entt::size_of_v<void>;
+```
+
 ### Member class type
 ### Member class type
 
 
 The `auto` template parameter introduced with C++17 made it possible to simplify
 The `auto` template parameter introduced with C++17 made it possible to simplify

+ 25 - 1
src/entt/core/type_traits.hpp

@@ -12,6 +12,30 @@
 namespace entt {
 namespace entt {
 
 
 
 
+/**
+ * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains.
+ * @tparam Type The type of which to return the size.
+ * @tparam The size of the type if `sizeof` accepts it, 0 otherwise.
+ */
+template<typename Type, typename = void>
+struct size_of: std::integral_constant<std::size_t, 0u> {};
+
+
+/*! @copydoc size_of */
+template<typename Type>
+struct size_of<Type, std::void_t<decltype(sizeof(Type))>>
+    : std::integral_constant<std::size_t, sizeof(Type)>
+{};
+
+
+/**
+* @brief Helper variable template.
+* @tparam Type The type of which to return the size.
+*/
+template<class Type>
+inline constexpr auto size_of_v = size_of<Type>::value;
+
+
 /**
 /**
  * @brief Using declaration to be used to _repeat_ the same type a number of
  * @brief Using declaration to be used to _repeat_ the same type a number of
  * times equal to the size of a given parameter pack.
  * times equal to the size of a given parameter pack.
@@ -215,7 +239,7 @@ inline constexpr auto type_list_contains_v = type_list_contains<List, Type>::val
  * equality comparable, false otherwise.
  * equality comparable, false otherwise.
  * @tparam Type Potentially equality comparable type.
  * @tparam Type Potentially equality comparable type.
  */
  */
-template<typename Type, typename = std::void_t<>>
+template<typename Type, typename = void>
 struct is_equality_comparable: std::false_type {};
 struct is_equality_comparable: std::false_type {};
 
 
 
 

+ 1 - 2
src/entt/entity/storage.hpp

@@ -45,7 +45,7 @@ namespace entt {
  * @tparam Entity A valid entity type (see entt_traits for more details).
  * @tparam Entity A valid entity type (see entt_traits for more details).
  * @tparam Type Type of objects assigned to the entities.
  * @tparam Type Type of objects assigned to the entities.
  */
  */
-template<typename Entity, typename Type, typename = std::void_t<>>
+template<typename Entity, typename Type, typename = void>
 class storage: public sparse_set<Entity> {
 class storage: public sparse_set<Entity> {
     static_assert(std::is_move_constructible_v<Type> && std::is_move_assignable_v<Type>, "The managed type must be at least move constructible and assignable");
     static_assert(std::is_move_constructible_v<Type> && std::is_move_assignable_v<Type>, "The managed type must be at least move constructible and assignable");
 
 
@@ -171,7 +171,6 @@ public:
     /*! @brief Constant reverse iterator type. */
     /*! @brief Constant reverse iterator type. */
     using const_reverse_iterator = const Type *;
     using const_reverse_iterator = const Type *;
 
 
-
     /**
     /**
      * @brief Increases the capacity of a storage.
      * @brief Increases the capacity of a storage.
      *
      *

+ 7 - 0
test/entt/core/type_traits.cpp

@@ -9,6 +9,13 @@
 #include <entt/core/hashed_string.hpp>
 #include <entt/core/hashed_string.hpp>
 #include <entt/core/type_traits.hpp>
 #include <entt/core/type_traits.hpp>
 
 
+TEST(TypeTraits, SizeOf) {
+    static_assert(entt::size_of_v<void> == 0u);
+    static_assert(entt::size_of_v<char> == sizeof(char));
+    static_assert(entt::size_of_v<int[]> == 0u);
+    static_assert(entt::size_of_v<int[3]> == sizeof(int[3]));
+}
+
 TEST(TypeTraits, UnpackAsType) {
 TEST(TypeTraits, UnpackAsType) {
     ASSERT_EQ([](auto &&... args) {
     ASSERT_EQ([](auto &&... args) {
         return [](entt::unpack_as_t<int, decltype(args)>... value) {
         return [](entt::unpack_as_t<int, decltype(args)>... value) {