From Jason Turner

[range.chunk.by]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpxesjn9d8/{from.md → to.md} +255 -0
tmp/tmpxesjn9d8/{from.md → to.md} RENAMED
@@ -0,0 +1,255 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ### Chunk by view <a id="range.chunk.by">[[range.chunk.by]]</a>
2
+
3
+ #### Overview <a id="range.chunk.by.overview">[[range.chunk.by.overview]]</a>
4
+
5
+ `chunk_by_view` takes a view and a predicate, and splits the view into
6
+ `subrange`s between each pair of adjacent elements for which the
7
+ predicate returns `false`.
8
+
9
+ The name `views::chunk_by` denotes a range adaptor object
10
+ [[range.adaptor.object]]. Given subexpressions `E` and `F`, the
11
+ expression `views::chunk_by(E, F)` is expression-equivalent to
12
+ `chunk_by_view(E, F)`.
13
+
14
+ [*Example 1*:
15
+
16
+ ``` cpp
17
+ vector v = {1, 2, 2, 3, 0, 4, 5, 2};
18
+
19
+ for (auto r : v | views::chunk_by(ranges::less_equal{})) {
20
+ cout << '[';
21
+ auto sep = "";
22
+ for (auto i : r) {
23
+ cout << sep << i;
24
+ sep = ", ";
25
+ }
26
+ cout << "] ";
27
+ }
28
+ // The above prints [1, 2, 2, 3] [0, 4, 5] [2]
29
+ ```
30
+
31
+ — *end example*]
32
+
33
+ #### Class template `chunk_by_view` <a id="range.chunk.by.view">[[range.chunk.by.view]]</a>
34
+
35
+ ``` cpp
36
+ namespace std::ranges {
37
+ template<forward_range V, indirect_binary_predicate<iterator_t<V>, iterator_t<V>> Pred>
38
+ requires view<V> && is_object_v<Pred>
39
+ class chunk_by_view : public view_interface<chunk_by_view<V, Pred>> {
40
+ V base_ = V(); // exposition only
41
+ movable-box<Pred> pred_; // exposition only
42
+
43
+ // [range.chunk.by.iter], class chunk_by_view::iterator
44
+ class iterator; // exposition only
45
+
46
+ public:
47
+ chunk_by_view() requires default_initializable<V> && default_initializable<Pred> = default;
48
+ constexpr explicit chunk_by_view(V base, Pred pred);
49
+
50
+ constexpr V base() const & requires copy_constructible<V> { return base_; }
51
+ constexpr V base() && { return std::move(base_); }
52
+
53
+ constexpr const Pred& pred() const;
54
+
55
+ constexpr iterator begin();
56
+ constexpr auto end();
57
+
58
+ constexpr iterator_t<V> find-next(iterator_t<V>); // exposition only
59
+ constexpr iterator_t<V> find-prev(iterator_t<V>) // exposition only
60
+ requires bidirectional_range<V>;
61
+ };
62
+
63
+ template<class R, class Pred>
64
+ chunk_by_view(R&&, Pred) -> chunk_by_view<views::all_t<R>, Pred>;
65
+ }
66
+ ```
67
+
68
+ ``` cpp
69
+ constexpr explicit chunk_by_view(V base, Pred pred);
70
+ ```
71
+
72
+ *Effects:* Initializes *base\_* with `std::move(base)` and *pred\_* with
73
+ `std::move(pred)`.
74
+
75
+ ``` cpp
76
+ constexpr const Pred& pred() const;
77
+ ```
78
+
79
+ *Effects:* Equivalent to: `return *`*`pred_`*`;`
80
+
81
+ ``` cpp
82
+ constexpr iterator begin();
83
+ ```
84
+
85
+ *Preconditions:* *`pred_`*`.has_value()` is `true`.
86
+
87
+ *Returns:*
88
+ *`iterator`*`(*this, ranges::begin(`*`base_`*`), `*`find-next`*`(ranges::begin(`*`base_`*`)))`.
89
+
90
+ *Remarks:* In order to provide the amortized constant-time complexity
91
+ required by the `range` concept, this function caches the result within
92
+ the `chunk_by_view` for use on subsequent calls.
93
+
94
+ ``` cpp
95
+ constexpr auto end();
96
+ ```
97
+
98
+ *Effects:* Equivalent to:
99
+
100
+ ``` cpp
101
+ if constexpr (common_range<V>) {
102
+ return iterator(*this, ranges::end(base_), ranges::end(base_));
103
+ } else {
104
+ return default_sentinel;
105
+ }
106
+ ```
107
+
108
+ ``` cpp
109
+ constexpr iterator_t<V> find-next(iterator_t<V> current);
110
+ ```
111
+
112
+ *Preconditions:* *`pred_`*`.has_value()` is `true`.
113
+
114
+ *Returns:*
115
+
116
+ ``` cpp
117
+ ranges::next(ranges::adjacent_find(current, ranges::end(base_), not_fn(ref(*pred_))),
118
+ 1, ranges::end(base_))
119
+ ```
120
+
121
+ ``` cpp
122
+ constexpr iterator_t<V> find-prev(iterator_t<V> current) requires bidirectional_range<V>;
123
+ ```
124
+
125
+ *Preconditions:*
126
+
127
+ - `current` is not equal to `ranges::begin(`*`base_`*`)`.
128
+ - *`pred_`*`.has_value()` is `true`.
129
+
130
+ *Returns:* An iterator `i` in the range \[`ranges::begin(`*`base_`*`)`,
131
+ `current`) such that:
132
+
133
+ - `ranges::adjacent_find(i, current, not_fn(ref(*`*`pred_`*`)))` is
134
+ equal to `current`; and
135
+ - if `i` is not equal to `ranges::begin(`*`base_`*`)`, then
136
+ `bool(invoke(*`*`pred_`*`, *ranges::prev(i), *i))` is `false`.
137
+
138
+ #### Class `chunk_by_view::iterator` <a id="range.chunk.by.iter">[[range.chunk.by.iter]]</a>
139
+
140
+ ``` cpp
141
+ namespace std::ranges {
142
+ template<forward_range V, indirect_binary_predicate<iterator_t<V>, iterator_t<V>> Pred>
143
+ requires view<V> && is_object_v<Pred>
144
+ class chunk_by_view<V, Pred>::iterator {
145
+ chunk_by_view* parent_ = nullptr; // exposition only
146
+ iterator_t<V> current_ = iterator_t<V>(); // exposition only
147
+ iterator_t<V> next_ = iterator_t<V>(); // exposition only
148
+
149
+ constexpr iterator(chunk_by_view& parent, iterator_t<V> current, // exposition only
150
+ iterator_t<V> next);
151
+
152
+ public:
153
+ using value_type = subrange<iterator_t<V>>;
154
+ using difference_type = range_difference_t<V>;
155
+ using iterator_category = input_iterator_tag;
156
+ using iterator_concept = see below;
157
+
158
+ iterator() = default;
159
+
160
+ constexpr value_type operator*() const;
161
+ constexpr iterator& operator++();
162
+ constexpr iterator operator++(int);
163
+
164
+ constexpr iterator& operator--() requires bidirectional_range<V>;
165
+ constexpr iterator operator--(int) requires bidirectional_range<V>;
166
+
167
+ friend constexpr bool operator==(const iterator& x, const iterator& y);
168
+ friend constexpr bool operator==(const iterator& x, default_sentinel_t);
169
+ };
170
+ }
171
+ ```
172
+
173
+ `iterator::iterator_concept` is defined as follows:
174
+
175
+ - If `V` models `bidirectional_range`, then `iterator_concept` denotes
176
+ `bidirectional_iterator_tag`.
177
+ - Otherwise, `iterator_concept` denotes `forward_iterator_tag`.
178
+
179
+ ``` cpp
180
+ constexpr iterator(chunk_by_view& parent, iterator_t<V> current, iterator_t<V> next);
181
+ ```
182
+
183
+ *Effects:* Initializes *parent\_* with `addressof(parent)`, *current\_*
184
+ with `current`, and *next\_* with `next`.
185
+
186
+ ``` cpp
187
+ constexpr value_type operator*() const;
188
+ ```
189
+
190
+ *Preconditions:* *current\_* is not equal to *next\_*.
191
+
192
+ *Returns:* `subrange(`*`current_`*`, `*`next_`*`)`.
193
+
194
+ ``` cpp
195
+ constexpr iterator& operator++();
196
+ ```
197
+
198
+ *Preconditions:* *current\_* is not equal to *next\_*.
199
+
200
+ *Effects:* Equivalent to:
201
+
202
+ ``` cpp
203
+ current_ = next_;
204
+ next_ = parent_->find-next(current_);
205
+ return *this;
206
+ ```
207
+
208
+ ``` cpp
209
+ constexpr iterator operator++(int);
210
+ ```
211
+
212
+ *Effects:* Equivalent to:
213
+
214
+ ``` cpp
215
+ auto tmp = *this;
216
+ ++*this;
217
+ return tmp;
218
+ ```
219
+
220
+ ``` cpp
221
+ constexpr iterator& operator--() requires bidirectional_range<V>;
222
+ ```
223
+
224
+ *Effects:* Equivalent to:
225
+
226
+ ``` cpp
227
+ next_ = current_;
228
+ current_ = parent_->find-prev(next_);
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
+ ```
247
+
248
+ *Returns:* `x.`*`current_`*` == y.`*`current_`*.
249
+
250
+ ``` cpp
251
+ friend constexpr bool operator==(const iterator& x, default_sentinel_t);
252
+ ```
253
+
254
+ *Returns:* `x.`*`current_`*` == x.`*`next_`*.
255
+