Title
Make base() const & consistent across iterator wrappers that supports input_iterators
Status
new
Section
[range.filter.iterator][range.transform.iterator][range.elements.iterator]
Submitter
Tomasz Kamiński

Created on 2021-03-14.00:00:00 last changed 1 month ago

Messages

Date: 2021-03-14.17:47:27

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 [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 [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 [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_;

Date: 2021-03-14.00:00:00

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.

History
Date User Action Args
2021-03-14 17:39:21adminsetmessages: + msg11745
2021-03-14 00:00:00admincreate