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

4558. drop_view and drop_while_view should be const-iterable for input-only range

Section: 25.7.12.2 [range.drop.view], 25.7.13.2 [range.drop.while.view] Status: New Submitter: Hewill Kang Opened: 2026-03-25 Last modified: 2026-03-26

Priority: Not Prioritized

View other active issues in [range.drop.view].

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

View all issues with New status.

Discussion:

After P3725R3, filter_view can be const-iterable as long as the underlying range is input-only range, implying that LEWG do believe that providing const-iterable properties for views does have some value.

Its turn out that drop_view and drop_while_view are also const-iterable in the same situation, because they do not internally need to cache the begin call on the first iteration.

Proposed resolution:

This wording is relative to N5032.

  1. Modify 25.7.12.2 [range.drop.view] as indicated:

    namespace std::ranges {
      template<view V>
      class drop_view : public view_interface<drop_view<V>> {
      public:
        […]
        constexpr auto begin()
          requires (!(simple-view<V> &&
                      ((random_access_range<const V> && sized_range<const V>) ||
                       (input_range<const V> && !forward_range<const V>))));
        constexpr auto begin() const
          requires (random_access_range<const V> && sized_range<const V>) ||
                   (input_range<const V> && !forward_range<const V>);
        […]
      };
      […]
    }
    
    constexpr auto begin()
       requires (!(simple-view<V> &&
                   ((random_access_range<const V> && sized_range<const V>) ||
                    (input_range<const V> && !forward_range<const V>))));
    constexpr auto begin() const
      requires (random_access_range<const V> && sized_range<const V>) ||
               (input_range<const V> && !forward_range<const V>);
    

    -3- Returns: ranges::next(ranges::begin(base_), count_, ranges::end(base_)).

    -4- Remarks: In order to provide the amortized constant-time complexity required by the range concept when drop_view models forward_range, the first overload caches the result within the drop_view for use on subsequent calls.

  2. Modify 25.7.13.2 [range.drop.while.view] as indicated:

    namespace std::ranges {
      template<view V, class Pred>
        requires input_range<V> && is_object_v<Pred> &&
                 indirect_unary_predicate<const Pred, iterator_t<V>>
      class drop_while_view : public view_interface<drop_while_view<V, Pred>> {
      public:
        […]
    
        constexpr auto begin()
          requires (!(simple-view<V> &&
                      input_range<const V> && !forward_range<const V>));
        constexpr auto begin() const
          requires (input_range<const V> && !forward_range<const V> &&
                    indirect_unary_predicate<const Pred, iterator_t<const V>>);
    
        constexpr auto end() requires (!simple-view<V>) { return ranges::end(base_); }
        constexpr auto end() const requires range<const V> { return ranges::end(base_); }
    
        […]
      };
      […]
    }
    
    […]
    constexpr auto begin()
      requires (!(simple-view<V> &&
                  input_range<const V> && !forward_range<const V>));
    constexpr auto begin() const
      requires (input_range<const V> && !forward_range<const V> &&
                indirect_unary_predicate<const Pred, iterator_t<const V>>);
    
    

    -3-Preconditions: pred_.has_value() is true.

    -4-Returns: ranges::find_if_not(base_, cref(*pred_)).

    -5-Remarks: In order to provide the amortized constant-time complexity required by the range concept when drop_while_view models forward_range, the first overloadcall caches the result within the drop_while_view for use on subsequent calls.