Title
join_view::iterator::operator-- is incorrectly constrained
Status
c++20
Section
[range.join.iterator]
Submitter
United States

Created on 2019-11-04.00:00:00 last changed 38 months ago

Messages

Date: 2019-11-07.08:20:25

Proposed resolution:

This wording is relative to N4835.

  1. Modify [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>>;
    
  2. Modify [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;
    

Date: 2019-11-07.08:20:25

[ 2019-11 Status to Ready during Tuesday morning issue processing in Belfast. ]

Date: 2019-11-04.00:00:00

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).

Eric Niebler:

From the WD, 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.

History
Date User Action Args
2021-02-25 10:48:01adminsetstatus: wp -> c++20
2020-02-24 16:02:59adminsetstatus: voting -> wp
2020-01-17 04:54:50adminsetstatus: ready -> voting
2019-11-07 08:20:25adminsetmessages: + msg10786
2019-11-07 08:20:25adminsetstatus: new -> ready
2019-11-04 19:58:29adminsetmessages: + msg10741
2019-11-04 00:00:00admincreate