24 Ranges library [ranges]

24.7 Range adaptors [range.adaptors]

24.7.6 Take view [range.take]

24.7.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
 ]

24.7.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
    range_difference_t<V> count_ = 0;                   // exposition only
    // [range.take.sentinel], class template take_­view​::​sentinel
    template<bool> struct sentinel;                     // exposition only
  public:
    take_view() = default;
    constexpr take_view(V base, range_difference_t<V> count);
    template<viewable_range R>
      requires constructible_from<V, all_view<R>>
    constexpr take_view(R&& r, range_difference_t<V> count);

    constexpr V base() const;

    constexpr auto begin() requires (!simple-view<V>) {
      if constexpr (sized_range<V>) {
        if constexpr (random_access_range<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 (sized_range<const V>) {
        if constexpr (random_access_range<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 (sized_range<V>) {
        if constexpr (random_access_range<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 (sized_range<const V>) {
        if constexpr (random_access_range<const V>)
          return ranges::begin(base_) + 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<range R>
    take_view(R&&, range_difference_t<R>)
      -> take_view<all_view<R>>;
}
constexpr take_view(V base, range_difference_t<V> count);
Effects: Initializes base_­ with std​::​move(base) and count_­ with count.
template<viewable_range R> requires constructible_from<V, all_view<R>> constexpr take_view(R&& r, range_difference_t<V> count);
Effects: Initializes base_­ with views​::​all(std​::​forward<R>(r)) and count_­ with count.
constexpr V base() const;
Effects: Equivalent to: return base_­;

24.7.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 && convertible_to<sentinel_t<V>, sentinel_t<Base>>;

    constexpr sentinel_t<Base> base() const;

    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 && convertible_to<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 CI& y, const sentinel& x);
Effects: Equivalent to: return y.count() == 0 || y.base() == x.end_­;

24.7.6.4 views​::​take [range.take.adaptor]

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