24 Ranges library [ranges]

24.2 Header <ranges> synopsis [ranges.syn]

#include <initializer_list>
#include <iterator>

namespace std::ranges {
  inline namespace unspecified {
    // [range.access], range access
    inline constexpr unspecified begin = unspecified;
    inline constexpr unspecified end = unspecified;
    inline constexpr unspecified cbegin = unspecified;
    inline constexpr unspecified cend = unspecified;
    inline constexpr unspecified rbegin = unspecified;
    inline constexpr unspecified rend = unspecified;
    inline constexpr unspecified crbegin = unspecified;
    inline constexpr unspecified crend = unspecified;

    inline constexpr unspecified size = unspecified;
    inline constexpr unspecified empty = unspecified;
    inline constexpr unspecified data = unspecified;
    inline constexpr unspecified cdata = unspecified;
  }

  // [range.range], ranges
  template<class T>
    using iterator_t = decltype(ranges::begin(declval<T&>()));

  template<class T>
    using sentinel_t = decltype(ranges::end(declval<T&>()));

  template<class T>
    concept Range = see below;

  // [range.sized], sized ranges
  template<class>
    inline constexpr bool disable_sized_range = false;

  template<class T>
    concept SizedRange = see below;

  // [range.view], views
  template<class T>
    inline constexpr bool enable_view = see below;

  struct view_base { };

  template<class T>
    concept View = see below;

  // [range.refinements], other range refinements
  template<class R, class T>
    concept OutputRange = see below;

  template<class T>
    concept InputRange = see below;

  template<class T>
    concept ForwardRange = see below;

  template<class T>
    concept BidirectionalRange = see below;

  template<class T>
    concept RandomAccessRange = see below;

  template<class T>
    concept ContiguousRange = see below;

  template<class T>
    concept CommonRange = see below;

  template<class T>
    concept ViewableRange = see below;

  // [view.interface], class template view_­interface
  template<class D>
    requires is_class_v<D> && Same<D, remove_cv_t<D>>
  class view_interface;

  // [range.subrange], sub-ranges
  enum class subrange_kind : bool { unsized, sized };

  template<Iterator I, Sentinel<I> S = I, subrange_kind K = see below>
    requires (K == subrange_kind::sized || !SizedSentinel<S, I>)
  class subrange;

  // [range.dangling], dangling iterator handling
  struct dangling;

  template<Range R>
    using safe_iterator_t = conditional_t<forwarding-range<R>, iterator_t<R>, dangling>;

  template<Range R>
    using safe_subrange_t =
      conditional_t<forwarding-range<R>, subrange<iterator_t<R>>, dangling>;

  // [range.empty], empty view
  template<class T>
    requires is_object_v<T>
  class empty_view;

  namespace view {
    template<class T>
      inline constexpr empty_view<T> empty{};
  }

  // [range.single], single view
  template<CopyConstructible T>
    requires is_object_v<T>
  class single_view;

  namespace view { inline constexpr unspecified single = unspecified; }

  // [range.iota], iota view
  template<WeaklyIncrementable W, Semiregular Bound = unreachable_sentinel_t>
    requires weakly-equality-comparable-with<W, Bound>
  class iota_view;

  namespace view { inline constexpr unspecified iota = unspecified; }

  // [range.all], all view
  namespace view { inline constexpr unspecified all = unspecified; }

  template<ViewableRange R>
    using all_view = decltype(view::all(declval<R>()));

  template<Range R>
    requires is_object_v<R>
  class ref_view;

  // [range.filter], filter view
  template<InputRange V, IndirectUnaryPredicate<iterator_t<V>> Pred>
    requires View<V> && is_object_v<Pred>
  class filter_view;

  namespace view { inline constexpr unspecified filter = unspecified; }

  // [range.transform], transform view
  template<InputRange V, CopyConstructible F>
    requires View<V> && is_object_v<F> &&
             RegularInvocable<F&, iter_reference_t<iterator_t<V>>>
  class transform_view;

  namespace view { inline constexpr unspecified transform = unspecified; }

  // [range.take], take view
  template<View> class take_view;

  namespace view { inline constexpr unspecified take = unspecified; }

  // [range.join], join view
  template<InputRange V>
    requires View<V> && InputRange<iter_reference_t<iterator_t<V>>> &&
             (is_reference_v<iter_reference_t<iterator_t<V>>> ||
              View<iter_value_t<iterator_t<V>>>)
  class join_view;

  namespace view { inline constexpr unspecified join = unspecified; }

  // [range.split], split view
  template<class R>
    concept tiny-range = see below;   // exposition only

  template<InputRange V, ForwardRange Pattern>
    requires View<V> && View<Pattern> &&
             IndirectlyComparable<iterator_t<V>, iterator_t<Pattern>, ranges::equal_to> &&
             (ForwardRange<V> || tiny-range<Pattern>)
  class split_view;

  namespace view { inline constexpr unspecified split = unspecified; }

  // [range.counted], counted view
  namespace view { inline constexpr unspecified counted = unspecified; }

  // [range.common], common view
  template<View V>
    requires (!CommonRange<V>)
  class common_view;

  namespace view { inline constexpr unspecified common = unspecified; }

  // [range.reverse], reverse view
  template<View V>
    requires BidirectionalRange<V>
  class reverse_view;

  namespace view { inline constexpr unspecified reverse = unspecified; }
}

namespace std {
  namespace view = ranges::view;

  template<class I, class S, ranges::subrange_kind K>
  struct tuple_size<ranges::subrange<I, S, K>>
    : integral_constant<size_t, 2> {};
  template<class I, class S, ranges::subrange_kind K>
  struct tuple_element<0, ranges::subrange<I, S, K>> {
    using type = I;
  };
  template<class I, class S, ranges::subrange_kind K>
  struct tuple_element<1, ranges::subrange<I, S, K>> {
    using type = S;
  };
}