Skip to content

Commit 37cc9c5

Browse files
authored
Merge pull request #191 from elbeno/bitset-enums
🎨 Preserve enum values in bitset `for_each`
2 parents e6b6404 + 23ddf02 commit 37cc9c5

File tree

2 files changed

+19
-4
lines changed

2 files changed

+19
-4
lines changed

include/stdx/bitset.hpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -101,13 +101,16 @@ class bitset {
101101
return lhs;
102102
}
103103

104+
using iter_arg_t = conditional_t<std::is_enum_v<decltype(Size)>,
105+
decltype(Size), std::size_t>;
106+
104107
template <typename F> constexpr auto for_each(F &&f) const -> F {
105108
std::size_t i = 0;
106109
for (auto e : storage) {
107110
while (e != 0) {
108111
auto const offset = static_cast<std::size_t>(countr_zero(e));
109112
e &= static_cast<elem_t>(~(bit << offset));
110-
f(i + offset);
113+
f(static_cast<iter_arg_t>(i + offset));
111114
}
112115
i += std::numeric_limits<elem_t>::digits;
113116
}
@@ -124,7 +127,8 @@ class bitset {
124127
while (e != 0) {
125128
auto const offset = static_cast<std::size_t>(countr_zero(e));
126129
e &= static_cast<elem_t>(~(bit << offset));
127-
init = r(std::move(init), f(i + offset));
130+
init =
131+
r(std::move(init), f(static_cast<iter_arg_t>(i + offset)));
128132
}
129133
i += std::numeric_limits<elem_t>::digits;
130134
}
@@ -440,8 +444,8 @@ constexpr auto for_each(F &&f, bitset<M, S> const &...bs) -> F {
440444
}
441445

442446
template <typename T, typename F, typename R, auto M, typename... S>
443-
constexpr auto transform_reduce(F &&f, R &&r, T init,
444-
bitset<M, S> const &...bs) -> T {
447+
[[nodiscard]] constexpr auto transform_reduce(F &&f, R &&r, T init,
448+
bitset<M, S> const &...bs) -> T {
445449
if constexpr (sizeof...(bs) == 1) {
446450
return (bs.transform_reduce(std::forward<F>(f), std::forward<R>(r),
447451
std::move(init)),

test/bitset.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -474,6 +474,17 @@ TEST_CASE("use bitset with enum struct (place_bits construct)", "[bitset]") {
474474
static_assert(bs.to_natural() == 1);
475475
}
476476

477+
TEST_CASE("use bitset with enum struct (for_each)", "[bitset]") {
478+
constexpr auto bs = stdx::bitset<Bits::MAX>{stdx::all_bits};
479+
for_each([](Bits) {}, bs);
480+
}
481+
482+
TEST_CASE("use bitset with enum struct (transform_reduce)", "[bitset]") {
483+
constexpr auto bs = stdx::bitset<Bits::MAX>{stdx::all_bits};
484+
CHECK(transform_reduce([](Bits) { return true; }, std::logical_or{}, false,
485+
bs));
486+
}
487+
477488
#if __cplusplus >= 202002L
478489
TEST_CASE("construct with a ct_string", "[bitset]") {
479490
using namespace stdx::literals;

0 commit comments

Comments
 (0)