From Jason Turner

[range.subrange]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpfa0lb9p0/{from.md → to.md} +293 -0
tmp/tmpfa0lb9p0/{from.md → to.md} RENAMED
@@ -0,0 +1,293 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ### Sub-ranges <a id="range.subrange">[[range.subrange]]</a>
2
+
3
+ The `subrange` class template combines together an iterator and a
4
+ sentinel into a single object that models the `view` concept.
5
+ Additionally, it models the `sized_range` concept when the final
6
+ template parameter is `subrange_kind::sized`.
7
+
8
+ ``` cpp
9
+ namespace std::ranges {
10
+ template<class From, class To>
11
+ concept convertible-to-non-slicing = // exposition only
12
+ convertible_to<From, To> &&
13
+ !(is_pointer_v<decay_t<From>> &&
14
+ is_pointer_v<decay_t<To>> &&
15
+ not-same-as<remove_pointer_t<decay_t<From>>, remove_pointer_t<decay_t<To>>>);
16
+
17
+ template<class T>
18
+ concept pair-like = // exposition only
19
+ !is_reference_v<T> && requires(T t) {
20
+ typename tuple_size<T>::type; // ensures tuple_size<T> is complete
21
+ requires derived_from<tuple_size<T>, integral_constant<size_t, 2>>;
22
+ typename tuple_element_t<0, remove_const_t<T>>;
23
+ typename tuple_element_t<1, remove_const_t<T>>;
24
+ { get<0>(t) } -> convertible_to<const tuple_element_t<0, T>&>;
25
+ { get<1>(t) } -> convertible_to<const tuple_element_t<1, T>&>;
26
+ };
27
+
28
+ template<class T, class U, class V>
29
+ concept pair-like-convertible-from = // exposition only
30
+ !range<T> && pair-like<T> &&
31
+ constructible_from<T, U, V> &&
32
+ convertible-to-non-slicing<U, tuple_element_t<0, T>> &&
33
+ convertible_to<V, tuple_element_t<1, T>>;
34
+
35
+ template<class T>
36
+ concept iterator-sentinel-pair = // exposition only
37
+ !range<T> && pair-like<T> &&
38
+ sentinel_for<tuple_element_t<1, T>, tuple_element_t<0, T>>;
39
+
40
+ template<input_or_output_iterator I, sentinel_for<I> S = I, subrange_kind K =
41
+ sized_sentinel_for<S, I> ? subrange_kind::sized : subrange_kind::unsized>
42
+ requires (K == subrange_kind::sized || !sized_sentinel_for<S, I>)
43
+ class subrange : public view_interface<subrange<I, S, K>> {
44
+ private:
45
+ static constexpr bool StoreSize = // exposition only
46
+ K == subrange_kind::sized && !sized_sentinel_for<S, I>;
47
+ I begin_ = I(); // exposition only
48
+ S end_ = S(); // exposition only
49
+ make-unsigned-like-t<iter_difference_t<I>> size_ = 0; // exposition only; present only
50
+ // when StoreSize is true
51
+ public:
52
+ subrange() = default;
53
+
54
+ constexpr subrange(convertible-to-non-slicing<I> auto i, S s) requires (!StoreSize);
55
+
56
+ constexpr subrange(convertible-to-non-slicing<I> auto i, S s,
57
+ make-unsigned-like-t<iter_difference_t<I>> n)
58
+ requires (K == subrange_kind::sized);
59
+
60
+ template<not-same-as<subrange> R>
61
+ requires borrowed_range<R> &&
62
+ convertible-to-non-slicing<iterator_t<R>, I> &&
63
+ convertible_to<sentinel_t<R>, S>
64
+ constexpr subrange(R&& r) requires (!StoreSize || sized_range<R>);
65
+
66
+ template<borrowed_range R>
67
+ requires convertible-to-non-slicing<iterator_t<R>, I> &&
68
+ convertible_to<sentinel_t<R>, S>
69
+ constexpr subrange(R&& r, make-unsigned-like-t<iter_difference_t<I>> n)
70
+ requires (K == subrange_kind::sized)
71
+ : subrange{ranges::begin(r), ranges::end(r), n}
72
+ {}
73
+
74
+ template<not-same-as<subrange> PairLike>
75
+ requires pair-like-convertible-from<PairLike, const I&, const S&>
76
+ constexpr operator PairLike() const;
77
+
78
+ constexpr I begin() const requires copyable<I>;
79
+ [[nodiscard]] constexpr I begin() requires (!copyable<I>);
80
+ constexpr S end() const;
81
+
82
+ constexpr bool empty() const;
83
+ constexpr make-unsigned-like-t<iter_difference_t<I>> size() const
84
+ requires (K == subrange_kind::sized);
85
+
86
+ [[nodiscard]] constexpr subrange next(iter_difference_t<I> n = 1) const &
87
+ requires forward_iterator<I>;
88
+ [[nodiscard]] constexpr subrange next(iter_difference_t<I> n = 1) &&;
89
+ [[nodiscard]] constexpr subrange prev(iter_difference_t<I> n = 1) const
90
+ requires bidirectional_iterator<I>;
91
+ constexpr subrange& advance(iter_difference_t<I> n);
92
+ };
93
+
94
+ template<input_or_output_iterator I, sentinel_for<I> S>
95
+ subrange(I, S) -> subrange<I, S>;
96
+
97
+ template<input_or_output_iterator I, sentinel_for<I> S>
98
+ subrange(I, S, make-unsigned-like-t<iter_difference_t<I>>) ->
99
+ subrange<I, S, subrange_kind::sized>;
100
+
101
+ template<iterator-sentinel-pair P>
102
+ subrange(P) -> subrange<tuple_element_t<0, P>, tuple_element_t<1, P>>;
103
+
104
+ template<iterator-sentinel-pair P>
105
+ subrange(P, make-unsigned-like-t<iter_difference_t<tuple_element_t<0, P>>>) ->
106
+ subrange<tuple_element_t<0, P>, tuple_element_t<1, P>, subrange_kind::sized>;
107
+
108
+ template<borrowed_range R>
109
+ subrange(R&&) ->
110
+ subrange<iterator_t<R>, sentinel_t<R>,
111
+ (sized_range<R> || sized_sentinel_for<sentinel_t<R>, iterator_t<R>>)
112
+ ? subrange_kind::sized : subrange_kind::unsized>;
113
+
114
+ template<borrowed_range R>
115
+ subrange(R&&, make-unsigned-like-t<range_difference_t<R>>) ->
116
+ subrange<iterator_t<R>, sentinel_t<R>, subrange_kind::sized>;
117
+
118
+ template<size_t N, class I, class S, subrange_kind K>
119
+ requires (N < 2)
120
+ constexpr auto get(const subrange<I, S, K>& r);
121
+
122
+ template<size_t N, class I, class S, subrange_kind K>
123
+ requires (N < 2)
124
+ constexpr auto get(subrange<I, S, K>&& r);
125
+ }
126
+
127
+ namespace std {
128
+ using ranges::get;
129
+ }
130
+ ```
131
+
132
+ #### Constructors and conversions <a id="range.subrange.ctor">[[range.subrange.ctor]]</a>
133
+
134
+ ``` cpp
135
+ constexpr subrange(convertible-to-non-slicing<I> auto i, S s) requires (!StoreSize);
136
+ ```
137
+
138
+ *Preconditions:* \[`i`, `s`) is a valid range.
139
+
140
+ *Effects:* Initializes *begin\_* with `std::move(i)` and *end\_* with
141
+ `s`.
142
+
143
+ ``` cpp
144
+ constexpr subrange(convertible-to-non-slicing<I> auto i, S s,
145
+ make-unsigned-like-t<iter_difference_t<I>> n)
146
+ requires (K == subrange_kind::sized);
147
+ ```
148
+
149
+ *Preconditions:* \[`i`, `s`) is a valid range, and
150
+ `n == `*`to-unsigned-like`*`(ranges::distance(i, s))`.
151
+
152
+ *Effects:* Initializes *begin\_* with `std::move(i)` and *end\_* with
153
+ `s`. If *StoreSize* is `true`, initializes *size\_* with `n`.
154
+
155
+ [*Note 1*: Accepting the length of the range and storing it to later
156
+ return from `size()` enables `subrange` to model `sized_range` even when
157
+ it stores an iterator and sentinel that do not model
158
+ `sized_sentinel_for`. — *end note*]
159
+
160
+ ``` cpp
161
+ template<not-same-as<subrange> R>
162
+ requires borrowed_range<R> &&
163
+ convertible-to-non-slicing<iterator_t<R>, I> &&
164
+ convertible_to<sentinel_t<R>, S>
165
+ constexpr subrange(R&& r) requires (!StoreSize || sized_range<R>);
166
+ ```
167
+
168
+ *Effects:* Equivalent to:
169
+
170
+ - If *StoreSize* is `true`, `subrange{r, ranges::size(r)}`.
171
+ - Otherwise, `subrange{ranges::begin(r), ranges::end(r)}`.
172
+
173
+ ``` cpp
174
+ template<not-same-as<subrange> PairLike>
175
+ requires pair-like-convertible-from<PairLike, const I&, const S&>
176
+ constexpr operator PairLike() const;
177
+ ```
178
+
179
+ *Effects:* Equivalent to: `return PairLike(`*`begin_`*`, `*`end_`*`);`
180
+
181
+ #### Accessors <a id="range.subrange.access">[[range.subrange.access]]</a>
182
+
183
+ ``` cpp
184
+ constexpr I begin() const requires copyable<I>;
185
+ ```
186
+
187
+ *Effects:* Equivalent to: `return `*`begin_`*`;`
188
+
189
+ ``` cpp
190
+ [[nodiscard]] constexpr I begin() requires (!copyable<I>);
191
+ ```
192
+
193
+ *Effects:* Equivalent to: `return std::move(`*`begin_`*`);`
194
+
195
+ ``` cpp
196
+ constexpr S end() const;
197
+ ```
198
+
199
+ *Effects:* Equivalent to: `return `*`end_`*`;`
200
+
201
+ ``` cpp
202
+ constexpr bool empty() const;
203
+ ```
204
+
205
+ *Effects:* Equivalent to: `return `*`begin_`*` == `*`end_`*`;`
206
+
207
+ ``` cpp
208
+ constexpr make-unsigned-like-t<iter_difference_t<I>> size() const
209
+ requires (K == subrange_kind::sized);
210
+ ```
211
+
212
+ *Effects:*
213
+
214
+ - If *StoreSize* is `true`, equivalent to: `return `*`size_`*`;`
215
+ - Otherwise, equivalent to:
216
+ `return `*`to-unsigned-like`*`(`*`end_`*` - `*`begin_`*`);`
217
+
218
+ ``` cpp
219
+ [[nodiscard]] constexpr subrange next(iter_difference_t<I> n = 1) const &
220
+ requires forward_iterator<I>;
221
+ ```
222
+
223
+ *Effects:* Equivalent to:
224
+
225
+ ``` cpp
226
+ auto tmp = *this;
227
+ tmp.advance(n);
228
+ return tmp;
229
+ ```
230
+
231
+ ``` cpp
232
+ [[nodiscard]] constexpr subrange next(iter_difference_t<I> n = 1) &&;
233
+ ```
234
+
235
+ *Effects:* Equivalent to:
236
+
237
+ ``` cpp
238
+ advance(n);
239
+ return std::move(*this);
240
+ ```
241
+
242
+ ``` cpp
243
+ [[nodiscard]] constexpr subrange prev(iter_difference_t<I> n = 1) const
244
+ requires bidirectional_iterator<I>;
245
+ ```
246
+
247
+ *Effects:* Equivalent to:
248
+
249
+ ``` cpp
250
+ auto tmp = *this;
251
+ tmp.advance(-n);
252
+ return tmp;
253
+ ```
254
+
255
+ ``` cpp
256
+ constexpr subrange& advance(iter_difference_t<I> n);
257
+ ```
258
+
259
+ *Effects:* Equivalent to:
260
+
261
+ - If *StoreSize* is `true`,
262
+ ``` cpp
263
+ auto d = n - ranges::advance(begin_, n, end_);
264
+ if (d >= 0)
265
+ size_ -= to-unsigned-like(d);
266
+ else
267
+ size_ += to-unsigned-like(-d);
268
+ return *this;
269
+ ```
270
+ - Otherwise,
271
+ ``` cpp
272
+ ranges::advance(begin_, n, end_);
273
+ return *this;
274
+ ```
275
+
276
+ ``` cpp
277
+ template<size_t N, class I, class S, subrange_kind K>
278
+ requires (N < 2)
279
+ constexpr auto get(const subrange<I, S, K>& r);
280
+ template<size_t N, class I, class S, subrange_kind K>
281
+ requires (N < 2)
282
+ constexpr auto get(subrange<I, S, K>&& r);
283
+ ```
284
+
285
+ *Effects:* Equivalent to:
286
+
287
+ ``` cpp
288
+ if constexpr (N == 0)
289
+ return r.begin();
290
+ else
291
+ return r.end();
292
+ ```
293
+