[range.take] (original) (raw)

25 Ranges library [ranges]

25.7 Range adaptors [range.adaptors]

25.7.10 Take view [range.take]

25.7.10.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.

Let E and F be expressions, let T be remove_cvref_t<decltype((E))>, and let D be range_difference_t<decltype((E))>.

If decltype((F)) does not modelconvertible_to<D>,views​::​take(E, F) is ill-formed.

Otherwise, the expression views​::​take(E, F)is expression-equivalent to:

[Example 1: vector<int> is{0,1,2,3,4,5,6,7,8,9};for (int i : is | views::take(5)) cout << i << ' '; — _end example_]

25.7.10.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(); range_difference_t<V> count_ = 0; template<bool> class sentinel; 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 if constexpr (sized_sentinel_for<sentinel_t<V>, iterator_t<V>>) { auto it = ranges::begin(base_);auto sz = std::min(count_, ranges::end(base_) - it);return counted_iterator(std::move(it), 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 if constexpr (sized_sentinel_for<sentinel_t<const V>, iterator_t<const V>>) { auto it = ranges::begin(base_);auto sz = std::min(count_, ranges::end(base_) - it);return counted_iterator(std::move(it), 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 if constexpr (sized_sentinel_for<sentinel_t<V>, iterator_t<V>>) { 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 if constexpr (sized_sentinel_for<sentinel_t<const V>, iterator_t<const V>>) { 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_));} constexpr auto reserve_hint() { if constexpr (approximately_sized_range<V>) { auto n = static_cast<range_difference_t<V>>(ranges::reserve_hint(base_));return to-unsigned-like(ranges::min(n, count_));} return to-unsigned-like(count_);} constexpr auto reserve_hint() const { if constexpr (approximately_sized_range<const V>) { auto n = static_cast<range_difference_t<const V>>(ranges::reserve_hint(base_));return to-unsigned-like(ranges::min(n, count_));} return to-unsigned-like(count_);} };template<class R> take_view(R&&, range_difference_t<R>) -> take_view<views::all_t<R>>;}

constexpr explicit take_view(V base, range_difference_t<V> count);

Preconditions: count >= 0 is true.

Effects: Initializes base_ with std​::​move(base) and_count__ with count.

25.7.10.3 Class template take_view​::​sentinel [range.take.sentinel]

namespace std::ranges { template<view V> template<bool Const> class take_view<V>::sentinel { private: using Base = maybe-const<Const, V>; template<bool OtherConst> using CI = counted_iterator<iterator_t<_maybe-const_<OtherConst, V>>>; sentinel_t<_Base_> end_ = sentinel_t<_Base_>(); 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);};}

constexpr explicit _sentinel_(sentinel_t<_Base_> end);

Effects: Initializes end_ with end.

constexpr _sentinel_(_sentinel_<!Const> s) requires Const && [convertible_to](concept.convertible#concept:convertible%5Fto "18.4.4 Concept convertible_­to [concept.convertible]")<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_<Const>& y, const _sentinel_& x);template<bool OtherConst = !Const> requires [sentinel_for](iterator.concept.sentinel#concept:sentinel%5Ffor "24.3.4.7 Concept sentinel_­for [iterator.concept.sentinel]")<sentinel_t<_Base_>, iterator_t<_maybe-const_<OtherConst, V>>> friend constexpr bool operator==(const _CI_<OtherConst>& y, const _sentinel_& x);

Effects: Equivalent to:return y.count() == 0 || y.base() == x.end_;