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_));
}
};
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.