Skip to content

Commit e7a4fdf

Browse files
committed
Add iterate() impl to cartesian_base
The final boss... In theory, we could make `cartesian_product` and `cartesian_product_map` iterable when the first argument is a non-sequence iterable, but that doesn't seem worth the effort.
1 parent af2afaa commit e7a4fdf

File tree

2 files changed

+28
-2
lines changed

2 files changed

+28
-2
lines changed

include/flux/adaptor/cartesian_base.hpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,11 +204,37 @@ struct cartesian_traits_base_impl : default_sequence_traits {
204204
}
205205
}
206206

207+
template <std::size_t I, typename Self, typename Predicate,
208+
typename... PartialElements>
209+
static constexpr auto iterate_impl(Self& self, Predicate& pred,
210+
PartialElements&&... partial_elements) -> bool
211+
{
212+
if constexpr (I == Arity - 1) {
213+
return flux::iterate(get_base<I>(self), [&](auto&& elem) {
214+
if constexpr (ReadKind == read_kind::tuple) {
215+
return std::invoke(pred, element_t<Self>(FLUX_FWD(partial_elements)..., FLUX_FWD(elem)));
216+
} else {
217+
return std::invoke(pred, std::invoke(self.func_, FLUX_FWD(partial_elements)..., FLUX_FWD(elem)));
218+
}
219+
});
220+
} else {
221+
return flux::iterate(get_base<I>(self), [&](auto&& elem) {
222+
return iterate_impl<I+1>(self, pred, FLUX_FWD(partial_elements)..., FLUX_FWD(elem));
223+
});
224+
}
225+
}
226+
207227
protected:
208228
using types = cartesian_traits_types<Arity, CartesianKind, ReadKind, Bases...>;
209229

210230
public:
211231

232+
template <typename Self, typename Pred>
233+
static constexpr auto iterate(Self& self, Pred&& pred) -> bool
234+
{
235+
return iterate_impl<0>(self, pred);
236+
}
237+
212238
template <typename Self>
213239
static constexpr auto first(Self& self)
214240
requires (CartesianKind == cartesian_kind::product)

test/test_cartesian_product.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -451,12 +451,12 @@ constexpr bool test_cartesian_product()
451451
STATIC_CHECK(count_j == 4);
452452
}
453453

454-
// `cartesian_product` `for_each_while` short circuits.
454+
// `cartesian_product` `iterate` short circuits.
455455
{
456456
auto cart = flux::cartesian_product(std::array{100, 200}, std::array{300, 0});
457457

458458
int count = 0;
459-
cart.for_each_while(flux::unpack([&] (auto, auto j) {
459+
flux::iterate(cart, flux::unpack([&] (auto, auto j) {
460460
++count;
461461
return j != 0;
462462
}));

0 commit comments

Comments
 (0)