Title
ranges::size is not required to be valid after a call to ranges::begin on an input range
Status
c++20
Section
[range.take.view][range.subrange.ctor]
Submitter
Eric Niebler

Created on 2019-09-10.00:00:00 last changed 38 months ago

Messages

Date: 2019-10-12.11:45:31

Proposed resolution:

This wording is relative to N4830.

  1. Modify [range.take.view], class template take_view synopsis, as indicated:

    namespace std::ranges {
      template<view V>
      class take_view : public view_interface<take_view<V>> {
      private:
        […]
      public:
        […]
        constexpr auto begin() requires (!simple-view<V>) {
          if constexpr (sized_range<V>) {
            if constexpr (random_access_range<V>)
              return ranges::begin(base_);
            else {
              auto sz = size();
              return counted_iterator{ranges::begin(base_), size()sz};
            }
          } else
            return counted_iterator{ranges::begin(base_), count_};
        }
    
        constexpr auto begin() const requires range<const V> {
          if constexpr (sized_range<const V>) {
            if constexpr (random_access_range<const V>)
              return ranges::begin(base_);
            else {
              auto sz = size();
              return counted_iterator{ranges::begin(base_), size()sz};
            }
          } else
            return counted_iterator{ranges::begin(base_), count_};
        }
        
        […]
      };
      […]
    }
    
  2. Modify [range.subrange.ctor] as indicated:

    template<not-same-as<subrange> R>
      requires forwarding-range<R> &&
        convertible_to<iterator_t<R>, I> && convertible_to<sentinel_t<R>, S>
    constexpr subrange(R&& r) requires (!StoreSize || sized_range<R>);
    

    -6- Effects: Equivalent to:

    1. (6.1) — If StoreSize is true, subrange{ranges::begin(r), ranges::end(r)r, ranges::size(r)}.

    2. (6.2) — Otherwise, subrange{ranges::begin(r), ranges::end(r)}.

Date: 2019-10-12.00:00:00

[ 2019-10-12 Issue Prioritization ]

Status to Tentatively Ready and priority to 0 after seven positive votes on the reflector.

Date: 2019-09-17.16:31:49

On an input (but not forward) range, begin(rng) is not required to be an equality-preserving expression ([range.range]/3.3). If the range is also sized, then it is not valid to call size(rng) after begin(rng) ([range.sized]/2.2). In several places in the ranges clause, this precondition is violated. A trivial re-expression of the effects clause fixes the problem.

History
Date User Action Args
2021-02-25 10:48:01adminsetstatus: wp -> c++20
2020-02-24 16:02:59adminsetstatus: voting -> wp
2020-01-17 04:54:50adminsetstatus: ready -> voting
2019-10-12 11:45:31adminsetmessages: + msg10697
2019-10-12 11:45:31adminsetstatus: new -> ready
2019-09-16 19:56:23adminsetmessages: + msg10643
2019-09-10 00:00:00admincreate