From Jason Turner

[range.filter]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmp7e0s7l8u/{from.md → to.md} +304 -0
tmp/tmp7e0s7l8u/{from.md → to.md} RENAMED
@@ -0,0 +1,304 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ### Filter view <a id="range.filter">[[range.filter]]</a>
2
+
3
+ #### Overview <a id="range.filter.overview">[[range.filter.overview]]</a>
4
+
5
+ `filter_view` presents a `view` of the elements of an underlying
6
+ sequence that satisfy a predicate.
7
+
8
+ The name `views::filter` denotes a range adaptor object
9
+ [[range.adaptor.object]]. Given subexpressions `E` and `P`, the
10
+ expression `views::filter(E, P)` is expression-equivalent to
11
+ `filter_view{E, P}`.
12
+
13
+ [*Example 1*:
14
+
15
+ ``` cpp
16
+ vector<int> is{ 0, 1, 2, 3, 4, 5, 6 };
17
+ filter_view evens{is, [](int i) { return 0 == i % 2; }};
18
+ for (int i : evens)
19
+ cout << i << ' '; // prints: 0 2 4 6
20
+ ```
21
+
22
+ — *end example*]
23
+
24
+ #### Class template `filter_view` <a id="range.filter.view">[[range.filter.view]]</a>
25
+
26
+ ``` cpp
27
+ namespace std::ranges {
28
+ template<input_range V, indirect_unary_predicate<iterator_t<V>> Pred>
29
+ requires view<V> && is_object_v<Pred>
30
+ class filter_view : public view_interface<filter_view<V, Pred>> {
31
+ private:
32
+ V base_ = V(); // exposition only
33
+ semiregular-box<Pred> pred_; // exposition only
34
+
35
+ // [range.filter.iterator], class filter_view::iterator
36
+ class iterator; // exposition only
37
+ // [range.filter.sentinel], class filter_view::sentinel
38
+ class sentinel; // exposition only
39
+
40
+ public:
41
+ filter_view() = default;
42
+ constexpr filter_view(V base, Pred pred);
43
+
44
+ constexpr V base() const& requires copy_constructible<V> { return base_; }
45
+ constexpr V base() && { return std::move(base_); }
46
+
47
+ constexpr const Pred& pred() const;
48
+
49
+ constexpr iterator begin();
50
+ constexpr auto end() {
51
+ if constexpr (common_range<V>)
52
+ return iterator{*this, ranges::end(base_)};
53
+ else
54
+ return sentinel{*this};
55
+ }
56
+ };
57
+
58
+ template<class R, class Pred>
59
+ filter_view(R&&, Pred) -> filter_view<views::all_t<R>, Pred>;
60
+ }
61
+ ```
62
+
63
+ ``` cpp
64
+ constexpr filter_view(V base, Pred pred);
65
+ ```
66
+
67
+ *Effects:* Initializes *base\_* with `std::move(base)` and initializes
68
+ *pred\_* with `std::move(pred)`.
69
+
70
+ ``` cpp
71
+ constexpr const Pred& pred() const;
72
+ ```
73
+
74
+ *Effects:* Equivalent to: `return *`*`pred_`*`;`
75
+
76
+ ``` cpp
77
+ constexpr iterator begin();
78
+ ```
79
+
80
+ *Preconditions:* `pred_.has_value()`.
81
+
82
+ *Returns:* `{*this, ranges::find_if(`*`base_`*`, ref(*`*`pred_`*`))}`.
83
+
84
+ *Remarks:* In order to provide the amortized constant time complexity
85
+ required by the `range` concept when `filter_view` models
86
+ `forward_range`, this function caches the result within the
87
+ `filter_view` for use on subsequent calls.
88
+
89
+ #### Class `filter_view::iterator` <a id="range.filter.iterator">[[range.filter.iterator]]</a>
90
+
91
+ ``` cpp
92
+ namespace std::ranges {
93
+ template<input_range V, indirect_unary_predicate<iterator_t<V>> Pred>
94
+ requires view<V> && is_object_v<Pred>
95
+ class filter_view<V, Pred>::iterator {
96
+ private:
97
+ iterator_t<V> current_ = iterator_t<V>(); // exposition only
98
+ filter_view* parent_ = nullptr; // exposition only
99
+ public:
100
+ using iterator_concept = see below;
101
+ using iterator_category = see below;
102
+ using value_type = range_value_t<V>;
103
+ using difference_type = range_difference_t<V>;
104
+
105
+ iterator() = default;
106
+ constexpr iterator(filter_view& parent, iterator_t<V> current);
107
+
108
+ constexpr iterator_t<V> base() const &
109
+ requires copyable<iterator_t<V>>;
110
+ constexpr iterator_t<V> base() &&;
111
+ constexpr range_reference_t<V> operator*() const;
112
+ constexpr iterator_t<V> operator->() const
113
+ requires has-arrow<iterator_t<V>> && copyable<iterator_t<V>>;
114
+
115
+ constexpr iterator& operator++();
116
+ constexpr void operator++(int);
117
+ constexpr iterator operator++(int) requires forward_range<V>;
118
+
119
+ constexpr iterator& operator--() requires bidirectional_range<V>;
120
+ constexpr iterator operator--(int) requires bidirectional_range<V>;
121
+
122
+ friend constexpr bool operator==(const iterator& x, const iterator& y)
123
+ requires equality_comparable<iterator_t<V>>;
124
+
125
+ friend constexpr range_rvalue_reference_t<V> iter_move(const iterator& i)
126
+ noexcept(noexcept(ranges::iter_move(i.current_)));
127
+ friend constexpr void iter_swap(const iterator& x, const iterator& y)
128
+ noexcept(noexcept(ranges::iter_swap(x.current_, y.current_)))
129
+ requires indirectly_swappable<iterator_t<V>>;
130
+ };
131
+ }
132
+ ```
133
+
134
+ Modification of the element a `filter_view::iterator` denotes is
135
+ permitted, but results in undefined behavior if the resulting value does
136
+ not satisfy the filter predicate.
137
+
138
+ `iterator::iterator_concept` is defined as follows:
139
+
140
+ - If `V` models `bidirectional_range`, then `iterator_concept` denotes
141
+ `bidirectional_iterator_tag`.
142
+ - Otherwise, if `V` models `forward_range`, then `iterator_concept`
143
+ denotes `forward_iterator_tag`.
144
+ - Otherwise, `iterator_concept` denotes `input_iterator_tag`.
145
+
146
+ `iterator::iterator_category` is defined as follows:
147
+
148
+ - Let `C` denote the type
149
+ `iterator_traits<iterator_t<V>>::iterator_category`.
150
+ - If `C` models `derived_from<bidirectional_iterator_tag>`, then
151
+ `iterator_category` denotes `bidirectional_iterator_tag`.
152
+ - Otherwise, if `C` models `derived_from<forward_iterator_tag>`, then
153
+ `iterator_category` denotes `forward_iterator_tag`.
154
+ - Otherwise, `iterator_category` denotes `C`.
155
+
156
+ ``` cpp
157
+ constexpr iterator(filter_view& parent, iterator_t<V> current);
158
+ ```
159
+
160
+ *Effects:* Initializes *current\_* with `std::move(current)` and
161
+ *parent\_* with `addressof(parent)`.
162
+
163
+ ``` cpp
164
+ constexpr iterator_t<V> base() const &
165
+ requires copyable<iterator_t<V>>;
166
+ ```
167
+
168
+ *Effects:* Equivalent to: `return `*`current_`*`;`
169
+
170
+ ``` cpp
171
+ constexpr iterator_t<V> base() &&;
172
+ ```
173
+
174
+ *Effects:* Equivalent to: `return std::move(current_);`
175
+
176
+ ``` cpp
177
+ constexpr range_reference_t<V> operator*() const;
178
+ ```
179
+
180
+ *Effects:* Equivalent to: `return *`*`current_`*`;`
181
+
182
+ ``` cpp
183
+ constexpr iterator_t<V> operator->() const
184
+ requires has-arrow<iterator_t<V>> && copyable<iterator_t<V>>;
185
+ ```
186
+
187
+ *Effects:* Equivalent to: `return `*`current_`*`;`
188
+
189
+ ``` cpp
190
+ constexpr iterator& operator++();
191
+ ```
192
+
193
+ *Effects:* Equivalent to:
194
+
195
+ ``` cpp
196
+ current_ = ranges::find_if(std::move(++current_), ranges::end(parent_->base_),
197
+ ref(*parent_->pred_));
198
+ return *this;
199
+ ```
200
+
201
+ ``` cpp
202
+ constexpr void operator++(int);
203
+ ```
204
+
205
+ *Effects:* Equivalent to `++*this`.
206
+
207
+ ``` cpp
208
+ constexpr iterator operator++(int) requires forward_range<V>;
209
+ ```
210
+
211
+ *Effects:* Equivalent to:
212
+
213
+ ``` cpp
214
+ auto tmp = *this;
215
+ ++*this;
216
+ return tmp;
217
+ ```
218
+
219
+ ``` cpp
220
+ constexpr iterator& operator--() requires bidirectional_range<V>;
221
+ ```
222
+
223
+ *Effects:* Equivalent to:
224
+
225
+ ``` cpp
226
+ do
227
+ --current_;
228
+ while (!invoke(*parent_->pred_, *current_));
229
+ return *this;
230
+ ```
231
+
232
+ ``` cpp
233
+ constexpr iterator operator--(int) requires bidirectional_range<V>;
234
+ ```
235
+
236
+ *Effects:* Equivalent to:
237
+
238
+ ``` cpp
239
+ auto tmp = *this;
240
+ --*this;
241
+ return tmp;
242
+ ```
243
+
244
+ ``` cpp
245
+ friend constexpr bool operator==(const iterator& x, const iterator& y)
246
+ requires equality_comparable<iterator_t<V>>;
247
+ ```
248
+
249
+ *Effects:* Equivalent to: `return x.`*`current_`*` == y.`*`current_`*`;`
250
+
251
+ ``` cpp
252
+ friend constexpr range_rvalue_reference_t<V> iter_move(const iterator& i)
253
+ noexcept(noexcept(ranges::iter_move(i.current_)));
254
+ ```
255
+
256
+ *Effects:* Equivalent to: `return ranges::iter_move(i.`*`current_`*`);`
257
+
258
+ ``` cpp
259
+ friend constexpr void iter_swap(const iterator& x, const iterator& y)
260
+ noexcept(noexcept(ranges::iter_swap(x.current_, y.current_)))
261
+ requires indirectly_swappable<iterator_t<V>>;
262
+ ```
263
+
264
+ *Effects:* Equivalent to
265
+ `ranges::iter_swap(x.`*`current_`*`, y.`*`current_`*`)`.
266
+
267
+ #### Class `filter_view::sentinel` <a id="range.filter.sentinel">[[range.filter.sentinel]]</a>
268
+
269
+ ``` cpp
270
+ namespace std::ranges {
271
+ template<input_range V, indirect_unary_predicate<iterator_t<V>> Pred>
272
+ requires view<V> && is_object_v<Pred>
273
+ class filter_view<V, Pred>::sentinel {
274
+ private:
275
+ sentinel_t<V> end_ = sentinel_t<V>(); // exposition only
276
+ public:
277
+ sentinel() = default;
278
+ constexpr explicit sentinel(filter_view& parent);
279
+
280
+ constexpr sentinel_t<V> base() const;
281
+
282
+ friend constexpr bool operator==(const iterator& x, const sentinel& y);
283
+ };
284
+ }
285
+ ```
286
+
287
+ ``` cpp
288
+ constexpr explicit sentinel(filter_view& parent);
289
+ ```
290
+
291
+ *Effects:* Initializes *end\_* with `ranges::end(parent.`*`base_`*`)`.
292
+
293
+ ``` cpp
294
+ constexpr sentinel_t<V> base() const;
295
+ ```
296
+
297
+ *Effects:* Equivalent to: `return `*`end_`*`;`
298
+
299
+ ``` cpp
300
+ friend constexpr bool operator==(const iterator& x, const sentinel& y);
301
+ ```
302
+
303
+ *Effects:* Equivalent to: `return x.`*`current_`*` == y.`*`end_`*`;`
304
+