Ver Fonte

traits: added size_of[_v]

Michele Caini há 5 anos atrás
pai
commit
7967c6dfc8

+ 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) {