W3cubDocs

/C++

Standard library header <ranges> (C++20)

This header is part of the ranges library.

Namespace aliases

namespace std {
    namespace views = ranges::views;
}

The namespace alias std::views is provided as a shorthand for std::ranges::views.

Concepts

Range concepts
Defined in namespace std::ranges
(C++20)
specifies that a type is a range, that is, it provides a begin iterator and an end sentinel
(concept)
(C++20)
specifies that a type is a range and iterators obtained from an expression of it can be safely returned without danger of dangling
(concept)
(C++20)
specifies that a range knows its size in constant time
(concept)
(C++20)
specifies that a range is a view, that is, it has constant time copy/move/assignment
(concept)
(C++20)
specifies a range whose iterator type satisfies input_iterator
(concept)
(C++20)
specifies a range whose iterator type satisfies output_iterator
(concept)
(C++20)
specifies a range whose iterator type satisfies forward_iterator
(concept)
(C++20)
specifies a range whose iterator type satisfies bidirectional_iterator
(concept)
(C++20)
specifies a range whose iterator type satisfies random_access_iterator
(concept)
(C++20)
specifies a range whose iterator type satisfies contiguous_iterator
(concept)
(C++20)
specifies that a range has identical iterator and sentinel types
(concept)
(C++20)
specifies the requirements for a range to be safely convertible to a view
(concept)
(C++23)
specifies that a range has read-only elements
(concept)

Functions

Range conversions
Defined in namespace std::ranges
(C++23)
constructs a new non-view object from an input range
(function template)

Classes

Range primitives
Defined in namespace std::ranges
(C++20)(C++23)(C++20)(C++23)(C++20)(C++20)(C++20)(C++20)(C++23)(C++20)(C++20)
obtains associated types of a range
(alias template)
Views
Defined in namespace std::ranges
(C++20)
helper class template for defining a view, using the curiously recurring template pattern
(class template)
(C++20)
combines an iterator-sentinel pair into a view
(class template)
Dangling iterator handling
Defined in namespace std::ranges
(C++20)
a placeholder type indicating that an iterator or a subrange should not be returned since it would be dangling
(class)
(C++20)
obtains iterator type or subrange type of a borrowed_range
(alias template)
Range adaptor objects utility
Defined in namespace std::ranges
(C++23)
helper base class template for defining a range adaptor closure object
(class template)
Factories
Defined in namespace std::ranges
(C++20)
an empty view with no elements
(class template) (variable template)
(C++20)
a view that contains a single element of a specified value
(class template) (customization point object)
(C++20)
a view consisting of a sequence generated by repeatedly incrementing an initial value
(class template) (customization point object)
(C++20)
a view consisting of the elements obtained by successive application of operator>> on the associated input stream
(class template) (customization point object)
(C++23)
a view consisting of a generated sequence by repeatedly producing the same value
(class template) (customization point object)
(C++23)
a view consisting of tuples of results calculated by the n-ary cartesian product of the adapted views
(class template) (customization point object)
Adaptors
Defined in namespace std::ranges
(C++20)
a view that includes all elements of a range
(alias template) (range adaptor object)
(C++20)
a view of the elements of some other range
(class template)
(C++20)
a view with unique ownership of some range
(class template)
(C++20)
a view that consists of the elements of a range that satisfies a predicate
(class template) (range adaptor object)
(C++20)
a view of a sequence that applies a transformation function to each element
(class template) (range adaptor object)
(C++20)
a view consisting of the first N elements of another view
(class template) (range adaptor object)
(C++20)
a view consisting of the initial elements of another view, until the first element on which a predicate returns false
(class template) (range adaptor object)
(C++20)
a view consisting of elements of another view, skipping the first N elements
(class template) (range adaptor object)
(C++20)
a view consisting of the elements of another view, skipping the initial subsequence of elements until the first element where the predicate returns false
(class template) (range adaptor object)
(C++20)
a view consisting of the sequence obtained from flattening a view of ranges
(class template) (range adaptor object)
(C++20)
a view over the subranges obtained from splitting another view using a delimiter
(class template) (range adaptor object)
(C++20)
a view over the subranges obtained from splitting another view using a delimiter
(class template) (range adaptor object)
(C++20)
creates a subrange from an iterator and a count
(customization point object)
(C++20)
converts a view into a common_range
(class template) (range adaptor object)
(C++20)
a view that iterates over the elements of another bidirectional view in reverse order
(class template) (range adaptor object)
(C++23)
converts a view into a constant_range
(class template) (range adaptor object)
(C++23)
a view of a sequence that casts each element to an rvalue
(class template) (range adaptor object)
(C++20)
takes a view consisting of tuple-like values and a number N and produces a view of N'th element of each tuple
(class template) (range adaptor object)
(C++20)
takes a view consisting of pair-like values and produces a view of the first elements of each pair
(class template) (range adaptor object)
(C++20)
takes a view consisting of pair-like values and produces a view of the second elements of each pair
(class template) (range adaptor object)
(C++23)
a view that maps each element of adapted sequence to a tuple of both the element's position and its value
(class template) (range adaptor object)
(C++23)
a view consisting of tuples of references to corresponding elements of the adapted views
(class template) (customization point object)
(C++23)
a view consisting of tuples of results of application of a transformation function to corresponding elements of the adapted views
(class template) (customization point object)
(C++23)
a view consisting of tuples of references to adjacent elements of the adapted view
(class template) (range adaptor object)
(C++23)
a view consisting of tuples of results of application of a transformation function to adjacent elements of the adapted view
(class template) (range adaptor object)
(C++23)
a view consisting of the sequence obtained from flattening a view of ranges, with the delimiter in between elements
(class template) (range adaptor object)
(C++23)
a view consisting of elements of another view, advancing over N elements at a time
(class template) (range adaptor object)
(C++23)
a view whose Mth element is a view over the Mth through (M + N - 1)th elements of another view
(class template) (range adaptor object)
(C++23)
a range of views that are N-sized non-overlapping successive chunks of the elements of another view
(class template) (range adaptor object)
(C++23)
splits the view into subranges between each pair of adjacent elements for which the given predicate returns false
(class template) (range adaptor object)

Customization point objects

Range access
Defined in namespace std::ranges
(C++20)
returns an iterator to the beginning of a range
(customization point object)
(C++20)
returns a sentinel indicating the end of a range
(customization point object)
(C++20)
returns an iterator to the beginning of a read-only range
(customization point object)
(C++20)
returns a sentinel indicating the end of a read-only range
(customization point object)
(C++20)
returns a reverse iterator to a range
(customization point object)
(C++20)
returns a reverse end iterator to a range
(customization point object)
(C++20)
returns a reverse iterator to a read-only range
(customization point object)
(C++20)
returns a reverse end iterator to a read-only range
(customization point object)
(C++20)
returns an integer equal to the size of a range
(customization point object)
(C++20)
returns a signed integer equal to the size of a range
(customization point object)
(C++20)
checks whether a range is empty
(customization point object)
(C++20)
obtains a pointer to the beginning of a contiguous range
(customization point object)
(C++20)
obtains a pointer to the beginning of a read-only contiguous range
(customization point object)

Enumerations

Defined in namespace std::ranges
(C++20)
specifies whether a std::ranges::subrange models std::ranges::sized_range
(enum)

Helpers

(C++20)
obtains the number of components of a std::ranges::subrange
(class template specialization)
(C++20)
obtains the type of the iterator or the sentinel of a std::ranges::subrange
(class template specialization)
(C++20)
obtains iterator or sentinel from a std::ranges::subrange
(function template)
(C++23)
from-range construction tag
(class) (constant)

Synopsis

#include <compare>
#include <initializer_list>
#include <iterator>
 
namespace std::ranges {
  inline namespace /* unspecified */ {
    // range access
    inline constexpr /* unspecified */ begin =   /* unspecified */;     // freestanding
    inline constexpr /* unspecified */ end =     /* unspecified */;     // freestanding
    inline constexpr /* unspecified */ cbegin =  /* unspecified */;     // freestanding
    inline constexpr /* unspecified */ cend =    /* unspecified */;     // freestanding
    inline constexpr /* unspecified */ rbegin =  /* unspecified */;     // freestanding
    inline constexpr /* unspecified */ rend =    /* unspecified */;     // freestanding
    inline constexpr /* unspecified */ crbegin = /* unspecified */;     // freestanding
    inline constexpr /* unspecified */ crend =   /* unspecified */;     // freestanding
 
    inline constexpr /* unspecified */ size =    /* unspecified */;     // freestanding
    inline constexpr /* unspecified */ ssize =   /* unspecified */;     // freestanding
    inline constexpr /* unspecified */ empty =   /* unspecified */;     // freestanding
    inline constexpr /* unspecified */ data =    /* unspecified */;     // freestanding
    inline constexpr /* unspecified */ cdata =   /* unspecified */;     // freestanding
  }
 
  // ranges
  template<class T>
    concept range = /* see description */;                              // freestanding
 
  template<class T>
    inline constexpr bool enable_borrowed_range = false;                // freestanding
 
  template<class T>
    concept borrowed_range = /* see description */;                     // freestanding
 
  template<class T>
    using iterator_t = decltype(ranges::begin(declval<T&>()));          // freestanding
  template<range R>
    using sentinel_t = decltype(ranges::end(declval<R&>()));            // freestanding
  template<range R>
    using const_iterator_t = const_iterator<iterator_t<R>>;             // freestanding
  template<range R>
    using range_difference_t = iter_difference_t<iterator_t<R>>;        // freestanding
  template<sized_range R>
    using range_size_t = decltype(ranges::size(declval<R&>()));         // freestanding
  template<range R>
    using range_value_t = iter_value_t<iterator_t<R>>;                  // freestanding
  template<range R>
    using range_reference_t = iter_reference_t<iterator_t<R>>;          // freestanding
  template<range R>
    using range_const_reference_t = iter_const_reference_t<iterator_t<R>>;
                                                                        // freestanding
  template<range R>
    using range_rvalue_reference_t = iter_rvalue_reference_t<iterator_t<R>>;
                                                                        // freestanding
  template<range R>
    using range_common_reference_t = iter_common_reference_t<iterator_t<R>>;
                                                                        // freestanding
 
  // sized ranges
  template<class>
    inline constexpr bool disable_sized_range = false;                  // freestanding
 
  template<class T>
    concept sized_range = /* see description */;                        // freestanding
 
  // views
  template<class T>
    inline constexpr bool enable_view = /* see description */;          // freestanding
 
  struct view_base {};                                                  // freestanding
 
  template<class T>
    concept view = /* see description */;                               // freestanding
 
  // other range refinements
  template<class R, class T>
    concept output_range = /* see description */;                       // freestanding
 
  template<class T>
    concept input_range = /* see description */;                        // freestanding
 
  template<class T>
    concept forward_range = /* see description */;                      // freestanding
 
  template<class T>
    concept bidirectional_range = /* see description */;                // freestanding
 
  template<class T>
    concept random_access_range = /* see description */;                // freestanding
 
  template<class T>
    concept contiguous_range = /* see description */;                   // freestanding
 
  template<class T>
    concept common_range = /* see description */;                       // freestanding
 
  template<class T>
    concept viewable_range = /* see description */;                     // freestanding
 
  template<class T>
    concept constant_range = /* see description */;                     // freestanding
 
  // class template view_interface
  template<class D>
    requires is_class_v<D> && same_as<D, remove_cv_t<D>>
  class view_interface;                                                 // freestanding
 
  // sub-ranges
  enum class subrange_kind : bool { unsized, sized };                   // freestanding
 
  template<input_or_output_iterator I, sentinel_for<I> S = I,
      subrange_kind K = /* see description */>
    requires (K == subrange_kind::sized || !sized_sentinel_for<S, I>)
  class subrange;                                                       // freestanding
 
  template<class I, class S, subrange_kind K>
    inline constexpr bool enable_borrowed_range<subrange<I, S, K>> = true; // freestanding
 
  template<size_t N, class I, class S, subrange_kind K>
    requires ((N == 0 && copyable<I>) || N == 1)
    constexpr auto get(const subrange<I, S, K>& r);                     // freestanding
 
  template<size_t N, class I, class S, subrange_kind K>
    requires (N < 2)
    constexpr auto get(subrange<I, S, K>&& r);                          // freestanding
}
 
namespace std {
  using ranges::get;                                                    // freestanding
}
 
namespace std::ranges {
  // dangling iterator handling
  struct dangling;                                                      // freestanding
 
  // class template elements_of
  template<range R, class Allocator = allocator<byte>>
    struct elements_of;
 
  template<range R>
    using borrowed_iterator_t = /* see description */;                  // freestanding
 
  template<range R>
    using borrowed_subrange_t = /* see description */;                  // freestanding
 
  // range conversions
  template<class C, input_range R, class... Args> requires (!view<C>)
    constexpr C to(R&& r, Args&&... args);                              // freestanding
  template<template<class...> class C, input_range R, class... Args>
    constexpr auto to(R&& r, Args&&... args);                           // freestanding
  template<class C, class... Args> requires (!view<C>)
    constexpr auto to(Args&&... args);                                  // freestanding
  template<template<class...> class C, class... Args>
    constexpr auto to(Args&&... args);                                  // freestanding
 
  // empty view
  template<class T>
    requires is_object_v<T>
  class empty_view;                                                     // freestanding
 
  template<class T>
    inline constexpr bool enable_borrowed_range<empty_view<T>> = true;  // freestanding
 
  namespace views {
    template<class T>
      inline constexpr empty_view<T> empty{};                           // freestanding
  }
 
  // single view
  template<move_constructible T>
    requires is_object_v<T>
  class single_view;                                                    // freestanding
 
  namespace views { inline constexpr /* unspecified */ single = /* unspecified */; }
                                                                        // freestanding
 
  template<bool Const, class T>
    using __maybe_const = conditional_t<Const, const T, T>;   // exposition only
 
  // iota view
  template<weakly_incrementable W, semiregular Bound = unreachable_sentinel_t>
    requires __weakly_equality_comparable_with<W, Bound> && copyable<W>
  class iota_view;                                                      // freestanding
 
  template<class W, class Bound>
    inline constexpr bool enable_borrowed_range<iota_view<W, Bound>> = true;
                                                                        // freestanding
 
  namespace views { inline constexpr /* unspecified */ iota = /* unspecified */; }
                                                                        // freestanding
 
  // repeat view
  template<move_constructible W, semiregular Bound = unreachable_sentinel_t>
    requires (is_object_v<W> && same_as<W, remove_cv_t<W>>
      && (__is_integer_like<Bound> || same_as<Bound, unreachable_sentinel_t>))
  class repeat_view;
 
  namespace views { inline constexpr /* unspecified */ repeat = /* unspecified */; }
 
  // istream view
  template<movable Val, class CharT, class Traits = char_traits<CharT>>
    requires /* see description */
  class basic_istream_view;
  template<class Val>
    using istream_view = basic_istream_view<Val, char>;
  template<class Val>
    using wistream_view = basic_istream_view<Val, wchar_t>;
 
  namespace views { template<class T> inline constexpr /* unspecified */ istream =
    /* unspecified */; }
 
  // range adaptor objects
  template<class D>
    requires is_class_v<D> && same_as<D, remove_cv_t<D>>
  class range_adaptor_closure { };                                      // freestanding
 
  // all view
  namespace views {
    inline constexpr /* unspecified */ all = /* unspecified */;         // freestanding
 
    template<viewable_range R>
      using all_t = decltype(all(declval<R>()));                        // freestanding
  }
 
  // ref view
  template<range R>
    requires is_object_v<R>
  class ref_view;                                                       // freestanding
 
  template<class T>
    inline constexpr bool enable_borrowed_range<ref_view<T>> = true;    // freestanding
 
  // owning view
  template<range R>
    requires /* see description */
  class owning_view;                                                    // freestanding
 
  template<class T>
    inline constexpr bool enable_borrowed_range<owning_view<T>> =       // freestanding
      enable_borrowed_range<T>;
 
  // as rvalue view
  template<view V>
    requires input_range<V>
  class as_rvalue_view;                                                 // freestanding
 
  template<class T>
    inline constexpr bool enable_borrowed_range<as_rvalue_view<T>> =    // freestanding
      enable_borrowed_range<T>;
 
  namespace views { inline constexpr /* unspecified */ as_rvalue = /* unspecified */; }
                                                                        // freestanding
 
  // filter view
  template<input_range V, indirect_unary_predicate<iterator_t<V>> Pred>
    requires view<V> && is_object_v<Pred>
  class filter_view;                                                    // freestanding
 
  namespace views { inline constexpr /* unspecified */ filter = /* unspecified */; }
                                                                        // freestanding
 
  // transform view
  template<input_range V, move_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>>>
  class transform_view;                                                 // freestanding
 
  namespace views { inline constexpr /* unspecified */ transform = /* unspecified */; }
                                                                        // freestanding
 
  // take view
  template<view> class take_view;                                       // freestanding
 
  template<class T>
    inline constexpr bool enable_borrowed_range<take_view<T>> =         // freestanding
      enable_borrowed_range<T>;
 
  namespace views { inline constexpr /* unspecified */ take = /* unspecified */; }
                                                                        // freestanding
 
  // take while view
  template<view V, class Pred>
    requires input_range<V> && is_object_v<Pred> &&
             indirect_unary_predicate<const Pred, iterator_t<V>>
    class take_while_view;                                              // freestanding
 
  namespace views { inline constexpr /* unspecified */ take_while = /* unspecified */; }
                                                                        // freestanding
 
  // drop view
  template<view V>
    class drop_view;                                                    // freestanding
 
  template<class T>
    inline constexpr bool enable_borrowed_range<drop_view<T>> =         // freestanding
      enable_borrowed_range<T>;
 
  namespace views { inline constexpr /* unspecified */ drop = /* unspecified */; }
                                                                        // freestanding
 
  // drop while view
  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;                                              // freestanding
 
  template<class T, class Pred>
    inline constexpr bool enable_borrowed_range<drop_while_view<T, Pred>> =
                                                                        // freestanding
      enable_borrowed_range<T>;
 
  namespace views { inline constexpr /* unspecified */ drop_while = /* unspecified */; }
                                                                        // freestanding
 
  // join view
  template<input_range V>
    requires view<V> && input_range<range_reference_t<V>>
  class join_view;                                                      // freestanding
 
  namespace views { inline constexpr /* unspecified */ join = /* unspecified */; }
                                                                        // freestanding
 
  // join with view
  template<class R, class P>
    concept __compatible_joinable_ranges = /* see description */; // exposition only
 
  template<input_range V, forward_range Pattern>
    requires view<V> && input_range<range_reference_t<V>>
          && view<Pattern>
          && __compatible_joinable_ranges<range_reference_t<V>, Pattern>
  class join_with_view;                                                 // freestanding
 
  namespace views { inline constexpr /* unspecified */ join_with = /* unspecified */; }
                                                                        // freestanding
 
  // lazy split view
  template<class R>
    concept __tiny_range = /* see description */;   // exposition only
 
  template<input_range V, forward_range Pattern>
    requires view<V> && view<Pattern> &&
             indirectly_comparable<iterator_t<V>, iterator_t<Pattern>,
             ranges::equal_to> &&
             (forward_range<V> || __tiny_range<Pattern>)
  class lazy_split_view;                                                // freestanding
 
  // split view
 template<forward_range V, forward_range Pattern>
   requires view<V> && view<Pattern> &&
            indirectly_comparable<iterator_t<V>, iterator_t<Pattern>, ranges::equal_to>
  class split_view;                                                     // freestanding
 
  namespace views {
    inline constexpr /* unspecified */ lazy_split = /* unspecified */;  // freestanding
    inline constexpr /* unspecified */ split = /* unspecified */;       // freestanding
  }
 
  // counted view
  namespace views { inline constexpr /* unspecified */ counted = /* unspecified */; }
                                                                        // freestanding
 
  // common view
  template<view V>
    requires (!common_range<V> && copyable<iterator_t<V>>)
  class common_view;                                                    // freestanding
 
  template<class T>
    inline constexpr bool enable_borrowed_range<common_view<T>> =       // freestanding
      enable_borrowed_range<T>;
 
  namespace views { inline constexpr /* unspecified */ common = /* unspecified */; }
                                                                        // freestanding
 
  // reverse view
  template<view V>
    requires bidirectional_range<V>
  class reverse_view;                                                   // freestanding
 
  template<class T>
    inline constexpr bool enable_borrowed_range<reverse_view<T>> =      // freestanding
      enable_borrowed_range<T>;
 
  namespace views { inline constexpr /* unspecified */ reverse = /* unspecified */; }
                                                                        // freestanding
 
  // as const view
  template<input_range R>
    constexpr auto& __possibly_const_range(R& r) {          // exposition only
      if constexpr (constant_range<const R> && !constant_range<R>) {
        return const_cast<const R&>(r);
      } else {
        return r;
      }
    }
 
  template<view V>
    requires input_range<V>
  class as_const_view;                                                  // freestanding
 
  template<class T>
    inline constexpr bool enable_borrowed_range<as_const_view<T>> =     // freestanding
      enable_borrowed_range<T>;
 
  namespace views { inline constexpr /* unspecified */ as_const = /* unspecified */; }
                                                                        // freestanding
 
  // elements view
  template<input_range V, size_t N>
    requires /* see description */
  class elements_view;                                                  // freestanding
 
  template<class T, size_t N>
    inline constexpr bool enable_borrowed_range<elements_view<T, N>> =  // freestanding
      enable_borrowed_range<T>;
 
  template<class R>
    using keys_view = elements_view<R, 0>;                              // freestanding
  template<class R>
    using values_view = elements_view<R, 1>;                            // freestanding
 
  namespace views {
    template<size_t N>
      inline constexpr /* unspecified */ elements = /* unspecified */;  // freestanding
    inline constexpr auto keys = elements<0>;                           // freestanding
    inline constexpr auto values = elements<1>;                         // freestanding
  }
 
  template<input_range View>
    requires view<View>
  class enumerate_view; // freestanding
 
  template<class View>
    inline constexpr bool enable_borrowed_range<enumerate_view<View>> = // freestanding
      enable_borrowed_range<View>;
 
  namespace views {
    inline constexpr /* unspecified */ enumerate = /* unspecified */;   // freestanding
  }
 
  // zip view
  template<input_range... Views>
    requires (view<Views> && ...) && (sizeof...(Views) > 0)
  class zip_view;                                                       // freestanding
 
  template<class... Views>
    inline constexpr bool enable_borrowed_range<zip_view<Views...>> =   // freestanding
      (enable_borrowed_range<Views> && ...);
 
  namespace views { inline constexpr /* unspecified */ zip = /* unspecified */; }
                                                                        // freestanding
 
  // zip transform view
  template<move_constructible F, input_range... Views>
    requires (view<Views> && ...) && (sizeof...(Views) > 0) && is_object_v<F> &&
             regular_invocable<F&, range_reference_t<Views>...> &&
             __can_reference<invoke_result_t<F&, range_reference_t<Views>...>>
  class zip_transform_view;                                             // freestanding
 
  namespace views { inline constexpr /* unspecified */ zip_transform =
    /* unspecified */; }                                                // freestanding
 
  // adjacent view
  template<forward_range V, size_t N>
    requires view<V> && (N > 0)
  class adjacent_view;                                                  // freestanding
 
  template<class V, size_t N>
    inline constexpr bool enable_borrowed_range<adjacent_view<V, N>> =  // freestanding
      enable_borrowed_range<V>;
 
  namespace views {
    template<size_t N>
      inline constexpr /* unspecified */ adjacent = /* unspecified */;  // freestanding
    inline constexpr auto pairwise = adjacent<2>;                       // freestanding
  }
 
  // adjacent transform view
  template<forward_range V, move_constructible F, size_t N>
    requires /* see description */
  class adjacent_transform_view;                                        // freestanding
 
  namespace views {
    template<size_t N>
      inline constexpr /* unspecified */ adjacent_transform =
        /* unspecified */;                                              // freestanding
    inline constexpr auto pairwise_transform = adjacent_transform<2>;   // freestanding
  }
 
  // chunk view
  template<view V>
    requires input_range<V>
  class chunk_view;                                                     // freestanding
 
  template<view V>
    requires forward_range<V>
  class chunk_view<V>;                                                  // freestanding
 
  template<class V>
    inline constexpr bool enable_borrowed_range<chunk_view<V>> =        // freestanding
      forward_range<V> && enable_borrowed_range<V>;
 
  namespace views { inline constexpr /* unspecified */ chunk =
    /* unspecified */; }                                                // freestanding
 
  // slide view
  template<forward_range V>
    requires view<V>
  class slide_view;                                                     // freestanding
 
  template<class V>
    inline constexpr bool enable_borrowed_range<slide_view<V>> =
      enable_borrowed_range<V>;                                         // freestanding
 
  namespace views { inline constexpr /* unspecified */ slide =
    /* unspecified */; }                                                // freestanding
 
  // chunk by view
  template<forward_range V, indirect_binary_predicate<iterator_t<V>, iterator_t<V>> Pred>
    requires view<V> && is_object_v<Pred>
  class chunk_by_view;                                                  // freestanding
 
  namespace views { inline constexpr /* unspecified */ chunk_by =
    /* unspecified */; }                                                // freestanding
 
  // stride view
  template<input_range V>
    requires view<V>
  class stride_view;
 
  template<class V>
    inline constexpr bool enable_borrowed_range<stride_view<V>> =
      enable_borrowed_range<V>;
 
  namespace views { inline constexpr /* unspecified */ stride = /* unspecified */; }
 
  // cartesian product view
  template<input_range First, forward_range... Vs>
    requires (view<First> && ... && view<Vs>)
  class cartesian_product_view;
 
  namespace views { inline constexpr /* unspecified */ cartesian_product =
    /* unspecified */; }
}
 
namespace std {
  namespace views = ranges::views;                                      // freestanding
 
  template<class T> struct tuple_size;                                  // freestanding
  template<size_t I, class T> struct tuple_element;                     // freestanding
 
  template<class I, class S, ranges::subrange_kind K>
  struct tuple_size<ranges::subrange<I, S, K>>                          // freestanding
    : integral_constant<size_t, 2> {};
  template<class I, class S, ranges::subrange_kind K>
  struct tuple_element<0, ranges::subrange<I, S, K>> {                  // freestanding
    using type = I;                                                     // freestanding
  };
  template<class I, class S, ranges::subrange_kind K>
  struct tuple_element<1, ranges::subrange<I, S, K>> {                  // freestanding
    using type = S;                                                     // freestanding
  };
  template<class I, class S, ranges::subrange_kind K>
  struct tuple_element<0, const ranges::subrange<I, S, K>> {            // freestanding
    using type = I;                                                     // freestanding
  };
  template<class I, class S, ranges::subrange_kind K>
  struct tuple_element<1, const ranges::subrange<I, S, K>> {            // freestanding
    using type = S;                                                     // freestanding
  };
 
  struct from_range_t { explicit from_range_t() = default; };           // freestanding
  inline constexpr from_range_t from_range{};                           // freestanding
}

Concept range

namespace std::ranges {
  template< class T >
    concept range = requires(T& t) {
      ranges::begin(t); // equality-preserving for forward iterators
      ranges::end(t);
  };
}

Concept borrowed_range

namespace std::ranges {
  template<class T>
    concept borrowed_range =
      range<T> && (is_lvalue_reference_v<T> ||
        enable_borrowed_range<remove_cvref_t<T>>);
}

Concept sized_range

namespace std::ranges {
  template< class T >
    concept sized_range = range<T> &&
      requires(T& t) {
        ranges::size(t);
      };
}

Concept view

namespace std::ranges {
  template<class T>
    inline constexpr bool enable_view = derived_from<T, view_base>;
 
  template<class T>
    concept view = range<T>
                && movable<T>
                && enable_view<T>;
}

Concept output_range

namespace std::ranges {
  template<class R, class T>
    concept output_range =
      range<R> && output_iterator<iterator_t<R>, T>;
}

Concept input_range

namespace std::ranges {
  template<class T>
    concept input_range =
      range<T> && input_iterator<iterator_t<T>>;
}

Concept forward_range

namespace std::ranges {
  template<class T>
    concept forward_range =
      input_range<T> && forward_iterator<iterator_t<T>>;
}

Concept bidirectional_range

namespace std::ranges {
  template<class T>
    concept bidirectional_range =
      forward_range<T> && bidirectional_iterator<iterator_t<T>>;
}

Concept random_access_range

namespace std::ranges {
  template<class T>
    concept random_access_range =
      bidirectional_range<T> && random_access_iterator<iterator_t<T>>;
}

Concept contiguous_range

namespace std::ranges {
  template<class T>
    concept contiguous_range =
      random_access_range<T> && contiguous_iterator<iterator_t<T>> &&
        requires(T& t) {
          { ranges::data(t) } -> same_as<add_pointer_t<range_reference_t<T>>>;
        };
}

Concept common_range

namespace std::ranges {
  template<class T>
    concept common_range =
      range<T> && same_as<iterator_t<T>, sentinel_t<T>>;
}

Concept viewable_range

namespace std::ranges {
  template<class T>
    concept viewable_range =
      range<T> && (borrowed_range<T> || view<remove_cvref_t<T>>);
}

Helper concepts

Note: The following names are only for exposition, they are not part of the interface.

namespace std::ranges { // unspecified, for name lookup only
  template<class R>
    concept __simple_view =                                       // exposition only
      view<R> && range<const R> &&
      same_as<iterator_t<R>, iterator_t<const R>> &&
      same_as<sentinel_t<R>, sentinel_t<const R>>;
 
  template<class I>
    concept __has_arrow =                                         // exposition only
      input_iterator<I> &&
      (is_pointer_v<I> || requires(I i) { i.operator->(); });
 
  template<class T, class U>
    concept __different_from =                                    // exposition only
      !same_as<remove_cvref_t<T>, remove_cvref_t<U>>;
}

Class template std::ranges::view_interface

namespace std::ranges {
  template<class D>
    requires is_class_v<D> && same_as<D, remove_cv_t<D>>
  class view_interface {
  private:
    constexpr D& derived() noexcept {               // exposition only
      return static_cast<D&>(*this);
    }
    constexpr const D& derived() const noexcept {   // exposition only
      return static_cast<const D&>(*this);
    }
 
  public:
    constexpr bool empty() requires sized_range<D> || forward_range<D> {
      if constexpr (sized_range<D>)
        return ranges::size(derived()) == 0;
      else
        return ranges::begin(derived()) == ranges::end(derived());
    }
    constexpr bool empty() const requires sized_range<const D> ||
        forward_range<const D> {
      if constexpr (sized_range<const D>)
        return ranges::size(derived()) == 0;
      else
        return ranges::begin(derived()) == ranges::end(derived());
    }
 
    constexpr auto cbegin() {
      return ranges::cbegin(derived());
    }
    constexpr auto cbegin() const requires range<const D> {
      return ranges::cbegin(derived());
    }
    constexpr auto cend() {
      return ranges::cend(derived());
    }
    constexpr auto cend() const requires range<const D> {
      return ranges::cend(derived());
    }
 
    constexpr explicit operator bool()
      requires requires { ranges::empty(derived()); } {
        return !ranges::empty(derived());
      }
    constexpr explicit operator bool() const
      requires requires { ranges::empty(derived()); } {
        return !ranges::empty(derived());
      }
 
    constexpr auto data() requires contiguous_iterator<iterator_t<D>> {
      return to_address(ranges::begin(derived()));
    }
    constexpr auto data() const
      requires range<const D> && contiguous_iterator<iterator_t<const D>> {
        return to_address(ranges::begin(derived()));
      }
 
    constexpr auto size() requires forward_range<D> &&
      sized_sentinel_for<sentinel_t<D>, iterator_t<D>> {
        return ranges::end(derived()) - ranges::begin(derived());
      }
    constexpr auto size() const requires forward_range<const D> &&
      sized_sentinel_for<sentinel_t<const D>, iterator_t<const D>> {
        return ranges::end(derived()) - ranges::begin(derived());
      }
 
    constexpr decltype(auto) front() requires forward_range<D>;
    constexpr decltype(auto) front() const requires forward_range<const D>;
 
    constexpr decltype(auto) back() requires bidirectional_range<D> && common_range<D>;
    constexpr decltype(auto) back() const
      requires bidirectional_range<const D> && common_range<const D>;
 
    template<random_access_range R = D>
      constexpr decltype(auto) operator[](range_difference_t<R> n) {
        return ranges::begin(derived())[n];
      }
    template<random_access_range R = const D>
      constexpr decltype(auto) operator[](range_difference_t<R> n) const {
        return ranges::begin(derived())[n];
      }
  };
}

Class template std::ranges::subrange

namespace std::ranges {
  template<class From, class To>
    concept __uses_nonqualification_pointer_conversion =      // exposition only
      is_pointer_v<From> && is_pointer_v<To> &&
      !convertible_to<remove_pointer_t<From>(*)[], remove_pointer_t<To>(*)[]>;
 
  template<class From, class To>
    concept __convertible_to_non_slicing =                    // exposition only
      convertible_to<From, To> &&
      !__uses_nonqualification_pointer_conversion<decay_t<From>, decay_t<To>>;
 
  template<class T, class U, class V>
    concept __pair_like_convertible_from =                    // exposition only
      !range<T> && !is_reference_v<T> && __pair_like<T> &&
      constructible_from<T, U, V> &&
      __convertible_to_non_slicing<U, tuple_element_t<0, T>> &&
      convertible_to<V, tuple_element_t<1, T>>;
 
  template<input_or_output_iterator I, sentinel_for<I> S = I, subrange_kind K =
      sized_sentinel_for<S, I> ? subrange_kind::sized : subrange_kind::unsized>
    requires (K == subrange_kind::sized || !sized_sentinel_for<S, I>)
  class subrange : public view_interface<subrange<I, S, K>> {
  private:
    static constexpr bool StoreSize =                       // exposition only
      K == subrange_kind::sized && !sized_sentinel_for<S, I>;
    I begin_ = I();                                         // exposition only
    S end_ = S();                                           // exposition only
    __make_unsigned_like_t<iter_difference_t<I>> size_ = 0;
        // exposition only; present only when StoreSize is true
  public:
    subrange() requires default_initializable<I> = default;
 
    constexpr subrange(__convertible_to_non_slicing<I> auto i, S s) requires (!StoreSize);
 
    constexpr subrange(__convertible_to_non_slicing<I> auto i, S s,
                       __make_unsigned_like_t<iter_difference_t<I>> n)
      requires (K == subrange_kind::sized);
 
    template<__different_from<subrange> R>
      requires borrowed_range<R> &&
               __convertible_to_non_slicing<iterator_t<R>, I> &&
               convertible_to<sentinel_t<R>, S>
    constexpr subrange(R&& r) requires (!StoreSize || sized_range<R>);
 
    template<borrowed_range R>
      requires __convertible_to_non_slicing<iterator_t<R>, I> &&
               convertible_to<sentinel_t<R>, S>
    constexpr subrange(R&& r, __make_unsigned_like_t<iter_difference_t<I>> n)
      requires (K == subrange_kind::sized)
        : subrange{ranges::begin(r), ranges::end(r), n} {}
 
    template<__different_from<subrange> PairLike>
      requires __pair_like_convertible_from<PairLike, const I&, const S&>
    constexpr operator PairLike() const;
 
    constexpr I begin() const requires copyable<I>;
    [[nodiscard]] constexpr I begin() requires (!copyable<I>);
    constexpr S end() const;
 
    constexpr bool empty() const;
    constexpr __make_unsigned_like_t<iter_difference_t<I>> size() const
      requires (K == subrange_kind::sized);
 
    [[nodiscard]] constexpr subrange next(iter_difference_t<I> n = 1) const &
      requires forward_iterator<I>;
    [[nodiscard]] constexpr subrange next(iter_difference_t<I> n = 1) &&;
    [[nodiscard]] constexpr subrange prev(iter_difference_t<I> n = 1) const
      requires bidirectional_iterator<I>;
    constexpr subrange& advance(iter_difference_t<I> n);
  };
 
  template<input_or_output_iterator I, sentinel_for<I> S>
    subrange(I, S) -> subrange<I, S>;
 
  template<input_or_output_iterator I, sentinel_for<I> S>
    subrange(I, S, __make_unsigned_like_t<iter_difference_t<I>>) ->
      subrange<I, S, subrange_kind::sized>;
 
  template<borrowed_range R>
    subrange(R&&) ->
      subrange<iterator_t<R>, sentinel_t<R>,
               (sized_range<R> || sized_sentinel_for<sentinel_t<R>, iterator_t<R>>)
                 ? subrange_kind::sized : subrange_kind::unsized>;
 
  template<borrowed_range R>
    subrange(R&&, __make_unsigned_like_t<range_difference_t<R>>) ->
      subrange<iterator_t<R>, sentinel_t<R>, subrange_kind::sized>;
}

Class std::ranges::dangling

namespace std::ranges {
  struct dangling {
    constexpr dangling() noexcept = default;
    constexpr dangling(auto&&...) noexcept {}
  };
}

Class std::ranges::elements_of

namespace std::ranges {
  template<range R, class Allocator = allocator<byte>>
  struct elements_of {
    [[no_unique_address]] R range;
    [[no_unique_address]] Allocator allocator = Allocator();
  };
 
  template<class R, class Allocator = allocator<byte>>
    elements_of(R&&, Allocator = Allocator()) -> elements_of<R&&, Allocator>;
}

Class template std::ranges::empty_view

namespace std::ranges {
  template<class T>
    requires is_object_v<T>
  class empty_view : public view_interface<empty_view<T>> {
  public:
    static constexpr T* begin() noexcept { return nullptr; }
    static constexpr T* end() noexcept { return nullptr; }
    static constexpr T* data() noexcept { return nullptr; }
    static constexpr size_t size() noexcept { return 0; }
    static constexpr bool empty() noexcept { return true; }
  };
}

Class template std::ranges::single_view

namespace std::ranges {
  template<move_constructible T>
    requires is_object_v<T>
  class single_view : public view_interface<single_view<T>> {
  private:
    __movable_box<T> value_;              // exposition only
 
  public:
    single_view() requires default_initializable<T> = default;
    constexpr explicit single_view(const T& t) requires copy_constructible<T>;
    constexpr explicit single_view(T&& t);
    template<class... Args>
      requires constructible_from<T, Args...>
    constexpr explicit single_view(in_place_t, Args&&... args);
 
    constexpr T* begin() noexcept;
    constexpr const T* begin() const noexcept;
    constexpr T* end() noexcept;
    constexpr const T* end() const noexcept;
    static constexpr size_t size() noexcept;
    constexpr T* data() noexcept;
    constexpr const T* data() const noexcept;
  };
 
  template<class T>
    single_view(T) -> single_view<T>;
}

Class template std::ranges::iota_view

namespace std::ranges {
  template<class I>
    concept decrementable = /* see description */;  // exposition only
 
  template<class I>
    concept advanceable = /* see description */;    // exposition only
 
  template<weakly_incrementable W, semiregular Bound = unreachable_sentinel_t>
    requires __weakly_equality_comparable_with<W, Bound> && copyable<W>
  class iota_view : public view_interface<iota_view<W, Bound>> {
  private:
    // class iota_view::iterator
    struct iterator;                    // exposition only
 
    // class iota_view::sentinel
    struct sentinel;                    // exposition only
 
    W value_ = W();                     // exposition only
    Bound bound_ = Bound();             // exposition only
 
  public:
    iota_view() requires default_initializable<W> = default;
    constexpr explicit iota_view(W value);
    constexpr explicit iota_view(type_identity_t<W> value, type_identity_t<Bound> bound);
    constexpr explicit iota_view(iterator first, /* see description */ last);
 
    constexpr iterator begin() const;
    constexpr auto end() const;
    constexpr iterator end() const requires same_as<W, Bound>;
 
    constexpr auto size() const requires /* see description */;
  };
 
  template<class W, class Bound>
    requires (!__is_integer_like<W> || !__is_integer_like<Bound> ||
              (__is_signed_integer_like<W> == __is_signed_integer_like<Bound>))
    iota_view(W, Bound) -> iota_view<W, Bound>;
}

Class template std::ranges::iota_view::iterator

namespace std::ranges {
  template<weakly_incrementable W, semiregular Bound>
    requires __weakly_equality_comparable_with<W, Bound> && copyable<W>
  struct iota_view<W, Bound>::iterator {
  private:
    W value_ = W();             // exposition only
  public:
    using iterator_concept = /* see description */;
    using iterator_category = input_iterator_tag; // present only if W models
      // __incrementable and __IOTA_DIFF_T(W) is an integral type
 
    using value_type = W;
    using difference_type = __IOTA_DIFF_T(W);
 
    iterator() requires default_initializable<W> = default;
    constexpr explicit iterator(W value);
 
    constexpr W operator*() const noexcept(is_nothrow_copy_constructible_v<W>);
 
    constexpr iterator& operator++();
    constexpr void operator++(int);
    constexpr iterator operator++(int) requires incrementable<W>;
 
    constexpr iterator& operator--() requires decrementable<W>;
    constexpr iterator operator--(int) requires decrementable<W>;
 
    constexpr iterator& operator+=(difference_type n)
      requires advanceable<W>;
    constexpr iterator& operator-=(difference_type n)
      requires advanceable<W>;
    constexpr W operator[](difference_type n) const
      requires advanceable<W>;
 
    friend constexpr bool operator==(const iterator& x, const iterator& y)
      requires equality_comparable<W>;
 
    friend constexpr bool operator<(const iterator& x, const iterator& y)
      requires totally_ordered<W>;
    friend constexpr bool operator>(const iterator& x, const iterator& y)
      requires totally_ordered<W>;
    friend constexpr bool operator<=(const iterator& x, const iterator& y)
      requires totally_ordered<W>;
    friend constexpr bool operator>=(const iterator& x, const iterator& y)
      requires totally_ordered<W>;
    friend constexpr auto operator<=>(const iterator& x, const iterator& y)
      requires totally_ordered<W> && three_way_comparable<W>;
 
    friend constexpr iterator operator+(iterator i, difference_type n)
      requires advanceable<W>;
    friend constexpr iterator operator+(difference_type n, iterator i)
      requires advanceable<W>;
 
    friend constexpr iterator operator-(iterator i, difference_type n)
      requires advanceable<W>;
    friend constexpr difference_type operator-(const iterator& x, const iterator& y)
      requires advanceable<W>;
  };
}

Class template std::ranges::iota_view::sentinel

namespace std::ranges {
  template<weakly_incrementable W, semiregular Bound>
    requires __weakly_equality_comparable_with<W, Bound> && copyable<W>
  struct iota_view<W, Bound>::sentinel {
  private:
    Bound bound_ = Bound();     // exposition only
  public:
    sentinel() = default;
    constexpr explicit sentinel(Bound bound);
 
    friend constexpr bool operator==(const iterator& x, const sentinel& y);
 
    friend constexpr iter_difference_t<W> operator-(const iterator& x, const sentinel& y)
      requires sized_sentinel_for<Bound, W>;
    friend constexpr iter_difference_t<W> operator-(const sentinel& x, const iterator& y)
      requires sized_sentinel_for<Bound, W>;
  };
}

Class template std::ranges::repeat_view

namespace std::ranges {
  template<move_constructible W, semiregular Bound = unreachable_sentinel_t>
    requires (is_object_v<W> && same_as<W, remove_cv_t<W>> &&
              (__is_integer_like<Bound> || same_as<Bound, unreachable_sentinel_t>))
  class repeat_view : public view_interface<repeat_view<W, Bound>> {
  private:
    // class repeat_view::iterator
    struct iterator;                            // exposition only
 
    __movable_box<W> value_ = W();              // exposition only
    Bound bound_ = Bound();                     // exposition only
 
  public:
    repeat_view() requires default_initializable<W> = default;
 
    constexpr explicit repeat_view(const W& value, Bound bound = Bound())
      requires copy_constructible<W>;
    constexpr explicit repeat_view(W&& value, Bound bound = Bound());
    template<class... WArgs, class... BoundArgs>
      requires constructible_from<W, WArgs...> &&
               constructible_from<Bound, BoundArgs...>
    constexpr explicit repeat_view(piecewise_construct_t,
      tuple<WArgs...> value_args, tuple<BoundArgs...> bound_args = tuple<>{});
 
    constexpr iterator begin() const;
    constexpr iterator end() const requires (!same_as<Bound, unreachable_sentinel_t>);
    constexpr unreachable_sentinel_t end() const noexcept;
 
    constexpr auto size() const requires (!same_as<Bound, unreachable_sentinel_t>);
  };
 
  template<class W, class Bound>
    repeat_view(W, Bound) -> repeat_view<W, Bound>;
}

Class template std::ranges::repeat_view::iterator

namespace std::ranges {
  template<move_constructible W, semiregular Bound = unreachable_sentinel_t>
    requires (is_object_v<W> && same_as<W, remove_cv_t<W>> &&
              (__is_integer_like<Bound> || same_as<Bound, unreachable_sentinel_t>))
  class repeat_view<W, Bound>::iterator {
  private:
    using __index_type =                            // exposition only
      conditional_t<same_as<Bound, unreachable_sentinel_t>, ptrdiff_t, Bound>;
    const W* value_ = nullptr;                      // exposition only
    __index_type current_ = __index_type();         // exposition only
 
    constexpr explicit iterator(const W* value,
                                __index_type b = __index_type());   // exposition only
 
  public:
    using iterator_concept = random_access_iterator_tag;
    using iterator_category = random_access_iterator_tag;
    using value_type = W;
    using difference_type = conditional_t<__is_signed_integer_like<__index_type>,
        __index_type,
        __IOTA_DIFF_T(__index_type)>;
 
    iterator() = default;
 
    constexpr const W& operator*() const noexcept;
 
    constexpr iterator& operator++();
    constexpr iterator operator++(int);
 
    constexpr iterator& operator--();
    constexpr iterator operator--(int);
 
    constexpr iterator& operator+=(difference_type n);
    constexpr iterator& operator-=(difference_type n);
    constexpr const W& operator[](difference_type n) const noexcept;
 
    friend constexpr bool operator==(const iterator& x, const iterator& y);
    friend constexpr auto operator<=>(const iterator& x, const iterator& y);
 
    friend constexpr iterator operator+(iterator i, difference_type n);
    friend constexpr iterator operator+(difference_type n, iterator i);
 
    friend constexpr iterator operator-(iterator i, difference_type n);
    friend constexpr difference_type operator-(const iterator& x, const iterator& y);
  };
}

Class template std::ranges::basic_istream_view

namespace std::ranges {
  template<class Val, class CharT, class Traits>
    concept __stream_extractable =                // exposition only
      requires(basic_istream<CharT, Traits>& is, Val& t) {
         is >> t;
      };
 
  template<movable Val, class CharT, class Traits = char_traits<CharT>>
    requires default_initializable<Val> && __stream_extractable<Val, CharT, Traits>
  class basic_istream_view :
    public view_interface<basic_istream_view<Val, CharT, Traits>> {
  public:
    constexpr explicit basic_istream_view(basic_istream<CharT, Traits>& stream);
 
    constexpr auto begin() {
      *stream_ >> value_;
      return iterator{*this};
    }
 
    constexpr default_sentinel_t end() const noexcept;
 
  private:
    // class basic_istream_view::iterator
    struct iterator;                            // exposition only
    basic_istream<CharT, Traits>* stream_;      // exposition only
    Val value_ = Val();                         // exposition only
  };
}

Class template std::ranges::basic_istream_view::iterator

namespace std::ranges {
  template<movable Val, class CharT, class Traits>
    requires default_initializable<Val> &&
             __stream_extractable<Val, CharT, Traits>
  class basic_istream_view<Val, CharT, Traits>::iterator {
  public:
    using iterator_concept = input_iterator_tag;
    using difference_type = ptrdiff_t;
    using value_type = Val;
 
    constexpr explicit iterator(basic_istream_view& parent) noexcept;
 
    iterator(const iterator&) = delete;
    iterator(iterator&&) = default;
 
    iterator& operator=(const iterator&) = delete;
    iterator& operator=(iterator&&) = default;
 
    iterator& operator++();
    void operator++(int);
 
    Val& operator*() const;
 
    friend bool operator==(const iterator& x, default_sentinel_t);
 
  private:
    basic_istream_view* parent_;                                // exposition only
  };
}

Class template std::ranges::ref_view

namespace std::ranges {
  template<range R>
    requires is_object_v<R>
  class ref_view : public view_interface<ref_view<R>> {
  private:
    R* r_;                      // exposition only
  public:
    template<__different_from<ref_view> T>
      requires /* see description */
    constexpr ref_view(T&& t);
 
    constexpr R& base() const { return *r_; }
 
    constexpr iterator_t<R> begin() const { return ranges::begin(*r_); }
    constexpr sentinel_t<R> end() const { return ranges::end(*r_); }
 
    constexpr bool empty() const
      requires requires { ranges::empty(*r_); }
    { return ranges::empty(*r_); }
 
    constexpr auto size() const requires sized_range<R>
    { return ranges::size(*r_); }
 
    constexpr auto data() const requires contiguous_range<R>
    { return ranges::data(*r_); }
  };
 
  template<class R>
    ref_view(R&) -> ref_view<R>;
}

Class template std::ranges::owning_view

namespace std::ranges {
  template<range R>
    requires movable<R> && (!__is_initializer_list<R>)
  class owning_view : public view_interface<owning_view<R>> {
  private:
    R r_ = R();         // exposition only
  public:
    owning_view() requires default_initializable<R> = default;
    constexpr owning_view(R&& t);
 
    owning_view(owning_view&&) = default;
    owning_view& operator=(owning_view&&) = default;
 
    constexpr R& base() & noexcept { return r_; }
    constexpr const R& base() const & noexcept { return r_; }
    constexpr R&& base() && noexcept { return std::move(r_); }
    constexpr const R&& base() const && noexcept { return std::move(r_); }
 
    constexpr iterator_t<R> begin() { return ranges::begin(r_); }
    constexpr sentinel_t<R> end() { return ranges::end(r_); }
 
    constexpr auto begin() const requires range<const R>
    { return ranges::begin(r_); }
    constexpr auto end() const requires range<const R>
    { return ranges::end(r_); }
 
    constexpr bool empty() requires requires { ranges::empty(r_); }
    { return ranges::empty(r_); }
    constexpr bool empty() const requires requires { ranges::empty(r_); }
    { return ranges::empty(r_); }
 
    constexpr auto size() requires sized_range<R>
    { return ranges::size(r_); }
    constexpr auto size() const requires sized_range<const R>
    { return ranges::size(r_); }
 
    constexpr auto data() requires contiguous_range<R>
    { return ranges::data(r_); }
    constexpr auto data() const requires contiguous_range<const R>
    { return ranges::data(r_); }
  };
}

Class template std::ranges::as_rvalue_view

namespace std::ranges {
  template<view V>
    requires input_range<V>
  class as_rvalue_view : public view_interface<as_rvalue_view<V>> {
    V base_ = V();      // exposition only
 
  public:
    as_rvalue_view() requires default_initializable<V> = default;
    constexpr explicit as_rvalue_view(V base);
 
    constexpr V base() const & requires copy_constructible<V> { return base_; }
    constexpr V base() && { return std::move(base_); }
 
    constexpr auto begin() requires (!__simple_view<V>)
    { return move_iterator(ranges::begin(base_)); }
    constexpr auto begin() const requires range<const V>
    { return move_iterator(ranges::begin(base_)); }
 
    constexpr auto end() requires (!__simple_view<V>) {
      if constexpr (common_range<V>) {
        return move_iterator(ranges::end(base_));
      } else {
        return move_sentinel(ranges::end(base_));
      }
    }
    constexpr auto end() const requires range<const V> {
      if constexpr (common_range<const V>) {
        return move_iterator(ranges::end(base_));
      } else {
        return move_sentinel(ranges::end(base_));
      }
    }
 
    constexpr auto size() requires sized_range<V> { return ranges::size(base_); }
    constexpr auto size() const requires sized_range<const V> {
        return ranges::size(base_);
    }
  };
 
  template<class R>
    as_rvalue_view(R&&) -> as_rvalue_view<views::all_t<R>>;
}

Class template std::ranges::filter_view

namespace std::ranges {
  template<input_range V, indirect_unary_predicate<iterator_t<V>> Pred>
    requires view<V> && is_object_v<Pred>
  class filter_view : public view_interface<filter_view<V, Pred>> {
  private:
    V base_ = V();                              // exposition only
    __movable_box<Pred> pred_;                  // exposition only
 
    // class filter_view::iterator
    class iterator;                             // exposition only
 
    // class filter_view::sentinel
    class sentinel;                             // exposition only
 
  public:
    filter_view() requires default_initializable<V> &&
      default_initializable<Pred> = default;
    constexpr explicit filter_view(V base, Pred pred);
 
    constexpr V base() const & requires copy_constructible<V> { return base_; }
    constexpr V base() && { return std::move(base_); }
 
    constexpr const Pred& pred() const;
 
    constexpr iterator begin();
    constexpr auto end() {
      if constexpr (common_range<V>)
        return iterator{*this, ranges::end(base_)};
      else
        return sentinel{*this};
    }
  };
 
  template<class R, class Pred>
    filter_view(R&&, Pred) -> filter_view<views::all_t<R>, Pred>;
}

Class template std::ranges::filter_view::iterator

namespace std::ranges {
  template<input_range V, indirect_unary_predicate<iterator_t<V>> Pred>
    requires view<V> && is_object_v<Pred>
  class filter_view<V, Pred>::iterator {
  private:
    iterator_t<V> current_ = iterator_t<V>();   // exposition only
    filter_view* parent_ = nullptr;             // exposition only
 
  public:
    using iterator_concept  = /* see description */;
    using iterator_category = /* see description */;        // not always present
    using value_type        = range_value_t<V>;
    using difference_type   = range_difference_t<V>;
 
    iterator() requires default_initializable<iterator_t<V>> = default;
    constexpr iterator(filter_view& parent, iterator_t<V> current);
 
    constexpr const iterator_t<V>& base() const & noexcept;
    constexpr iterator_t<V> base() &&;
    constexpr range_reference_t<V> operator*() const;
    constexpr iterator_t<V> operator->() const
      requires __has_arrow<iterator_t<V>> && copyable<iterator_t<V>>;
 
    constexpr iterator& operator++();
    constexpr void operator++(int);
    constexpr iterator operator++(int) requires forward_range<V>;
 
    constexpr iterator& operator--() requires bidirectional_range<V>;
    constexpr iterator operator--(int) requires bidirectional_range<V>;
 
    friend constexpr bool operator==(const iterator& x, const iterator& y)
      requires equality_comparable<iterator_t<V>>;
 
    friend constexpr range_rvalue_reference_t<V> iter_move(const iterator& i)
      noexcept(noexcept(ranges::iter_move(i.current_)));
 
    friend constexpr void iter_swap(const iterator& x, const iterator& y)
      noexcept(noexcept(ranges::iter_swap(x.current_, y.current_)))
      requires indirectly_swappable<iterator_t<V>>;
  };
}

Class template std::ranges::filter_view::sentinel

namespace std::ranges {
  template<input_range V, indirect_unary_predicate<iterator_t<V>> Pred>
    requires view<V> && is_object_v<Pred>
  class filter_view<V, Pred>::sentinel {
  private:
    sentinel_t<V> end_ = sentinel_t<V>();       // exposition only
 
  public:
    sentinel() = default;
    constexpr explicit sentinel(filter_view& parent);
 
    constexpr sentinel_t<V> base() const;
 
    friend constexpr bool operator==(const iterator& x, const sentinel& y);
  };
}

Class template std::ranges::transform_view

namespace std::ranges {
  template<input_range V, move_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>>>
  class transform_view : public view_interface<transform_view<V, F>> {
  private:
    // class template transform_view::iterator
    template<bool> struct iterator;             // exposition only
 
    // class template transform_view::sentinel
    template<bool> struct sentinel;             // exposition only
 
    V base_ = V();                              // exposition only
    __movable_box<F> fun_;                      // exposition only
 
  public:
    transform_view() requires default_initializable<V> &&
      default_initializable<F> = default;
    constexpr explicit transform_view(V base, F fun);
 
    constexpr V base() const & requires copy_constructible<V> { return base_; }
    constexpr V base() && { return std::move(base_); }
 
    constexpr iterator<false> begin();
    constexpr iterator<true> begin() const
      requires range<const V> &&
               regular_invocable<const F&, range_reference_t<const V>>;
 
    constexpr sentinel<false> end();
    constexpr iterator<false> end() requires common_range<V>;
    constexpr sentinel<true> end() const
      requires range<const V> &&
               regular_invocable<const F&, range_reference_t<const V>>;
    constexpr iterator<true> end() const
      requires common_range<const V> &&
               regular_invocable<const F&, range_reference_t<const V>>;
 
    constexpr auto size() requires sized_range<V> { return ranges::size(base_); }
    constexpr auto size() const requires sized_range<const V>
    { return ranges::size(base_); }
  };
 
  template<class R, class F>
    transform_view(R&&, F) -> transform_view<views::all_t<R>, F>;
}

Class template std::ranges::transform_view::iterator

namespace std::ranges {
  template<input_range V, move_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 {
  private:
    using Parent = __maybe_const<Const, transform_view>;        // exposition only
    using Base = __maybe_const<Const, V>;                       // exposition only
    iterator_t<Base> current_ = iterator_t<Base>();             // exposition only
    Parent* parent_ = nullptr;                                  // exposition only
 
  public:
    using iterator_concept  = /* see description */;
    using iterator_category = /* see description */;            // not always present
    using value_type        =
      remove_cvref_t<invoke_result_t<__maybe_const<Const, F>&, range_reference_t<Base>>>;
    using difference_type   = range_difference_t<Base>;
 
    iterator() requires default_initializable<iterator_t<Base>> = default;
    constexpr iterator(Parent& parent, iterator_t<Base> current);
    constexpr iterator(iterator<!Const> i)
      requires Const && convertible_to<iterator_t<V>, iterator_t<Base>>;
 
    constexpr const iterator_t<Base>& base() const & noexcept;
    constexpr iterator_t<Base> base() &&;
 
    constexpr decltype(auto) operator*() const
      noexcept(noexcept(invoke(*parent_->fun_, *current_))) {
      return invoke(*parent_->fun_, *current_);
    }
 
    constexpr iterator& operator++();
    constexpr void operator++(int);
    constexpr iterator operator++(int) requires forward_range<Base>;
 
    constexpr iterator& operator--() requires bidirectional_range<Base>;
    constexpr iterator operator--(int) requires bidirectional_range<Base>;
 
    constexpr iterator& operator+=(difference_type n)
      requires random_access_range<Base>;
    constexpr iterator& operator-=(difference_type n)
      requires random_access_range<Base>;
 
    constexpr decltype(auto) operator[](difference_type n) const
      requires random_access_range<Base> {
      return invoke(*parent_->fun_, current_[n]);
    }
 
    friend constexpr bool operator==(const iterator& x, const iterator& y)
      requires equality_comparable<iterator_t<Base>>;
 
    friend constexpr bool operator<(const iterator& x, const iterator& y)
      requires random_access_range<Base>;
    friend constexpr bool operator>(const iterator& x, const iterator& y)
      requires random_access_range<Base>;
    friend constexpr bool operator<=(const iterator& x, const iterator& y)
      requires random_access_range<Base>;
    friend constexpr bool operator>=(const iterator& x, const iterator& y)
      requires random_access_range<Base>;
    friend constexpr auto operator<=>(const iterator& x, const iterator& y)
      requires random_access_range<Base> && three_way_comparable<iterator_t<Base>>;
 
    friend constexpr iterator operator+(iterator i, difference_type n)
      requires random_access_range<Base>;
    friend constexpr iterator operator+(difference_type n, iterator i)
      requires random_access_range<Base>;
 
    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 sized_sentinel_for<iterator_t<Base>, iterator_t<Base>>;
  };
}

Class template std::ranges::transform_view::sentinel

namespace std::ranges {
  template<input_range V, move_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>::sentinel {
  private:
    using Parent = __maybe_const<Const, transform_view>;    // exposition only
    using Base = __maybe_const<Const, V>;                   // exposition only
    sentinel_t<Base> end_ = sentinel_t<Base>();             // exposition only
  public:
    sentinel() = default;
    constexpr explicit sentinel(sentinel_t<Base> end);
    constexpr sentinel(sentinel<!Const> i)
      requires Const && convertible_to<sentinel_t<V>, sentinel_t<Base>>;
 
    constexpr sentinel_t<Base> base() const;
 
    template<bool OtherConst>
      requires sentinel_for<sentinel_t<Base>, iterator_t<__maybe_const<OtherConst, V>>>
    friend constexpr bool operator==(const iterator<OtherConst>& x, const sentinel& y);
 
    template<bool OtherConst>
      requires sized_sentinel_for<sentinel_t<Base>,
        iterator_t<__maybe_const<OtherConst, V>>>
    friend constexpr range_difference_t<__maybe_const<OtherConst, V>>
      operator-(const iterator<OtherConst>& x, const sentinel& y);
 
    template<bool OtherConst>
      requires sized_sentinel_for<sentinel_t<Base>,
        iterator_t<__maybe_const<OtherConst, V>>>
    friend constexpr range_difference_t<__maybe_const<OtherConst, V>>
      operator-(const sentinel& y, const iterator<OtherConst>& x);
  };
}

Class template std::ranges::take_view

namespace std::ranges {
  template<view V>
  class take_view : public view_interface<take_view<V>> {
  private:
    V base_ = V();                                      // exposition only
    range_difference_t<V> count_ = 0;                   // exposition only
 
    // class template take_view::sentinel
    template<bool> class sentinel;                      // exposition only
 
  public:
    take_view() requires default_initializable<V> = default;
    constexpr explicit take_view(V base, range_difference_t<V> count);
 
    constexpr V base() const & requires copy_constructible<V> { return base_; }
    constexpr V base() && { return std::move(base_); }
 
    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 = range_difference_t<V>(size());
          return counted_iterator(ranges::begin(base_), 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 = range_difference_t<const V>(size());
          return counted_iterator(ranges::begin(base_), sz);
        }
      } else {
        return counted_iterator(ranges::begin(base_), count_);
      }
    }
 
    constexpr auto end() requires (!__simple_view<V>) {
      if constexpr (sized_range<V>) {
        if constexpr (random_access_range<V>)
          return ranges::begin(base_) + range_difference_t<V>(size());
        else
          return default_sentinel;
      } else {
        return sentinel<false>{ranges::end(base_)};
      }
    }
 
    constexpr auto end() const requires range<const V> {
      if constexpr (sized_range<const V>) {
        if constexpr (random_access_range<const V>)
          return ranges::begin(base_) + range_difference_t<const V>(size());
        else
          return default_sentinel;
      } else {
        return sentinel<true>{ranges::end(base_)};
      }
    }
 
    constexpr auto size() requires sized_range<V> {
      auto n = ranges::size(base_);
      return ranges::min(n, static_cast<decltype(n)>(count_));
    }
 
    constexpr auto size() const requires sized_range<const V> {
      auto n = ranges::size(base_);
      return ranges::min(n, static_cast<decltype(n)>(count_));
    }
  };
 
  template<class R>
    take_view(R&&, range_difference_t<R>)
      -> take_view<views::all_t<R>>;
}

Class template std::ranges::take_view::sentinel

namespace std::ranges {
  template<view V>
  template<bool Const>
  class take_view<V>::sentinel {
  private:
    using Base = __maybe_const<Const, V>;                           // exposition only
    template<bool OtherConst>
      using CI = counted_iterator<
        iterator_t<__maybe_const<OtherConst, V>>>;                  // exposition only
    sentinel_t<Base> end_ = sentinel_t<Base>();                     // exposition only
  public:
    sentinel() = default;
    constexpr explicit sentinel(sentinel_t<Base> end);
    constexpr sentinel(sentinel<!Const> s)
      requires Const && convertible_to<sentinel_t<V>, sentinel_t<Base>>;
 
    constexpr sentinel_t<Base> base() const;
 
    friend constexpr bool operator==(const CI<Const>& y, const sentinel& x);
 
    template<bool OtherConst = !Const>
      requires sentinel_for<sentinel_t<Base>, iterator_t<__maybe_const<OtherConst, V>>>
    friend constexpr bool operator==(const CI<OtherConst>& y, const sentinel& x);
  };
}

Class template std::ranges::take_while_view

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 take_while_view : public view_interface<take_while_view<V, Pred>> {
    // class template take_while_view::sentinel
    template<bool> class sentinel;                      // exposition only
 
    V base_ = V();                                      // exposition only
    __movable_box<Pred> pred_;                          // exposition only
 
  public:
    take_while_view() requires default_initializable<V> &&
      default_initializable<Pred> = default;
    constexpr explicit take_while_view(V base, Pred pred);
 
    constexpr V base() const & requires copy_constructible<V> { return base_; }
    constexpr V base() && { return std::move(base_); }
 
    constexpr const Pred& pred() const;
 
    constexpr auto begin() requires (!__simple_view<V>)
    { return ranges::begin(base_); }
 
    constexpr auto begin() const
      requires range<const V> &&
               indirect_unary_predicate<const Pred, iterator_t<const V>>
    { return ranges::begin(base_); }
 
    constexpr auto end() requires (!__simple_view<V>)
    { return sentinel<false>(ranges::end(base_), addressof(*pred_)); }
 
    constexpr auto end() const
      requires range<const V> &&
               indirect_unary_predicate<const Pred, iterator_t<const V>>
    { return sentinel<true>(ranges::end(base_), addressof(*pred_)); }
  };
 
  template<class R, class Pred>
    take_while_view(R&&, Pred) -> take_while_view<views::all_t<R>, Pred>;
}

Class template std::ranges::take_while_view::sentinel

namespace std::ranges {
  template<view V, class Pred>
    requires input_range<V> && is_object_v<Pred> &&
             indirect_unary_predicate<const Pred, iterator_t<V>>
  template<bool Const>
  class take_while_view<V, Pred>::sentinel {
    using Base = __maybe_const<Const, V>;               // exposition only
 
    sentinel_t<Base> end_ = sentinel_t<Base>();         // exposition only
    const Pred* pred_ = nullptr;                        // exposition only
 
  public:
    sentinel() = default;
    constexpr explicit sentinel(sentinel_t<Base> end, const Pred* pred);
    constexpr sentinel(sentinel<!Const> s)
      requires Const && convertible_to<sentinel_t<V>, sentinel_t<Base>>;
 
    constexpr sentinel_t<Base> base() const { return end_; }
 
    friend constexpr bool operator==(const iterator_t<Base>& x, const sentinel& y);
 
    template<bool OtherConst = !Const>
      requires sentinel_for<sentinel_t<Base>, iterator_t<__maybe_const<OtherConst, V>>>
    friend constexpr bool operator==(const iterator_t<__maybe_const<OtherConst, V>>& x,
                                     const sentinel& y);
  };
}

Class template std::ranges::drop_view

namespace std::ranges {
  template<view V>
  class drop_view : public view_interface<drop_view<V>> {
  public:
    drop_view() requires default_initializable<V> = default;
    constexpr explicit drop_view(V base, range_difference_t<V> count);
 
    constexpr V base() const & requires copy_constructible<V> { return base_; }
    constexpr V base() && { return std::move(base_); }
 
    constexpr auto begin()
      requires (!(__simple_view<V> &&
                  random_access_range<const V> && sized_range<const V>));
    constexpr auto begin() const
      requires random_access_range<const V> && sized_range<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 size() requires sized_range<V> {
      const auto s = ranges::size(base_);
      const auto c = static_cast<decltype(s)>(count_);
      return s < c ? 0 : s - c;
    }
 
    constexpr auto size() const requires sized_range<const V> {
      const auto s = ranges::size(base_);
      const auto c = static_cast<decltype(s)>(count_);
      return s < c ? 0 : s - c;
    }
 
  private:
    V base_ = V();                              // exposition only
    range_difference_t<V> count_ = 0;           // exposition only
  };
 
  template<class R>
    drop_view(R&&, range_difference_t<R>) -> drop_view<views::all_t<R>>;
}

Class template std::ranges::drop_while_view

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:
    drop_while_view() requires default_initializable<V> &&
      default_initializable<Pred> = default;
    constexpr explicit drop_while_view(V base, Pred pred);
 
    constexpr V base() const & requires copy_constructible<V> { return base_; }
    constexpr V base() && { return std::move(base_); }
 
    constexpr const Pred& pred() const;
 
    constexpr auto begin();
 
    constexpr auto end() { return ranges::end(base_); }
 
  private:
    V base_ = V();                                      // exposition only
    __movable_box<Pred> pred_;                          // exposition only
  };
 
  template<class R, class Pred>
    drop_while_view(R&&, Pred) -> drop_while_view<views::all_t<R>, Pred>;
}

Class template std::ranges::join_view

namespace std::ranges {
  template<input_range V>
    requires view<V> && input_range<range_reference_t<V>>
  class join_view : public view_interface<join_view<V>> {
  private:
    using InnerRng = range_reference_t<V>;                  // exposition only
 
    // class template join_view::iterator
    template<bool Const>
      struct iterator;                                      // exposition only
 
    // class template join_view::sentinel
    template<bool Const>
      struct sentinel;                                      // exposition only
 
    V base_ = V();                                          // exposition only
 
    __non_propagating_cache<remove_cv_t<InnerRng>> inner_;
                                                    // exposition only, present only
                                                    // when !is_reference_v<InnerRng>
 
  public:
    join_view() requires default_initializable<V> = default;
    constexpr explicit join_view(V base);
 
    constexpr V base() const & requires copy_constructible<V> { return base_; }
    constexpr V base() && { return std::move(base_); }
 
    constexpr auto begin() {
      constexpr bool use_const = __simple_view<V> &&
                                 is_reference_v<InnerRng>;
      return iterator<use_const>{*this, ranges::begin(base_)};
    }
 
    constexpr auto begin() const
      requires input_range<const V> &&
               is_reference_v<range_reference_t<const V>>
    { return iterator<true>{*this, ranges::begin(base_)}; }
 
    constexpr auto end() {
      if constexpr (forward_range<V> &&
                    is_reference_v<InnerRng> && forward_range<InnerRng> &&
                    common_range<V> && common_range<InnerRng>)
        return iterator<__simple_view<V>>{*this, ranges::end(base_)};
      else
        return sentinel<__simple_view<V>>{*this};
    }
 
    constexpr auto end() const
      requires input_range<const V> &&
               is_reference_v<range_reference_t<const V>> {
      if constexpr (forward_range<const V> &&
                    forward_range<range_reference_t<const V>> &&
                    common_range<const V> &&
                    common_range<range_reference_t<const V>>)
        return iterator<true>{*this, ranges::end(base_)};
      else
        return sentinel<true>{*this};
    }
  };
 
  template<class R>
    explicit join_view(R&&) -> join_view<views::all_t<R>>;
}

Class template std::ranges::join_view::iterator

namespace std::ranges {
  template<input_range V>
    requires view<V> && input_range<range_reference_t<V>>
  template<bool Const>
  struct join_view<V>::iterator {
  private:
    using Parent    = __maybe_const<Const, join_view>;          // exposition only
    using Base      = __maybe_const<Const, V>;                  // exposition only
    using OuterIter = iterator_t<Base>;                         // exposition only
    using InnerIter = iterator_t<range_reference_t<Base>>;      // exposition only
 
    static constexpr bool __ref_is_glvalue =                    // exposition only
      is_reference_v<range_reference_t<Base>>;
 
    OuterIter outer_ = OuterIter();                             // exposition only
    InnerIter inner_ = InnerIter();                             // exposition only
    Parent* parent_  = nullptr;                                 // exposition only
 
    constexpr void satisfy();                                   // exposition only
 
  public:
    using iterator_concept  = /* see description */;
    using iterator_category = /* see description */;            // not always present
    using value_type        = range_value_t<range_reference_t<Base>>;
    using difference_type   = /* see description */;
 
    iterator() requires default_initializable<OuterIter> &&
                         default_initializable<InnerIter> = default;
    constexpr iterator(Parent& parent, OuterIter outer);
    constexpr iterator(iterator<!Const> i)
      requires Const &&
               convertible_to<iterator_t<V>, OuterIter> &&
               convertible_to<iterator_t<InnerRng>, InnerIter>;
 
    constexpr decltype(auto) operator*() const { return *inner_; }
 
    constexpr InnerIter operator->() const
      requires __has_arrow<InnerIter> && copyable<InnerIter>;
 
    constexpr iterator& operator++();
    constexpr void operator++(int);
    constexpr iterator operator++(int)
      requires __ref_is_glvalue && forward_range<Base> &&
               forward_range<range_reference_t<Base>>;
 
    constexpr iterator& operator--()
      requires __ref_is_glvalue && bidirectional_range<Base> &&
               bidirectional_range<range_reference_t<Base>> &&
               common_range<range_reference_t<Base>>;
 
    constexpr iterator operator--(int)
      requires __ref_is_glvalue && bidirectional_range<Base> &&
               bidirectional_range<range_reference_t<Base>> &&
               common_range<range_reference_t<Base>>;
 
    friend constexpr bool operator==(const iterator& x, const iterator& y)
      requires __ref_is_glvalue && equality_comparable<iterator_t<Base>> &&
               equality_comparable<iterator_t<range_reference_t<Base>>>;
 
    friend constexpr decltype(auto) iter_move(const iterator& i)
    noexcept(noexcept(ranges::iter_move(i.inner_))) {
      return ranges::iter_move(i.inner_);
    }
 
    friend constexpr void iter_swap(const iterator& x, const iterator& y)
      noexcept(noexcept(ranges::iter_swap(x.inner_, y.inner_)))
      requires indirectly_swappable<InnerIter>;
  };
}

Class template std::ranges::join_view::sentinel

namespace std::ranges {
  template<input_range V>
    requires view<V> && input_range<range_reference_t<V>>
  template<bool Const>
  struct join_view<V>::sentinel {
  private:
    using Parent = __maybe_const<Const, join_view>;     // exposition only
    using Base = __maybe_const<Const, V>;               // exposition only
    sentinel_t<Base> end_ = sentinel_t<Base>();         // exposition only
 
  public:
    sentinel() = default;
 
    constexpr explicit sentinel(Parent& parent);
    constexpr sentinel(sentinel<!Const> s)
      requires Const && convertible_to<sentinel_t<V>, sentinel_t<Base>>;
 
    template<bool OtherConst>
      requires sentinel_for<sentinel_t<Base>, iterator_t<__maybe_const<OtherConst, V>>>
    friend constexpr bool operator==(const iterator<OtherConst>& x, const sentinel& y);
  };
}

Class template std::ranges::join_with_view

namespace std::ranges {
  template<class R, class P>
  concept __compatible_joinable_ranges =            // exposition only
      common_with<range_value_t<R>, range_value_t<P>> &&
      common_reference_with<range_reference_t<R>, range_reference_t<P>> &&
      common_reference_with<range_rvalue_reference_t<R>, range_rvalue_reference_t<P>>;
 
  template<class R>
  concept __bidirectional_common = bidirectional_range<R> &&
    common_range<R>;                                        // exposition only
 
  template<input_range V, forward_range Pattern>
    requires view<V> && input_range<range_reference_t<V>>
          && view<Pattern>
          && __compatible_joinable_ranges<range_reference_t<V>, Pattern>
  class join_with_view : public view_interface<join_with_view<V, Pattern>> {
    using InnerRng = range_reference_t<V>;                  // exposition only
 
    V base_ = V();                                          // exposition only
    __non_propagating_cache<remove_cv_t<InnerRng>> inner_;
        // exposition only, present only
        // when !is_reference_v<InnerRng>
 
    Pattern pattern_ = Pattern();                           // exposition only
 
    // class template join_with_view::iterator
    template<bool Const> struct iterator;                   // exposition only
 
    // class template join_with_view::sentinel
    template<bool Const> struct sentinel;                   // exposition only
 
  public:
    join_with_view()
      requires default_initializable<V> && default_initializable<Pattern> = default;
 
    constexpr explicit join_with_view(V base, Pattern pattern);
 
    template<input_range R>
      requires constructible_from<V, views::all_t<R>> &&
               constructible_from<Pattern, single_view<range_value_t<InnerRng>>>
    constexpr explicit join_with_view(R&& r, range_value_t<InnerRng> e);
 
    constexpr V base() const & requires copy_constructible<V> { return base_; }
    constexpr V base() && { return std::move(base_); }
 
    constexpr auto begin() {
      constexpr bool use_const =
        __simple_view<V> && is_reference_v<InnerRng> && __simple_view<Pattern>;
      return iterator<use_const>{*this, ranges::begin(base_)};
    }
    constexpr auto begin() const
      requires input_range<const V> &&
               forward_range<const Pattern> &&
               is_reference_v<range_reference_t<const V>> {
      return iterator<true>{*this, ranges::begin(base_)};
    }
 
    constexpr auto end() {
      if constexpr (forward_range<V> &&
                    is_reference_v<InnerRng> && forward_range<InnerRng> &&
                    common_range<V> && common_range<InnerRng>)
        return iterator<__simple_view<V> &&
          __simple_view<Pattern>>{*this, ranges::end(base_)};
      else
        return sentinel<__simple_view<V> && __simple_view<Pattern>>{*this};
    }
    constexpr auto end() const
      requires input_range<const V> && forward_range<const Pattern> &&
               is_reference_v<range_reference_t<const V>> {
      using InnerConstRng = range_reference_t<const V>;
      if constexpr (forward_range<const V> && forward_range<InnerConstRng> &&
                    common_range<const V> && common_range<InnerConstRng>)
        return iterator<true>{*this, ranges::end(base_)};
      else
        return sentinel<true>{*this};
    }
  };
 
  template<class R, class P>
    join_with_view(R&&, P&&) -> join_with_view<views::all_t<R>, views::all_t<P>>;
 
  template<input_range R>
    join_with_view(R&&, range_value_t<range_reference_t<R>>)
      -> join_with_view<views::all_t<R>,
            single_view<range_value_t<range_reference_t<R>>>>;
}

Class template std::ranges::join_with_view::iterator

namespace std::ranges {
  template<input_range V, forward_range Pattern>
    requires view<V> && input_range<range_reference_t<V>>
          && view<Pattern> && __compatible_joinable_ranges<range_reference_t<V>, Pattern>
  template<bool Const>
  class join_with_view<V, Pattern>::iterator {
    using Parent = __maybe_const<Const, join_with_view>;                // exposition only
    using Base = __maybe_const<Const, V>;                               // exposition only
    using InnerBase = range_reference_t<Base>;                          // exposition only
    using PatternBase = __maybe_const<Const, Pattern>;                  // exposition only
 
    using OuterIter = iterator_t<Base>;                                 // exposition only
    using InnerIter = iterator_t<InnerBase>;                            // exposition only
    using PatternIter = iterator_t<PatternBase>;                        // exposition only
 
    static constexpr bool __ref_is_glvalue = is_reference_v<InnerBase>; // exposition only
 
    Parent* parent_ = nullptr;                                          // exposition only
    OuterIter outer_it_ = OuterIter();                                  // exposition only
    variant<PatternIter, InnerIter> inner_it_;                          // exposition only
 
    constexpr iterator(Parent& parent, iterator_t<Base> outer);         // exposition only
    constexpr auto&& __update_inner(const OuterIter&);                  // exposition only
    constexpr auto&& __get_inner(const OuterIter&);                     // exposition only
    constexpr void satisfy();                                           // exposition only
 
  public:
    using iterator_concept = /* see description */;
    using iterator_category = /* see description */;            // not always present
    using value_type = /* see description */;
    using difference_type = /* see description */;
 
    iterator() requires default_initializable<OuterIter> = default;
    constexpr iterator(iterator<!Const> i)
      requires Const && convertible_to<iterator_t<V>, OuterIter> &&
               convertible_to<iterator_t<InnerRng>, InnerIter> &&
               convertible_to<iterator_t<Pattern>, PatternIter>;
 
    constexpr decltype(auto) operator*() const;
 
    constexpr iterator& operator++();
    constexpr void operator++(int);
    constexpr iterator operator++(int)
      requires __ref_is_glvalue && forward_iterator<OuterIter> &&
               forward_iterator<InnerIter>;
 
    constexpr iterator& operator--()
      requires __ref_is_glvalue && bidirectional_range<Base> &&
               __bidirectional_common<InnerBase> && __bidirectional_common<PatternBase>;
    constexpr iterator operator--(int)
      requires __ref_is_glvalue && bidirectional_range<Base> &&
               __bidirectional_common<InnerBase> && __bidirectional_common<PatternBase>;
 
    friend constexpr bool operator==(const iterator& x, const iterator& y)
      requires __ref_is_glvalue && equality_comparable<OuterIter> &&
               equality_comparable<InnerIter>;
 
    friend constexpr decltype(auto) iter_move(const iterator& x) {
      using rvalue_reference = common_reference_t<
        iter_rvalue_reference_t<InnerIter>,
        iter_rvalue_reference_t<PatternIter>>;
      return visit<rvalue_reference>(ranges::iter_move, x.inner_it_);
    }
 
    friend constexpr void iter_swap(const iterator& x, const iterator& y)
      requires indirectly_swappable<InnerIter, PatternIter> {
      visit(ranges::iter_swap, x.inner_it_, y.inner_it_);
    }
  };
}

Class template std::ranges::join_with_view::sentinel

namespace std::ranges {
  template<input_range V, forward_range Pattern>
    requires view<V> && input_range<range_reference_t<V>>
          && view<Pattern> && __compatible_joinable_ranges<range_reference_t<V>, Pattern>
  template<bool Const>
  class join_with_view<V, Pattern>::sentinel {
    using Parent = __maybe_const<Const, join_with_view>;    // exposition only
    using Base = __maybe_const<Const, V>;                   // exposition only
    sentinel_t<Base> end_ = sentinel_t<Base>();             // exposition only
 
    constexpr explicit sentinel(Parent& parent);            // exposition only
 
  public:
    sentinel() = default;
    constexpr sentinel(sentinel<!Const> s)
      requires Const && convertible_to<sentinel_t<V>, sentinel_t<Base>>;
 
    template<bool OtherConst>
      requires sentinel_for<sentinel_t<Base>, iterator_t<__maybe_const<OtherConst, V>>>
    friend constexpr bool operator==(const iterator<OtherConst>& x, const sentinel& y);
  };
}

Class template std::ranges::lazy_split_view

namespace std::ranges {
  template<auto> struct __require_constant;                       // exposition only
 
  template<class R>
  concept __tiny_range =                                          // exposition only
    sized_range<R> &&
    requires { typename __require_constant<remove_reference_t<R>::size()>; } &&
    (remove_reference_t<R>::size() <= 1);
 
  template<input_range V, forward_range Pattern>
    requires view<V> && view<Pattern> &&
             indirectly_comparable<iterator_t<V>, iterator_t<Pattern>, ranges::equal_to>
             &&
             (forward_range<V> || __tiny_range<Pattern>)
  class lazy_split_view : public view_interface<lazy_split_view<V, Pattern>> {
  private:
    V base_ = V();                                              // exposition only
    Pattern pattern_ = Pattern();                               // exposition only
 
    __non_propagating_cache<iterator_t<V>> current_;    // exposition only, present only
                                                        // if !forward_range<V>
 
    // class template lazy_split_view::outer-iterator
    template<bool> struct __outer_iterator;                     // exposition only
 
    // class template lazy_split_view::inner-iterator
    template<bool> struct __inner_iterator;                     // exposition only
 
  public:
    lazy_split_view()
      requires default_initializable<V> && default_initializable<Pattern> = default;
    constexpr explicit lazy_split_view(V base, Pattern pattern);
 
    template<input_range R>
      requires constructible_from<V, views::all_t<R>> &&
               constructible_from<Pattern, single_view<range_value_t<R>>>
    constexpr explicit lazy_split_view(R&& r, range_value_t<R> e);
 
    constexpr V base() const & requires copy_constructible<V> { return base_; }
    constexpr V base() && { return std::move(base_); }
 
    constexpr auto begin() {
      if constexpr (forward_range<V>) {
        return __outer_iterator<__simple_view<V> && __simple_view<Pattern>>
          {*this, ranges::begin(base_)};
      } else {
        current_ = ranges::begin(base_);
        return __outer_iterator<false>{*this};
      }
    }
 
    constexpr auto begin() const requires forward_range<V> && forward_range<const V> {
      return __outer_iterator<true>{*this, ranges::begin(base_)};
    }
 
    constexpr auto end() requires forward_range<V> && common_range<V> {
      return __outer_iterator<__simple_view<V> && __simple_view<Pattern>>
        {*this, ranges::end(base_)};
    }
 
    constexpr auto end() const {
      if constexpr (forward_range<V> && forward_range<const V> && common_range<const V>)
        return __outer_iterator<true>{*this, ranges::end(base_)};
      else
        return default_sentinel;
    }
  };
 
  template<class R, class P>
    lazy_split_view(R&&, P&&) -> lazy_split_view<views::all_t<R>, views::all_t<P>>;
 
  template<input_range R>
    lazy_split_view(R&&, range_value_t<R>)
      -> lazy_split_view<views::all_t<R>, single_view<range_value_t<R>>>;
}

Class template std::ranges::lazy_split_view::outer_iterator

namespace std::ranges {
  template<input_range V, forward_range Pattern>
    requires view<V> && view<Pattern> &&
             indirectly_comparable<iterator_t<V>, iterator_t<Pattern>, ranges::equal_to>
             &&
             (forward_range<V> || __tiny_range<Pattern>)
  template<bool Const>
  struct lazy_split_view<V, Pattern>::__outer_iterator {
  private:
    using Parent = __maybe_const<Const, lazy_split_view>;   // exposition only
    using Base = __maybe_const<Const, V>;                   // exposition only
    Parent* parent_ = nullptr;                              // exposition only
 
    iterator_t<Base> current_ = iterator_t<Base>();     // exposition only, present only
                                                        // if V models forward_range
 
    bool trailing_empty_ = false;                           // exposition only
 
  public:
    using iterator_concept  =
      conditional_t<forward_range<Base>, forward_iterator_tag, input_iterator_tag>;
 
    using iterator_category = input_iterator_tag;           // present only if Base
                                                            // models forward_range
 
    // class lazy_split_view::outer-iterator::value_type
    struct value_type;
    using difference_type   = range_difference_t<Base>;
 
    __outer_iterator() = default;
    constexpr explicit __outer_iterator(Parent& parent)
      requires (!forward_range<Base>);
    constexpr __outer_iterator(Parent& parent, iterator_t<Base> current)
      requires forward_range<Base>;
    constexpr __outer_iterator(__outer_iterator<!Const> i)
      requires Const && convertible_to<iterator_t<V>, iterator_t<Base>>;
 
    constexpr value_type operator*() const;
 
    constexpr __outer_iterator& operator++();
    constexpr decltype(auto) operator++(int) {
      if constexpr (forward_range<Base>) {
        auto tmp = *this;
        ++*this;
        return tmp;
      } else
        ++*this;
    }
 
    friend constexpr bool operator==(const __outer_iterator& x, const __outer_iterator& y)
      requires forward_range<Base>;
 
    friend constexpr bool operator==(const __outer_iterator& x, default_sentinel_t);
  };
}

Class template std::ranges::lazy_split_view::outer_iterator::value_type

namespace std::ranges {
  template<input_range V, forward_range Pattern>
    requires view<V> && view<Pattern> &&
             indirectly_comparable<iterator_t<V>, iterator_t<Pattern>, ranges::equal_to>
             &&
             (forward_range<V> || __tiny_range<Pattern>)
  template<bool Const>
  struct lazy_split_view<V, Pattern>::__outer_iterator<Const>::value_type
    : view_interface<value_type> {
  private:
    __outer_iterator i_ = __outer_iterator();               // exposition only
  public:
    value_type() = default;
    constexpr explicit value_type(__outer_iterator i);
 
    constexpr __inner_iterator<Const> begin() const;
    constexpr default_sentinel_t end() const noexcept;
  };
}

Class template std::ranges::lazy_split_view::inner_iterator

namespace std::ranges {
  template<input_range V, forward_range Pattern>
    requires view<V> && view<Pattern> &&
             indirectly_comparable<iterator_t<V>, iterator_t<Pattern>, ranges::equal_to>
             &&
             (forward_range<V> || __tiny_range<Pattern>)
  template<bool Const>
  struct lazy_split_view<V, Pattern>::__inner_iterator {
  private:
    using Base = __maybe_const<Const, V>;                   // exposition only
    __outer_iterator<Const> i_ = __outer_iterator<Const>(); // exposition only
    bool incremented_ = false;                              // exposition only
 
  public:
    using iterator_concept  = typename __outer_iterator<Const>::iterator_concept;
 
    using iterator_category = /* see description */;        // present only if Base
                                                            // models forward_range
    using value_type        = range_value_t<Base>;
    using difference_type   = range_difference_t<Base>;
 
    __inner_iterator() = default;
    constexpr explicit __inner_iterator(__outer_iterator<Const> i);
 
    constexpr const iterator_t<Base>& base() const & noexcept;
    constexpr iterator_t<Base> base() && requires forward_range<V>;
 
    constexpr decltype(auto) operator*() const { return *i_.current; }
 
    constexpr __inner_iterator& operator++();
    constexpr decltype(auto) operator++(int) {
      if constexpr (forward_range<Base>) {
        auto tmp = *this;
        ++*this;
        return tmp;
      } else
        ++*this;
    }
 
    friend constexpr bool operator==(const __inner_iterator& x, const __inner_iterator& y)
      requires forward_range<Base>;
 
    friend constexpr bool operator==(const __inner_iterator& x, default_sentinel_t);
 
    friend constexpr decltype(auto) iter_move(const __inner_iterator& i)
    noexcept(noexcept(ranges::iter_move(i.i_.current))) {
      return ranges::iter_move(i.i_.current);
    }
 
    friend constexpr void iter_swap(const __inner_iterator& x, const __inner_iterator& y)
      noexcept(noexcept(ranges::iter_swap(x.i_.current, y.i_.current)))
      requires indirectly_swappable<iterator_t<Base>>;
  };
}

Class template std::ranges::split_view

namespace std::ranges {
  template<forward_range V, forward_range Pattern>
    requires view<V> && view<Pattern> &&
             indirectly_comparable<iterator_t<V>, iterator_t<Pattern>, ranges::equal_to>
  class split_view : public view_interface<split_view<V, Pattern>> {
  private:
    V base_ = V();                              // exposition only
    Pattern pattern_ = Pattern();               // exposition only
 
    // class split_view::iterator
    struct iterator;                            // exposition only
 
    // class split_view::sentinel
    struct sentinel;                            // exposition only
 
  public:
    split_view()
      requires default_initializable<V> && default_initializable<Pattern> = default;
    constexpr explicit split_view(V base, Pattern pattern);
 
    template<forward_range R>
      requires constructible_from<V, views::all_t<R>> &&
               constructible_from<Pattern, single_view<range_value_t<R>>>
    constexpr explicit split_view(R&& r, range_value_t<R> e);
 
    constexpr V base() const & requires copy_constructible<V> { return base_; }
    constexpr V base() && { return std::move(base_); }
 
    constexpr iterator begin();
 
    constexpr auto end() {
      if constexpr (common_range<V>) {
        return iterator{*this, ranges::end(base_), {}};
      } else {
        return sentinel{*this};
      }
    }
 
    constexpr subrange<iterator_t<V>> __find_next(iterator_t<V>); // exposition only
  };
 
  template<class R, class P>
    split_view(R&&, P&&) -> split_view<views::all_t<R>, views::all_t<P>>;
 
  template<forward_range R>
    split_view(R&&, range_value_t<R>)
      -> split_view<views::all_t<R>, single_view<range_value_t<R>>>;
}

Class template std::ranges::split_view::iterator

namespace std::ranges {
  template<forward_range V, forward_range Pattern>
    requires view<V> && view<Pattern> &&
             indirectly_comparable<iterator_t<V>, iterator_t<Pattern>, ranges::equal_to>
  class split_view<V, Pattern>::iterator {
  private:
    split_view* parent_ = nullptr;                              // exposition only
    iterator_t<V> cur_ = iterator_t<V>();                       // exposition only
    subrange<iterator_t<V>> next_ = subrange<iterator_t<V>>();  // exposition only
    bool trailing_empty_ = false;                               // exposition only
 
  public:
    using iterator_concept = forward_iterator_tag;
    using iterator_category = input_iterator_tag;
    using value_type = subrange<iterator_t<V>>;
    using difference_type = range_difference_t<V>;
 
    iterator() = default;
    constexpr iterator(split_view& parent, iterator_t<V> current,
                       subrange<iterator_t<V>> next);
 
    constexpr iterator_t<V> base() const;
    constexpr value_type operator*() const;
 
    constexpr iterator& operator++();
    constexpr iterator operator++(int);
 
    friend constexpr bool operator==(const iterator& x, const iterator& y);
  };
}

Class template std::ranges::split_view::sentinel

namespace std::ranges {
  template<forward_range V, forward_range Pattern>
    requires view<V> && view<Pattern> &&
             indirectly_comparable<iterator_t<V>, iterator_t<Pattern>, ranges::equal_to>
  struct split_view<V, Pattern>::sentinel {
  private:
    sentinel_t<V> end_ = sentinel_t<V>();               // exposition only
 
  public:
    sentinel() = default;
    constexpr explicit sentinel(split_view& parent);
 
    friend constexpr bool operator==(const iterator& x, const sentinel& y);
  };
}

Class template std::ranges::common_view

namespace std::ranges {
  template<view V>
    requires (!common_range<V> && copyable<iterator_t<V>>)
  class common_view : public view_interface<common_view<V>> {
  private:
    V base_ = V();  // exposition only
  public:
    common_view() requires default_initializable<V> = default;
 
    constexpr explicit common_view(V r);
 
    constexpr V base() const & requires copy_constructible<V> { return base_; }
    constexpr V base() && { return std::move(base_); }
 
    constexpr auto begin() {
      if constexpr (random_access_range<V> && sized_range<V>)
        return ranges::begin(base_);
      else
        return common_iterator<iterator_t<V>, sentinel_t<V>>(ranges::begin(base_));
    }
 
    constexpr auto begin() const requires range<const V> {
      if constexpr (random_access_range<const V> && sized_range<const V>)
        return ranges::begin(base_);
      else
        return common_iterator<iterator_t<const V>, sentinel_t<const V>>(
          ranges::begin(base_));
    }
 
    constexpr auto end() {
      if constexpr (random_access_range<V> && sized_range<V>)
        return ranges::begin(base_) + ranges::size(base_);
      else
        return common_iterator<iterator_t<V>, sentinel_t<V>>(ranges::end(base_));
    }
 
    constexpr auto end() const requires range<const V> {
      if constexpr (random_access_range<const V> && sized_range<const V>)
        return ranges::begin(base_) + ranges::size(base_);
      else
        return common_iterator<iterator_t<const V>, sentinel_t<const V>>(
          ranges::end(base_));
    }
 
    constexpr auto size() requires sized_range<V> {
      return ranges::size(base_);
    }
    constexpr auto size() const requires sized_range<const V> {
      return ranges::size(base_);
    }
  };
 
  template<class R>
    common_view(R&&) -> common_view<views::all_t<R>>;
}

Class template std::ranges::reverse_view

namespace std::ranges {
  template<view V>
    requires bidirectional_range<V>
  class reverse_view : public view_interface<reverse_view<V>> {
  private:
    V base_ = V();  // exposition only
  public:
    reverse_view() requires default_initializable<V> = default;
 
    constexpr explicit reverse_view(V r);
 
    constexpr V base() const & requires copy_constructible<V> { return base_; }
    constexpr V base() && { return std::move(base_); }
 
    constexpr reverse_iterator<iterator_t<V>> begin();
    constexpr reverse_iterator<iterator_t<V>> begin() requires common_range<V>;
    constexpr auto begin() const requires common_range<const V>;
 
    constexpr reverse_iterator<iterator_t<V>> end();
    constexpr auto end() const requires common_range<const V>;
 
    constexpr auto size() requires sized_range<V> {
      return ranges::size(base_);
    }
 
    constexpr auto size() const requires sized_range<const V> {
      return ranges::size(base_);
    }
  };
 
  template<class R>
    reverse_view(R&&) -> reverse_view<views::all_t<R>>;
}

Class template std::ranges::as_const_view

namespace std::ranges {
  template<view V>
    requires input_range<V>
  class as_const_view : public view_interface<as_const_view<V>> {
    V base_ = V();      // exposition only
 
  public:
    as_const_view() requires default_initializable<V> = default;
    constexpr explicit as_const_view(V base);
 
    constexpr V base() const & requires copy_constructible<V> { return base_; }
    constexpr V base() && { return std::move(base_); }
 
    constexpr auto begin() requires (!__simple_view<V>) { return ranges::cbegin(base_); }
    constexpr auto begin() const requires range<const V> { return ranges::cbegin(base_); }
 
    constexpr auto end() requires (!__simple_view<V>) { return ranges::cend(base_); }
    constexpr auto end() const requires range<const V> { return ranges::cend(base_); }
 
    constexpr auto size() requires sized_range<V> { return ranges::size(base_); }
    constexpr auto size() const requires sized_range<const V> {
      return ranges::size(base_);
    }
  };
 
  template<class R>
    as_const_view(R&&) -> as_const_view<views::all_t<R>>;
}

Class template std::ranges::elements_view

namespace std::ranges {
  template<class T, size_t N>
  concept __has_tuple_element =                   // exposition only
    __tuple_like<T> && N < tuple_size_v<T>;
 
  template<class T, size_t N>
  concept __returnable_element =                  // exposition only
    is_reference_v<T> || move_constructible<tuple_element_t<N, T>>;
 
  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> &&
             __returnable_element<range_reference_t<V>, N>
  class elements_view : public view_interface<elements_view<V, N>> {
  public:
    elements_view() requires default_initializable<V> = default;
    constexpr explicit elements_view(V base);
 
    constexpr V base() const & requires copy_constructible<V> { return base_; }
    constexpr V base() && { return std::move(base_); }
 
    constexpr auto begin() requires (!__simple_view<V>)
    { return iterator<false>(ranges::begin(base_)); }
 
    constexpr auto begin() const requires range<const V>
    { return iterator<true>(ranges::begin(base_)); }
 
    constexpr auto end() requires (!__simple_view<V> && !common_range<V>)
    { return sentinel<false>{ranges::end(base_)}; }
 
    constexpr auto end() requires (!__simple_view<V> && common_range<V>)
    { return iterator<false>{ranges::end(base_)}; }
 
    constexpr auto end() const requires range<const V>
    { return sentinel<true>{ranges::end(base_)}; }
 
    constexpr auto end() const requires common_range<const V>
    { return iterator<true>{ranges::end(base_)}; }
 
    constexpr auto size() requires sized_range<V>
    { return ranges::size(base_); }
 
    constexpr auto size() const requires sized_range<const V>
    { return ranges::size(base_); }
 
  private:
    // class template elements_view::iterator
    template<bool> class iterator;                      // exposition only
 
    // class template elements_view::sentinel
    template<bool> class sentinel;                      // exposition only
 
    V base_ = V();                                      // exposition only
  };
}

Class template std::ranges::elements_view::iterator

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> &&
             __returnable_element<range_reference_t<V>, N>
  template<bool Const>
  class elements_view<V, N>::iterator {
    using Base = __maybe_const<Const, V>;               // exposition only
 
    iterator_t<Base> current_ = iterator_t<Base>();     // exposition only
 
    static constexpr decltype(auto)
      __get_element(const iterator_t<Base>& i);         // exposition only
 
  public:
    using iterator_concept = /* see description */;
    using iterator_category = /* see description */;                // not always present
    using value_type = remove_cvref_t<tuple_element_t<N, range_value_t<Base>>>;
    using difference_type = range_difference_t<Base>;
 
    iterator() requires default_initializable<iterator_t<Base>> = default;
    constexpr explicit iterator(iterator_t<Base> current);
    constexpr iterator(iterator<!Const> i)
      requires Const && convertible_to<iterator_t<V>, iterator_t<Base>>;
 
    constexpr const iterator_t<Base>& base() const & noexcept;
    constexpr iterator_t<Base> base() &&;
 
    constexpr decltype(auto) operator*() const
    { return __get_element(current_); }
 
    constexpr iterator& operator++();
    constexpr void operator++(int);
    constexpr iterator operator++(int) requires forward_range<Base>;
 
    constexpr iterator& operator--() requires bidirectional_range<Base>;
    constexpr iterator operator--(int) requires bidirectional_range<Base>;
 
    constexpr iterator& operator+=(difference_type x)
      requires random_access_range<Base>;
    constexpr iterator& operator-=(difference_type x)
      requires random_access_range<Base>;
 
    constexpr decltype(auto) operator[](difference_type n) const
      requires random_access_range<Base>
    { return __get_element(current_ + n); }
 
    friend constexpr bool operator==(const iterator& x, const iterator& y)
      requires equality_comparable<iterator_t<Base>>;
 
    friend constexpr bool operator<(const iterator& x, const iterator& y)
      requires random_access_range<Base>;
    friend constexpr bool operator>(const iterator& x, const iterator& y)
      requires random_access_range<Base>;
    friend constexpr bool operator<=(const iterator& x, const iterator& y)
      requires random_access_range<Base>;
    friend constexpr bool operator>=(const iterator& x, const iterator& y)
      requires random_access_range<Base>;
    friend constexpr auto operator<=>(const iterator& x, const iterator& y)
      requires random_access_range<Base> && three_way_comparable<iterator_t<Base>>;
 
    friend constexpr iterator operator+(const iterator& x, difference_type y)
      requires random_access_range<Base>;
    friend constexpr iterator operator+(difference_type x, const iterator& y)
      requires random_access_range<Base>;
    friend constexpr iterator operator-(const iterator& x, difference_type y)
      requires random_access_range<Base>;
    friend constexpr difference_type operator-(const iterator& x, const iterator& y)
      requires sized_sentinel_for<iterator_t<Base>, iterator_t<Base>>;
  };
}

Class template std::ranges::elements_view::sentinel

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> &&
             __returnable_element<range_reference_t<V>, N>
  template<bool Const>
  class elements_view<V, N>::sentinel {
  private:
    using Base = __maybe_const<Const, V>;               // exposition only
    sentinel_t<Base> end_ = sentinel_t<Base>();         // exposition only
  public:
    sentinel() = default;
    constexpr explicit sentinel(sentinel_t<Base> end);
    constexpr sentinel(sentinel<!Const> other)
      requires Const && convertible_to<sentinel_t<V>, sentinel_t<Base>>;
 
    constexpr sentinel_t<Base> base() const;
 
    template<bool OtherConst>
      requires sentinel_for<sentinel_t<Base>, iterator_t<__maybe_const<OtherConst, V>>>
    friend constexpr bool operator==(const iterator<OtherConst>& x, const sentinel& y);
 
    template<bool OtherConst>
      requires sized_sentinel_for<sentinel_t<Base>,
        iterator_t<__maybe_const<OtherConst, V>>>
    friend constexpr range_difference_t<__maybe_const<OtherConst, V>>
      operator-(const iterator<OtherConst>& x, const sentinel& y);
 
    template<bool OtherConst>
      requires sized_sentinel_for<sentinel_t<Base>,
        iterator_t<__maybe_const<OtherConst, V>>>
    friend constexpr range_difference_t<__maybe_const<OtherConst, V>>
      operator-(const sentinel& x, const iterator<OtherConst>& y);
  };
}

Class template std::ranges::enumerate_view

template<view V>
requires __range_with_movable_references<V>
class enumerate_view : public view_interface<enumerate_view<V>>
{
  V base_ = V(); // exposition only
  template<bool Const>
  class iterator; // exposition only
  template<bool Const>
  class sentinel; // exposition only
public:
  constexpr enumerate_view() requires default_initializable<V> = default;
  constexpr explicit enumerate_view(V base);
  constexpr auto begin() requires(!__simple_view<V>) {
    return iterator<false>(ranges::begin(base_), 0);
  }
  constexpr auto begin() const requires __range_with_movable_references<const V> {
    return iterator<true>(ranges::begin(base_), 0);
  }
  constexpr auto end() requires(!__simple_view<V>) {
    if constexpr (common_range<V> && sized_range<V>)
      return iterator<false>(ranges::end(base_), ranges::distance(base_));
    else
      return sentinel<false>(ranges::end(base_));
  }
  constexpr auto end() const requires __range_with_movable_references<const V> {
    if constexpr (common_range<const V> && sized_range<const V>)
      return iterator<true>(ranges::end(base_), ranges::distance(base_));
    else
      return sentinel<true>(ranges::end(base_));
  }
  constexpr auto size() requires sized_range<V> { return ranges::size(base_); }
  constexpr auto size() const requires sized_range<const V> {
    return ranges::size(base_);
  }
  constexpr V base() const& requires copy_constructible<V> { return base_; }
  constexpr V base() && { return std::move(base_); }
};
template<class R>
  enumerate_view(R&&) -> enumerate_view<views::all_t<R>>;
}

Class template std::ranges::enumerate_view::iterator

namespace std::ranges {
  template<view V>
  requires __range_with_movable_references<V>
  template<bool Const>
  class enumerate_view<V>::iterator
  {
    using Base = __maybe_const<Const, V>; // exposition only
  public:
    using iterator_category = input_iterator_tag;
    using iterator_concept  = /* see description */;
    using difference_type   = range_difference_t<Base>;
    using value_type        = tuple<difference_type, range_value_t<Base>>;
 
  private:
    using __reference_type = // exposition only
      tuple<difference_type, range_reference_t<Base>>;
    iterator_t<Base> current_ = iterator_t<Base>(); // exposition only
    difference_type pos_      = 0;                  // exposition only
    constexpr explicit iterator(iterator_t<Base> current,
                                difference_type pos); // exposition only
  public:
    iterator() requires default_initializable<iterator_t<Base>>
    = default;
    constexpr iterator(iterator<!Const> i) requires Const
      && convertible_to<iterator_t<V>, iterator_t<Base>>;
    constexpr const iterator_t<Base>& base() const& noexcept;
    constexpr iterator_t<Base> base() &&;
    constexpr difference_type index() const noexcept;
    constexpr auto operator*() const { return __reference_type(pos_, *current_); }
    constexpr iterator& operator++();
    constexpr void operator++(int);
    constexpr iterator operator++(int) requires forward_range<Base>;
    constexpr iterator& operator--() requires bidirectional_range<Base>;
    constexpr iterator operator--(int) requires bidirectional_range<Base>;
    constexpr iterator& operator+=(difference_type x) requires random_access_range<Base>;
    constexpr iterator& operator-=(difference_type x) requires random_access_range<Base>;
    constexpr auto operator[](difference_type n) const requires random_access_range<Base>
    {
      return __reference_type(pos_ + n, current_[n]);
    }
    friend constexpr bool operator==(const iterator& x, const iterator& y) noexcept;
    friend constexpr strong_ordering operator<=>(const iterator& x,
                                                 const iterator& y) noexcept;
    friend constexpr iterator operator+(const iterator& x, difference_type y) requires
      random_access_range<Base>;
    friend constexpr iterator operator+(difference_type x, const iterator& y) requires
      random_access_range<Base>;
    friend constexpr iterator operator-(const iterator& x, difference_type y) requires
      random_access_range<Base>;
    friend constexpr difference_type operator-(const iterator& x, const iterator& y);
    friend constexpr auto iter_move(const iterator& i) noexcept(
      noexcept(ranges::iter_move(i.current_)) &&
      is_nothrow_move_constructible_v<range_rvalue_reference_t<Base>>)
    {
      return tuple<difference_type, range_rvalue_reference_t<Base>>(
        pos_, ranges::iter_move(i.current_));
    }
  };
}

Class template std::ranges::enumerate_view::sentinel

namespace std::ranges {
  template<view V>
  requires __range_with_movable_references<V>
  template<bool Const>
  class enumerate_view<V>::sentinel
  {                                                  // exposition only
    using Base            = __maybe_const<Const, V>; // exposition only
    sentinel_t<Base> end_ = sentinel_t<Base>();      // exposition only
    constexpr explicit sentinel(sentinel_t<Base> end);
 
  public:
    sentinel() = default;
    constexpr sentinel(sentinel<!Const> other) requires Const
      && convertible_to<sentinel_t<V>, sentinel_t<Base>>;
    constexpr sentinel_t<Base> base() const;
    template<bool OtherConst>
    requires sentinel_for<sentinel_t<Base>, iterator_t<__maybe_const<OtherConst, V>>>
    friend constexpr bool operator==(const iterator<OtherConst>& x, const sentinel& y);
    template<bool OtherConst>
    requires sized_sentinel_for<sentinel_t<Base>,
                                iterator_t<__maybe_const<OtherConst, V>>>
    friend constexpr range_difference_t<__maybe_const<OtherConst, V>> operator-(
      const iterator<OtherConst>& x,
      const sentinel& y);
    template<bool OtherConst>
    requires sized_sentinel_for<sentinel_t<Base>,
                                iterator_t<__maybe_const<OtherConst, V>>>
    friend constexpr range_difference_t<__maybe_const<OtherConst, V>> operator-(
      const sentinel& x,
      const iterator<OtherConst>& y);
  };
}

Class template std::ranges::zip_view

namespace std::ranges {
  template<class... Rs>
  concept __zip_is_common =             // exposition only
    (sizeof...(Rs) == 1 && (common_range<Rs> && ...)) ||
    (!(bidirectional_range<Rs> && ...) && (common_range<Rs> && ...)) ||
    ((random_access_range<Rs> && ...) && (sized_range<Rs> && ...));
 
  template<input_range... Views>
    requires (view<Views> && ...) && (sizeof...(Views) > 0)
  class zip_view : public view_interface<zip_view<Views...>> {
    tuple<Views...> views_;             // exposition only
 
    // class template zip_view::iterator
    template<bool> class iterator;      // exposition only
 
    // class template zip_view::sentinel
    template<bool> class sentinel;      // exposition only
 
  public:
    zip_view() = default;
    constexpr explicit zip_view(Views... views);
 
    constexpr auto begin() requires (!(__simple_view<Views> && ...)) {
      return iterator<false>(__tuple_transform(ranges::begin, views_));
    }
    constexpr auto begin() const requires (range<const Views> && ...) {
      return iterator<true>(__tuple_transform(ranges::begin, views_));
    }
 
    constexpr auto end() requires (!(__simple_view<Views> && ...)) {
      if constexpr (!__zip_is_common<Views...>) {
        return sentinel<false>(__tuple_transform(ranges::end, views_));
      } else if constexpr ((random_access_range<Views> && ...)) {
        return begin() + iter_difference_t<iterator<false>>(size());
      } else {
        return iterator<false>(__tuple_transform(ranges::end, views_));
      }
    }
 
    constexpr auto end() const requires (range<const Views> && ...) {
      if constexpr (!__zip_is_common<const Views...>) {
        return sentinel<true>(__tuple_transform(ranges::end, views_));
      } else if constexpr ((random_access_range<const Views> && ...)) {
        return begin() + iter_difference_t<iterator<true>>(size());
      } else {
        return iterator<true>(__tuple_transform(ranges::end, views_));
      }
    }
 
    constexpr auto size() requires (sized_range<Views> && ...);
    constexpr auto size() const requires (sized_range<const Views> && ...);
  };
 
  template<class... Rs>
    zip_view(Rs&&...) -> zip_view<views::all_t<Rs>...>;
}

Class template std::ranges::zip_view::iterator

namespace std::ranges {
  template<bool Const, class... Views>
    concept __all_random_access =                 // exposition only
      (random_access_range<__maybe_const<Const, Views>> && ...);
  template<bool Const, class... Views>
    concept __all_bidirectional =                 // exposition only
      (bidirectional_range<__maybe_const<Const, Views>> && ...);
  template<bool Const, class... Views>
    concept __all_forward =                       // exposition only
      (forward_range<__maybe_const<Const, Views>> && ...);
 
  template<input_range... Views>
    requires (view<Views> && ...) && (sizeof...(Views) > 0)
  template<bool Const>
  class zip_view<Views...>::iterator {
    tuple<iterator_t<__maybe_const<Const, Views>>...> current_;     // exposition only
    constexpr explicit iterator(tuple<iterator_t<__maybe_const<Const, Views>>...>);
                                                                    // exposition only
  public:
    using iterator_category = input_iterator_tag;                   // not always present
    using iterator_concept  = /* see description */;
    using value_type = tuple<range_value_t<__maybe_const<Const, Views>>...>;
    using difference_type = common_type_t<range_difference_t<
      __maybe_const<Const, Views>>...>;
 
    iterator() = default;
    constexpr iterator(iterator<!Const> i)
      requires Const && (convertible_to<iterator_t<Views>, iterator_t<const Views>>
        && ...);
 
    constexpr auto operator*() const;
    constexpr iterator& operator++();
    constexpr void operator++(int);
    constexpr iterator operator++(int) requires __all_forward<Const, Views...>;
 
    constexpr iterator& operator--() requires __all_bidirectional<Const, Views...>;
    constexpr iterator operator--(int) requires __all_bidirectional<Const, Views...>;
 
    constexpr iterator& operator+=(difference_type x)
      requires __all_random_access<Const, Views...>;
    constexpr iterator& operator-=(difference_type x)
      requires __all_random_access<Const, Views...>;
 
    constexpr auto operator[](difference_type n) const
      requires __all_random_access<Const, Views...>;
 
    friend constexpr bool operator==(const iterator& x, const iterator& y)
      requires (equality_comparable<iterator_t<__maybe_const<Const, Views>>> && ...);
 
    friend constexpr auto operator<=>(const iterator& x, const iterator& y)
      requires __all_random_access<Const, Views...>;
 
    friend constexpr iterator operator+(const iterator& i, difference_type n)
      requires __all_random_access<Const, Views...>;
    friend constexpr iterator operator+(difference_type n, const iterator& i)
      requires __all_random_access<Const, Views...>;
    friend constexpr iterator operator-(const iterator& i, difference_type n)
      requires __all_random_access<Const, Views...>;
    friend constexpr difference_type operator-(const iterator& x, const iterator& y)
      requires (sized_sentinel_for<iterator_t<__maybe_const<Const, Views>>,
                                   iterator_t<__maybe_const<Const, Views>>> && ...);
 
    friend constexpr auto iter_move(const iterator& i) noexcept(/* see description */);
 
    friend constexpr void iter_swap(const iterator& l, const iterator& r)
        noexcept(/* see description */)
      requires (indirectly_swappable<iterator_t<__maybe_const<Const, Views>>> && ...);
  };
}

Class template std::ranges::zip_view::sentinel

namespace std::ranges {
  template<input_range... Views>
    requires (view<Views> && ...) && (sizeof...(Views) > 0)
  template<bool Const>
  class zip_view<Views...>::sentinel {
    tuple<sentinel_t<__maybe_const<Const, Views>>...> end_;         // exposition only
    constexpr explicit sentinel(tuple<sentinel_t<__maybe_const<Const, Views>>...> end);
                                                                    // exposition only
  public:
    sentinel() = default;
    constexpr sentinel(sentinel<!Const> i)
      requires Const && (convertible_to<sentinel_t<Views>,
                         sentinel_t<const Views>> && ...);
 
    template<bool OtherConst>
      requires (sentinel_for<sentinel_t<__maybe_const<Const, Views>>,
                             iterator_t<__maybe_const<OtherConst, Views>>> && ...)
    friend constexpr bool operator==(const iterator<OtherConst>& x, const sentinel& y);
 
    template<bool OtherConst>
      requires (sized_sentinel_for<sentinel_t<__maybe_const<Const, Views>>,
                                   iterator_t<__maybe_const<OtherConst, Views>>> && ...)
    friend
      constexpr common_type_t<range_difference_t<__maybe_const<OtherConst, Views>>...>
      operator-(const iterator<OtherConst>& x, const sentinel& y);
 
    template<bool OtherConst>
      requires (sized_sentinel_for<sentinel_t<__maybe_const<Const, Views>>,
                                   iterator_t<__maybe_const<OtherConst, Views>>> && ...)
    friend
      constexpr common_type_t<range_difference_t<__maybe_const<OtherConst, Views>>...>
      operator-(const sentinel& y, const iterator<OtherConst>& x);
  };
}

Class template std::ranges::zip_transform_view

namespace std::ranges {
  template<move_constructible F, input_range... Views>
    requires (view<Views> && ...) && (sizeof...(Views) > 0) && is_object_v<F> &&
              regular_invocable<F&, range_reference_t<Views>...> &&
              __can_reference<invoke_result_t<F&, range_reference_t<Views>...>>
  class zip_transform_view : public view_interface<zip_transform_view<F, Views...>> {
    __movable_box<F> fun_;                    // exposition only
    zip_view<Views...> zip_;                // exposition only
 
    using InnerView = zip_view<Views...>;   // exposition only
    template<bool Const>
      using ziperator = iterator_t<__maybe_const<Const, InnerView>>;    // exposition only
    template<bool Const>
      using zentinel = sentinel_t<__maybe_const<Const, InnerView>>;     // exposition only
 
    // class template zip_transform_view::iterator
    template<bool> class iterator;          // exposition only
 
    // class template zip_transform_view::sentinel
    template<bool> class sentinel;          // exposition only
 
  public:
    zip_transform_view() = default;
 
    constexpr explicit zip_transform_view(F fun, Views... views);
 
    constexpr auto begin() { return iterator<false>(*this, zip_.begin()); }
 
    constexpr auto begin() const
      requires range<const InnerView> &&
               regular_invocable<const F&, range_reference_t<const Views>...> {
      return iterator<true>(*this, zip_.begin());
    }
 
    constexpr auto end() {
      if constexpr (common_range<InnerView>) {
        return iterator<false>(*this, zip_.end());
      } else {
        return sentinel<false>(zip_.end());
      }
    }
 
    constexpr auto end() const
      requires range<const InnerView> &&
               regular_invocable<const F&, range_reference_t<const Views>...> {
      if constexpr (common_range<const InnerView>) {
        return iterator<true>(*this, zip_.end());
      } else {
        return sentinel<true>(zip_.end());
      }
    }
 
    constexpr auto size() requires sized_range<InnerView> {
      return zip_.size();
    }
 
    constexpr auto size() const requires sized_range<const InnerView> {
      return zip_.size();
    }
  };
 
  template<class F, class... Rs>
    zip_transform_view(F, Rs&&...) -> zip_transform_view<F, views::all_t<Rs>...>;
}

Class template std::ranges::zip_transform_view::iterator

namespace std::ranges {
  template<move_constructible F, input_range... Views>
    requires (view<Views> && ...) && (sizeof...(Views) > 0) && is_object_v<F> &&
              regular_invocable<F&, range_reference_t<Views>...> &&
              __can_reference<invoke_result_t<F&, range_reference_t<Views>...>>
  template<bool Const>
  class zip_transform_view<F, Views...>::iterator {
    using Parent = __maybe_const<Const, zip_transform_view>;    // exposition only
    using Base = __maybe_const<Const, InnerView>;               // exposition only
    Parent* parent_ = nullptr;                                  // exposition only
    ziperator<Const> inner_;                                    // exposition only
 
    constexpr iterator(Parent& parent, ziperator<Const> inner); // exposition only
 
  public:
    using iterator_category = /* see description */;            // not always present
    using iterator_concept  = typename ziperator<Const>::iterator_concept;
    using value_type =
      remove_cvref_t<invoke_result_t<__maybe_const<Const, F>&,
                                     range_reference_t<__maybe_const<Const, Views>>...>>;
    using difference_type = range_difference_t<Base>;
 
    iterator() = default;
    constexpr iterator(iterator<!Const> i)
      requires Const && convertible_to<ziperator<false>, ziperator<Const>>;
 
    constexpr decltype(auto) operator*() const noexcept(/* see description */);
    constexpr iterator& operator++();
    constexpr void operator++(int);
    constexpr iterator operator++(int) requires forward_range<Base>;
 
    constexpr iterator& operator--() requires bidirectional_range<Base>;
    constexpr iterator operator--(int) requires bidirectional_range<Base>;
 
    constexpr iterator& operator+=(difference_type x) requires random_access_range<Base>;
    constexpr iterator& operator-=(difference_type x) requires random_access_range<Base>;
 
    constexpr decltype(auto) operator[](difference_type n) const
      requires random_access_range<Base>;
 
    friend constexpr bool operator==(const iterator& x, const iterator& y)
      requires equality_comparable<ziperator<Const>>;
 
    friend constexpr auto operator<=>(const iterator& x, const iterator& y)
      requires random_access_range<Base>;
 
    friend constexpr iterator operator+(const iterator& i, difference_type n)
      requires random_access_range<Base>;
    friend constexpr iterator operator+(difference_type n, const iterator& i)
      requires random_access_range<Base>;
    friend constexpr iterator operator-(const iterator& i, difference_type n)
      requires random_access_range<Base>;
    friend constexpr difference_type operator-(const iterator& x, const iterator& y)
      requires sized_sentinel_for<ziperator<Const>, ziperator<Const>>;
  };
}

Class template std::ranges::zip_transform_view::sentinel

namespace std::ranges {
  template<move_constructible F, input_range... Views>
    requires (view<Views> && ...) && (sizeof...(Views) > 0) && is_object_v<F> &&
              regular_invocable<F&, range_reference_t<Views>...> &&
              __can_reference<invoke_result_t<F&, range_reference_t<Views>...>>
  template<bool Const>
  class zip_transform_view<F, Views...>::sentinel {
    zentinel<Const> inner_;                                     // exposition only
    constexpr explicit sentinel(zentinel<Const> inner);         // exposition only
 
  public:
    sentinel() = default;
    constexpr sentinel(sentinel<!Const> i)
      requires Const && convertible_to<zentinel<false>, zentinel<Const>>;
 
    template<bool OtherConst>
      requires sentinel_for<zentinel<Const>, ziperator<OtherConst>>
    friend constexpr bool operator==(const iterator<OtherConst>& x, const sentinel& y);
 
    template<bool OtherConst>
      requires sized_sentinel_for<zentinel<Const>, ziperator<OtherConst>>
    friend constexpr range_difference_t<__maybe_const<OtherConst, InnerView>>
      operator-(const iterator<OtherConst>& x, const sentinel& y);
 
    template<bool OtherConst>
      requires sized_sentinel_for<zentinel<Const>, ziperator<OtherConst>>
    friend constexpr range_difference_t<__maybe_const<OtherConst, InnerView>>
      operator-(const sentinel& x, const iterator<OtherConst>& y);
  };
}

Class template std::ranges::adjacent_view

namespace std::ranges {
  template<forward_range V, size_t N>
    requires view<V> && (N > 0)
  class adjacent_view : public view_interface<adjacent_view<V, N>> {
    V base_ = V();                      // exposition only
 
    // class template adjacent_view::iterator
    template<bool> class iterator;      // exposition only
 
    // class template adjacent_view::sentinel
    template<bool> class sentinel;      // exposition only
 
    struct __as_sentinel{};             // exposition only
 
  public:
    adjacent_view() requires default_initializable<V> = default;
    constexpr explicit adjacent_view(V base);
 
    constexpr auto begin() requires (!__simple_view<V>) {
      return iterator<false>(ranges::begin(base_), ranges::end(base_));
    }
 
    constexpr auto begin() const requires range<const V> {
      return iterator<true>(ranges::begin(base_), ranges::end(base_));
    }
 
    constexpr auto end() requires (!__simple_view<V>) {
      if constexpr (common_range<V>) {
        return iterator<false>(__as_sentinel{}, ranges::begin(base_), ranges::end(base_));
      } else {
        return sentinel<false>(ranges::end(base_));
      }
    }
 
    constexpr auto end() const requires range<const V> {
      if constexpr (common_range<const V>) {
        return iterator<true>(__as_sentinel{}, ranges::begin(base_), ranges::end(base_));
      } else {
        return sentinel<true>(ranges::end(base_));
      }
    }
 
    constexpr auto size() requires sized_range<V>;
    constexpr auto size() const requires sized_range<const V>;
  };
}

Class template std::ranges::adjacent_view::iterator

namespace std::ranges {
  template<forward_range V, size_t N>
    requires view<V> && (N > 0)
  template<bool Const>
  class adjacent_view<V, N>::iterator {
    using Base = __maybe_const<Const, V>;                               // exposition only
    array<iterator_t<Base>, N> current_ = array<iterator_t<Base>, N>(); // exposition only
    constexpr iterator(iterator_t<Base> first, sentinel_t<Base> last);  // exposition only
    constexpr iterator(__as_sentinel, iterator_t<Base> first, iterator_t<Base> last);
                                                                        // exposition only
  public:
    using iterator_category = input_iterator_tag;
    using iterator_concept  = /* see description */;
    using value_type = tuple<__REPEAT(range_value_t<Base>, N)...>;
    using difference_type = range_difference_t<Base>;
 
    iterator() = default;
    constexpr iterator(iterator<!Const> i)
      requires Const && convertible_to<iterator_t<V>, iterator_t<Base>>;
 
    constexpr auto operator*() const;
    constexpr iterator& operator++();
    constexpr iterator operator++(int);
 
    constexpr iterator& operator--() requires bidirectional_range<Base>;
    constexpr iterator operator--(int) requires bidirectional_range<Base>;
 
    constexpr iterator& operator+=(difference_type x)
      requires random_access_range<Base>;
    constexpr iterator& operator-=(difference_type x)
      requires random_access_range<Base>;
 
    constexpr auto operator[](difference_type n) const
      requires random_access_range<Base>;
 
    friend constexpr bool operator==(const iterator& x, const iterator& y);
    friend constexpr bool operator<(const iterator& x, const iterator& y)
      requires random_access_range<Base>;
    friend constexpr bool operator>(const iterator& x, const iterator& y)
      requires random_access_range<Base>;
    friend constexpr bool operator<=(const iterator& x, const iterator& y)
      requires random_access_range<Base>;
    friend constexpr bool operator>=(const iterator& x, const iterator& y)
      requires random_access_range<Base>;
    friend constexpr auto operator<=>(const iterator& x, const iterator& y)
      requires random_access_range<Base> &&
               three_way_comparable<iterator_t<Base>>;
 
    friend constexpr iterator operator+(const iterator& i, difference_type n)
      requires random_access_range<Base>;
    friend constexpr iterator operator+(difference_type n, const iterator& i)
      requires random_access_range<Base>;
    friend constexpr iterator operator-(const iterator& i, difference_type n)
      requires random_access_range<Base>;
    friend constexpr difference_type operator-(const iterator& x, const iterator& y)
      requires sized_sentinel_for<iterator_t<Base>, iterator_t<Base>>;
 
    friend constexpr auto iter_move(const iterator& i) noexcept(/* see description */);
    friend constexpr void iter_swap(const iterator& l,
                                    const iterator& r) noexcept(/* see description */)
      requires indirectly_swappable<iterator_t<Base>>;
  };
}

Class template std::ranges::adjacent_view::sentinel

namespace std::ranges {
  template<forward_range V, size_t N>
    requires view<V> && (N > 0)
  template<bool Const>
  class adjacent_view<V, N>::sentinel {
    using Base = __maybe_const<Const, V>;                       // exposition only
    sentinel_t<Base> end_ = sentinel_t<Base>();                 // exposition only
    constexpr explicit sentinel(sentinel_t<Base> end);          // exposition only
 
  public:
    sentinel() = default;
    constexpr sentinel(sentinel<!Const> i)
      requires Const && convertible_to<sentinel_t<V>, sentinel_t<Base>>;
 
    template<bool OtherConst>
      requires sentinel_for<sentinel_t<Base>, iterator_t<__maybe_const<OtherConst, V>>>
    friend constexpr bool operator==(const iterator<OtherConst>& x, const sentinel& y);
 
    template<bool OtherConst>
      requires sized_sentinel_for<sentinel_t<Base>,
        iterator_t<__maybe_const<OtherConst, V>>>
    friend constexpr range_difference_t<__maybe_const<OtherConst, V>>
      operator-(const iterator<OtherConst>& x, const sentinel& y);
 
    template<bool OtherConst>
      requires sized_sentinel_for<sentinel_t<Base>,
        iterator_t<__maybe_const<OtherConst, V>>>
    friend constexpr range_difference_t<__maybe_const<OtherConst, V>>
      operator-(const sentinel& y, const iterator<OtherConst>& x);
  };
}

Class template std::ranges::adjacent_transform_view

namespace std::ranges {
  template<forward_range V, move_constructible F, size_t N>
    requires view<V> && (N > 0) && is_object_v<F> &&
             regular_invocable<F&, __REPEAT(range_reference_t<V>, N)...> &&
             __can_reference<invoke_result_t<F&, __REPEAT(range_reference_t<V>, N)...>>
  class adjacent_transform_view :
    public view_interface<adjacent_transform_view<V, F, N>> {
    __movable_box<F> fun_;                      // exposition only
    adjacent_view<V, N> inner_;                 // exposition only
 
    using InnerView = adjacent_view<V, N>;      // exposition only
    template<bool Const>
      using __inner_iterator =
        iterator_t<__maybe_const<Const, InnerView>>;    // exposition only
    template<bool Const>
      using __inner_sentinel =
        sentinel_t<__maybe_const<Const, InnerView>>;    // exposition only
 
    // class template adjacent_transform_view::iterator
    template<bool> class iterator;              // exposition only
 
    // class template adjacent_transform_view::sentinel
    template<bool> class sentinel;              // exposition only
 
  public:
    adjacent_transform_view() = default;
    constexpr explicit adjacent_transform_view(V base, F fun);
 
    constexpr auto begin() {
      return iterator<false>(*this, inner_.begin());
    }
 
    constexpr auto begin() const
      requires range<const InnerView> &&
               regular_invocable<const F&, __REPEAT(range_reference_t<const V>, N)...> {
      return iterator<true>(*this, inner_.begin());
    }
 
    constexpr auto end() {
      if constexpr (common_range<InnerView>) {
        return iterator<false>(*this, inner_.end());
      } else {
        return sentinel<false>(inner_.end());
      }
    }
 
    constexpr auto end() const
      requires range<const InnerView> &&
               regular_invocable<const F&, __REPEAT(range_reference_t<const V>, N)...> {
      if constexpr (common_range<const InnerView>) {
        return iterator<true>(*this, inner_.end());
      } else {
        return sentinel<true>(inner_.end());
      }
    }
 
    constexpr auto size() requires sized_range<InnerView> {
      return inner_.size();
    }
 
    constexpr auto size() const requires sized_range<const InnerView> {
      return inner_.size();
    }
  };
}

Class template std::ranges::adjacent_transform_view::iterator

namespace std::ranges {
  template<forward_range V, move_constructible F, size_t N>
    requires view<V> && (N > 0) && is_object_v<F> &&
             regular_invocable<F&, __REPEAT(range_reference_t<V>, N)...> &&
             __can_reference<invoke_result_t<F&, __REPEAT(range_reference_t<V>, N)...>>
  template<bool Const>
  class adjacent_transform_view<V, F, N>::iterator {
    using Parent = __maybe_const<Const, adjacent_transform_view>;       // exposition only
    using Base = __maybe_const<Const, V>;                               // exposition only
    Parent* parent_ = nullptr;                                          // exposition only
    __inner_iterator<Const> inner_;                                     // exposition only
 
    constexpr iterator(Parent& parent, __inner_iterator<Const> inner);  // exposition only
 
  public:
    using iterator_category = /* see description */;
    using iterator_concept  = typename __inner_iterator<Const>::iterator_concept;
    using value_type =
      remove_cvref_t<invoke_result_t<__maybe_const<Const, F>&,
                                     __REPEAT(range_reference_t<Base>, N)...>>;
    using difference_type = range_difference_t<Base>;
 
    iterator() = default;
    constexpr iterator(iterator<!Const> i)
      requires Const && convertible_to<__inner_iterator<false>, __inner_iterator<Const>>;
 
    constexpr decltype(auto) operator*() const noexcept(/* see description */);
    constexpr iterator& operator++();
    constexpr iterator operator++(int);
    constexpr iterator& operator--() requires bidirectional_range<Base>;
    constexpr iterator operator--(int) requires bidirectional_range<Base>;
    constexpr iterator& operator+=(difference_type x) requires random_access_range<Base>;
    constexpr iterator& operator-=(difference_type x) requires random_access_range<Base>;
 
    constexpr decltype(auto) operator[](difference_type n) const
      requires random_access_range<Base>;
 
    friend constexpr bool operator==(const iterator& x, const iterator& y);
    friend constexpr bool operator<(const iterator& x, const iterator& y)
      requires random_access_range<Base>;
    friend constexpr bool operator>(const iterator& x, const iterator& y)
      requires random_access_range<Base>;
    friend constexpr bool operator<=(const iterator& x, const iterator& y)
      requires random_access_range<Base>;
    friend constexpr bool operator>=(const iterator& x, const iterator& y)
      requires random_access_range<Base>;
    friend constexpr auto operator<=>(const iterator& x, const iterator& y)
      requires random_access_range<Base> && three_way_comparable<__inner_iterator<Const>>;
 
    friend constexpr iterator operator+(const iterator& i, difference_type n)
      requires random_access_range<Base>;
    friend constexpr iterator operator+(difference_type n, const iterator& i)
      requires random_access_range<Base>;
    friend constexpr iterator operator-(const iterator& i, difference_type n)
      requires random_access_range<Base>;
    friend constexpr difference_type operator-(const iterator& x, const iterator& y)
      requires sized_sentinel_for<__inner_iterator<Const>, __inner_iterator<Const>>;
  };
}

Class template std::ranges::adjacent_transform_view::sentinel

namespace std::ranges {
  template<forward_range V, move_constructible F, size_t N>
    requires view<V> && (N > 0) && is_object_v<F> &&
             regular_invocable<F&, __REPEAT(range_reference_t<V>, N)...> &&
             __can_reference<invoke_result_t<F&, __REPEAT(range_reference_t<V>, N)...>>
  template<bool Const>
  class adjacent_transform_view<V, F, N>::sentinel {
    __inner_sentinel<Const> inner_;                               // exposition only
    constexpr explicit sentinel(__inner_sentinel<Const> inner);   // exposition only
 
  public:
    sentinel() = default;
    constexpr sentinel(sentinel<!Const> i)
      requires Const && convertible_to<__inner_sentinel<false>, __inner_sentinel<Const>>;
 
    template<bool OtherConst>
      requires sentinel_for<__inner_sentinel<Const>, __inner_iterator<OtherConst>>
    friend constexpr bool operator==(const iterator<OtherConst>& x, const sentinel& y);
 
    template<bool OtherConst>
      requires sized_sentinel_for<__inner_sentinel<Const>, __inner_iterator<OtherConst>>
    friend constexpr range_difference_t<__maybe_const<OtherConst, InnerView>>
      operator-(const iterator<OtherConst>& x, const sentinel& y);
 
    template<bool OtherConst>
      requires sized_sentinel_for<__inner_sentinel<Const>, __inner_iterator<OtherConst>>
    friend constexpr range_difference_t<__maybe_const<OtherConst, InnerView>>
      operator-(const sentinel& x, const iterator<OtherConst>& y);
  };
}

Class template std::ranges::chunk_view for input_ranges

namespace std::ranges {
  template<class I>
  constexpr I __div_ceil(I num, I denom) {                  // exposition only
    I r = num / denom;
    if (num % denom)
      ++r;
    return r;
  }
 
  template<view V>
    requires input_range<V>
  class chunk_view : public view_interface<chunk_view<V>> {
    V base_;                                                // exposition only
    range_difference_t<V> n_;                               // exposition only
    range_difference_t<V> remainder_ = 0;                   // exposition only
 
    __non_propagating_cache<iterator_t<V>> current_;        // exposition only
 
    // class chunk_view::outer-iterator
    class __outer_iterator;                                 // exposition only
 
    // class chunk_view::inner-iterator
    class __inner_iterator;                                 // exposition only
 
  public:
    constexpr explicit chunk_view(V base, range_difference_t<V> n);
 
    constexpr V base() const & requires copy_constructible<V> { return base_; }
    constexpr V base() && { return std::move(base_); }
 
    constexpr __outer_iterator begin();
    constexpr default_sentinel_t end() const noexcept;
 
    constexpr auto size() requires sized_range<V>;
    constexpr auto size() const requires sized_range<const V>;
  };
 
  template<class R>
    chunk_view(R&&, range_difference_t<R>) -> chunk_view<views::all_t<R>>;
}

Class template std::ranges::chunk_view::outer_iterator for input_ranges

namespace std::ranges {
  template<view V>
    requires input_range<V>
  class chunk_view<V>::__outer_iterator {
    chunk_view* parent_;                                        // exposition only
 
    constexpr explicit __outer_iterator(chunk_view& parent);    // exposition only
 
  public:
    using iterator_concept = input_iterator_tag;
    using difference_type  = range_difference_t<V>;
 
    // class chunk_view::outer-iterator::value_type
    struct value_type;
 
    __outer_iterator(__outer_iterator&&) = default;
    __outer_iterator& operator=(__outer_iterator&&) = default;
 
    constexpr value_type operator*() const;
    constexpr __outer_iterator& operator++();
    constexpr void operator++(int);
 
    friend constexpr bool operator==(const __outer_iterator& x, default_sentinel_t);
 
    friend constexpr difference_type operator-(default_sentinel_t y,
                                               const __outer_iterator& x)
      requires sized_sentinel_for<sentinel_t<V>, iterator_t<V>>;
    friend constexpr difference_type operator-(const __outer_iterator& x,
                                               default_sentinel_t y)
      requires sized_sentinel_for<sentinel_t<V>, iterator_t<V>>;
  };
}

Class template std::ranges::chunk_view::outer_iterator::value_type for input_ranges

namespace std::ranges {
  template<view V>
    requires input_range<V>
  struct chunk_view<V>::__outer_iterator::value_type : view_interface<value_type> {
  private:
    chunk_view* parent_;                                        // exposition only
 
    constexpr explicit value_type(chunk_view& parent);          // exposition only
 
  public:
    constexpr __inner_iterator begin() const noexcept;
    constexpr default_sentinel_t end() const noexcept;
 
    constexpr auto size() const
      requires sized_sentinel_for<sentinel_t<V>, iterator_t<V>>;
  };
}

Class template std::ranges::chunk_view::inner_iterator for input_ranges

namespace std::ranges {
  template<view V>
    requires input_range<V>
  class chunk_view<V>::__inner_iterator {
    chunk_view* parent_;                                                // exposition only
 
    constexpr explicit __inner_iterator(chunk_view& parent) noexcept;   // exposition only
 
  public:
    using iterator_concept = input_iterator_tag;
    using difference_type = range_difference_t<V>;
    using value_type = range_value_t<V>;
 
    __inner_iterator(__inner_iterator&&) = default;
    __inner_iterator& operator=(__inner_iterator&&) = default;
 
    constexpr const iterator_t<V>& base() const &;
 
    constexpr range_reference_t<V> operator*() const;
    constexpr __inner_iterator& operator++();
    constexpr void operator++(int);
 
    friend constexpr bool operator==(const __inner_iterator& x, default_sentinel_t);
 
    friend constexpr difference_type operator-(default_sentinel_t y,
                                               const __inner_iterator& x)
      requires sized_sentinel_for<sentinel_t<V>, iterator_t<V>>;
    friend constexpr difference_type operator-(const __inner_iterator& x,
                                               default_sentinel_t y)
      requires sized_sentinel_for<sentinel_t<V>, iterator_t<V>>;
  };
}

Class template std::ranges::chunk_view for forward_ranges

namespace std::ranges {
  template<view V>
    requires forward_range<V>
  class chunk_view<V> : public view_interface<chunk_view<V>> {
    V base_;                            // exposition only
    range_difference_t<V> n_;           // exposition only
 
    // class template chunk_view::iterator
    template<bool> class iterator;      // exposition only
 
  public:
    constexpr explicit chunk_view(V base, range_difference_t<V> n);
 
    constexpr V base() const & requires copy_constructible<V> { return base_; }
    constexpr V base() && { return std::move(base_); }
 
    constexpr auto begin() requires (!__simple_view<V>) {
      return iterator<false>(this, ranges::begin(base_));
    }
 
    constexpr auto begin() const requires forward_range<const V> {
      return iterator<true>(this, ranges::begin(base_));
    }
 
    constexpr auto end() requires (!__simple_view<V>) {
      if constexpr (common_range<V> && sized_range<V>) {
        auto missing = (n_ - ranges::distance(base_) % n_) % n_;
        return iterator<false>(this, ranges::end(base_), missing);
      } else if constexpr (common_range<V> && !bidirectional_range<V>) {
        return iterator<false>(this, ranges::end(base_));
      } else {
        return default_sentinel;
      }
    }
 
    constexpr auto end() const requires forward_range<const V> {
      if constexpr (common_range<const V> && sized_range<const V>) {
        auto missing = (n_ - ranges::distance(base_) % n_) % n_;
        return iterator<true>(this, ranges::end(base_), missing);
      } else if constexpr (common_range<const V> && !bidirectional_range<const V>) {
        return iterator<true>(this, ranges::end(base_));
      } else {
        return default_sentinel;
      }
    }
 
    constexpr auto size() requires sized_range<V>;
    constexpr auto size() const requires sized_range<const V>;
  };
}

Class template std::ranges::chunk_view::iterator for forward_ranges

namespace std::ranges {
  template<view V>
    requires forward_range<V>
  template<bool Const>
  class chunk_view<V>::iterator {
    using Parent = __maybe_const<Const, chunk_view>;                    // exposition only
    using Base = __maybe_const<Const, V>;                               // exposition only
 
    iterator_t<Base> current_ = iterator_t<Base>();                     // exposition only
    sentinel_t<Base> end_ = sentinel_t<Base>();                         // exposition only
    range_difference_t<Base> n_ = 0;                                    // exposition only
    range_difference_t<Base> missing_ = 0;                              // exposition only
 
    constexpr iterator(Parent* parent, iterator_t<Base> current,        // exposition only
                       range_difference_t<Base> missing = 0);
 
  public:
    using iterator_category = input_iterator_tag;
    using iterator_concept = /* see description */;
    using value_type = decltype(views::take(subrange(current_, end_), n_));
    using difference_type = range_difference_t<Base>;
 
    iterator() = default;
    constexpr iterator(iterator<!Const> i)
      requires Const && convertible_to<iterator_t<V>, iterator_t<Base>>
                     && convertible_to<sentinel_t<V>, sentinel_t<Base>>;
 
    constexpr iterator_t<Base> base() const;
 
    constexpr value_type operator*() const;
    constexpr iterator& operator++();
    constexpr iterator operator++(int);
 
    constexpr iterator& operator--() requires bidirectional_range<Base>;
    constexpr iterator operator--(int) requires bidirectional_range<Base>;
 
    constexpr iterator& operator+=(difference_type x)
      requires random_access_range<Base>;
    constexpr iterator& operator-=(difference_type x)
      requires random_access_range<Base>;
 
    constexpr value_type operator[](difference_type n) const
      requires random_access_range<Base>;
 
    friend constexpr bool operator==(const iterator& x, const iterator& y);
    friend constexpr bool operator==(const iterator& x, default_sentinel_t);
 
    friend constexpr bool operator<(const iterator& x, const iterator& y)
      requires random_access_range<Base>;
    friend constexpr bool operator>(const iterator& x, const iterator& y)
      requires random_access_range<Base>;
    friend constexpr bool operator<=(const iterator& x, const iterator& y)
      requires random_access_range<Base>;
    friend constexpr bool operator>=(const iterator& x, const iterator& y)
      requires random_access_range<Base>;
    friend constexpr auto operator<=>(const iterator& x, const iterator& y)
      requires random_access_range<Base> &&
               three_way_comparable<iterator_t<Base>>;
 
    friend constexpr iterator operator+(const iterator& i, difference_type n)
      requires random_access_range<Base>;
    friend constexpr iterator operator+(difference_type n, const iterator& i)
      requires random_access_range<Base>;
    friend constexpr iterator operator-(const iterator& i, difference_type n)
      requires random_access_range<Base>;
    friend constexpr difference_type operator-(const iterator& x, const iterator& y)
      requires sized_sentinel_for<iterator_t<Base>, iterator_t<Base>>;
 
    friend constexpr difference_type operator-(default_sentinel_t y, const iterator& x)
      requires sized_sentinel_for<sentinel_t<Base>, iterator_t<Base>>;
    friend constexpr difference_type operator-(const iterator& x, default_sentinel_t y)
      requires sized_sentinel_for<sentinel_t<Base>, iterator_t<Base>>;
  };
}

Class template std::ranges::slide_view

namespace std::ranges {
  template<class V>
  concept __slide_caches_nothing = random_access_range<V> &&
    sized_range<V>;                                             // exposition only
 
  template<class V>
  concept __slide_caches_last =                                 // exposition only
    !__slide_caches_nothing<V> && bidirectional_range<V> && common_range<V>;
 
  template<class V>
  concept __slide_caches_first =                                // exposition only
    !__slide_caches_nothing<V> && !__slide_caches_last<V>;
 
  template<forward_range V>
    requires view<V>
  class slide_view : public view_interface<slide_view<V>> {
    V base_;                            // exposition only
    range_difference_t<V> n_;           // exposition only
 
    // class template slide_view::iterator
    template<bool> class iterator;      // exposition only
 
    // class slide_view::sentinel
    class sentinel;                     // exposition only
 
  public:
    constexpr explicit slide_view(V base, range_difference_t<V> n);
 
    constexpr auto begin()
      requires (!(__simple_view<V> && __slide_caches_nothing<const V>));
    constexpr auto begin() const requires __slide_caches_nothing<const V>;
 
    constexpr auto end()
      requires (!(__simple_view<V> && __slide_caches_nothing<const V>));
    constexpr auto end() const requires __slide_caches_nothing<const V>;
 
    constexpr auto size() requires sized_range<V>;
    constexpr auto size() const requires sized_range<const V>;
  };
 
  template<class R>
    slide_view(R&&, range_difference_t<R>) -> slide_view<views::all_t<R>>;
}

Class template std::ranges::slide_view::iterator

namespace std::ranges {
  template<forward_range V>
    requires view<V>
  template<bool Const>
  class slide_view<V>::iterator {
    using Base = __maybe_const<Const, V>;               // exposition only
    iterator_t<Base> current_   = iterator_t<Base>();   // exposition only
    iterator_t<Base> last_ele_  = iterator_t<Base>();   // exposition only,
                                    // present only if Base models slide-caches-first
    range_difference_t<Base> n_ = 0;                    // exposition only
 
    constexpr iterator(iterator_t<Base> current,        // exposition only
                       range_difference_t<Base> n)
      requires (!__slide_caches_first<Base>);
 
    constexpr iterator(iterator_t<Base> current,        // exposition only
                       iterator_t<Base> last_ele,
                       range_difference_t<Base> n)
      requires __slide_caches_first<Base>;
 
  public:
    using iterator_category = input_iterator_tag;
    using iterator_concept = /* see description */;
    using value_type = decltype(views::counted(current_, n_));
    using difference_type = range_difference_t<Base>;
 
    iterator() = default;
    constexpr iterator(iterator<!Const> i)
      requires Const && convertible_to<iterator_t<V>, iterator_t<Base>>;
 
    constexpr auto operator*() const;
    constexpr iterator& operator++();
    constexpr iterator operator++(int);
 
    constexpr iterator& operator--() requires bidirectional_range<Base>;
    constexpr iterator operator--(int) requires bidirectional_range<Base>;
 
    constexpr iterator& operator+=(difference_type x)
      requires random_access_range<Base>;
    constexpr iterator& operator-=(difference_type x)
      requires random_access_range<Base>;
 
    constexpr auto operator[](difference_type n) const
      requires random_access_range<Base>;
 
    friend constexpr bool operator==(const iterator& x, const iterator& y);
 
    friend constexpr bool operator<(const iterator& x, const iterator& y)
      requires random_access_range<Base>;
    friend constexpr bool operator>(const iterator& x, const iterator& y)
      requires random_access_range<Base>;
    friend constexpr bool operator<=(const iterator& x, const iterator& y)
      requires random_access_range<Base>;
    friend constexpr bool operator>=(const iterator& x, const iterator& y)
      requires random_access_range<Base>;
    friend constexpr auto operator<=>(const iterator& x, const iterator& y)
      requires random_access_range<Base> &&
               three_way_comparable<iterator_t<Base>>;
 
    friend constexpr iterator operator+(const iterator& i, difference_type n)
      requires random_access_range<Base>;
    friend constexpr iterator operator+(difference_type n, const iterator& i)
      requires random_access_range<Base>;
    friend constexpr iterator operator-(const iterator& i, difference_type n)
      requires random_access_range<Base>;
    friend constexpr difference_type operator-(const iterator& x, const iterator& y)
      requires sized_sentinel_for<iterator_t<Base>, iterator_t<Base>>;
  };
}

Class template std::ranges::slide_view::sentinel

namespace std::ranges {
  template<forward_range V>
    requires view<V>
  class slide_view<V>::sentinel {
    sentinel_t<V> end_ = sentinel_t<V>();             // exposition only
    constexpr explicit sentinel(sentinel_t<V> end);   // exposition only
 
  public:
    sentinel() = default;
 
    friend constexpr bool operator==(const iterator<false>& x, const sentinel& y);
 
    friend constexpr range_difference_t<V>
      operator-(const iterator<false>& x, const sentinel& y)
        requires sized_sentinel_for<sentinel_t<V>, iterator_t<V>>;
 
    friend constexpr range_difference_t<V>
      operator-(const sentinel& y, const iterator<false>& x)
        requires sized_sentinel_for<sentinel_t<V>, iterator_t<V>>;
  };
}

Class template std::ranges::chunk_by_view

namespace std::ranges {
  template<forward_range V, indirect_binary_predicate<iterator_t<V>, iterator_t<V>> Pred>
    requires view<V> && is_object_v<Pred>
  class chunk_by_view : public view_interface<chunk_by_view<V, Pred>> {
    V base_ = V();                                          // exposition only
    __movable_box<Pred> pred_ = Pred();                     // exposition only
 
    // class chunk_by_view::iterator
    class iterator;                                         // exposition only
 
  public:
    chunk_by_view() requires default_initializable<V> &&
        default_initializable<Pred> = default;
    constexpr explicit chunk_by_view(V base, Pred pred);
 
    constexpr V base() const & requires copy_constructible<V> { return base_; }
    constexpr V base() && { return std::move(base_); }
 
    constexpr const Pred& pred() const;
 
    constexpr iterator begin();
    constexpr auto end();
 
    constexpr iterator_t<V> __find_next(iterator_t<V>);       // exposition only
    constexpr iterator_t<V> __find_prev(iterator_t<V>)        // exposition only
      requires bidirectional_range<V>;
  };
 
  template<class R, class Pred>
    chunk_by_view(R&&, Pred) -> chunk_by_view<views::all_t<R>, Pred>;
}

Class template std::ranges::chunk_by_view::iterator

namespace std::ranges {
  template<forward_range V, indirect_binary_predicate<iterator_t<V>, iterator_t<V>> Pred>
    requires view<V> && is_object_v<Pred>
  class chunk_by_view<V, Pred>::iterator {
    chunk_by_view* parent_ = nullptr;                                   // exposition only
    iterator_t<V> current_ = iterator_t<V>();                           // exposition only
    iterator_t<V> next_    = iterator_t<V>();                           // exposition only
 
    constexpr iterator(chunk_by_view& parent, iterator_t<V> current,    // exposition only
                       iterator_t<V> next);
 
  public:
    using value_type = subrange<iterator_t<V>>;
    using difference_type  = range_difference_t<V>;
    using iterator_category = input_iterator_tag;
    using iterator_concept = /* see description */;
 
    iterator() = default;
 
    constexpr value_type operator*() const;
    constexpr iterator& operator++();
    constexpr iterator operator++(int);
 
    constexpr iterator& operator--() requires bidirectional_range<V>;
    constexpr iterator operator--(int) requires bidirectional_range<V>;
 
    friend constexpr bool operator==(const iterator& x, const iterator& y);
    friend constexpr bool operator==(const iterator& x, default_sentinel_t);
  };
}

Class template std::ranges::stride_view

namespace std::ranges {
  template<input_range V>
    requires view<V>
  class stride_view : public view_interface<stride_view<V>> {
    V base_;                                    // exposition only
    range_difference_t<V> stride_;              // exposition only
    // class template stride_view::iterator
    template<bool> class iterator;              // exposition only
  public:
    constexpr explicit stride_view(V base, range_difference_t<V> stride);
 
    constexpr V base() const & requires copy_constructible<V> { return base_; }
    constexpr V base() && { return std::move(base_); }
 
    constexpr range_difference_t<V> stride() const noexcept;
 
    constexpr auto begin() requires (!__simple_view<V>) {
      return iterator<false>(this, ranges::begin(base_));
    }
 
    constexpr auto begin() const requires range<const V> {
      return iterator<true>(this, ranges::begin(base_));
    }
 
    constexpr auto end() requires (!__simple_view<V>) {
      if constexpr (common_range<V> && sized_range<V> && forward_range<V>) {
        auto missing = (stride_ - ranges::distance(base_) % stride_) % stride_;
        return iterator<false>(this, ranges::end(base_), missing);
      } else if constexpr (common_range<V> && !bidirectional_range<V>) {
        return iterator<false>(this, ranges::end(base_));
      } else {
        return default_sentinel;
      }
    }
 
    constexpr auto end() const requires range<const V> {
      if constexpr (common_range<const V> && sized_range<const V> &&
          forward_range<const V>) {
        auto missing = (stride_ - ranges::distance(base_) % stride_) % stride_;
        return iterator<true>(this, ranges::end(base_), missing);
      } else if constexpr (common_range<const V> && !bidirectional_range<const V>) {
        return iterator<true>(this, ranges::end(base_));
      } else {
        return default_sentinel;
      }
    }
 
    constexpr auto size() requires sized_range<V>;
    constexpr auto size() const requires sized_range<const V>;
  };
 
  template<class R>
    stride_view(R&&, range_difference_t<R>) -> stride_view<views::all_t<R>>;
}

Class template std::ranges::stride_view::iterator

namespace std::ranges {
  template<input_range V>
    requires view<V>
  template<bool Const>
  class stride_view<V>::iterator {
    using Parent = __maybe_const<Const, stride_view>;               // exposition only
    using Base = __maybe_const<Const, V>;                           // exposition only
 
    iterator_t<Base> current_ = iterator_t<Base>();                 // exposition only
    sentinel_t<Base> end_ = sentinel_t<Base>();                     // exposition only
    range_difference_t<Base> stride_ = 0;                           // exposition only
    range_difference_t<Base> missing_ = 0;                          // exposition only
 
    constexpr iterator(Parent* parent, iterator_t<Base> current,    // exposition only
                       range_difference_t<Base> missing = 0);
  public:
    using difference_type = range_difference_t<Base>;
    using value_type = range_value_t<Base>;
    using iterator_concept = /* see description */;
    using iterator_category = /* see description */;    // not always present
 
    iterator() requires default_initializable<iterator_t<Base>> = default;
 
    constexpr iterator(iterator<!Const> other)
      requires Const && convertible_to<iterator_t<V>, iterator_t<Base>>
                     && convertible_to<sentinel_t<V>, sentinel_t<Base>>;
 
    constexpr iterator_t<Base> base() &&;
    constexpr const iterator_t<Base>& base() const & noexcept;
 
    constexpr decltype(auto) operator*() const { return *current_; }
 
    constexpr iterator& operator++();
    constexpr void operator++(int);
    constexpr iterator operator++(int) requires forward_range<Base>;
 
    constexpr iterator& operator--() requires bidirectional_range<Base>;
    constexpr iterator operator--(int) requires bidirectional_range<Base>;
 
    constexpr iterator& operator+=(difference_type n) requires random_access_range<Base>;
    constexpr iterator& operator-=(difference_type n) requires random_access_range<Base>;
 
    constexpr decltype(auto) operator[](difference_type n) const
      requires random_access_range<Base>
    { return *(*this + n); }
 
    friend constexpr bool operator==(const iterator& x, default_sentinel_t);
 
    friend constexpr bool operator==(const iterator& x, const iterator& y)
      requires equality_comparable<iterator_t<Base>>;
 
    friend constexpr bool operator<(const iterator& x, const iterator& y)
      requires random_access_range<Base>;
 
    friend constexpr bool operator>(const iterator& x, const iterator& y)
      requires random_access_range<Base>;
 
    friend constexpr bool operator<=(const iterator& x, const iterator& y)
      requires random_access_range<Base>;
 
    friend constexpr bool operator>=(const iterator& x, const iterator& y)
      requires random_access_range<Base>;
 
    friend constexpr auto operator<=>(const iterator& x, const iterator& y)
      requires random_access_range<Base> && three_way_comparable<iterator_t<Base>>;
 
    friend constexpr iterator operator+(const iterator& x, difference_type n)
      requires random_access_range<Base>;
    friend constexpr iterator operator+(difference_type n, const iterator& x)
      requires random_access_range<Base>;
    friend constexpr iterator operator-(const iterator& x, difference_type n)
      requires random_access_range<Base>;
    friend constexpr difference_type operator-(const iterator& x, const iterator& y)
      requires sized_sentinel_for<iterator_t<Base>, iterator_t<Base>>;
 
    friend constexpr difference_type operator-(default_sentinel_t y, const iterator& x)
      requires sized_sentinel_for<sentinel_t<Base>, iterator_t<Base>>;
    friend constexpr difference_type operator-(const iterator& x, default_sentinel_t y)
      requires sized_sentinel_for<sentinel_t<Base>, iterator_t<Base>>;
 
    friend constexpr range_rvalue_reference_t<Base> iter_move(const iterator& i)
      noexcept(noexcept(ranges::iter_move(i.current_)));
 
    friend constexpr void iter_swap(const iterator& x, const iterator& y)
      noexcept(noexcept(ranges::iter_swap(x.current_, y.current_)))
      requires indirectly_swappable<iterator_t<Base>>;
  };
}

Class template std::ranges::cartesian_product_view

namespace std::ranges {
  template<bool Const, class First, class... Vs>
  concept __cartesian_product_is_random_access =          // exposition only
    (random_access_range<__maybe_const<Const, First>> && ... &&
      (random_access_range<__maybe_const<Const, Vs>>
        && sized_range<__maybe_const<Const, Vs>>));
 
  template<class R>
  concept __cartesian_product_common_arg =                // exposition only
    common_range<R> || (sized_range<R> && random_access_range<R>);
 
  template<bool Const, class First, class... Vs>
  concept __cartesian_product_is_bidirectional =          // exposition only
    (bidirectional_range<__maybe_const<Const, First>> && ... &&
      (bidirectional_range<__maybe_const<Const, Vs>>
        && __cartesian_product_common_arg<__maybe_const<Const, Vs>>));
 
  template<class First, class... Vs>
  concept __cartesian_product_is_common =                 // exposition only
    __cartesian_product_common_arg<First>;
 
  template<class... Vs>
  concept __cartesian_product_is_sized =                  // exposition only
    (sized_range<Vs> && ...);
 
  template<bool Const, template<class> class FirstSent, class First, class... Vs>
    concept __cartesian_is_sized_sentinel =               // exposition only
      (sized_sentinel_for<FirstSent<__maybe_const<Const, First>>,
          iterator_t<__maybe_const<Const, First>>> && ...
        && (sized_range<__maybe_const<Const, Vs>>
          && sized_sentinel_for<iterator_t<__maybe_const<Const, Vs>>,
              iterator_t<__maybe_const<Const, Vs>>>));
 
  template<__cartesian_product_common_arg R>
  constexpr auto __cartesian_common_arg_end(R& r) {       // exposition only
    if constexpr (common_range<R>) {
      return ranges::end(r);
    } else {
      return ranges::begin(r) + ranges::distance(r);
    }
  }
 
  template<input_range First, forward_range... Vs>
    requires (view<First> && ... && view<Vs>)
  class cartesian_product_view :
    public view_interface<cartesian_product_view<First, Vs...>> {
  private:
    tuple<First, Vs...> bases_;                 // exposition only
    // class template cartesian_product_view::iterator
    template<bool Const> class iterator;       // exposition only
  public:
    constexpr cartesian_product_view() = default;
    constexpr explicit cartesian_product_view(First first_base, Vs... bases);
 
    constexpr iterator<false> begin()
      requires (!__simple_view<First> || ... || !__simple_view<Vs>);
    constexpr iterator<true> begin() const
      requires (range<const First> && ... && range<const Vs>);
 
    constexpr iterator<false> end()
      requires ((!__simple_view<First> || ... || !__simple_view<Vs>) &&
        __cartesian_product_is_common<First, Vs...>);
    constexpr iterator<true> end() const
      requires __cartesian_product_is_common<const First, const Vs...>;
    constexpr default_sentinel_t end() const noexcept;
 
    constexpr /* see description */ size()
      requires __cartesian_product_is_sized<First, Vs...>;
    constexpr /* see description */ size() const
      requires __cartesian_product_is_sized<const First, const Vs...>;
  };
 
  template<class... Vs>
    cartesian_product_view(Vs&&...) -> cartesian_product_view<all_t<Vs>...>;
}

Class template std::ranges::cartesian_product_view::iterator

namespace std::ranges {
  template<input_range First, forward_range... Vs>
    requires (view<First> && ... && view<Vs>)
  template<bool Const>
  class cartesian_product_view<First, Vs...>::iterator {
  public:
    using iterator_category = input_iterator_tag;
    using iterator_concept  = /* see description */;
    using value_type = tuple<range_value_t<__maybe_const<Const, First>>,
      range_value_t<__maybe_const<Const, Vs>>...>;
    using reference = tuple<range_reference_t<__maybe_const<Const, First>>,
      range_reference_t<__maybe_const<Const, Vs>>...>;
    using difference_type = /* see description */;
 
    iterator() requires forward_range<__maybe_const<Const, First>> = default;
 
    constexpr iterator(iterator<!Const> i) requires Const &&
      (convertible_to<iterator_t<First>, iterator_t<const First>> &&
        ... && convertible_to<iterator_t<Vs>, iterator_t<const Vs>>);
 
    constexpr auto operator*() const;
    constexpr iterator& operator++();
    constexpr void operator++(int);
    constexpr iterator operator++(int)
      requires forward_range<__maybe_const<Const, First>>;
 
    constexpr iterator& operator--()
      requires __cartesian_product_is_bidirectional<Const, First, Vs...>;
    constexpr iterator operator--(int)
      requires __cartesian_product_is_bidirectional<Const, First, Vs...>;
 
    constexpr iterator& operator+=(difference_type x)
      requires __cartesian_product_is_random_access<Const, First, Vs...>;
    constexpr iterator& operator-=(difference_type x)
      requires __cartesian_product_is_random_access<Const, First, Vs...>;
 
    constexpr reference operator[](difference_type n) const
      requires __cartesian_product_is_random_access<Const, First, Vs...>;
 
    friend constexpr bool operator==(const iterator& x, const iterator& y)
      requires equality_comparable<iterator_t<__maybe_const<Const, First>>>;
 
    friend constexpr bool operator==(const iterator& x, default_sentinel_t);
 
    friend constexpr auto operator<=>(const iterator& x, const iterator& y)
      requires __all_random_access<Const, First, Vs...>;
 
    friend constexpr iterator operator+(const iterator& x, difference_type y)
      requires __cartesian_product_is_random_access<Const, First, Vs...>;
    friend constexpr iterator operator+(difference_type x, const iterator& y)
      requires __cartesian_product_is_random_access<Const, First, Vs...>;
    friend constexpr iterator operator-(const iterator& x, difference_type y)
      requires __cartesian_product_is_random_access<Const, First, Vs...>;
    friend constexpr difference_type operator-(const iterator& x, const iterator& y)
      requires __cartesian_is_sized_sentinel<Const, iterator_t, First, Vs...>;
 
    friend constexpr difference_type operator-(iterator i, default_sentinel_t)
      requires __cartesian_is_sized_sentinel<Const, sentinel_t, First, Vs...>;
    friend constexpr difference_type operator-(default_sentinel_t, iterator i)
      requires __cartesian_is_sized_sentinel<Const, sentinel_t, First, Vs...>;
 
    friend constexpr auto iter_move(const iterator& i) noexcept(/* see description */);
 
    friend constexpr void iter_swap(const iterator& l, const iterator& r)
        noexcept(/* see description */)
      requires (indirectly_swappable<iterator_t<__maybe_const<Const, First>>> && ... &&
        indirectly_swappable<iterator_t<__maybe_const<Const, Vs>>>);
 
  private:
    __maybe_const<Const, cartesian_product_view>* parent_ = nullptr;  // exposition only
    tuple<iterator_t<__maybe_const<Const, First>>,
      iterator_t<__maybe_const<Const, Vs>>...> current_;              // exposition only
 
    template<size_t N = sizeof...(Vs)>
      constexpr void next();                                          // exposition only
 
    template<size_t N = sizeof...(Vs)>
      constexpr void prev();                                          // exposition only
 
    template<class Tuple>
      constexpr difference_type __distance_from(Tuple t);             // exposition only
 
    constexpr explicit iterator(tuple<iterator_t<__maybe_const<Const, First>>,
      iterator_t<__maybe_const<Const, Vs>>...> current);              // exposition only
  };
}

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/header/ranges