Files
2025-10-25 03:02:53 +03:00

149 lines
9.3 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[range.drop]
# 25 Ranges library [[ranges]](./#ranges)
## 25.7 Range adaptors [[range.adaptors]](range.adaptors#range.drop)
### 25.7.12 Drop view [range.drop]
#### [25.7.12.1](#overview) Overview [[range.drop.overview]](range.drop.overview)
[1](#overview-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L6345)
drop_view produces a view
excluding the first N elements from another view, or
an empty range if the adapted view contains fewer than N elements[.](#overview-1.sentence-1)
[2](#overview-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L6350)
The name views::drop denotes
a range adaptor object ([[range.adaptor.object]](range.adaptor.object "25.7.2Range adaptor objects"))[.](#overview-2.sentence-1)
Let E and F be expressions,
let T be remove_cvref_t<decltype((E))>, and
let D be range_difference_t<decltype((E))>[.](#overview-2.sentence-2)
If decltype((F)) does not model[convertible_to](concept.convertible#concept:convertible_to "18.4.4Concept convertible_­to[concept.convertible]")<D>,views::drop(E, F) is ill-formed[.](#overview-2.sentence-3)
Otherwise, the expression views::drop(E, F) is expression-equivalent to:
- [(2.1)](#overview-2.1)
If T is a specialization ofempty_view ([[range.empty.view]](range.empty.view "25.6.2.2Class template empty_­view")),
then ((void)F, *decay-copy*(E)),
except that the evaluations of E and F are indeterminately sequenced[.](#overview-2.1.sentence-1)
- [(2.2)](#overview-2.2)
Otherwise, if T models[random_access_range](range.refinements#concept:random_access_range "25.4.6Other range refinements[range.refinements]") and [sized_range](range.sized#concept:sized_range "25.4.4Sized ranges[range.sized]") and is
* [(2.2.1)](#overview-2.2.1)
a specialization of span ([[views.span]](views.span "23.7.2.2Class template span")),
* [(2.2.2)](#overview-2.2.2)
a specialization of basic_string_view ([[string.view]](string.view "27.3String view classes")),
* [(2.2.3)](#overview-2.2.3)
a specialization of iota_view ([[range.iota.view]](range.iota.view "25.6.4.2Class template iota_­view")), or
* [(2.2.4)](#overview-2.2.4)
a specialization of subrange ([[range.subrange]](range.subrange "25.5.4Sub-ranges"))
where T::*StoreSize* is false,
then U(ranges::begin(E) + std::min<D>(ranges::distance(E), F), ranges::end(E)),
except that E is evaluated only once,
where U is span<typename T::element_type> if T is a specialization of span and T otherwise[.](#overview-2.2.sentence-1)
- [(2.3)](#overview-2.3)
Otherwise,
if T is
a specialization of subrange that models [random_access_range](range.refinements#concept:random_access_range "25.4.6Other range refinements[range.refinements]") and [sized_range](range.sized#concept:sized_range "25.4.4Sized ranges[range.sized]"),
thenT(ranges::begin(E) + std::min<D>(ranges::distance(E), F), ranges::end(E),*to-unsigned-like*(ranges::distance(E) - std::min<D>(ranges::distance(E), F))),
except that E and F are each evaluated only once[.](#overview-2.3.sentence-1)
- [(2.4)](#overview-2.4)
Otherwise, if T is
a specialization of repeat_view ([[range.repeat.view]](range.repeat.view "25.6.5.2Class template repeat_­view")):
* [(2.4.1)](#overview-2.4.1)
if T models [sized_range](range.sized#concept:sized_range "25.4.4Sized ranges[range.sized]"),
thenviews::repeat(*E.*value_*, ranges::distance(E) - std::min<D>(ranges::distance(E), F)) except that E is evaluated only once;
* [(2.4.2)](#overview-2.4.2)
otherwise, ((void)F, *decay-copy*(E)),
except that the evaluations of E and F are indeterminately sequenced[.](#overview-2.4.sentence-1)
- [(2.5)](#overview-2.5)
Otherwise, drop_view(E, F)[.](#overview-2.5.sentence-1)
[3](#overview-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L6417)
[*Example [1](#overview-example-1)*: auto ints = views::iota(0) | views::take(10);for (auto i : ints | views::drop(5)) { cout << i << ' '; // prints 5 6 7 8 9} — *end example*]
#### [25.7.12.2](#view) Class template drop_view [[range.drop.view]](range.drop.view)
[🔗](#lib:drop_view)
namespace std::ranges {template<[view](range.view#concept:view "25.4.5Views[range.view]") V>class drop_view : public view_interface<drop_view<V>> {public: drop_view() requires [default_initializable](concept.default.init#concept:default_initializable "18.4.12Concept default_­initializable[concept.default.init]")<V> = default; constexpr explicit drop_view(V base, range_difference_t<V> count); constexpr V base() const & requires [copy_constructible](concept.copyconstructible#concept:copy_constructible "18.4.14Concept copy_­constructible[concept.copyconstructible]")<V> { return *base_*; }constexpr V base() && { return std::move(*base_*); }constexpr auto begin()requires (!([*simple-view*](range.utility.helpers#concept:simple-view "25.5.2Helper concepts[range.utility.helpers]")<V> &&[random_access_range](range.refinements#concept:random_access_range "25.4.6Other range refinements[range.refinements]")<const V> && [sized_range](range.sized#concept:sized_range "25.4.4Sized ranges[range.sized]")<const V>)); constexpr auto begin() constrequires [random_access_range](range.refinements#concept:random_access_range "25.4.6Other range refinements[range.refinements]")<const V> && [sized_range](range.sized#concept:sized_range "25.4.4Sized ranges[range.sized]")<const V>; constexpr auto end() requires (![*simple-view*](range.utility.helpers#concept:simple-view "25.5.2Helper concepts[range.utility.helpers]")<V>){ return ranges::end(*base_*); }constexpr auto end() const requires [range](range.range#concept:range "25.4.2Ranges[range.range]")<const V>{ return ranges::end(*base_*); }constexpr auto size() requires [sized_range](range.sized#concept:sized_range "25.4.4Sized ranges[range.sized]")<V> {const auto s = ranges::size(*base_*); const auto c = static_cast<decltype(s)>(*count_*); return s < c ? 0 : s - c; }constexpr auto size() const requires [sized_range](range.sized#concept:sized_range "25.4.4Sized ranges[range.sized]")<const V> {const auto s = ranges::size(*base_*); const auto c = static_cast<decltype(s)>(*count_*); return s < c ? 0 : s - c; }constexpr auto reserve_hint() requires [approximately_sized_range](range.approximately.sized#concept:approximately_sized_range "25.4.3Approximately sized ranges[range.approximately.sized]")<V> {const auto s = static_cast<range_difference_t<V>>(ranges::reserve_hint(*base_*)); return *to-unsigned-like*(s < *count_* ? 0 : s - *count_*); }constexpr auto reserve_hint() const requires [approximately_sized_range](range.approximately.sized#concept:approximately_sized_range "25.4.3Approximately sized ranges[range.approximately.sized]")<const V> {const auto s = static_cast<range_difference_t<const V>>(ranges::reserve_hint(*base_*)); return *to-unsigned-like*(s < *count_* ? 0 : s - *count_*); }private: V *base_* = V(); // *exposition only* range_difference_t<V> *count_* = 0; // *exposition only*}; template<class R> drop_view(R&&, range_difference_t<R>) -> drop_view<views::all_t<R>>;}
[🔗](#lib:drop_view,constructor)
`constexpr explicit drop_view(V base, range_difference_t<V> count);
`
[1](#view-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L6494)
*Preconditions*: count >= 0 is true[.](#view-1.sentence-1)
[2](#view-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L6498)
*Effects*: Initializes *base_* with std::move(base) and*count_* with count[.](#view-2.sentence-1)
[🔗](#lib:begin,drop_view)
`constexpr auto begin()
requires (!([simple-view](range.utility.helpers#concept:simple-view "25.5.2Helper concepts[range.utility.helpers]")<V> &&
[random_access_range](range.refinements#concept:random_access_range "25.4.6Other range refinements[range.refinements]")<const V> && [sized_range](range.sized#concept:sized_range "25.4.4Sized ranges[range.sized]")<const V>));
constexpr auto begin() const
requires [random_access_range](range.refinements#concept:random_access_range "25.4.6Other range refinements[range.refinements]")<const V> && [sized_range](range.sized#concept:sized_range "25.4.4Sized ranges[range.sized]")<const V>;
`
[3](#view-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L6514)
*Returns*: ranges::next(ranges::begin(*base_*), *count_*, ranges::end(*base_*))[.](#view-3.sentence-1)
[4](#view-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L6518)
*Remarks*: In order to provide the amortized constant-time complexity required
by the [range](range.range#concept:range "25.4.2Ranges[range.range]") concept
when drop_view models [forward_range](range.refinements#concept:forward_range "25.4.6Other range refinements[range.refinements]"),
the first overload caches the result within the drop_view for use on subsequent calls[.](#view-4.sentence-1)
[*Note [1](#view-note-1)*:
Without this,
applying a reverse_view over a drop_view would have quadratic iteration complexity[.](#view-4.sentence-2)
— *end note*]