24 Ranges library [ranges]

24.7 Range adaptors [range.adaptors]

24.7.15 Elements view [range.elements]

24.7.15.2 Class template elements_­view [range.elements.view]

namespace std::ranges {
  template<class T, size_t N>
  concept has-tuple-element =                   // exposition only
    requires(T t) {
      typename tuple_size<T>::type;
      requires N < tuple_size_v<T>;
      typename tuple_element_t<N, T>;
      { get<N>(t) } -> const 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>
  class elements_view : public view_interface<elements_view<V, N>> {
  public:
    elements_view() = 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 simple-view<V>
    { return iterator<true>(ranges::begin(base_)); }

    constexpr auto end() requires (!simple-view<V>)
    { return ranges::end(base_); }

    constexpr auto end() const requires simple-view<V>
    { return 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:
    template<bool> struct iterator;                     // exposition only
    V base_ = V();                                      // exposition only
  };
}
constexpr explicit elements_view(V base);
Effects: Initializes base_­ with std​::​move(base).