join_view::iterator::operator--
is incorrectly constrainedSection: 25.7.14.3 [range.join.iterator] Status: C++20 Submitter: United States Opened: 2019-11-04 Last modified: 2021-02-25
Priority: 0
View all other issues in [range.join.iterator].
View all issues with C++20 status.
Discussion:
Addresses US 294
join_view::iterator::operator--
is improperly constrained. In the Effects: clause in
paragraph 14, we see the statement:
inner_ = ranges::end(*--outer_);
However, this only well-formed when end
returns an iterator, not a sentinel. This
requirement is not reflected in the constraints of the function(s).
join_view::iterator::operator--
is specified as:
constexpr iterator& operator--() requires ref_is_glvalue && bidirectional_range<Base> && bidirectional_range<range_reference_t<Base>>;-14- Effects: Equivalent to:if (outer_ == ranges::end(parent_->base_)) inner_ = ranges::end(*--outer_); while (inner_ == ranges::begin(*outer_)) inner_ = ranges::end(*--outer_); --inner_; return *this;
The trouble is from the lines that do:
inner_ = ranges::end(*--outer_);
Clearly this will only compile when *--outer
returns a common_range
, but
nowhere is that requirement stated.
[2019-11 Status to Ready during Tuesday morning issue processing in Belfast.]
Proposed resolution:
This wording is relative to N4835.
Modify 25.7.14.3 [range.join.iterator], class template join_view::iterator
synopsis,
as indicated:
constexpr iterator& operator--() requires ref_is_glvalue && bidirectional_range<Base> && bidirectional_range<range_reference_t<Base>> && common_range<range_reference_t<Base>>; constexpr iterator operator--(int) requires ref_is_glvalue && bidirectional_range<Base> && bidirectional_range<range_reference_t<Base>> && common_range<range_reference_t<Base>>;
Modify 25.7.14.3 [range.join.iterator] as indicated:
constexpr iterator& operator--() requires ref_is_glvalue && bidirectional_range<Base> && bidirectional_range<range_reference_t<Base>> && common_range<range_reference_t<Base>>;-14- Effects: Equivalent to:
if (outer_ == ranges::end(parent_->base_)) inner_ = ranges::end(*--outer_); while (inner_ == ranges::begin(*outer_)) inner_ = ranges::end(*--outer_); --inner_; return *this;constexpr iterator operator--(int) requires ref_is_glvalue && bidirectional_range<Base> && bidirectional_range<range_reference_t<Base>> && common_range<range_reference_t<Base>>;-15- Effects: Equivalent to:
auto tmp = *this; --*this; return tmp;