memory: fast_mod no longer requires a compile-time modulus (but it's still a constexpr function)
This commit is contained in:
@@ -98,14 +98,13 @@ constexpr void propagate_on_container_swap([[maybe_unused]] Allocator &lhs, [[ma
|
||||
|
||||
/**
|
||||
* @brief Fast module utility function (powers of two only).
|
||||
* @tparam Value Compile-time page size, it must be a power of two.
|
||||
* @param value A value for which to calculate the modulus.
|
||||
* @return Remainder of division.
|
||||
* @param mod _Modulus_, it must be a power of two.
|
||||
* @return The common remainder.
|
||||
*/
|
||||
template<std::size_t Value>
|
||||
[[nodiscard]] constexpr std::size_t fast_mod(const std::size_t value) ENTT_NOEXCEPT {
|
||||
static_assert(is_power_of_two(Value), "Value must be a power of two");
|
||||
return value & (Value - 1u);
|
||||
[[nodiscard]] inline constexpr std::size_t fast_mod(const std::size_t value, const std::size_t mod) ENTT_NOEXCEPT {
|
||||
ENTT_ASSERT(is_power_of_two(mod), "Value must be a power of two");
|
||||
return value & (mod - 1u);
|
||||
}
|
||||
|
||||
} // namespace entt
|
||||
|
||||
@@ -171,13 +171,13 @@ class basic_sparse_set {
|
||||
[[nodiscard]] auto sparse_ptr(const Entity entt) const {
|
||||
const auto pos = static_cast<size_type>(entity_traits::to_entity(entt));
|
||||
const auto page = pos / sparse_page_v;
|
||||
return (page < sparse.size() && sparse[page]) ? (sparse[page] + fast_mod<sparse_page_v>(pos)) : nullptr;
|
||||
return (page < sparse.size() && sparse[page]) ? (sparse[page] + fast_mod(pos, sparse_page_v)) : nullptr;
|
||||
}
|
||||
|
||||
[[nodiscard]] auto &sparse_ref(const Entity entt) const {
|
||||
ENTT_ASSERT(sparse_ptr(entt), "Invalid element");
|
||||
const auto pos = static_cast<size_type>(entity_traits::to_entity(entt));
|
||||
return sparse[pos / sparse_page_v][fast_mod<sparse_page_v>(pos)];
|
||||
return sparse[pos / sparse_page_v][fast_mod(pos, sparse_page_v)];
|
||||
}
|
||||
|
||||
void release_sparse_pages() {
|
||||
@@ -253,7 +253,7 @@ protected:
|
||||
std::uninitialized_fill(sparse[page], sparse[page] + sparse_page_v, null);
|
||||
}
|
||||
|
||||
auto &elem = sparse[page][fast_mod<sparse_page_v>(pos)];
|
||||
auto &elem = sparse[page][fast_mod(pos, sparse_page_v)];
|
||||
ENTT_ASSERT(entity_traits::to_version(elem) == entity_traits::to_version(tombstone), "Slot not available");
|
||||
|
||||
if(free_list == null) {
|
||||
|
||||
@@ -123,7 +123,7 @@ public:
|
||||
|
||||
[[nodiscard]] pointer operator->() const ENTT_NOEXCEPT {
|
||||
const auto pos = index - 1;
|
||||
return (*packed)[pos / packed_page_v] + fast_mod<packed_page_v>(pos);
|
||||
return (*packed)[pos / packed_page_v] + fast_mod(pos, packed_page_v);
|
||||
}
|
||||
|
||||
[[nodiscard]] reference operator*() const ENTT_NOEXCEPT {
|
||||
@@ -182,7 +182,7 @@ class basic_storage: public basic_sparse_set<Entity, typename std::allocator_tra
|
||||
using container_type = std::vector<typename alloc_traits::pointer, typename alloc_traits::template rebind_alloc<typename alloc_traits::pointer>>;
|
||||
|
||||
[[nodiscard]] auto &element_at(const std::size_t pos) const {
|
||||
return packed.first()[pos / packed_page_v][fast_mod<packed_page_v>(pos)];
|
||||
return packed.first()[pos / packed_page_v][fast_mod(pos, packed_page_v)];
|
||||
}
|
||||
|
||||
auto assure_at_least(const std::size_t pos) {
|
||||
@@ -204,7 +204,7 @@ class basic_storage: public basic_sparse_set<Entity, typename std::allocator_tra
|
||||
}
|
||||
}
|
||||
|
||||
return container[idx] + fast_mod<packed_page_v>(pos);
|
||||
return container[idx] + fast_mod(pos, packed_page_v);
|
||||
}
|
||||
|
||||
void release_unused_pages() {
|
||||
|
||||
@@ -65,7 +65,10 @@ TEST(Memory, NextPowerOfTwo) {
|
||||
}
|
||||
|
||||
TEST(Memory, FastMod) {
|
||||
ASSERT_EQ(entt::fast_mod<8u>(0u), 0u);
|
||||
ASSERT_EQ(entt::fast_mod<8u>(7u), 7u);
|
||||
ASSERT_EQ(entt::fast_mod<8u>(8u), 0u);
|
||||
// constexpr-ness guaranteed
|
||||
constexpr auto fast_mod_of_zero = entt::fast_mod(0u, 8u);
|
||||
|
||||
ASSERT_EQ(fast_mod_of_zero, 0u);
|
||||
ASSERT_EQ(entt::fast_mod(7u, 8u), 7u);
|
||||
ASSERT_EQ(entt::fast_mod(8u, 8u), 0u);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user