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

memory: all of a sudden I remembered what greater than or equal to means :)

Michele Caini 4 лет назад
Родитель
Сommit
ff41faa3fe
2 измененных файлов с 14 добавлено и 19 удалено
  1. 5 9
      src/entt/core/memory.hpp
  2. 9 10
      test/entt/core/memory.cpp

+ 5 - 9
src/entt/core/memory.hpp

@@ -2,6 +2,7 @@
 #define ENTT_CORE_MEMORY_HPP
 
 #include <cstddef>
+#include <limits>
 #include <memory>
 #include <type_traits>
 #include <utility>
@@ -81,16 +82,11 @@ constexpr void propagate_on_container_swap([[maybe_unused]] Allocator &lhs, [[ma
  * @return The smallest power of two greater than or equal to the given value.
  */
 [[nodiscard]] inline constexpr std::size_t next_power_of_two(const std::size_t value) ENTT_NOEXCEPT {
-    std::size_t curr = value;
+    ENTT_ASSERT(value < (std::size_t{1u} << (std::numeric_limits<std::size_t>::digits - 1)), "Numeric limits exceeded");
+    std::size_t curr = value - (value != 0u);
 
-    curr |= curr >> 1;
-    curr |= curr >> 2;
-    curr |= curr >> 4;
-    curr |= curr >> 8;
-    curr |= curr >> 16;
-
-    if constexpr(sizeof(value) > sizeof(std::uint32_t)) {
-        curr |= curr >> 32;
+    for(int next = 1; next < std::numeric_limits<std::size_t>::digits; next = next * 2) {
+        curr |= curr >> next;
     }
 
     return ++curr;

+ 9 - 10
test/entt/core/memory.cpp

@@ -1,4 +1,5 @@
 #include <cmath>
+#include <limits>
 #include <memory>
 #include <gtest/gtest.h>
 #include <entt/core/memory.hpp>
@@ -51,17 +52,15 @@ TEST(Memory, NextPowerOfTwo) {
     constexpr auto next_power_of_two_of_zero = entt::next_power_of_two(0u);
 
     ASSERT_EQ(next_power_of_two_of_zero, 1u);
-    ASSERT_EQ(entt::next_power_of_two(1u), 2u);
+    ASSERT_EQ(entt::next_power_of_two(1u), 1u);
+    ASSERT_EQ(entt::next_power_of_two(2u), 2u);
+    ASSERT_EQ(entt::next_power_of_two(3u), 4u);
     ASSERT_EQ(entt::next_power_of_two(17u), 32u);
-    ASSERT_EQ(entt::next_power_of_two(32u), 64u);
-    ASSERT_EQ(entt::next_power_of_two(32u), 64u);
-
-    if constexpr(sizeof(std::size_t) > sizeof(std::uint32_t)) {
-        ASSERT_EQ(entt::next_power_of_two(std::pow(2, 32)), std::pow(2, 33));
-        ASSERT_EQ(entt::next_power_of_two(std::pow(2, 64)), 0u);
-    } else {
-        ASSERT_EQ(entt::next_power_of_two(std::pow(2, 32)), 0u);
-    }
+    ASSERT_EQ(entt::next_power_of_two(32u), 32u);
+    ASSERT_EQ(entt::next_power_of_two(33u), 64u);
+    ASSERT_EQ(entt::next_power_of_two(std::pow(2, 16)), std::pow(2, 16));
+    ASSERT_EQ(entt::next_power_of_two(std::pow(2, 16) + 1u), std::pow(2, 17));
+    ASSERT_DEATH(static_cast<void>(entt::next_power_of_two((std::size_t{1u} << (std::numeric_limits<std::size_t>::digits - 1)) + 1)), "");
 }
 
 TEST(Memory, FastMod) {