From 4c8f1f62a245e1fe4949943b567bb01191b486f2 Mon Sep 17 00:00:00 2001 From: Ben Deane Date: Thu, 21 Mar 2024 09:36:55 -0600 Subject: [PATCH] :art: Refactor field to use stdx::bit_mask Simplified `bits_locator_t::insert` a little: two compile-time cases can be collapsed into one. --- CMakeLists.txt | 2 +- include/msg/field.hpp | 74 +++++++++++++++++-------------------------- 2 files changed, 30 insertions(+), 46 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 077ef6d9..fbcd7d24 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -29,7 +29,7 @@ add_versioned_package( OPTIONS "FMT_INSTALL OFF" "FMT_OS OFF") -add_versioned_package("gh:intel/cpp-std-extensions#9a49ddd") +add_versioned_package("gh:intel/cpp-std-extensions#cff7a15") add_versioned_package("gh:intel/cpp-baremetal-concurrency#8d49b6d") add_library(cib INTERFACE) diff --git a/include/msg/field.hpp b/include/msg/field.hpp index 4147ab6b..202c53a9 100644 --- a/include/msg/field.hpp +++ b/include/msg/field.hpp @@ -72,19 +72,6 @@ concept field_location = requires(T const &t) { }; namespace detail { -template CONSTEVAL auto bit_size() { return sizeof(T) * CHAR_BIT; } - -template ()> - requires(BitSize <= bit_size()) -CONSTEVAL auto bit_mask() -> T { - if constexpr (BitSize == 0u) { - return {}; - } else { - return static_cast(std::numeric_limits::max() >> - (bit_size() - BitSize)); - } -} - template struct field_spec_t { using type = T; @@ -100,7 +87,7 @@ struct bits_locator_t { template [[nodiscard]] constexpr static auto fold(T value) -> T { - if constexpr (BitSize == bit_size()) { + if constexpr (BitSize == stdx::bit_size()) { return {}; } else { return static_cast(value >> BitSize); @@ -109,7 +96,7 @@ struct bits_locator_t { template [[nodiscard]] constexpr static auto unfold(T value) -> T { - if constexpr (BitSize == bit_size()) { + if constexpr (BitSize == stdx::bit_size()) { return {}; } else { return static_cast(value << BitSize); @@ -125,7 +112,7 @@ struct bits_locator_t { constexpr auto BaseIndex = DWordIndex * sizeof(std::uint32_t) / sizeof(elem_t); - constexpr auto elem_size = bit_size(); + constexpr auto elem_size = stdx::bit_size(); constexpr auto max_idx = BaseIndex + Msb / elem_size; constexpr auto min_idx = BaseIndex + Lsb / elem_size; @@ -135,7 +122,7 @@ struct bits_locator_t { constexpr auto current_idx = BaseIndex + CurrentMsb / elem_size; if constexpr (current_idx == max_idx and current_idx == min_idx) { constexpr auto mask = - bit_mask(); + stdx::bit_mask(); constexpr auto shift = Lsb % elem_size; return (std::forward(rng)[current_idx] & mask) >> shift; } else if constexpr (current_idx == min_idx) { @@ -144,7 +131,7 @@ struct bits_locator_t { return value | (std::forward(rng)[current_idx] >> shift); } else if constexpr (current_idx == max_idx) { constexpr auto mask = - bit_mask(); + stdx::bit_mask(); constexpr auto NewMsb = (CurrentMsb / elem_size) * elem_size - 1u; MUSTTAIL return recurse.template operator()( @@ -171,47 +158,44 @@ struct bits_locator_t { constexpr auto BaseIndex = DWordIndex * sizeof(std::uint32_t) / sizeof(elem_t); - constexpr auto elem_size = bit_size(); - constexpr auto max_idx = BaseIndex + Msb / elem_size; - constexpr auto min_idx = BaseIndex + Lsb / elem_size; + constexpr auto elem_size = stdx::bit_size(); + [[maybe_unused]] constexpr auto min_idx = BaseIndex + Lsb / elem_size; + [[maybe_unused]] constexpr auto max_idx = BaseIndex + Msb / elem_size; constexpr auto f = []([[maybe_unused]] auto recurse, Rng &&rng, T value) -> void { constexpr auto current_idx = BaseIndex + CurrentLsb / elem_size; - if constexpr (current_idx == max_idx and current_idx == min_idx) { - constexpr auto shift = CurrentLsb % elem_size; - constexpr auto numbits = Msb - CurrentLsb + 1u; - constexpr auto value_mask = bit_mask() - << shift; - constexpr auto leftover_mask = ~value_mask; + if constexpr (current_idx == max_idx) { + constexpr auto lsb = CurrentLsb % elem_size; + constexpr auto msb = Msb % elem_size; + constexpr auto leftover_mask = + ~stdx::bit_mask(); + auto &elem = std::forward(rng)[current_idx]; elem &= leftover_mask; - elem |= static_cast(value << shift); + elem |= static_cast(value << lsb); } else if constexpr (current_idx == min_idx) { - constexpr auto shift = CurrentLsb % elem_size; - constexpr auto numbits = elem_size - shift; - constexpr auto value_mask = bit_mask(); - constexpr auto leftover_mask = bit_mask(); + constexpr auto lsb = CurrentLsb % elem_size; + constexpr auto numbits = elem_size - lsb; + constexpr auto value_mask = + stdx::bit_mask(); + constexpr auto leftover_mask = ~(value_mask << lsb); + auto &elem = std::forward(rng)[current_idx]; elem &= leftover_mask; - elem |= static_cast((value & value_mask) << shift); + elem |= static_cast((value & value_mask) << lsb); + constexpr auto NewLsb = CurrentLsb + numbits; MUSTTAIL return recurse.template operator()( recurse, std::forward(rng), value >> numbits); - } else if constexpr (current_idx == max_idx) { - constexpr auto numbits = Msb - CurrentLsb + 1u; - constexpr auto value_mask = bit_mask(); - constexpr auto leftover_mask = ~value_mask; - - auto &elem = std::forward(rng)[current_idx]; - elem &= leftover_mask; - elem |= static_cast(value); } else { - constexpr auto value_mask = bit_mask(); + constexpr auto value_mask = stdx::bit_mask(); + auto &elem = std::forward(rng)[current_idx]; elem = value & value_mask; + constexpr auto NewLsb = CurrentLsb + elem_size; MUSTTAIL return recurse.template operator()( recurse, std::forward(rng), value >> elem_size); @@ -272,7 +256,7 @@ template struct field_locator_t { auto const insert_bits = [&]() { B::insert( std::forward(r), - static_cast(raw & detail::bit_mask())); + static_cast(raw & stdx::bit_mask())); raw = B::fold(raw); }; @@ -378,7 +362,7 @@ class field_t : public field_spec_t>, } static_assert((... and Ats.valid()), "Individual field location size cannot exceed 64 bits!"); - static_assert(detail::bit_size() >= (0u + ... + Ats.size()), + static_assert(stdx::bit_size() >= (0u + ... + Ats.size()), "Field size is smaller than sum of locations!"); public: @@ -399,7 +383,7 @@ class field_t : public field_spec_t>, template constexpr static auto fits_inside() -> bool { constexpr auto bits_capacity = - detail::bit_size() * + stdx::bit_size() * stdx::ct_capacity_v; return locator_t::template fits_inside(); }