Title
transform_view::iterator's difference is overconstrained
Status
c++23
Section
[range.transform.iterator][range.elements.iterator]
Submitter
Casey Carter

Created on 2020-09-04.00:00:00 last changed 12 months ago

Messages

Date: 2020-11-09.21:40:50

Proposed resolution:

This wording is relative to N4861.

  1. Modify [range.transform.iterator] as indicated:

    namespace std::ranges {
      template<input_range V, copy_constructible F>
        requires view<V> && is_object_v<F> &&   
                 regular_invocable<F&, range_reference_t<V>> &&
                 can-reference<invoke_result_t<F&, range_reference_t<V>>>
      template<bool Const>
      class transform_view<V, F>::iterator {
      public:
        […]
        friend constexpr iterator operator-(iterator i, difference_type n)
          requires random_access_range<Base>;
        friend constexpr difference_type operator-(const iterator& x, const iterator& y)
          requires random_access_range<Base>sized_sentinel_for<iterator_t<Base>, iterator_t<Base>>;
        […]
      };
    }
    
    […]
    friend constexpr difference_type operator-(const iterator& x, const iterator& y)
      requires random_access_range<Base>sized_sentinel_for<iterator_t<Base>, iterator_t<Base>>;
    

    -22- Effects: return x.current_ - y.current_;

  2. Modify [range.elements.iterator] as indicated:

    namespace std::ranges {
      template<input_range V, size_t N>
        requires view<V> && has-tuple-element<range_value_t<V>, N> &&
                 has-tuple-element<remove_reference_t<range_reference_t<V>>, N>
      template<bool Const>
      class elements_view<V, N>::iterator {  // exposition only
        […]
        friend constexpr iterator operator-(iterator x, difference_type y)
          requires random_access_range<Base>;
        friend constexpr difference_type operator-(const iterator& x, const iterator& y)
          requires random_access_range<Base>sized_sentinel_for<iterator_t<Base>, iterator_t<Base>>;
      };
    }
    
    […]
    constexpr difference_type operator-(const iterator& x, const iterator& y)
      requires random_access_range<Base>sized_sentinel_for<iterator_t<Base>, iterator_t<Base>>;
    

    -21- Effects: return x.current_ - y.current_;

Date: 2020-11-09.00:00:00

[ 2020-11-09 Approved In November virtual meeting. Status changed: Tentatively Ready → WP. ]

Date: 2020-09-15.00:00:00

[ 2020-09-13; Reflector prioritization ]

Set priority to 0 and status to Tentatively Ready after seven votes in favour during reflector discussions.

Date: 2020-09-15.00:00:00

[ 2020-09-08; Reflector discussion ]

During reflector discussions it was observed that elements_view::iterator has the same issue and the proposed wording has been extended to cover this template as well.

Date: 2020-09-04.00:00:00

The difference operation for transform_view::iterator is specified in [range.transform.iterator] as:

friend constexpr difference_type operator-(const iterator& x, const iterator& y)
  requires random_access_range<Base>;

-22- Effects: Equivalent to: return x.current_ - y.current_;

The member current_ is an iterator of type iterator_t<Base>, where Base is V for transform_view<V, F>::iterator<false> and const V for transform_view<V, F>::iterator<true>. The difference of iterators that appears in the above Effects: element is notably well-defined if their type models sized_sentinel_for<iterator_t<Base>, iterator_t<Base>> which random_access_range<Base> refines. This overstrong requirement seems to be simply the result of an oversight; it has been present since P0789R0, without — to my recollection — ever having been discussed. We should relax this requirement to provide difference capability for transform_view's iterators whenever the underlying iterators do.

History
Date User Action Args
2023-11-22 15:47:43adminsetstatus: wp -> c++23
2020-11-09 21:40:50adminsetmessages: + msg11592
2020-11-09 21:40:50adminsetstatus: ready -> wp
2020-09-13 15:09:03adminsetmessages: + msg11486
2020-09-13 15:09:03adminsetstatus: new -> ready
2020-09-08 15:40:54adminsetmessages: + msg11476
2020-09-06 13:38:49adminsetmessages: + msg11475
2020-09-04 00:00:00admincreate