@@ -117,6 +117,24 @@ class bitset {
117117 template <typename F, auto M, typename ... S>
118118 friend constexpr auto for_each (F &&f, bitset<M, S> const &...bs) -> F;
119119
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+
120138 public:
121139 constexpr bitset () = default;
122140 constexpr explicit bitset (std::uint64_t value) {
@@ -421,6 +439,19 @@ constexpr auto for_each(F &&f, bitset<M, S> const &...bs) -> F {
421439 }
422440}
423441
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+
424455#if __cplusplus >= 202002L
425456template <std::size_t N> bitset (ct_string<N>) -> bitset<N - 1>;
426457#endif
0 commit comments