Przeglądaj źródła

config/sparse_set/storage: avoid power-of-two check at config level

Michele Caini 4 lat temu
rodzic
commit
2f12e524dd

+ 2 - 6
src/entt/config/config.h

@@ -37,16 +37,12 @@
 #endif
 #endif
 
 
 
 
-#ifdef ENTT_SPARSE_PAGE
-	static_assert(ENTT_SPARSE_PAGE && ((ENTT_SPARSE_PAGE & (ENTT_SPARSE_PAGE - 1)) == 0), "ENTT_SPARSE_PAGE must be a power of two");
-#else
+#ifndef ENTT_SPARSE_PAGE
 #   define ENTT_SPARSE_PAGE 4096
 #   define ENTT_SPARSE_PAGE 4096
 #endif
 #endif
 
 
 
 
-#ifdef ENTT_PACKED_PAGE
-static_assert(ENTT_PACKED_PAGE && ((ENTT_PACKED_PAGE & (ENTT_PACKED_PAGE - 1)) == 0), "ENTT_PACKED_PAGE must be a power of two");
-#else
+#ifndef ENTT_PACKED_PAGE
 #   define ENTT_PACKED_PAGE 1024
 #   define ENTT_PACKED_PAGE 1024
 #endif
 #endif
 
 

+ 3 - 3
src/entt/entity/sparse_set.hpp

@@ -185,12 +185,12 @@ class basic_sparse_set {
 
 
     using entity_traits = entt_traits<Entity>;
     using entity_traits = entt_traits<Entity>;
 
 
-    [[nodiscard]] static constexpr auto page(const Entity entt) ENTT_NOEXCEPT {
+    [[nodiscard]] static constexpr std::size_t page(const Entity entt) ENTT_NOEXCEPT {
         return static_cast<size_type>(entity_traits::to_entity(entt) / sparse_page_v);
         return static_cast<size_type>(entity_traits::to_entity(entt) / sparse_page_v);
     }
     }
 
 
-    [[nodiscard]] static constexpr auto offset(const Entity entt) ENTT_NOEXCEPT {
-        return static_cast<size_type>(entity_traits::to_entity(entt) & (sparse_page_v - 1));
+    [[nodiscard]] static constexpr std::size_t offset(const Entity entt) ENTT_NOEXCEPT {
+        return fast_mod<sparse_page_v>(static_cast<size_type>(entity_traits::to_entity(entt)));
     }
     }
 
 
     [[nodiscard]] auto assure_page(const std::size_t idx) {
     [[nodiscard]] auto assure_page(const std::size_t idx) {

+ 11 - 11
src/entt/entity/storage.hpp

@@ -51,7 +51,7 @@ namespace entt {
  */
  */
 template<typename Entity, typename Type, typename Allocator, typename>
 template<typename Entity, typename Type, typename Allocator, typename>
 class basic_storage: public basic_sparse_set<Entity, typename std::allocator_traits<Allocator>::template rebind_alloc<Entity>> {
 class basic_storage: public basic_sparse_set<Entity, typename std::allocator_traits<Allocator>::template rebind_alloc<Entity>> {
-    static constexpr auto packed_page = ENTT_PACKED_PAGE;
+    static constexpr auto packed_page_v = ENTT_PACKED_PAGE;
 
 
     using allocator_traits = std::allocator_traits<Allocator>;
     using allocator_traits = std::allocator_traits<Allocator>;
 
 
@@ -167,12 +167,12 @@ class basic_storage: public basic_sparse_set<Entity, typename std::allocator_tra
         difference_type index;
         difference_type index;
     };
     };
 
 
-    [[nodiscard]] static auto page(const std::size_t pos) ENTT_NOEXCEPT {
-        return pos / packed_page;
+    [[nodiscard]] static constexpr std::size_t page(const std::size_t pos) ENTT_NOEXCEPT {
+        return pos / packed_page_v;
     }
     }
 
 
-    [[nodiscard]] static auto offset(const std::size_t pos) ENTT_NOEXCEPT {
-        return pos & (packed_page - 1);
+    [[nodiscard]] static constexpr std::size_t offset(const std::size_t pos) ENTT_NOEXCEPT {
+        return fast_mod<packed_page_v>(pos);
     }
     }
 
 
     void release_memory() {
     void release_memory() {
@@ -185,7 +185,7 @@ class basic_storage: public basic_sparse_set<Entity, typename std::allocator_tra
             alloc_ptr allocator_ptr{allocator};
             alloc_ptr allocator_ptr{allocator};
 
 
             for(size_type pos{}; pos < len; ++pos) {
             for(size_type pos{}; pos < len; ++pos) {
-                alloc_traits::deallocate(allocator, packed[pos], packed_page);
+                alloc_traits::deallocate(allocator, packed[pos], packed_page_v);
                 alloc_ptr_traits::destroy(allocator_ptr, std::addressof(packed[pos]));
                 alloc_ptr_traits::destroy(allocator_ptr, std::addressof(packed[pos]));
             }
             }
 
 
@@ -207,11 +207,11 @@ class basic_storage: public basic_sparse_set<Entity, typename std::allocator_tra
 
 
             ENTT_TRY {
             ENTT_TRY {
                 for(auto next = len; next < sz; ++next) {
                 for(auto next = len; next < sz; ++next) {
-                    mem[next] = alloc_traits::allocate(allocator, packed_page);
+                    mem[next] = alloc_traits::allocate(allocator, packed_page_v);
                 }
                 }
             } ENTT_CATCH {
             } ENTT_CATCH {
                 for(auto next = len; next < sz && mem[next]; ++next) {
                 for(auto next = len; next < sz && mem[next]; ++next) {
-                    alloc_traits::deallocate(allocator, mem[next], packed_page);
+                    alloc_traits::deallocate(allocator, mem[next], packed_page_v);
                 }
                 }
 
 
                 std::destroy(mem + len, mem + sz);
                 std::destroy(mem + len, mem + sz);
@@ -233,7 +233,7 @@ class basic_storage: public basic_sparse_set<Entity, typename std::allocator_tra
     }
     }
 
 
     void release_unused_pages() {
     void release_unused_pages() {
-        if(const auto length = base_type::size() / packed_page; length < bucket.second()) {
+        if(const auto length = base_type::size() / packed_page_v; length < bucket.second()) {
             auto &allocator = bucket.first();
             auto &allocator = bucket.first();
             auto &len = bucket.second();
             auto &len = bucket.second();
             alloc_ptr allocator_ptr{allocator};
             alloc_ptr allocator_ptr{allocator};
@@ -242,7 +242,7 @@ class basic_storage: public basic_sparse_set<Entity, typename std::allocator_tra
             std::uninitialized_copy(packed, packed + length, mem);
             std::uninitialized_copy(packed, packed + length, mem);
 
 
             for(auto pos = length; pos < len; ++pos) {
             for(auto pos = length; pos < len; ++pos) {
-                alloc_traits::deallocate(allocator, packed[pos], packed_page);
+                alloc_traits::deallocate(allocator, packed[pos], packed_page_v);
             }
             }
 
 
             std::destroy(packed, packed + len);
             std::destroy(packed, packed + len);
@@ -479,7 +479,7 @@ public:
      * @return Capacity of the storage.
      * @return Capacity of the storage.
      */
      */
     [[nodiscard]] size_type capacity() const ENTT_NOEXCEPT override {
     [[nodiscard]] size_type capacity() const ENTT_NOEXCEPT override {
-        return bucket.second() * packed_page;
+        return bucket.second() * packed_page_v;
     }
     }
 
 
     /*! @brief Requests the removal of unused capacity. */
     /*! @brief Requests the removal of unused capacity. */