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

From cppreference.com
< cpp‎ | header

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`
ranges::range (C++20) | specifies that a type is a range, that is, it provides a `begin` iterator and an `end` sentinel (concept)
ranges::borrowed_range (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)
ranges::sized_range (C++20) | specifies that a range knows its size in constant time (concept)
ranges::view (C++20) | specifies that a range is a view, that is, it has constant time copy/move/assignment (concept)
ranges::input_range (C++20) | specifies a range whose iterator type satisfies `input_iterator` (concept)
ranges::output_range (C++20) | specifies a range whose iterator type satisfies `output_iterator` (concept)
ranges::forward_range (C++20) | specifies a range whose iterator type satisfies `forward_iterator` (concept)
ranges::bidirectional_range (C++20) | specifies a range whose iterator type satisfies `bidirectional_iterator` (concept)
ranges::random_access_range (C++20) | specifies a range whose iterator type satisfies `random_access_iterator` (concept)
ranges::contiguous_range (C++20) | specifies a range whose iterator type satisfies `contiguous_iterator` (concept)
ranges::common_range (C++20) | specifies that a range has identical iterator and sentinel types (concept)
ranges::viewable_range (C++20) | specifies the requirements for a `range` to be safely convertible to a `view` (concept)
ranges::constant_range (C++23) | specifies that a range has read-only elements (concept)
### Functions
##### Range conversions
Defined in namespace `std::ranges`
ranges::to (C++23) | constructs a new non-view object from an input range (function template)
### Classes
##### Range primitives
Defined in namespace `std::ranges`
ranges::iterator_t ranges::const_iterator_t ranges::sentinel_t ranges::const_sentinel_t ranges::range_difference_t ranges::range_size_t ranges::range_value_t ranges::range_reference_t ranges::range_const_reference_t ranges::range_rvalue_reference_t ranges::range_common_reference_t (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`
ranges::view_interface (C++20) | helper class template for defining a `view`, using the curiously recurring template pattern (class template)
ranges::subrange (C++20) | combines an iterator-sentinel pair into a `view` (class template)
##### Dangling iterator handling
Defined in namespace `std::ranges`
ranges::dangling (C++20) | a placeholder type indicating that an iterator or a `subrange` should not be returned since it would be dangling (class)
ranges::borrowed_iterator_t ranges::borrowed_subrange_t (C++20) | obtains iterator type or `subrange` type of a `borrowed_range` (alias template)
##### Range adaptor objects utility
Defined in namespace `std::ranges`
ranges::range_adaptor_closure (C++23) | helper base class template for defining a range adaptor closure object (class template)
##### Factories
Defined in namespace `std::ranges`
ranges::empty_view views::empty (C++20) | an empty `view` with no elements (class template) (variable template)
ranges::single_view views::single (C++20) | a `view` that contains a single element of a specified value (class template) (customization point object)
ranges::iota_view views::iota (C++20) | a `view` consisting of a sequence generated by repeatedly incrementing an initial value (class template) (customization point object)
ranges::basic_istream_view views::istream (C++20) | a `view` consisting of the elements obtained by successive application of `operator>>` on the associated input stream (class template) (customization point object)
ranges::repeat_view views::repeat (C++23) | a `view` consisting of a generated sequence by repeatedly producing the same value (class template) (customization point object)
ranges::cartesian_product_view views::cartesian_product (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`
views::all_t views::all (C++20) | a `view` that includes all elements of a `range` (alias template) (range adaptor object)
ranges::ref_view (C++20) | a `view` of the elements of some other `range` (class template)
ranges::owning_view (C++20) | a `view` with unique ownership of some `range` (class template)
ranges::filter_view views::filter (C++20) | a `view` that consists of the elements of a `range` that satisfies a predicate (class template) (range adaptor object)
ranges::transform_view views::transform (C++20) | a `view` of a sequence that applies a transformation function to each element (class template) (range adaptor object)
ranges::take_view views::take (C++20) | a `view` consisting of the first N elements of another `view` (class template) (range adaptor object)
ranges::take_while_view views::take_while (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)
ranges::drop_view views::drop (C++20) | a `view` consisting of elements of another `view`, skipping the first N elements (class template) (range adaptor object)
ranges::drop_while_view views::drop_while (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)
ranges::join_view views::join (C++20) | a `view` consisting of the sequence obtained from flattening a `view` of `range`s (class template) (range adaptor object)
ranges::lazy_split_view views::lazy_split (C++20) | a `view` over the subranges obtained from splitting another `view` using a delimiter (class template) (range adaptor object)
ranges::split_view views::split (C++20) | a `view` over the subranges obtained from splitting another `view` using a delimiter (class template) (range adaptor object)
views::counted (C++20) | creates a subrange from an iterator and a count (customization point object)
ranges::common_view views::common (C++20) | converts a `view` into a `common_range` (class template) (range adaptor object)
ranges::reverse_view views::reverse (C++20) | a `view` that iterates over the elements of another bidirectional view in reverse order (class template) (range adaptor object)
ranges::as_const_view views::as_const (C++23) | converts a `view` into a `constant_range` (class template) (range adaptor object)
ranges::as_rvalue_view views::as_rvalue (C++23) | a `view` of a sequence that casts each element to an rvalue (class template) (range adaptor object)
ranges::elements_view views::elements (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)
ranges::keys_view views::keys (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)
ranges::values_view views::values (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)
ranges::enumerate_view views::enumerate (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)
ranges::zip_view views::zip (C++23) | a `view` consisting of tuples of references to corresponding elements of the adapted views (class template) (customization point object)
ranges::zip_transform_view views::zip_transform (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)
ranges::adjacent_view views::adjacent (C++23) | a `view` consisting of tuples of references to adjacent elements of the adapted view (class template) (range adaptor object)
ranges::adjacent_transform_view views::adjacent_transform (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)
ranges::join_with_view views::join_with (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)
ranges::stride_view views::stride (C++23) | a `view` consisting of elements of another `view`, advancing over N elements at a time (class template) (range adaptor object)
ranges::slide_view views::slide (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)
ranges::chunk_view views::chunk (C++23) | a range of `view`s that are `N`-sized non-overlapping successive chunks of the elements of another `view` (class template) (range adaptor object)
ranges::chunk_by_view views::chunk_by (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`
ranges::begin (C++20) | returns an iterator to the beginning of a range (customization point object)
ranges::end (C++20) | returns a sentinel indicating the end of a range (customization point object)
ranges::cbegin (C++20) | returns an iterator to the beginning of a read-only range (customization point object)
ranges::cend (C++20) | returns a sentinel indicating the end of a read-only range (customization point object)
ranges::rbegin (C++20) | returns a reverse iterator to a range (customization point object)
ranges::rend (C++20) | returns a reverse end iterator to a range (customization point object)
ranges::crbegin (C++20) | returns a reverse iterator to a read-only range (customization point object)
ranges::crend (C++20) | returns a reverse end iterator to a read-only range (customization point object)
ranges::size (C++20) | returns an integer equal to the size of a range (customization point object)
ranges::ssize (C++20) | returns a signed integer equal to the size of a range (customization point object)
ranges::empty (C++20) | checks whether a range is empty (customization point object)
ranges::data (C++20) | obtains a pointer to the beginning of a contiguous range (customization point object)
ranges::cdata (C++20) | obtains a pointer to the beginning of a read-only contiguous range (customization point object)
### Enumerations
Defined in namespace `std::ranges`
ranges::subrange_kind (C++20) | specifies whether a std::ranges::subrange models std::ranges::sized_range (enum)
### Helpers
std::tuple_size<std::ranges::subrange> (C++20) | obtains the number of components of a std::ranges::subrange (class template specialization)
std::tuple_element<std::ranges::subrange> (C++20) | obtains the type of the iterator or the sentinel of a std::ranges::subrange (class template specialization)
get(std::ranges::subrange) (C++20) | obtains iterator or sentinel from a std::ranges::subrange (function template)
from_range_t from_range (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_range`s

    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_range`s

    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_range`s

    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_range`s

    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_range`s

    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_range`s

    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
      };
    }

Retrieved from "https://en.cppreference.com/mwiki/index.php?title=cpp/header/ranges&oldid=154578"