Skip to content

Commit

Permalink
Merge pull request #191 from elbeno/bitset-enums
Browse files Browse the repository at this point in the history
🎨 Preserve enum values in bitset `for_each`
  • Loading branch information
bdeane-intel authored Feb 12, 2025
2 parents e6b6404 + 23ddf02 commit 37cc9c5
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 4 deletions.
12 changes: 8 additions & 4 deletions include/stdx/bitset.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,13 +101,16 @@ class bitset {
return lhs;
}

using iter_arg_t = conditional_t<std::is_enum_v<decltype(Size)>,
decltype(Size), std::size_t>;

template <typename F> constexpr auto for_each(F &&f) const -> F {
std::size_t i = 0;
for (auto e : storage) {
while (e != 0) {
auto const offset = static_cast<std::size_t>(countr_zero(e));
e &= static_cast<elem_t>(~(bit << offset));
f(i + offset);
f(static_cast<iter_arg_t>(i + offset));
}
i += std::numeric_limits<elem_t>::digits;
}
Expand All @@ -124,7 +127,8 @@ class bitset {
while (e != 0) {
auto const offset = static_cast<std::size_t>(countr_zero(e));
e &= static_cast<elem_t>(~(bit << offset));
init = r(std::move(init), f(i + offset));
init =
r(std::move(init), f(static_cast<iter_arg_t>(i + offset)));
}
i += std::numeric_limits<elem_t>::digits;
}
Expand Down Expand Up @@ -440,8 +444,8 @@ constexpr auto for_each(F &&f, bitset<M, S> const &...bs) -> F {
}

template <typename T, typename F, typename R, auto M, typename... S>
constexpr auto transform_reduce(F &&f, R &&r, T init,
bitset<M, S> const &...bs) -> T {
[[nodiscard]] constexpr auto transform_reduce(F &&f, R &&r, T init,
bitset<M, S> const &...bs) -> T {
if constexpr (sizeof...(bs) == 1) {
return (bs.transform_reduce(std::forward<F>(f), std::forward<R>(r),
std::move(init)),
Expand Down
11 changes: 11 additions & 0 deletions test/bitset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,17 @@ TEST_CASE("use bitset with enum struct (place_bits construct)", "[bitset]") {
static_assert(bs.to_natural() == 1);
}

TEST_CASE("use bitset with enum struct (for_each)", "[bitset]") {
constexpr auto bs = stdx::bitset<Bits::MAX>{stdx::all_bits};
for_each([](Bits) {}, bs);
}

TEST_CASE("use bitset with enum struct (transform_reduce)", "[bitset]") {
constexpr auto bs = stdx::bitset<Bits::MAX>{stdx::all_bits};
CHECK(transform_reduce([](Bits) { return true; }, std::logical_or{}, false,
bs));
}

#if __cplusplus >= 202002L
TEST_CASE("construct with a ct_string", "[bitset]") {
using namespace stdx::literals;
Expand Down

0 comments on commit 37cc9c5

Please sign in to comment.