std::ranges::iota_view<int, long>
has non-subtractable iterator
and
sentinel
typesSection: 25.6.4.4 [range.iota.sentinel] Status: New Submitter: Jiang An Opened: 2021-09-25 Last modified: 2021-10-14
Priority: 3
View all issues with New status.
Discussion:
Currently std::ranges::iota_view<int, long>
uses its special sentinel
type, as its
W
and Bound
are different types and Bound
is not std::unreachable_sentinel_t
.
However, as W
(int
) is not an iterator type, the iterator and sentinel types don't satisfy
std::sized_sentinel_for
, and thus not subtractable.
operator-
overloads for iota_view::iterator
and iota_view::sentinel
like iota_view::size
and operator-
for iota_view::iterator
.
[2021-10-14; Reflector poll]
Set priority to 3 after reflector poll.
[Tim Song commented:]
We might be able to simplify the (y_value > x.value_)
conditional
since we know that we are working with an iterator and its sentinel.
Proposed resolution:
This wording is relative to N4892.
Modify 25.6.4.4 [range.iota.sentinel] as indicated:
namespace std::ranges { template<weakly_incrementable W, semiregular Bound> requires weakly-equality-comparable-with<W, Bound> && copyable<W> struct iota_view<W, Bound>::sentinel { private: Bound bound_ = Bound(); // exposition only public: sentinel() = default; constexpr explicit sentinel(Bound bound); friend constexpr bool operator==(const iterator& x, const sentinel& y); friend constexpriter_difference_t<W>IOTA-DIFF-T(W) operator-(const iterator& x, const sentinel& y) requires (is-integer-like<W> && is-integer-like<Bound>) || sized_sentinel_for<Bound, W>; friend constexpriter_difference_t<W>IOTA-DIFF-T(W) operator-(const sentinel& x, const iterator& y) requires (is-integer-like<W> && is-integer-like<Bound>) || sized_sentinel_for<Bound, W>; }; }[…]
friend constexpriter_difference_t<W>IOTA-DIFF-T(W) operator-(const iterator& x, const sentinel& y) requires (is-integer-like<W> && is-integer-like<Bound>) || sized_sentinel_for<Bound, W>;-3- Effects: Equivalent to:
return x.value_ - y.bound_;
using D = IOTA-DIFF-T(W); if constexpr (is-integer-like<W>) { auto y_value = W(y.bound_); if constexpr (is-signed-integer-like<W>) { return D(D(x.value_) - D(y_value)); } else { return (y_value > x.value_) ? D(-D(y_value - x.value_)) : D(x.value_ - y_value); } } else { return x.value_ - y.bound_; }friend constexpriter_difference_t<W>IOTA-DIFF-T(W) operator-(const sentinel& x, const iterator& y) requires (is-integer-like<W> && is-integer-like<Bound>) || sized_sentinel_for<Bound, W>;-4- Effects: Equivalent to:
return -(y - x);