4012. common_view::begin/end are missing the simple-view check

Section: 25.7.20.2 [range.common.view] Status: WP Submitter: Hewill Kang Opened: 2023-11-11 Last modified: 2024-04-02

Priority: Not Prioritized

View all other issues in [range.common.view].

View all issues with WP status.

Discussion:

common_view::begin/end have exactly the same implementation as their corresponding const versions, which implies that when the underlying V satisfies simple-view, it is sufficient to just provide const-qualified members.

[2024-03-11; Reflector poll]

Set status to Tentatively Ready after six votes in favour during reflector poll.

[Tokyo 2024-03-23; Status changed: Voting → WP.]

Proposed resolution:

This wording is relative to N4964.

  1. Modify 25.7.20.2 [range.common.view] as indicated:

    namespace std::ranges {
      template<view V>
        requires (!common_range<V> && copyable<iterator_t<V>>)
      class common_view : public view_interface<common_view<V>> {
      private:
        V base_ = V();  // exposition only
    
      public:
        […]
        constexpr auto begin() requires (!simple-view<V>) {
          if constexpr (random_access_range<V> && sized_range<V>)
            return ranges::begin(base_);
          else
            return common_iterator<iterator_t<V>, sentinel_t<V>>(ranges::begin(base_));
        }
    
        constexpr auto begin() const requires range<const V> {
          if constexpr (random_access_range<const V> && sized_range<const V>)
            return ranges::begin(base_);
          else
            return common_iterator<iterator_t<const V>, sentinel_t<const V>>(ranges::begin(base_));
        }
        
        constexpr auto end() requires (!simple-view<V>) {
          if constexpr (random_access_range<V> && sized_range<V>)
            return ranges::begin(base_) + ranges::distance(base_);
          else
            return common_iterator<iterator_t<V>, sentinel_t<V>>(ranges::end(base_));
        }
    
        constexpr auto end() const requires range<const V> {
          if constexpr (random_access_range<const V> && sized_range<const V>)
            return ranges::begin(base_) + ranges::distance(base_);
          else
            return common_iterator<iterator_t<const V>, sentinel_t<const V>>(ranges::end(base_));
        }
    
        […]
      };
    […]
    }