Title
The const overload of lazy_split_view::begin should be constrained by const Pattern
Status
new
Section
[range.lazy.split.view]
Submitter
Hewill Kang

Created on 2021-09-23.00:00:00 last changed 37 months ago

Messages

Date: 2021-10-14.11:35:36

Proposed resolution:

This wording is relative to N4892.

  1. Modify [range.lazy.split.view], class template lazy_split_view synopsis, as indicated:

    namespace std::ranges {
    
      […]
    
      template<input_range V, forward_range Pattern>
        requires view<V> && view<Pattern> &&
                 indirectly_comparable<iterator_t<V>, iterator_t<Pattern>, ranges::equal_to> &&
                (forward_range<V> || tiny-range<Pattern>)
      class lazy_split_view : public view_interface<lazy_split_view<V, Pattern>> {
      private:
        […]
      public:
        […]
    
        constexpr auto begin() {
          […]
        }
        
        constexpr auto begin() const requires forward_range<V> && forward_range<const V> &&
                                              forward_range<const Pattern>{
          return outer-iterator<true>{*this, ranges::begin(base_)};
        }
        
        constexpr auto end() requires forward_range<V> && common_range<V> {
          […]
        }
    
        constexpr auto end() const {
          if constexpr (forward_range<V> && forward_range<const V> && common_range<const V> &&
                        forward_range<const Pattern>)
            return outer-iterator<true>{*this, ranges::end(base_)};
          else
            return default_sentinel;
        }
      };
      
      […]
      
    }
    
Date: 2021-10-15.00:00:00

[ 2021-10-14; Reflector poll ]

Set priority to 3 after reflector poll.

Date: 2021-09-15.00:00:00

[ 2021-09-24; Daniel comments ]

This issue is related to LWG 3592.

Date: 2021-09-23.00:00:00

Consider the following code snippet:

#include <ranges>

int main() {
  auto p = std::views::iota(0)
         | std::views::take(1)
         | std::views::reverse;
  auto r = std::views::single(42)
         | std::views::lazy_split(p);
  auto f = r.front();
}

r.front() is ill-formed even if r is a forward_range.

This is because the const overload of lazy_split_view::begin is not constrained by the const Pattern, which makes it still well-formed in such cases. When the const overload of view_interface<lazy_split_view<V, Pattern>>::front is instantiated, the subrange{parent_->pattern_} inside lazy_split_view::outer-iterator<true>::operator++() will cause a hard error since const Pattern is not a range.

History
Date User Action Args
2021-10-14 11:35:36adminsetmessages: + msg12155
2021-09-24 16:20:15adminsetmessages: + msg12066
2021-09-24 16:20:15adminsetmessages: + msg12065
2021-09-23 00:00:00admincreate