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.

### 3533. Make `base() const &` consistent across iterator wrappers that supports `input_iterator`s

Section: 26.7.8.3 [range.filter.iterator], 26.7.9.3 [range.transform.iterator], 26.7.22.3 [range.elements.iterator] Status: WP Submitter: Tomasz Kamiński Opened: 2021-03-14 Last modified: 2021-06-07

Priority: Not Prioritized

View all issues with WP status.

Discussion:

The resolution of LWG issue 3391 changed the `base()` function for the `counted_iterator`/`move_iterator` to return `const &`, because the previous specification prevented non-mutating uses of the base iterator (comparing against sentinel) and made `take_view` unimplementable. However, this change was not applied for all other iterators wrappers, that may wrap move-only input iterators. As consequence, we end-up with inconsistency where a user can perform the following operations on some adapters, but not on others (e. g. `take_view` uses `counted_iterator` so it supports them).

1. read the original value of the base iterator, by calling `operator*`

2. find position of an element in the underlying iterator, when sentinel is sized by calling `operator-` (e.g. all input iterators wrapped into `counted_iterator`).

To fix above, the proposed wording below proposes to modify the signature of `iterator::base() const &` member function for all iterators adapters that support input iterator. These include:

- `filter_view::iterator` (uses case B)

- `transform_view::iterator` (uses case A)

- `elements_view::iterator` (uses case B)

- `lazy_split_view<V, Pattern>::inner-iterator` (uses case B) if P2210 is accepted

Note: `common_iterator` does not expose the `base()` function (because it can either point to iterator or sentinel), so changes to above are not proposed. However, both (A) and (B) use cases are supported.

[2021-04-20; Reflector poll]

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

[2021-06-07 Approved at June 2021 virtual plenary. Status changed: Voting → WP.]

Proposed resolution:

This wording is relative to N4878.

> If P2210 would become accepted, the corresponding subclause [range.lazy.split.inner] (?) for `lazy_split_view::inner-iterator` would require a similar change.

1. Modify 26.7.8.3 [range.filter.iterator] as indicated:

   > >     […]
   > >     constexpr const iterator_t<V>& base() const &
   > >       requires copyable<iterator_t<V>>;
   > >     […]

   […]

   >     constexpr const iterator_t<V>& base() const &
   >       requires copyable<iterator_t<V>>;

   > > -5- Effects: Equivalent to: `return current_;`

2. Modify 26.7.9.3 [range.transform.iterator] as indicated:

   > >     […]
   > >     constexpr const iterator_t<Base>& base() const &
   > >       requires copyable<iterator_t<Base>>;
   > >     […]

   […]

   >     constexpr const iterator_t<Base>& base() const &
   >       requires copyable<iterator_t<Base>>;

   > > -5- Effects: Equivalent to: `return current_;`

3. Modify 26.7.22.3 [range.elements.iterator] as indicated:

   > >     […]
   > >     constexpr const iterator_t<Base>& base() const &
   > >       requires copyable<iterator_t<Base>>;
   > >     […]

   […]

   >     constexpr const iterator_t<Base>& base() const &
   >       requires copyable<iterator_t<Base>>;

   > > -3- Effects: Equivalent to: `return current_;`