iota_view::sentinel
is not always iota_view
's sentinelSection: 25.6.4.2 [range.iota.view] Status: C++23 Submitter: Tim Song Opened: 2021-02-17 Last modified: 2023-11-22
Priority: Not Prioritized
View all other issues in [range.iota.view].
View all issues with C++23 status.
Discussion:
P1739R4 added the following constructor to
iota_view
:
constexpr iota_view(iterator first, sentinel last) : iota_view(*first, last.bound_) {}
However, while iota_view
's iterator type is always iota_view::iterator
, its sentinel type
is not always iota_view::sentinel
. First, if Bound
is unreachable_sentinel_t
, then
the sentinel type is unreachable_sentinel_t
too - we don't add an unnecessary level of wrapping
on top. Second, when W
and Bound
are the same type, iota_view
models common_range
, and
the sentinel type is the same as the iterator type - that is, iterator
, not sentinel
.
Presumably the intent is to use the view's actual sentinel type, rather than always use the
sentinel
type.
[2021-03-12; Reflector poll]
Set status to Tentatively Ready after five votes in favour during reflector poll.
[2021-06-07 Approved at June 2021 virtual plenary. Status changed: Voting → WP.]
Proposed resolution:
This wording is relative to N4878.
Edit 25.6.4.2 [range.iota.view], as indicated:
namespace std::ranges { // [...] template<weakly_incrementable W, semiregular Bound = unreachable_sentinel_t> requires weakly-equality-comparable-with<W, Bound> && semiregular<W> class iota_view : public view_interface<iota_view<W, Bound>> { private: // [range.iota.iterator], class iota_view::iterator struct iterator; // exposition only // [range.iota.sentinel], class iota_view::sentinel struct sentinel; // exposition only W value_ = W(); // exposition only Bound bound_ = Bound(); // exposition only public: iota_view() = default; constexpr explicit iota_view(W value); constexpr iota_view(type_identity_t<W> value, type_identity_t<Bound> bound); constexpr iota_view(iterator first,sentinelsee below last);: iota_view(*first, last.bound_) {}constexpr iterator begin() const; constexpr auto end() const; constexpr iterator end() const requires same_as<W, Bound>; constexpr auto size() const requires see below; }; template<class W, class Bound> requires (!is-integer-like<W> || !is-integer-like<Bound> || (is-signed-integer-like<W> == is-signed-integer-like<Bound>)) iota_view(W, Bound) -> iota_view<W, Bound>; }[...]
constexpr iota_view(type_identity_t<W> value, type_identity_t<Bound> bound);-8- Preconditions:
Bound
denotesunreachable_sentinel_t
orbound
is reachable fromvalue
. WhenW
andBound
modeltotally_ordered_with
, thenbool(value <= bound)
is true.-9- Effects: Initializes
value_
withvalue
andbound_
withbound
.constexpr iota_view(iterator first, see below last);-?- Effects: Equivalent to:
(?.1) — If
same_as<W, Bound>
istrue
,iota_view(first.value_, last.value_)
.(?.2) — Otherwise, if
Bound
denotesunreachable_sentinel_t
,iota_view(first.value_, last)
.(?.3) — Otherwise,
iota_view(first.value_, last.bound_)
.-?- Remarks: The type of
last
is:
(?.1) — If
same_as<W, Bound>
istrue
,iterator
.(?.2) — Otherwise, if
Bound
denotesunreachable_sentinel_t
,Bound
.(?.3) — Otherwise,
sentinel
.