23 Ranges library [ranges]

23.8 Range adaptors [range.adaptors]

23.8.6 Take view [range.take]

23.8.6.1 Overview [range.take.overview]

take_­view produces a View of the first N elements from another View, or all the elements if the adapted View contains fewer than N.
[Example
:
vector<int> is{0,1,2,3,4,5,6,7,8,9};
take_view few{is, 5};
for (int i : few)
  cout << i << ' '; // prints: 0 1 2 3 4
end example
]

23.8.6.2 Class template take_­view [range.take.view]

namespace std::ranges {
  template<View V>
  class take_view : public view_interface<take_view<V>> {
  private:
    V base_ = V();                                      // exposition only
    iter_difference_t<iterator_t<V>> count_ = 0;        // exposition only
    template<bool> struct sentinel;                     // exposition only
  public:
    take_view() = default;
    constexpr take_view(V base, iter_difference_t<iterator_t<V>> count);
    template<ViewableRange R>
      requires Constructible<V, all_view<R>>
    constexpr take_view(R&& r, iter_difference_t<iterator_t<V>> count);

    constexpr V base() const;

    constexpr auto begin() requires (!simple-view<V>) {
      if constexpr (SizedRange<V>) {
        if constexpr (RandomAccessRange<V>)
          return ranges::begin(base_);
        else
          return counted_iterator{ranges::begin(base_), size()};
      } else
        return counted_iterator{ranges::begin(base_), count_};
    }

    constexpr auto begin() const requires Range<const V> {
      if constexpr (SizedRange<const V>) {
        if constexpr (RandomAccessRange<const V>)
          return ranges::begin(base_);
        else
          return counted_iterator{ranges::begin(base_), size()};
      } else
        return counted_iterator{ranges::begin(base_), count_};
    }

    constexpr auto end() requires (!simple-view<V>) {
      if constexpr (SizedRange<V>) {
        if constexpr (RandomAccessRange<V>)
          return ranges::begin(base_) + size();
        else
          return default_sentinel;
      } else
        return sentinel<false>{ranges::end(base_)};
    }

    constexpr auto end() const requires Range<const V> {
      if constexpr (SizedRange<const V>) {
        if constexpr (RandomAccessRange<const V>)
          return ranges::begin(base_) + size();
        else
          return default_sentinel;
      } else
        return sentinel<true>{ranges::end(base_)};
    }

    constexpr auto size() requires SizedRange<V> {
      auto n = ranges::size(base_);
      return ranges::min(n, static_cast<decltype(n)>(count_));
    }

    constexpr auto size() const requires SizedRange<const V> {
      auto n = ranges::size(base_);
      return ranges::min(n, static_cast<decltype(n)>(count_));
    }
  };

  template<Range R>
    take_view(R&&, iter_difference_t<iterator_t<R>>)
      -> take_view<all_view<R>>;
}
constexpr take_view(V base, iter_difference_t<iterator_t<V>> count);
Effects: Initializes base_­ with std::move(base) and count_­ with count.
template<ViewableRange R> requires Constructible<V, all_view<R>> constexpr take_view(R&& r, iter_difference_t<iterator_t<V>> count);
Effects: Initializes base_­ with view::all(std::forward<R>(r)) and count_­ with count.
constexpr V base() const;
Effects: Equivalent to: return base_­;

23.8.6.3 Class template take_­view​::​sentinel [range.take.sentinel]

namespace std::ranges {
  template<class V>
  template<bool Const>
  class take_view<V>::sentinel {
  private:
    using Base = conditional_t<Const, const V, V>;      // exposition only
    using CI = counted_iterator<iterator_t<Base>>;      // 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 && ConvertibleTo<sentinel_t<V>, sentinel_t<Base>>;

    constexpr sentinel_t<Base> base() const;

    friend constexpr bool operator==(const sentinel& x, const CI& y);
    friend constexpr bool operator==(const CI& y, const sentinel& x);
    friend constexpr bool operator!=(const sentinel& x, const CI& y);
    friend constexpr bool operator!=(const CI& y, const sentinel& x);
  };
}
constexpr explicit sentinel(sentinel_t<Base> end);
Effects: Initializes end_­ with end.
constexpr sentinel(sentinel<!Const> s) requires Const && ConvertibleTo<sentinel_t<V>, sentinel_t<Base>>;
Effects: Initializes end_­ with std::move(s.end_­).
constexpr sentinel_t<Base> base() const;
Effects: Equivalent to: return end_­;
friend constexpr bool operator==(const sentinel& x, const CI& y); friend constexpr bool operator==(const CI& y, const sentinel& x);
Effects: Equivalent to: return y.count() == 0 || y.base() == x.end_­;
friend constexpr bool operator!=(const sentinel& x, const CI& y); friend constexpr bool operator!=(const CI& y, const sentinel& x);
Effects: Equivalent to: return !(x == y);

23.8.6.4 view​::​take [range.take.adaptor]

The name view::take denotes a range adaptor object.
For some subexpressions E and F, the expression view::take(E, F) is expression-equivalent to take_­view{E, F}.