From Jason Turner

[range.take]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmp7b75j605/{from.md → to.md} +176 -0
tmp/tmp7b75j605/{from.md → to.md} RENAMED
@@ -0,0 +1,176 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ### Take view <a id="range.take">[[range.take]]</a>
2
+
3
+ #### Overview <a id="range.take.overview">[[range.take.overview]]</a>
4
+
5
+ `take_view` produces a `view` of the first N elements from another
6
+ `view`, or all the elements if the adapted `view` contains fewer than N.
7
+
8
+ The name `views::take` denotes a range adaptor object
9
+ [[range.adaptor.object]]. Let `E` and `F` be expressions, let `T` be
10
+ `remove_cvref_t<decltype((E))>`, and let `D` be
11
+ `range_difference_t<decltype((E))>`. If `decltype((F))` does not model
12
+ `convertible_to<D>`, `views::take(E, F)` is ill-formed. Otherwise, the
13
+ expression `views::take(E, F)` is expression-equivalent to:
14
+
15
+ - If `T` is a specialization of `ranges::empty_view`
16
+ [[range.empty.view]], then `((void) F, decay-copy(E))`.
17
+ - Otherwise, if `T` models `random_access_range` and `sized_range` and
18
+ is
19
+ - a specialization of `span` [[views.span]] where
20
+ `T::extent == dynamic_extent`,
21
+ - a specialization of `basic_string_view` [[string.view]],
22
+ - a specialization of `ranges::iota_view` [[range.iota.view]], or
23
+ - a specialization of `ranges::subrange` [[range.subrange]],
24
+
25
+ then
26
+ `T{ranges::begin(E), ranges::begin(E) + min<D>(ranges::size(E), F)}`,
27
+ except that `E` is evaluated only once.
28
+ - Otherwise, `ranges::take_view{E, F}`.
29
+
30
+ [*Example 1*:
31
+
32
+ ``` cpp
33
+ vector<int> is{0,1,2,3,4,5,6,7,8,9};
34
+ take_view few{is, 5};
35
+ for (int i : few)
36
+ cout << i << ' '; // prints: 0 1 2 3 4
37
+ ```
38
+
39
+ — *end example*]
40
+
41
+ #### Class template `take_view` <a id="range.take.view">[[range.take.view]]</a>
42
+
43
+ ``` cpp
44
+ namespace std::ranges {
45
+ template<view V>
46
+ class take_view : public view_interface<take_view<V>> {
47
+ private:
48
+ V base_ = V(); // exposition only
49
+ range_difference_t<V> count_ = 0; // exposition only
50
+ // [range.take.sentinel], class template take_view::sentinel
51
+ template<bool> struct sentinel; // exposition only
52
+ public:
53
+ take_view() = default;
54
+ constexpr take_view(V base, range_difference_t<V> count);
55
+
56
+ constexpr V base() const& requires copy_constructible<V> { return base_; }
57
+ constexpr V base() && { return std::move(base_); }
58
+
59
+ constexpr auto begin() requires (!simple-view<V>) {
60
+ if constexpr (sized_range<V>) {
61
+ if constexpr (random_access_range<V>)
62
+ return ranges::begin(base_);
63
+ else {
64
+ auto sz = size();
65
+ return counted_iterator{ranges::begin(base_), sz};
66
+ }
67
+ } else
68
+ return counted_iterator{ranges::begin(base_), count_};
69
+ }
70
+
71
+ constexpr auto begin() const requires range<const V> {
72
+ if constexpr (sized_range<const V>) {
73
+ if constexpr (random_access_range<const V>)
74
+ return ranges::begin(base_);
75
+ else {
76
+ auto sz = size();
77
+ return counted_iterator{ranges::begin(base_), sz};
78
+ }
79
+ } else
80
+ return counted_iterator{ranges::begin(base_), count_};
81
+ }
82
+
83
+ constexpr auto end() requires (!simple-view<V>) {
84
+ if constexpr (sized_range<V>) {
85
+ if constexpr (random_access_range<V>)
86
+ return ranges::begin(base_) + size();
87
+ else
88
+ return default_sentinel;
89
+ } else
90
+ return sentinel<false>{ranges::end(base_)};
91
+ }
92
+
93
+ constexpr auto end() const requires range<const V> {
94
+ if constexpr (sized_range<const V>) {
95
+ if constexpr (random_access_range<const V>)
96
+ return ranges::begin(base_) + size();
97
+ else
98
+ return default_sentinel;
99
+ } else
100
+ return sentinel<true>{ranges::end(base_)};
101
+ }
102
+
103
+ constexpr auto size() requires sized_range<V> {
104
+ auto n = ranges::size(base_);
105
+ return ranges::min(n, static_cast<decltype(n)>(count_));
106
+ }
107
+
108
+ constexpr auto size() const requires sized_range<const V> {
109
+ auto n = ranges::size(base_);
110
+ return ranges::min(n, static_cast<decltype(n)>(count_));
111
+ }
112
+ };
113
+
114
+ template<range R>
115
+ take_view(R&&, range_difference_t<R>)
116
+ -> take_view<views::all_t<R>>;
117
+ }
118
+ ```
119
+
120
+ ``` cpp
121
+ constexpr take_view(V base, range_difference_t<V> count);
122
+ ```
123
+
124
+ *Effects:* Initializes *base\_* with `std::move(base)` and *count\_*
125
+ with `count`.
126
+
127
+ #### Class template `take_view::sentinel` <a id="range.take.sentinel">[[range.take.sentinel]]</a>
128
+
129
+ ``` cpp
130
+ namespace std::ranges {
131
+ template<view V>
132
+ template<bool Const>
133
+ class take_view<V>::sentinel {
134
+ private:
135
+ using Base = conditional_t<Const, const V, V>; // exposition only
136
+ using CI = counted_iterator<iterator_t<Base>>; // exposition only
137
+ sentinel_t<Base> end_ = sentinel_t<Base>(); // exposition only
138
+ public:
139
+ sentinel() = default;
140
+ constexpr explicit sentinel(sentinel_t<Base> end);
141
+ constexpr sentinel(sentinel<!Const> s)
142
+ requires Const && convertible_to<sentinel_t<V>, sentinel_t<Base>>;
143
+
144
+ constexpr sentinel_t<Base> base() const;
145
+
146
+ friend constexpr bool operator==(const CI& y, const sentinel& x);
147
+ };
148
+ }
149
+ ```
150
+
151
+ ``` cpp
152
+ constexpr explicit sentinel(sentinel_t<Base> end);
153
+ ```
154
+
155
+ *Effects:* Initializes *end\_* with `end`.
156
+
157
+ ``` cpp
158
+ constexpr sentinel(sentinel<!Const> s)
159
+ requires Const && convertible_to<sentinel_t<V>, sentinel_t<Base>>;
160
+ ```
161
+
162
+ *Effects:* Initializes *end\_* with `std::move(s.`*`end_`*`)`.
163
+
164
+ ``` cpp
165
+ constexpr sentinel_t<Base> base() const;
166
+ ```
167
+
168
+ *Effects:* Equivalent to: `return `*`end_`*`;`
169
+
170
+ ``` cpp
171
+ friend constexpr bool operator==(const CI& y, const sentinel& x);
172
+ ```
173
+
174
+ *Effects:* Equivalent to:
175
+ `return y.count() == 0 || y.base() == x.`*`end_`*`;`
176
+