Skip to content

Commit

Permalink
Fix zip_transform_view by not using possibly ill-formed member
Browse files Browse the repository at this point in the history
  • Loading branch information
frederick-vs-ja committed Feb 20, 2024
1 parent c53ac59 commit e814b2e
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 5 deletions.
11 changes: 6 additions & 5 deletions stl/inc/ranges
Original file line number Diff line number Diff line change
Expand Up @@ -8582,6 +8582,10 @@ namespace ranges {
_EXPORT_STD inline constexpr _Zip_fn zip{};
} // namespace views

template <class _Func, class... _ViewTypes>
concept _Can_const_iterate_zip_transform_view =
range<const zip_view<_ViewTypes...>> && regular_invocable<const _Func&, range_reference_t<const _ViewTypes>...>;

_EXPORT_STD template <class _Func, class... _ViewTypes>
requires _Zip_transform_constraints<_Func, _ViewTypes...>
class zip_transform_view : public view_interface<zip_transform_view<_Func, _ViewTypes...>> {
Expand Down Expand Up @@ -8833,9 +8837,6 @@ namespace ranges {
}
}

static constexpr bool _Enable_const_begin_end =
(range<const _Inner_view> && regular_invocable<const _Func&, range_reference_t<const _ViewTypes>...>);

public:
zip_transform_view() = default;

Expand All @@ -8849,7 +8850,7 @@ namespace ranges {
}

_NODISCARD constexpr auto begin() const noexcept(noexcept(_Iterator<true>{*this, _Zip.begin()})) // strengthened
requires _Enable_const_begin_end
requires _Can_const_iterate_zip_transform_view<_Func, _ViewTypes...>
{
return _Iterator<true>{*this, _Zip.begin()};
}
Expand All @@ -8863,7 +8864,7 @@ namespace ranges {
}

_NODISCARD constexpr auto end() const noexcept(_Is_end_noexcept<true>()) // strengthened
requires _Enable_const_begin_end
requires _Can_const_iterate_zip_transform_view<_Func, _ViewTypes...>
{
if constexpr (common_range<const _Inner_view>) {
return _Iterator<true>{*this, _Zip.end()};
Expand Down
18 changes: 18 additions & 0 deletions tests/std/tests/P2321R2_views_zip_transform/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -806,6 +806,20 @@ constexpr bool validate_empty_ranges() {
return true;
}

// Also test GH-4414: "<ranges>: zip_transform does not accept non const iterable ranges"
constexpr bool test_gh_4414() {
auto evens_and_odds = views::zip_transform([](int even, int odd) { return even + odd; },
views::iota(0, 10) | views::filter([](int i) { return i % 2 == 0; }),
views::iota(0, 10) | views::filter([](int i) { return i % 2 != 0; }));

using ZipppedTransformed = decltype(evens_and_odds);
STATIC_ASSERT(ranges::range<ZippedTransformed>);
STATIC_ASSERT(!ranges::range<const ZippedTransformed>);

constexpr int expected_results[]{1, 5, 9, 13, 17};
return ranges::equal(expected_results, evens_and_odds);
}

int main() {
// Empty RangeTypes... parameter pack
{
Expand Down Expand Up @@ -858,6 +872,10 @@ int main() {
test_one(three_element_transform_closure, three_range_transform_results_array, test_element_array_one,
test_element_array_two, test_element_array_three);
}
{
STATIC_ASSERT(test_gh_4414());
assert(test_gh_4414());
}

return 0;
}

0 comments on commit e814b2e

Please sign in to comment.