@@ -117,6 +117,24 @@ class bitset {
117
117
template <typename F, auto M, typename ... S>
118
118
friend constexpr auto for_each (F &&f, bitset<M, S> const &...bs) -> F;
119
119
120
+ template <typename T, typename F, typename R>
121
+ constexpr auto transform_reduce (F &&f, R &&r, T init) const -> T {
122
+ std::size_t i = 0 ;
123
+ for (auto e : storage) {
124
+ while (e != 0 ) {
125
+ auto const offset = static_cast <std::size_t >(countr_zero (e));
126
+ e &= static_cast <elem_t >(~(bit << offset));
127
+ init = r (std::move (init), f (i + offset));
128
+ }
129
+ i += std::numeric_limits<elem_t >::digits;
130
+ }
131
+ return init;
132
+ }
133
+
134
+ template <typename T, typename F, typename R, auto M, typename ... S>
135
+ friend constexpr auto transform_reduce (F &&f, R &&r, T init,
136
+ bitset<M, S> const &...bs) -> T;
137
+
120
138
public:
121
139
constexpr bitset () = default;
122
140
constexpr explicit bitset (std::uint64_t value) {
@@ -421,6 +439,19 @@ constexpr auto for_each(F &&f, bitset<M, S> const &...bs) -> F {
421
439
}
422
440
}
423
441
442
+ 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 {
445
+ if constexpr (sizeof ...(bs) == 1 ) {
446
+ return (bs.transform_reduce (std::forward<F>(f), std::forward<R>(r),
447
+ std::move (init)),
448
+ ...);
449
+ } else {
450
+ static_assert (stdx::always_false_v<F>, " unimplemented" );
451
+ return init;
452
+ }
453
+ }
454
+
424
455
#if __cplusplus >= 202002L
425
456
template <std::size_t N> bitset (ct_string<N>) -> bitset<N - 1>;
426
457
#endif
0 commit comments