This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of WP status.

### 3717. `common_view::end` should improve `random_access_range` case

Section: 26.7.19.2 [range.common.view] Status: WP Submitter: Hewill Kang Opened: 2022-06-15 Last modified: 2022-11-17

Priority: 3

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

View all issues with WP status.

Discussion:

This issue is part of NB comment US 47-109 26 [ranges] Resolve open issues

In view of the fact that random access iterators are only required to work with its difference type, P2393R1 improves the wording of `take_view`, which first convert the integer type to difference type and then operate with the iterator. However, the paper omits the handling of random access iterators in `common_view::end`, which directly operates on the return types of `ranges::begin` and `ranges::size`. We should improve this, too.

[2022-07-06; Reflector poll]

Set priority to 3 after reflector poll.

Previous resolution [SUPERSEDED]:

> This wording is relative to N4910.

> 1. Modify 26.7.19.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() {
>    >           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() {
>    >           if constexpr (random_access_range<V> && sized_range<V>)
>    >             return ranges::begin(base_) + range_difference_t<V>(size())ranges::size(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_) + range_difference_t<const V>(size())ranges::size(base_);
>    >           else
>    >             return common_iterator<iterator_t<const V>, sentinel_t<const V>>(ranges::end(base_));
>    >         }

>    >         constexpr auto size() requires sized_range<V> {
>    >           return ranges::size(base_);
>    >         }
>    >         constexpr auto size() const requires sized_range<const V> {
>    >           return ranges::size(base_);
>    >         }
>    >       };
>    >       […]
>    >     }

[Kona 2022-11-08; Discussed at joint LWG/SG9 session. Move to Open]

[2022-11-09 Tim updates wording per LWG discussion]

[Kona 2022-11-10; Move to Immediate]

[2022-11-12 Approved at November 2022 meeting in Kona. Status changed: Immediate → WP.]

Proposed resolution:

This wording is relative to N4917.

1. Modify 26.7.19.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() {
   >           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() {
   >           if constexpr (random_access_range<V> && sized_range<V>)
   >             return ranges::begin(base_) + ranges::sizedistance(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::sizedistance(base_);
   >           else
   >             return common_iterator<iterator_t<const V>, sentinel_t<const V>>(ranges::end(base_));
   >         }

   >         constexpr auto size() requires sized_range<V> {
   >           return ranges::size(base_);
   >         }
   >         constexpr auto size() const requires sized_range<const V> {
   >           return ranges::size(base_);
   >         }
   >       };
   >       […]
   >     }