Created on 2022-11-08.00:00:00 last changed 13 months ago
Proposed resolution:
This wording is relative to N4917.
Modify [ranges.cartesian.iterator] as indicated:
template<size_t N = sizeof...(Vs)> constexpr void prev();-6- Effects: Equivalent to:
auto& it = std::get<N>(current_); if constexpr (N > 0) { if (it == ranges::begin(std::get<N>(parent_->bases_))) { it = cartesian-common-arg-end(std::get<N>(parent_->bases_));if constexpr (N > 0) {prev<N - 1>();}} } --it;
[ 2023-02-13 Approved at February 2023 meeting in Issaquah. Status changed: Voting → WP. ]
[ Kona 2022-11-08; Move to Ready ]
Currently, cartesian_product_view::iterator::prev has the following Effects:
auto& it = std::get<N>(current_); if (it == ranges::begin(std::get<N>(parent_->bases_))) { it = cartesian-common-arg-end(std::get<N>(parent_->bases_)); if constexpr (N > 0) { prev<N - 1>(); } } --it;
which decrements the underlying iterator one by one using recursion. However, when N == 0, it still detects if the first iterator has reached the beginning and assigns it to the end, which is not only unnecessary, but also causes cartesian-common-arg-end to be applied to the first range, making it ill-formed in some cases, for example:
#include <ranges>
int main() {
auto r = std::views::cartesian_product(std::views::iota(0));
r.begin() += 3; // hard error
}
This is because, for the first range, cartesian_product_view::iterator::operator+= only requires it to model random_access_range. However, when x is negative, this function will call prev and indirectly calls cartesian-common-arg-end, since the latter constrains its argument to satisfy cartesian-product-common-arg, that is, common_range<R> || (sized_range<R> && random_access_range<R>), which is not the case for the unbounded iota_view, resulting in a hard error in prev's function body.
The proposed resolution changes the position of the if constexpr so that we just decrement the first iterator and nothing else.History | |||
---|---|---|---|
Date | User | Action | Args |
2023-11-22 15:47:43 | admin | set | status: wp -> c++23 |
2023-02-13 10:17:57 | admin | set | messages: + msg13361 |
2023-02-13 10:17:57 | admin | set | status: voting -> wp |
2023-02-06 15:33:48 | admin | set | status: ready -> voting |
2022-11-10 23:33:23 | admin | set | messages: + msg13013 |
2022-11-10 23:33:23 | admin | set | status: new -> ready |
2022-11-08 19:04:02 | admin | set | messages: + msg12963 |
2022-11-08 00:00:00 | admin | create |