Skip to content

Commit

Permalink
Merge pull request #180 from tcbrindle/pr/fix_cart_prod_last
Browse files Browse the repository at this point in the history
Fix cartesian_product::last with empty sequence
  • Loading branch information
tcbrindle authored Mar 14, 2024
2 parents 6719d90 + a25f209 commit 05c555e
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 3 deletions.
17 changes: 14 additions & 3 deletions include/flux/op/cartesian_base.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -270,9 +270,20 @@ struct cartesian_traits_base_impl {
static constexpr auto last(Self& self) -> cursor_t<Self>
requires cartesian_is_bounded<Bases...>
{
auto cur = first(self);
std::get<0>(cur) = flux::last(get_base<0>(self));
return cur;
if constexpr (CartesianKind == cartesian_kind::product) {
auto cur = first(self);
bool any_is_empty = std::apply([](auto& /*ignored*/, auto&... bases) {
return (flux::is_empty(bases) || ...);
}, self.bases_);
if (!any_is_empty) {
std::get<0>(cur) = flux::last(get_base<0>(self));
}
return cur;
} else {
auto cur = first(self);
std::get<0>(cur) = flux::last(get_base<0>(self));
return cur;
}
}

template <typename Self>
Expand Down
15 changes: 15 additions & 0 deletions test/test_cartesian_power.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -261,9 +261,24 @@ constexpr bool test_cartesian_power()

static_assert(test_cartesian_power());

// https://github.com/tcbrindle/flux/issues/177
constexpr bool issue_177()
{
auto seq = flux::cartesian_power<3>(flux::empty<int>);

STATIC_CHECK(seq.is_empty());
STATIC_CHECK(seq.size() == 0);
STATIC_CHECK(seq.is_last(seq.first()));
STATIC_CHECK(seq.first() == seq.last());

return true;
}
static_assert(issue_177());

}

TEST_CASE("cartesian power")
{
REQUIRE(test_cartesian_power());
REQUIRE(issue_177());
}
15 changes: 15 additions & 0 deletions test/test_cartesian_product.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -509,11 +509,26 @@ void issue_167()
REQUIRE_THROWS_AS(flux::size(prod), flux::unrecoverable_error);
}

// https://github.com/tcbrindle/flux/issues/177
constexpr bool issue_177()
{
auto seq = flux::cartesian_product(std::array{1, 2, 3}, flux::empty<int>);

STATIC_CHECK(seq.is_empty());
STATIC_CHECK(seq.size() == 0);
STATIC_CHECK(seq.is_last(seq.first()));
STATIC_CHECK(seq.first() == seq.last());

return true;
}
static_assert(issue_177());

}

TEST_CASE("cartesian_product")
{
REQUIRE(test_cartesian_product());

issue_167();
REQUIRE(issue_177());
}

0 comments on commit 05c555e

Please sign in to comment.