From Jason Turner

[ranges]

Large diff (144.3 KB) - rendering may be slow on some devices

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpa9j4yfnd/{from.md → to.md} +1911 -318
tmp/tmpa9j4yfnd/{from.md → to.md} RENAMED
@@ -21,552 +21,585 @@ components for range primitives and range generators as summarized in
21
 
22
 
23
  ## Header `<ranges>` synopsis <a id="ranges.syn">[[ranges.syn]]</a>
24
 
25
  ``` cpp
 
26
  #include <compare> // see [compare.syn]
27
  #include <initializer_list> // see [initializer.list.syn]
28
  #include <iterator> // see [iterator.synopsis]
29
 
30
  namespace std::ranges {
31
  inline namespace unspecified {
32
  // [range.access], range access
33
- inline constexpr unspecified begin = unspecified; // freestanding
34
- inline constexpr unspecified end = unspecified; // freestanding
35
- inline constexpr unspecified cbegin = unspecified; // freestanding
36
- inline constexpr unspecified cend = unspecified; // freestanding
37
- inline constexpr unspecified rbegin = unspecified; // freestanding
38
- inline constexpr unspecified rend = unspecified; // freestanding
39
- inline constexpr unspecified crbegin = unspecified; // freestanding
40
- inline constexpr unspecified crend = unspecified; // freestanding
41
 
42
- inline constexpr unspecified size = unspecified; // freestanding
43
- inline constexpr unspecified ssize = unspecified; // freestanding
44
- inline constexpr unspecified empty = unspecified; // freestanding
45
- inline constexpr unspecified data = unspecified; // freestanding
46
- inline constexpr unspecified cdata = unspecified; // freestanding
 
47
  }
48
 
49
  // [range.range], ranges
50
  template<class T>
51
- concept range = see below; // freestanding
52
 
53
  template<class T>
54
- constexpr bool enable_borrowed_range = false; // freestanding
55
 
56
  template<class T>
57
- concept borrowed_range = see below; // freestanding
58
 
59
  template<class T>
60
- using iterator_t = decltype(ranges::begin(declval<T&>())); // freestanding
61
  template<range R>
62
- using sentinel_t = decltype(ranges::end(declval<R&>())); // freestanding
63
  template<range R>
64
- using const_iterator_t = const_iterator<iterator_t<R>>; // freestanding
65
  template<range R>
66
- using const_sentinel_t = const_sentinel<sentinel_t<R>>; // freestanding
67
  template<range R>
68
- using range_difference_t = iter_difference_t<iterator_t<R>>; // freestanding
69
  template<sized_range R>
70
- using range_size_t = decltype(ranges::size(declval<R&>())); // freestanding
71
  template<range R>
72
- using range_value_t = iter_value_t<iterator_t<R>>; // freestanding
73
  template<range R>
74
- using range_reference_t = iter_reference_t<iterator_t<R>>; // freestanding
75
  template<range R>
76
- using range_const_reference_t = iter_const_reference_t<iterator_t<R>>; // freestanding
77
  template<range R>
78
- using range_rvalue_reference_t = iter_rvalue_reference_t<iterator_t<R>>; // freestanding
79
  template<range R>
80
- using range_common_reference_t = iter_common_reference_t<iterator_t<R>>; // freestanding
81
 
82
  // [range.sized], sized ranges
83
  template<class>
84
- constexpr bool disable_sized_range = false; // freestanding
85
 
86
  template<class T>
87
- concept sized_range = see below; // freestanding
 
 
 
88
 
89
  // [range.view], views
90
  template<class T>
91
- constexpr bool enable_view = see below; // freestanding
92
 
93
- struct view_base {}; // freestanding
94
 
95
  template<class T>
96
- concept view = see below; // freestanding
97
 
98
  // [range.refinements], other range refinements
99
  template<class R, class T>
100
- concept output_range = see below; // freestanding
101
 
102
  template<class T>
103
- concept input_range = see below; // freestanding
104
 
105
  template<class T>
106
- concept forward_range = see below; // freestanding
107
 
108
  template<class T>
109
- concept bidirectional_range = see below; // freestanding
110
 
111
  template<class T>
112
- concept random_access_range = see below; // freestanding
113
 
114
  template<class T>
115
- concept contiguous_range = see below; // freestanding
116
 
117
  template<class T>
118
- concept common_range = see below; // freestanding
119
 
120
  template<class T>
121
- concept viewable_range = see below; // freestanding
122
 
123
  template<class T>
124
- concept constant_range = see below; // freestanding
 
 
 
125
 
126
  // [view.interface], class template view_interface
127
  template<class D>
128
  requires is_class_v<D> && same_as<D, remove_cv_t<D>>
129
- class view_interface; // freestanding
130
 
131
  // [range.subrange], sub-ranges
132
- enum class subrange_kind : bool { unsized, sized }; // freestanding
133
 
134
  template<input_or_output_iterator I, sentinel_for<I> S = I, subrange_kind K = see below>
135
  requires (K == subrange_kind::sized || !sized_sentinel_for<S, I>)
136
- class subrange; // freestanding
137
 
138
  template<class I, class S, subrange_kind K>
139
- constexpr bool enable_borrowed_range<subrange<I, S, K>> = true; // freestanding
140
 
141
  template<size_t N, class I, class S, subrange_kind K>
142
  requires ((N == 0 && copyable<I>) || N == 1)
143
- constexpr auto get(const subrange<I, S, K>& r); // freestanding
144
 
145
  template<size_t N, class I, class S, subrange_kind K>
146
  requires (N < 2)
147
- constexpr auto get(subrange<I, S, K>&& r); // freestanding
148
  }
149
 
150
  namespace std {
151
- using ranges::get; // freestanding
152
  }
153
 
154
  namespace std::ranges {
155
  // [range.dangling], dangling iterator handling
156
- struct dangling; // freestanding
157
 
158
  // [range.elementsof], class template elements_of
159
  template<range R, class Allocator = allocator<byte>>
160
- struct elements_of;
161
 
162
  template<range R>
163
- using borrowed_iterator_t = see below; // freestanding
164
 
165
  template<range R>
166
- using borrowed_subrange_t = see below; // freestanding
167
 
168
  // [range.utility.conv], range conversions
169
  template<class C, input_range R, class... Args> requires (!view<C>)
170
- constexpr C to(R&& r, Args&&... args); // freestanding
171
  template<template<class...> class C, input_range R, class... Args>
172
- constexpr auto to(R&& r, Args&&... args); // freestanding
173
  template<class C, class... Args> requires (!view<C>)
174
- constexpr auto to(Args&&... args); // freestanding
175
  template<template<class...> class C, class... Args>
176
- constexpr auto to(Args&&... args); // freestanding
177
 
178
  // [range.empty], empty view
179
  template<class T>
180
  requires is_object_v<T>
181
- class empty_view; // freestanding
182
 
183
  template<class T>
184
- constexpr bool enable_borrowed_range<empty_view<T>> = true; // freestanding
185
 
186
  namespace views {
187
  template<class T>
188
- constexpr empty_view<T> empty{}; // freestanding
189
  }
190
 
191
  // [range.single], single view
192
  template<move_constructible T>
193
  requires is_object_v<T>
194
- class single_view; // freestanding
195
 
196
- namespace views { inline constexpr unspecified single = unspecified; } // freestanding
197
 
198
  template<bool Const, class T>
199
  using maybe-const = conditional_t<Const, const T, T>; // exposition only
200
 
201
  // [range.iota], iota view
202
  template<weakly_incrementable W, semiregular Bound = unreachable_sentinel_t>
203
  requires weakly-equality-comparable-with<W, Bound> && copyable<W>
204
- class iota_view; // freestanding
205
 
206
  template<class W, class Bound>
207
- constexpr bool enable_borrowed_range<iota_view<W, Bound>> = true; // freestanding
208
 
209
- namespace views { inline constexpr unspecified iota = unspecified; } // freestanding
 
 
 
210
 
211
  // [range.repeat], repeat view
212
  template<move_constructible T, semiregular Bound = unreachable_sentinel_t>
213
  requires see below
214
- class repeat_view; // freestanding
215
 
216
- namespace views { inline constexpr unspecified repeat = unspecified; } // freestanding
217
 
218
  // [range.istream], istream view
219
  template<movable Val, class CharT, class Traits = char_traits<CharT>>
220
  requires see below
221
- class basic_istream_view;
222
  template<class Val>
223
- using istream_view = basic_istream_view<Val, char>;
224
  template<class Val>
225
- using wistream_view = basic_istream_view<Val, wchar_t>;
226
 
227
- namespace views { template<class T> constexpr unspecified istream = unspecified; }
 
 
228
 
229
  // [range.adaptor.object], range adaptor objects
230
  template<class D>
231
  requires is_class_v<D> && same_as<D, remove_cv_t<D>>
232
- class range_adaptor_closure { }; // freestanding
233
 
234
  // [range.all], all view
235
  namespace views {
236
- inline constexpr unspecified all = unspecified; // freestanding
237
 
238
  template<viewable_range R>
239
- using all_t = decltype(all(declval<R>())); // freestanding
240
  }
241
 
242
  // [range.ref.view], ref view
243
  template<range R>
244
  requires is_object_v<R>
245
- class ref_view; // freestanding
246
 
247
  template<class T>
248
- constexpr bool enable_borrowed_range<ref_view<T>> = true; // freestanding
249
 
250
  // [range.owning.view], owning view
251
  template<range R>
252
  requires see below
253
- class owning_view; // freestanding
254
 
255
  template<class T>
256
- constexpr bool enable_borrowed_range<owning_view<T>> = // freestanding
257
  enable_borrowed_range<T>;
258
 
259
  // [range.as.rvalue], as rvalue view
260
  template<view V>
261
  requires input_range<V>
262
- class as_rvalue_view; // freestanding
263
 
264
  template<class T>
265
- constexpr bool enable_borrowed_range<as_rvalue_view<T>> = // freestanding
266
  enable_borrowed_range<T>;
267
 
268
- namespace views { inline constexpr unspecified as_rvalue = unspecified; } // freestanding
269
 
270
  // [range.filter], filter view
271
  template<input_range V, indirect_unary_predicate<iterator_t<V>> Pred>
272
  requires view<V> && is_object_v<Pred>
273
- class filter_view; // freestanding
274
 
275
- namespace views { inline constexpr unspecified filter = unspecified; } // freestanding
276
 
277
  // [range.transform], transform view
278
  template<input_range V, move_constructible F>
279
  requires view<V> && is_object_v<F> &&
280
  regular_invocable<F&, range_reference_t<V>> &&
281
  can-reference<invoke_result_t<F&, range_reference_t<V>>>
282
- class transform_view; // freestanding
283
 
284
- namespace views { inline constexpr unspecified transform = unspecified; } // freestanding
285
 
286
  // [range.take], take view
287
- template<view> class take_view; // freestanding
288
 
289
  template<class T>
290
- constexpr bool enable_borrowed_range<take_view<T>> = // freestanding
291
  enable_borrowed_range<T>;
292
 
293
- namespace views { inline constexpr unspecified take = unspecified; } // freestanding
294
 
295
  // [range.take.while], take while view
296
  template<view V, class Pred>
297
  requires input_range<V> && is_object_v<Pred> &&
298
  indirect_unary_predicate<const Pred, iterator_t<V>>
299
- class take_while_view; // freestanding
300
 
301
- namespace views { inline constexpr unspecified take_while = unspecified; } // freestanding
302
 
303
  // [range.drop], drop view
304
  template<view V>
305
- class drop_view; // freestanding
306
 
307
  template<class T>
308
- constexpr bool enable_borrowed_range<drop_view<T>> = // freestanding
309
  enable_borrowed_range<T>;
310
 
311
- namespace views { inline constexpr unspecified drop = unspecified; } // freestanding
312
 
313
  // [range.drop.while], drop while view
314
  template<view V, class Pred>
315
  requires input_range<V> && is_object_v<Pred> &&
316
  indirect_unary_predicate<const Pred, iterator_t<V>>
317
- class drop_while_view; // freestanding
318
 
319
  template<class T, class Pred>
320
- constexpr bool enable_borrowed_range<drop_while_view<T, Pred>> = // freestanding
321
  enable_borrowed_range<T>;
322
 
323
- namespace views { inline constexpr unspecified drop_while = unspecified; } // freestanding
324
 
325
  // [range.join], join view
326
  template<input_range V>
327
  requires view<V> && input_range<range_reference_t<V>>
328
- class join_view; // freestanding
329
 
330
- namespace views { inline constexpr unspecified join = unspecified; } // freestanding
331
 
332
  // [range.join.with], join with view
333
- template<class R, class P>
334
- concept compatible-joinable-ranges = see below; // exposition only
335
-
336
  template<input_range V, forward_range Pattern>
337
- requires view<V> && input_range<range_reference_t<V>>
338
- && view<Pattern>
339
- && compatible-joinable-ranges<range_reference_t<V>, Pattern>
340
- class join_with_view; // freestanding
341
 
342
- namespace views { inline constexpr unspecified join_with = unspecified; } // freestanding
343
 
344
  // [range.lazy.split], lazy split view
345
  template<class R>
346
  concept tiny-range = see below; // exposition only
347
 
348
  template<input_range V, forward_range Pattern>
349
  requires view<V> && view<Pattern> &&
350
  indirectly_comparable<iterator_t<V>, iterator_t<Pattern>, ranges::equal_to> &&
351
  (forward_range<V> || tiny-range<Pattern>)
352
- class lazy_split_view; // freestanding
353
 
354
  // [range.split], split view
355
  template<forward_range V, forward_range Pattern>
356
  requires view<V> && view<Pattern> &&
357
  indirectly_comparable<iterator_t<V>, iterator_t<Pattern>, ranges::equal_to>
358
- class split_view; // freestanding
359
 
360
  namespace views {
361
- inline constexpr unspecified lazy_split = unspecified; // freestanding
362
- inline constexpr unspecified split = unspecified; // freestanding
363
  }
364
 
 
 
 
 
 
 
 
365
  // [range.counted], counted view
366
- namespace views { inline constexpr unspecified counted = unspecified; } // freestanding
367
 
368
  // [range.common], common view
369
  template<view V>
370
  requires (!common_range<V> && copyable<iterator_t<V>>)
371
- class common_view; // freestanding
372
 
373
  template<class T>
374
- constexpr bool enable_borrowed_range<common_view<T>> = // freestanding
375
  enable_borrowed_range<T>;
376
 
377
- namespace views { inline constexpr unspecified common = unspecified; } // freestanding
378
 
379
  // [range.reverse], reverse view
380
  template<view V>
381
  requires bidirectional_range<V>
382
- class reverse_view; // freestanding
383
 
384
  template<class T>
385
- constexpr bool enable_borrowed_range<reverse_view<T>> = // freestanding
386
  enable_borrowed_range<T>;
387
 
388
- namespace views { inline constexpr unspecified reverse = unspecified; } // freestanding
389
 
390
  // [range.as.const], as const view
391
  template<input_range R>
392
- constexpr auto& possibly-const-range(R& r) { // exposition only
393
- if constexpr (constant_range<const R> && !constant_range<R>) {
394
  return const_cast<const R&>(r);
395
  } else {
396
  return r;
397
  }
398
  }
399
 
400
  template<view V>
401
  requires input_range<V>
402
- class as_const_view; // freestanding
403
 
404
  template<class T>
405
- constexpr bool enable_borrowed_range<as_const_view<T>> = // freestanding
406
  enable_borrowed_range<T>;
407
 
408
- namespace views { inline constexpr unspecified as_const = unspecified; } // freestanding
409
 
410
  // [range.elements], elements view
411
  template<input_range V, size_t N>
412
  requires see below
413
- class elements_view; // freestanding
414
 
415
  template<class T, size_t N>
416
- constexpr bool enable_borrowed_range<elements_view<T, N>> = // freestanding
417
  enable_borrowed_range<T>;
418
 
419
  template<class R>
420
- using keys_view = elements_view<R, 0>; // freestanding
421
  template<class R>
422
- using values_view = elements_view<R, 1>; // freestanding
423
 
424
  namespace views {
425
  template<size_t N>
426
- constexpr unspecified elements = unspecified; // freestanding
427
- inline constexpr auto keys = elements<0>; // freestanding
428
- inline constexpr auto values = elements<1>; // freestanding
429
  }
430
 
431
  // [range.enumerate], enumerate view
432
- template<input_range View>
433
- requires view<View>
434
- class enumerate_view; // freestanding
435
 
436
  template<class View>
437
- constexpr bool enable_borrowed_range<enumerate_view<View>> = // freestanding
438
  enable_borrowed_range<View>;
439
 
440
- namespace views { inline constexpr unspecified enumerate = unspecified; } // freestanding
441
 
442
  // [range.zip], zip view
443
  template<input_range... Views>
444
  requires (view<Views> && ...) && (sizeof...(Views) > 0)
445
- class zip_view; // freestanding
446
 
447
  template<class... Views>
448
- constexpr bool enable_borrowed_range<zip_view<Views...>> = // freestanding
449
  (enable_borrowed_range<Views> && ...);
450
 
451
- namespace views { inline constexpr unspecified zip = unspecified; } // freestanding
452
 
453
  // [range.zip.transform], zip transform view
454
  template<move_constructible F, input_range... Views>
455
  requires (view<Views> && ...) && (sizeof...(Views) > 0) && is_object_v<F> &&
456
  regular_invocable<F&, range_reference_t<Views>...> &&
457
  can-reference<invoke_result_t<F&, range_reference_t<Views>...>>
458
- class zip_transform_view; // freestanding
459
 
460
- namespace views { inline constexpr unspecified zip_transform = unspecified; } // freestanding
461
 
462
  // [range.adjacent], adjacent view
463
  template<forward_range V, size_t N>
464
  requires view<V> && (N > 0)
465
- class adjacent_view; // freestanding
466
 
467
  template<class V, size_t N>
468
- constexpr bool enable_borrowed_range<adjacent_view<V, N>> = // freestanding
469
  enable_borrowed_range<V>;
470
 
471
  namespace views {
472
  template<size_t N>
473
- constexpr unspecified adjacent = unspecified; // freestanding
474
- inline constexpr auto pairwise = adjacent<2>; // freestanding
475
  }
476
 
477
  // [range.adjacent.transform], adjacent transform view
478
  template<forward_range V, move_constructible F, size_t N>
479
  requires see below
480
- class adjacent_transform_view; // freestanding
481
 
482
  namespace views {
483
  template<size_t N>
484
- constexpr unspecified adjacent_transform = unspecified; // freestanding
485
- inline constexpr auto pairwise_transform = adjacent_transform<2>; // freestanding
486
  }
487
 
488
  // [range.chunk], chunk view
489
  template<view V>
490
  requires input_range<V>
491
- class chunk_view; // freestanding
492
 
493
  template<view V>
494
  requires forward_range<V>
495
- class chunk_view<V>; // freestanding
496
 
497
  template<class V>
498
- constexpr bool enable_borrowed_range<chunk_view<V>> = // freestanding
499
  forward_range<V> && enable_borrowed_range<V>;
500
 
501
- namespace views { inline constexpr unspecified chunk = unspecified; } // freestanding
502
 
503
  // [range.slide], slide view
504
  template<forward_range V>
505
  requires view<V>
506
- class slide_view; // freestanding
507
 
508
  template<class V>
509
- constexpr bool enable_borrowed_range<slide_view<V>> =
510
- enable_borrowed_range<V>; // freestanding
511
 
512
- namespace views { inline constexpr unspecified slide = unspecified; } // freestanding
513
 
514
  // [range.chunk.by], chunk by view
515
  template<forward_range V, indirect_binary_predicate<iterator_t<V>, iterator_t<V>> Pred>
516
  requires view<V> && is_object_v<Pred>
517
- class chunk_by_view; // freestanding
518
 
519
- namespace views { inline constexpr unspecified chunk_by = unspecified; } // freestanding
520
 
521
  // [range.stride], stride view
522
  template<input_range V>
523
  requires view<V>
524
- class stride_view; // freestanding
525
 
526
  template<class V>
527
- constexpr bool enable_borrowed_range<stride_view<V>> = // freestanding
528
  enable_borrowed_range<V>;
529
 
530
- namespace views { inline constexpr unspecified stride = unspecified; } // freestanding
531
 
532
  // [range.cartesian], cartesian product view
533
  template<input_range First, forward_range... Vs>
534
  requires (view<First> && ... && view<Vs>)
535
- class cartesian_product_view; // freestanding
536
 
537
- namespace views { inline constexpr unspecified cartesian_product = unspecified; } // freestanding
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
538
  }
539
 
540
  namespace std {
541
- namespace views = ranges::views; // freestanding
542
 
543
- template<class T> struct tuple_size; // freestanding
544
- template<size_t I, class T> struct tuple_element; // freestanding
545
 
546
  template<class I, class S, ranges::subrange_kind K>
547
- struct tuple_size<ranges::subrange<I, S, K>> // freestanding
548
  : integral_constant<size_t, 2> {};
549
  template<class I, class S, ranges::subrange_kind K>
550
- struct tuple_element<0, ranges::subrange<I, S, K>> { // freestanding
551
- using type = I; // freestanding
552
  };
553
  template<class I, class S, ranges::subrange_kind K>
554
- struct tuple_element<1, ranges::subrange<I, S, K>> { // freestanding
555
- using type = S; // freestanding
556
  };
557
  template<class I, class S, ranges::subrange_kind K>
558
- struct tuple_element<0, const ranges::subrange<I, S, K>> { // freestanding
559
- using type = I; // freestanding
560
  };
561
  template<class I, class S, ranges::subrange_kind K>
562
- struct tuple_element<1, const ranges::subrange<I, S, K>> { // freestanding
563
- using type = S; // freestanding
564
  };
565
 
566
- struct from_range_t { explicit from_range_t() = default; }; // freestanding
567
- inline constexpr from_range_t from_range{}; // freestanding
568
  }
569
  ```
570
 
571
  Within this Clause, for an integer-like type `X`
572
  [[iterator.concept.winc]], `make-unsigned-like-t<X>` denotes
@@ -584,11 +617,11 @@ type of the same width as `X`.
584
 
585
  ### General <a id="range.access.general">[[range.access.general]]</a>
586
 
587
  In addition to being available via inclusion of the `<ranges>` header,
588
  the customization point objects in [[range.access]] are available when
589
- `<iterator>` is included.
590
 
591
  Within [[range.access]], the *reified object* of a subexpression `E`
592
  denotes
593
 
594
  - the same object as `E` if `E` is a glvalue, or
@@ -846,10 +879,37 @@ denotes the reified object for `E`. If `ranges::size(t)` is ill-formed,
846
  `ranges::ssize(E)` is ill-formed. Otherwise let `D` be
847
  `make-signed-like-t<decltype(ranges::{}size(t))>`, or `ptrdiff_t` if it
848
  is wider than that type; `ranges::ssize(E)` is expression-equivalent to
849
  `static_cast<D>(ranges::size(t))`.
850
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
851
  ### `ranges::empty` <a id="range.prim.empty">[[range.prim.empty]]</a>
852
 
853
  The name `ranges::empty` denotes a customization point object
854
  [[customization.point.object]].
855
 
@@ -906,11 +966,11 @@ pointer to object type. — *end note*]
906
 
907
  ### `ranges::cdata` <a id="range.prim.cdata">[[range.prim.cdata]]</a>
908
 
909
  ``` cpp
910
  template<class T>
911
- constexpr auto as-const-pointer(const T* p) { return p; } // exposition only
912
  ```
913
 
914
  The name `ranges::cdata` denotes a customization point object
915
  [[customization.point.object]]. Given a subexpression `E` with type `T`,
916
  let `t` be an lvalue that denotes the reified object for `E`. Then:
@@ -964,14 +1024,10 @@ template<class T>
964
  ranges::begin(t); // sometimes equality-preserving (see below)
965
  ranges::end(t);
966
  };
967
  ```
968
 
969
- The required expressions `ranges::begin(t)` and `ranges::end(t)` of the
970
- `range` concept do not require implicit expression
971
- variations [[concepts.equality]].
972
-
973
  Given an expression `t` such that `decltype((t))` is `T&`, `T` models
974
  `range` only if
975
 
976
  - \[`ranges::begin(t)`, `ranges::end(t)`) denotes a
977
  range [[iterator.requirements.general]],
@@ -1025,20 +1081,48 @@ models `borrowed_range` because
1025
  - `S`’s iterators do not have validity tied to the lifetime of an `S`
1026
  object because they are “borrowed” from some other range.
1027
 
1028
  — *end example*]
1029
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1030
  ### Sized ranges <a id="range.sized">[[range.sized]]</a>
1031
 
1032
- The `sized_range` concept refines `range` with the requirement that the
1033
- number of elements in the range can be determined in amortized constant
1034
- time using `ranges::size`.
1035
 
1036
  ``` cpp
1037
  template<class T>
1038
  concept sized_range =
1039
- range<T> && requires(T& t) { ranges::size(t); };
1040
  ```
1041
 
1042
  Given an lvalue `t` of type `remove_reference_t<T>`, `T` models
1043
  `sized_range` only if
1044
 
@@ -1060,11 +1144,11 @@ template<class>
1060
  *Remarks:* Pursuant to [[namespace.std]], users may specialize
1061
  `disable_sized_range` for cv-unqualified program-defined types. Such
1062
  specializations shall be usable in constant expressions [[expr.const]]
1063
  and have type `const bool`.
1064
 
1065
- [*Note 1*: `disable_sized_range` allows use of range types with the
1066
  library that satisfy but do not in fact model
1067
  `sized_range`. — *end note*]
1068
 
1069
  ### Views <a id="range.view">[[range.view]]</a>
1070
 
@@ -1076,11 +1160,11 @@ constructing range adaptor pipelines [[range.adaptors]].
1076
  template<class T>
1077
  concept view =
1078
  range<T> && movable<T> && enable_view<T>;
1079
  ```
1080
 
1081
- `T` models `view` only if:
1082
 
1083
  - `T` has 𝑂(1) move construction; and
1084
  - move assignment of an object of type `T` is no more complex than
1085
  destruction followed by move construction; and
1086
  - if N copies and/or moves are made from an object of type `T` that
@@ -1124,12 +1208,12 @@ For a type `T`, *`is-derived-from-view-interface`*`<T>` is `true` if and
1124
  only if `T` has exactly one public base class `view_interface<U>` for
1125
  some type `U` and `T` has no base classes of type `view_interface<V>`
1126
  for any other type `V`.
1127
 
1128
  *Remarks:* Pursuant to [[namespace.std]], users may specialize
1129
- `enable_view` to `true` for cv-unqualified program-defined types which
1130
- model `view`, and `false` for types which do not. Such specializations
1131
  shall be usable in constant expressions [[expr.const]] and have type
1132
  `const bool`.
1133
 
1134
  ### Other range refinements <a id="range.refinements">[[range.refinements]]</a>
1135
 
@@ -1215,32 +1299,45 @@ type whose elements are not modifiable.
1215
  template<class T>
1216
  concept constant_range =
1217
  input_range<T> && constant-iterator<iterator_t<T>>;
1218
  ```
1219
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1220
  ## Range utilities <a id="range.utility">[[range.utility]]</a>
1221
 
1222
  ### General <a id="range.utility.general">[[range.utility.general]]</a>
1223
 
1224
  The components in [[range.utility]] are general utilities for
1225
  representing and manipulating ranges.
1226
 
1227
  ### Helper concepts <a id="range.utility.helpers">[[range.utility.helpers]]</a>
1228
 
1229
- Many of the types in subclause  [[range.utility]] are specified in terms
1230
- of the following exposition-only concepts:
1231
 
1232
  ``` cpp
1233
  template<class R>
1234
  concept simple-view = // exposition only
1235
  view<R> && range<const R> &&
1236
  same_as<iterator_t<R>, iterator_t<const R>> &&
1237
  same_as<sentinel_t<R>, sentinel_t<const R>>;
1238
 
1239
  template<class I>
1240
  concept has-arrow = // exposition only
1241
- input_iterator<I> && (is_pointer_v<I> || requires(I i) { i.operator->(); });
1242
 
1243
  template<class T, class U>
1244
  concept different-from = // exposition only
1245
  !same_as<remove_cvref_t<T>, remove_cvref_t<U>>;
1246
 
@@ -1354,21 +1451,21 @@ shall be complete, and model both `derived_from<view_interface<D>>` and
1354
  ``` cpp
1355
  constexpr decltype(auto) front() requires forward_range<D>;
1356
  constexpr decltype(auto) front() const requires forward_range<const D>;
1357
  ```
1358
 
1359
- *Preconditions:* `!empty()` is `true`.
1360
 
1361
  *Effects:* Equivalent to: `return *ranges::begin(`*`derived`*`());`
1362
 
1363
  ``` cpp
1364
  constexpr decltype(auto) back() requires bidirectional_range<D> && common_range<D>;
1365
  constexpr decltype(auto) back() const
1366
  requires bidirectional_range<const D> && common_range<const D>;
1367
  ```
1368
 
1369
- *Preconditions:* `!empty()` is `true`.
1370
 
1371
  *Effects:* Equivalent to:
1372
  `return *ranges::prev(ranges::end(`*`derived`*`()));`
1373
 
1374
  ### Sub-ranges <a id="range.subrange">[[range.subrange]]</a>
@@ -1435,21 +1532,21 @@ namespace std::ranges {
1435
  template<different-from<subrange> PairLike>
1436
  requires pair-like-convertible-from<PairLike, const I&, const S&>
1437
  constexpr operator PairLike() const;
1438
 
1439
  constexpr I begin() const requires copyable<I>;
1440
- [[nodiscard]] constexpr I begin() requires (!copyable<I>);
1441
  constexpr S end() const;
1442
 
1443
  constexpr bool empty() const;
1444
  constexpr make-unsigned-like-t<iter_difference_t<I>> size() const
1445
  requires (K == subrange_kind::sized);
1446
 
1447
- [[nodiscard]] constexpr subrange next(iter_difference_t<I> n = 1) const &
1448
  requires forward_iterator<I>;
1449
- [[nodiscard]] constexpr subrange next(iter_difference_t<I> n = 1) &&;
1450
- [[nodiscard]] constexpr subrange prev(iter_difference_t<I> n = 1) const
1451
  requires bidirectional_iterator<I>;
1452
  constexpr subrange& advance(iter_difference_t<I> n);
1453
  };
1454
 
1455
  template<input_or_output_iterator I, sentinel_for<I> S>
@@ -1528,11 +1625,11 @@ constexpr I begin() const requires copyable<I>;
1528
  ```
1529
 
1530
  *Effects:* Equivalent to: `return `*`begin_`*`;`
1531
 
1532
  ``` cpp
1533
- [[nodiscard]] constexpr I begin() requires (!copyable<I>);
1534
  ```
1535
 
1536
  *Effects:* Equivalent to: `return std::move(`*`begin_`*`);`
1537
 
1538
  ``` cpp
@@ -1557,11 +1654,11 @@ constexpr make-unsigned-like-t<iter_difference_t<I>> size() const
1557
  - If *StoreSize* is `true`, equivalent to: `return `*`size_`*`;`
1558
  - Otherwise, equivalent to:
1559
  `return `*`to-unsigned-like`*`(`*`end_`*` - `*`begin_`*`);`
1560
 
1561
  ``` cpp
1562
- [[nodiscard]] constexpr subrange next(iter_difference_t<I> n = 1) const &
1563
  requires forward_iterator<I>;
1564
  ```
1565
 
1566
  *Effects:* Equivalent to:
1567
 
@@ -1570,22 +1667,22 @@ auto tmp = *this;
1570
  tmp.advance(n);
1571
  return tmp;
1572
  ```
1573
 
1574
  ``` cpp
1575
- [[nodiscard]] constexpr subrange next(iter_difference_t<I> n = 1) &&;
1576
  ```
1577
 
1578
  *Effects:* Equivalent to:
1579
 
1580
  ``` cpp
1581
  advance(n);
1582
  return std::move(*this);
1583
  ```
1584
 
1585
  ``` cpp
1586
- [[nodiscard]] constexpr subrange prev(iter_difference_t<I> n = 1) const
1587
  requires bidirectional_iterator<I>;
1588
  ```
1589
 
1590
  *Effects:* Equivalent to:
1591
 
@@ -1749,30 +1846,38 @@ constexpr bool reservable-container = // exposition only
1749
  { c.capacity() } -> same_as<decltype(n)>;
1750
  { c.max_size() } -> same_as<decltype(n)>;
1751
  };
1752
  ```
1753
 
1754
- Let *`container-insertable`* be defined as follows:
1755
 
1756
  ``` cpp
1757
  template<class Container, class Ref>
1758
- constexpr bool container-insertable = // exposition only
1759
  requires(Container& c, Ref&& ref) {
1760
- requires (requires { c.push_back(std::forward<Ref>(ref)); } ||
 
 
1761
  requires { c.insert(c.end(), std::forward<Ref>(ref)); });
1762
  };
1763
  ```
1764
 
1765
- Let *`container-inserter`* be defined as follows:
1766
 
1767
  ``` cpp
1768
- template<class Ref, class Container>
1769
- constexpr auto container-inserter(Container& c) { // exposition only
1770
- if constexpr (requires { c.push_back(declval<Ref>()); })
1771
- return back_inserter(c);
 
 
 
 
 
1772
  else
1773
- return inserter(c, c.end());
 
1774
  }
1775
  ```
1776
 
1777
  #### `ranges::to` <a id="range.utility.conv.to">[[range.utility.conv.to]]</a>
1778
 
@@ -1808,21 +1913,22 @@ the following manner:
1808
  ``` cpp
1809
  C(ranges::begin(r), ranges::end(r), std::forward<Args>(args)...)
1810
  ```
1811
  - Otherwise, if
1812
  - `constructible_from<C, Args...>` is `true`, and
1813
- - *`container-insertable`*`<C, range_reference_t<R>>` is `true`:
1814
 
1815
  ``` cpp
1816
  C c(std::forward<Args>(args)...);
1817
- if constexpr (sized_range<R> && reservable-container<C>)
1818
- c.reserve(static_cast<range_size_t<C>>(ranges::size(r)));
1819
- ranges::copy(r, container-inserter<range_reference_t<R>>(c));
1820
  ```
 
1821
  - Otherwise, if `input_range<range_reference_t<R>>` is `true`:
1822
  ``` cpp
1823
- to<C>(r | views::transform([](auto&& elem) {
1824
  return to<range_value_t<C>>(std::forward<decltype(elem)>(elem));
1825
  }), std::forward<Args>(args)...);
1826
  ```
1827
  - Otherwise, the program is ill-formed.
1828
 
@@ -1973,10 +2079,11 @@ namespace std::ranges {
1973
 
1974
  constexpr T* begin() noexcept;
1975
  constexpr const T* begin() const noexcept;
1976
  constexpr T* end() noexcept;
1977
  constexpr const T* end() const noexcept;
 
1978
  static constexpr size_t size() noexcept;
1979
  constexpr T* data() noexcept;
1980
  constexpr const T* data() const noexcept;
1981
  };
1982
 
@@ -2018,10 +2125,16 @@ constexpr T* end() noexcept;
2018
  constexpr const T* end() const noexcept;
2019
  ```
2020
 
2021
  *Effects:* Equivalent to: `return data() + 1;`
2022
 
 
 
 
 
 
 
2023
  ``` cpp
2024
  static constexpr size_t size() noexcept;
2025
  ```
2026
 
2027
  *Effects:* Equivalent to: `return 1;`
@@ -2041,22 +2154,28 @@ constexpr const T* data() const noexcept;
2041
  an initial value.
2042
 
2043
  The name `views::iota` denotes a customization point object
2044
  [[customization.point.object]]. Given subexpressions `E` and `F`, the
2045
  expressions `views::iota(E)` and `views::iota(E, F)` are
2046
- expression-equivalent to `iota_view(E)` and `iota_view(E, F)`,
2047
- respectively.
2048
 
2049
  [*Example 1*:
2050
 
2051
  ``` cpp
2052
  for (int i : views::iota(1, 10))
2053
  cout << i << ' '; // prints 1 2 3 4 5 6 7 8 9
2054
  ```
2055
 
2056
  — *end example*]
2057
 
 
 
 
 
 
 
2058
  #### Class template `iota_view` <a id="range.iota.view">[[range.iota.view]]</a>
2059
 
2060
  ``` cpp
2061
  namespace std::ranges {
2062
  template<class I>
@@ -2086,10 +2205,11 @@ namespace std::ranges {
2086
 
2087
  constexpr iterator begin() const;
2088
  constexpr auto end() const;
2089
  constexpr iterator end() const requires same_as<W, Bound>;
2090
 
 
2091
  constexpr auto size() const requires see below;
2092
  };
2093
 
2094
  template<class W, class Bound>
2095
  requires (!is-integer-like<W> || !is-integer-like<Bound> ||
@@ -2233,10 +2353,16 @@ else
2233
  constexpr iterator end() const requires same_as<W, Bound>;
2234
  ```
2235
 
2236
  *Effects:* Equivalent to: `return `*`iterator`*`{`*`bound_`*`};`
2237
 
 
 
 
 
 
 
2238
  ``` cpp
2239
  constexpr auto size() const requires see below;
2240
  ```
2241
 
2242
  *Effects:* Equivalent to:
@@ -2599,12 +2725,12 @@ friend constexpr iter_difference_t<W> operator-(const sentinel& x, const iterato
2599
  the same value.
2600
 
2601
  The name `views::repeat` denotes a customization point object
2602
  [[customization.point.object]]. Given subexpressions `E` and `F`, the
2603
  expressions `views::repeat(E)` and `views::repeat(E, F)` are
2604
- expression-equivalent to `repeat_view(E)` and `repeat_view(E, F)`,
2605
- respectively.
2606
 
2607
  [*Example 1*:
2608
 
2609
  ``` cpp
2610
  for (int i : views::repeat(17, 4))
@@ -2651,12 +2777,12 @@ namespace std::ranges {
2651
  constexpr unreachable_sentinel_t end() const noexcept;
2652
 
2653
  constexpr auto size() const requires (!same_as<Bound, unreachable_sentinel_t>);
2654
  };
2655
 
2656
- template<class T, class Bound>
2657
- repeat_view(T, Bound) -> repeat_view<T, Bound>;
2658
  }
2659
  ```
2660
 
2661
  ``` cpp
2662
  constexpr explicit repeat_view(const T& value, Bound bound = Bound())
@@ -3215,11 +3341,11 @@ exactly like `optional<T>` with the following differences:
3215
  - Otherwise, `movable-box<T>` should store only a `T` if either `T`
3216
  models `movable` or `is_nothrow_move_constructible_v<T>` is `true`.
3217
 
3218
  ### Non-propagating cache <a id="range.nonprop.cache">[[range.nonprop.cache]]</a>
3219
 
3220
- Some types in subclause [[range.adaptors]] are specified in terms of an
3221
  exposition-only class template *`non-propagating-{}cache`*.
3222
  `non-propagating-cache<T>` behaves exactly like `optional<T>` with the
3223
  following differences:
3224
 
3225
  - `non-propagating-cache<T>` constrains its type parameter `T` with
@@ -3294,10 +3420,20 @@ namespace std::ranges {
3294
 
3295
  template<class T>
3296
  constexpr T& as-lvalue(T&& t) { // exposition only
3297
  return static_cast<T&>(t);
3298
  }
 
 
 
 
 
 
 
 
 
 
3299
  }
3300
  ```
3301
 
3302
  ### All view <a id="range.all">[[range.all]]</a>
3303
 
@@ -3341,10 +3477,13 @@ namespace std::ranges {
3341
  { return ranges::empty(*r_); }
3342
 
3343
  constexpr auto size() const requires sized_range<R>
3344
  { return ranges::size(*r_); }
3345
 
 
 
 
3346
  constexpr auto data() const requires contiguous_range<R>
3347
  { return ranges::data(*r_); }
3348
  };
3349
 
3350
  template<class R>
@@ -3414,10 +3553,15 @@ namespace std::ranges {
3414
  constexpr auto size() requires sized_range<R>
3415
  { return ranges::size(r_); }
3416
  constexpr auto size() const requires sized_range<const R>
3417
  { return ranges::size(r_); }
3418
 
 
 
 
 
 
3419
  constexpr auto data() requires contiguous_range<R>
3420
  { return ranges::data(r_); }
3421
  constexpr auto data() const requires contiguous_range<const R>
3422
  { return ranges::data(r_); }
3423
  };
@@ -3442,11 +3586,11 @@ to replace copying with moving.
3442
  The name `views::as_rvalue` denotes a range adaptor object
3443
  [[range.adaptor.object]]. Let `E` be an expression and let `T` be
3444
  `decltype((E))`. The expression `views::as_rvalue(E)` is
3445
  expression-equivalent to:
3446
 
3447
- - `views::all(E)` if
3448
  `same_as<range_rvalue_reference_t<T>, range_reference_t<T>>` is
3449
  `true`.
3450
  - Otherwise, `as_rvalue_view(E)`.
3451
 
3452
  [*Example 1*:
@@ -3496,10 +3640,15 @@ namespace std::ranges {
3496
  }
3497
  }
3498
 
3499
  constexpr auto size() requires sized_range<V> { return ranges::size(base_); }
3500
  constexpr auto size() const requires sized_range<const V> { return ranges::size(base_); }
 
 
 
 
 
3501
  };
3502
 
3503
  template<class R>
3504
  as_rvalue_view(R&&) -> as_rvalue_view<views::all_t<R>>;
3505
  }
@@ -3883,10 +4032,15 @@ namespace std::ranges {
3883
  regular_invocable<const F&, range_reference_t<const V>>;
3884
 
3885
  constexpr auto size() requires sized_range<V> { return ranges::size(base_); }
3886
  constexpr auto size() const requires sized_range<const V>
3887
  { return ranges::size(base_); }
 
 
 
 
 
3888
  };
3889
 
3890
  template<class R, class F>
3891
  transform_view(R&&, F) -> transform_view<views::all_t<R>, F>;
3892
  }
@@ -4466,10 +4620,26 @@ namespace std::ranges {
4466
 
4467
  constexpr auto size() const requires sized_range<const V> {
4468
  auto n = ranges::size(base_);
4469
  return ranges::min(n, static_cast<decltype(n)>(count_));
4470
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4471
  };
4472
 
4473
  template<class R>
4474
  take_view(R&&, range_difference_t<R>)
4475
  -> take_view<views::all_t<R>>;
@@ -4719,12 +4889,12 @@ expression `views::drop(E, F)` is expression-equivalent to:
4719
  then
4720
  `U(ranges::begin(E) + std::min<D>(ranges::distance(E), F), ranges::end(E))`,
4721
  except that `E` is evaluated only once, where `U` is
4722
  `span<typename T::element_type>` if `T` is a specialization of `span`
4723
  and `T` otherwise.
4724
- - Otherwise, if `T` is a specialization of `subrange` [[range.subrange]]
4725
- that models `random_access_range` and `sized_range`, then
4726
  `T(ranges::begin(E) + std::min<D>(ranges::distance(E), F), ranges::{}end(E),
4727
  to-unsigned-like(ranges::distance(E) -
4728
  std::min<D>(ranges::distance(E), F)))`, except that `E` and `F` are
4729
  each evaluated only once.
4730
  - Otherwise, if `T` is a specialization of `repeat_view`
@@ -4785,10 +4955,20 @@ namespace std::ranges {
4785
  const auto s = ranges::size(base_);
4786
  const auto c = static_cast<decltype(s)>(count_);
4787
  return s < c ? 0 : s - c;
4788
  }
4789
 
 
 
 
 
 
 
 
 
 
 
4790
  private:
4791
  V base_ = V(); // exposition only
4792
  range_difference_t<V> count_ = 0; // exposition only
4793
  };
4794
 
@@ -5291,11 +5471,11 @@ friend constexpr void iter_swap(const iterator& x, const iterator& y)
5291
  noexcept(noexcept(ranges::iter_swap(*x.inner_, *y.inner_)))
5292
  requires indirectly_swappable<InnerIter>;
5293
  ```
5294
 
5295
  *Effects:* Equivalent to:
5296
- `return ranges::iter_swap(*x.`*`inner_`*`, *y.`*`inner_`*`);`
5297
 
5298
  #### Class template `join_view::sentinel` <a id="range.join.sentinel">[[range.join.sentinel]]</a>
5299
 
5300
  ``` cpp
5301
  namespace std::ranges {
@@ -5370,23 +5550,17 @@ for (char c : vs | views::join_with('-')) {
5370
 
5371
  #### Class template `join_with_view` <a id="range.join.with.view">[[range.join.with.view]]</a>
5372
 
5373
  ``` cpp
5374
  namespace std::ranges {
5375
- template<class R, class P>
5376
- concept compatible-joinable-ranges = // exposition only
5377
- common_with<range_value_t<R>, range_value_t<P>> &&
5378
- common_reference_with<range_reference_t<R>, range_reference_t<P>> &&
5379
- common_reference_with<range_rvalue_reference_t<R>, range_rvalue_reference_t<P>>;
5380
-
5381
  template<class R>
5382
  concept bidirectional-common = bidirectional_range<R> && common_range<R>; // exposition only
5383
 
5384
  template<input_range V, forward_range Pattern>
5385
  requires view<V> && input_range<range_reference_t<V>>
5386
  && view<Pattern>
5387
- && compatible-joinable-ranges<range_reference_t<V>, Pattern>
5388
  class join_with_view : public view_interface<join_with_view<V, Pattern>> {
5389
  using InnerRng = range_reference_t<V>; // exposition only
5390
 
5391
  V base_ = V(); // exposition only
5392
  non-propagating-cache<iterator_t<V>> outer_it_; // exposition only, present only
@@ -5428,11 +5602,12 @@ namespace std::ranges {
5428
  }
5429
  constexpr auto begin() const
5430
  requires forward_range<const V> &&
5431
  forward_range<const Pattern> &&
5432
  is_reference_v<range_reference_t<const V>> &&
5433
- input_range<range_reference_t<const V>> {
 
5434
  return iterator<true>{*this, ranges::begin(base_)};
5435
  }
5436
 
5437
  constexpr auto end() {
5438
  if constexpr (forward_range<V> &&
@@ -5443,11 +5618,12 @@ namespace std::ranges {
5443
  return sentinel<simple-view<V> && simple-view<Pattern>>{*this};
5444
  }
5445
  constexpr auto end() const
5446
  requires forward_range<const V> && forward_range<const Pattern> &&
5447
  is_reference_v<range_reference_t<const V>> &&
5448
- input_range<range_reference_t<const V>> {
 
5449
  using InnerConstRng = range_reference_t<const V>;
5450
  if constexpr (forward_range<InnerConstRng> &&
5451
  common_range<const V> && common_range<InnerConstRng>)
5452
  return iterator<true>{*this, ranges::end(base_)};
5453
  else
@@ -5485,11 +5661,11 @@ and *pattern\_* with `views::single(std::move(e))`.
5485
 
5486
  ``` cpp
5487
  namespace std::ranges {
5488
  template<input_range V, forward_range Pattern>
5489
  requires view<V> && input_range<range_reference_t<V>>
5490
- && view<Pattern> && compatible-joinable-ranges<range_reference_t<V>, Pattern>
5491
  template<bool Const>
5492
  class join_with_view<V, Pattern>::iterator {
5493
  using Parent = maybe-const<Const, join_with_view>; // exposition only
5494
  using Base = maybe-const<Const, V>; // exposition only
5495
  using InnerBase = range_reference_t<Base>; // exposition only
@@ -5588,11 +5764,11 @@ as follows:
5588
  iter_reference_t<PatternIter>>>
5589
  ```
5590
 
5591
  is `false`, `iterator_category` denotes `input_iterator_tag`.
5592
  - Otherwise, if *OUTERC*, *INNERC*, and *PATTERNC* each model
5593
- `derived_from<bidirectional_iterator_category>` and *`InnerBase`* and
5594
  *`PatternBase`* each model `common_range`, `iterator_category` denotes
5595
  `bidirectional_iterator_tag`.
5596
  - Otherwise, if *OUTERC*, *INNERC*, and *PATTERNC* each model
5597
  `derived_from<forward_iterator_tag>`, `iterator_category` denotes
5598
  `forward_iterator_tag`.
@@ -5656,20 +5832,20 @@ constexpr void satisfy();
5656
  ``` cpp
5657
  while (true) {
5658
  if (inner_it_.index() == 0) {
5659
  if (std::get<0>(inner_it_) != ranges::end(parent_->pattern_))
5660
  break;
5661
- inner_it_.emplace<1>(ranges::begin(update-inner()));
5662
  } else {
5663
  if (std::get<1>(inner_it_) != ranges::end(get-inner()))
5664
  break;
5665
  if (++outer() == ranges::end(parent_->base_)) {
5666
  if constexpr (ref-is-glvalue)
5667
- inner_it_.emplace<0>();
5668
  break;
5669
  }
5670
- inner_it_.emplace<0>(ranges::begin(parent_->pattern_));
5671
  }
5672
  }
5673
  ```
5674
 
5675
  [*Note 1*: `join_with_view` iterators use the *satisfy* function to
@@ -5686,11 +5862,11 @@ constexpr explicit iterator(Parent& parent)
5686
  first overload, also initializes *outer_it\_* with `std::move(outer)`.
5687
  Then, equivalent to:
5688
 
5689
  ``` cpp
5690
  if (outer() != ranges::end(parent_->base_)) {
5691
- inner_it_.emplace<1>(ranges::begin(update-inner()));
5692
  satisfy();
5693
  }
5694
  ```
5695
 
5696
  ``` cpp
@@ -5703,13 +5879,13 @@ constexpr iterator(iterator<!Const> i)
5703
  *Effects:* Initializes *outer_it\_* with `std::move(i.`*`outer_it_`*`)`
5704
  and *parent\_* with `i.`*`parent_`*. Then, equivalent to:
5705
 
5706
  ``` cpp
5707
  if (i.inner_it_.index() == 0)
5708
- inner_it_.emplace<0>(std::get<0>(std::move(i.inner_it_)));
5709
  else
5710
- inner_it_.emplace<1>(std::get<1>(std::move(i.inner_it_)));
5711
  ```
5712
 
5713
  [*Note 2*: `Const` can only be `true` when *Base* models
5714
  `forward_range`. — *end note*]
5715
 
@@ -5765,27 +5941,27 @@ constexpr iterator& operator--()
5765
  *Effects:* Equivalent to:
5766
 
5767
  ``` cpp
5768
  if (outer_it_ == ranges::end(parent_->base_)) {
5769
  auto&& inner = *--outer_it_;
5770
- inner_it_.emplace<1>(ranges::end(inner));
5771
  }
5772
 
5773
  while (true) {
5774
  if (inner_it_.index() == 0) {
5775
  auto& it = std::get<0>(inner_it_);
5776
  if (it == ranges::begin(parent_->pattern_)) {
5777
  auto&& inner = *--outer_it_;
5778
- inner_it_.emplace<1>(ranges::end(inner));
5779
  } else {
5780
  break;
5781
  }
5782
  } else {
5783
  auto& it = std::get<1>(inner_it_);
5784
  auto&& inner = *outer_it_;
5785
  if (it == ranges::begin(inner)) {
5786
- inner_it_.emplace<0>(ranges::end(parent_->pattern_));
5787
  } else {
5788
  break;
5789
  }
5790
  }
5791
  }
@@ -5823,11 +5999,11 @@ return x.outer_it_ == y.outer_it_ && x.inner_it_ == y.inner_it_;
5823
 
5824
  ``` cpp
5825
  namespace std::ranges {
5826
  template<input_range V, forward_range Pattern>
5827
  requires view<V> && input_range<range_reference_t<V>>
5828
- && view<Pattern> && compatible-joinable-ranges<range_reference_t<V>, Pattern>
5829
  template<bool Const>
5830
  class join_with_view<V, Pattern>::sentinel {
5831
  using Parent = maybe-const<Const, join_with_view>; // exposition only
5832
  using Base = maybe-const<Const, V>; // exposition only
5833
  sentinel_t<Base> end_ = sentinel_t<Base>(); // exposition only
@@ -6072,12 +6248,13 @@ constexpr outer-iterator(Parent& parent, iterator_t<Base> current)
6072
  ``` cpp
6073
  constexpr outer-iterator(outer-iterator<!Const> i)
6074
  requires Const && convertible_to<iterator_t<V>, iterator_t<Base>>;
6075
  ```
6076
 
6077
- *Effects:* Initializes *parent\_* with `i.`*`parent_`* and *current\_*
6078
- with `std::move(i.`*`current_`*`)`.
 
6079
 
6080
  ``` cpp
6081
  constexpr value_type operator*() const;
6082
  ```
6083
 
@@ -6152,14 +6329,13 @@ namespace std::ranges {
6152
  struct lazy_split_view<V, Pattern>::outer-iterator<Const>::value_type
6153
  : view_interface<value_type> {
6154
  private:
6155
  outer-iterator i_ = outer-iterator(); // exposition only
6156
 
6157
- public:
6158
- value_type() = default;
6159
- constexpr explicit value_type(outer-iterator i);
6160
 
 
6161
  constexpr inner-iterator<Const> begin() const;
6162
  constexpr default_sentinel_t end() const noexcept;
6163
  };
6164
  }
6165
  ```
@@ -6197,11 +6373,11 @@ namespace std::ranges {
6197
  using Base = maybe-const<Const, V>; // exposition only
6198
  outer-iterator<Const> i_ = outer-iterator<Const>(); // exposition only
6199
  bool incremented_ = false; // exposition only
6200
 
6201
  public:
6202
- using iterator_concept = typename outer-iterator<Const>::iterator_concept;
6203
 
6204
  using iterator_category = see belownc; // present only if Base
6205
  // models forward_range
6206
  using value_type = range_value_t<Base>;
6207
  using difference_type = range_difference_t<Base>;
@@ -6492,17 +6668,17 @@ constexpr iterator(split_view& parent, iterator_t<V> current, subrange<iterator_
6492
 
6493
  ``` cpp
6494
  constexpr iterator_t<V> base() const;
6495
  ```
6496
 
6497
- *Effects:* Equivalent to `return `*`cur_`*`;`
6498
 
6499
  ``` cpp
6500
  constexpr value_type operator*() const;
6501
  ```
6502
 
6503
- *Effects:* Equivalent to `return {`*`cur_`*`, `*`next_`*`.begin()};`
6504
 
6505
  ``` cpp
6506
  constexpr iterator& operator++();
6507
  ```
6508
 
@@ -6577,10 +6753,798 @@ friend constexpr bool operator==(const iterator& x, const sentinel& y);
6577
  ```
6578
 
6579
  *Effects:* Equivalent to:
6580
  `return x.`*`cur_`*` == y.`*`end_`*` && !x.`*`trailing_empty_`*`;`
6581
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6582
  ### Counted view <a id="range.counted">[[range.counted]]</a>
6583
 
6584
  A counted view presents a view of the elements of the counted range
6585
  [[iterator.requirements.general]] `i`+\[0, `n`) for an iterator `i` and
6586
  non-negative integer `n`.
@@ -6657,11 +7621,11 @@ namespace std::ranges {
6657
  constexpr explicit common_view(V r);
6658
 
6659
  constexpr V base() const & requires copy_constructible<V> { return base_; }
6660
  constexpr V base() && { return std::move(base_); }
6661
 
6662
- constexpr auto begin() {
6663
  if constexpr (random_access_range<V> && sized_range<V>)
6664
  return ranges::begin(base_);
6665
  else
6666
  return common_iterator<iterator_t<V>, sentinel_t<V>>(ranges::begin(base_));
6667
  }
@@ -6671,11 +7635,11 @@ namespace std::ranges {
6671
  return ranges::begin(base_);
6672
  else
6673
  return common_iterator<iterator_t<const V>, sentinel_t<const V>>(ranges::begin(base_));
6674
  }
6675
 
6676
- constexpr auto end() {
6677
  if constexpr (random_access_range<V> && sized_range<V>)
6678
  return ranges::begin(base_) + ranges::distance(base_);
6679
  else
6680
  return common_iterator<iterator_t<V>, sentinel_t<V>>(ranges::end(base_));
6681
  }
@@ -6691,10 +7655,17 @@ namespace std::ranges {
6691
  return ranges::size(base_);
6692
  }
6693
  constexpr auto size() const requires sized_range<const V> {
6694
  return ranges::size(base_);
6695
  }
 
 
 
 
 
 
 
6696
  };
6697
 
6698
  template<class R>
6699
  common_view(R&&) -> common_view<views::all_t<R>>;
6700
  }
@@ -6716,25 +7687,20 @@ iterates the same elements in reverse order.
6716
  The name `views::reverse` denotes a range adaptor object
6717
  [[range.adaptor.object]]. Given a subexpression `E`, the expression
6718
  `views::reverse(E)` is expression-equivalent to:
6719
 
6720
  - If the type of `E` is a (possibly cv-qualified) specialization of
6721
- `reverse_view`, equivalent to `E.base()`.
6722
  - Otherwise, if the type of `E` is cv
6723
  `subrange<reverse_iterator<I>, reverse_iterator<I>, K>` for some
6724
  iterator type `I` and value `K` of type `subrange_kind`,
6725
- - if `K` is `subrange_kind::sized`, equivalent to:
6726
- ``` cpp
6727
- subrange<I, I, K>(E.end().base(), E.begin().base(), E.size())
6728
- ```
6729
- - otherwise, equivalent to:
6730
- ``` cpp
6731
- subrange<I, I, K>(E.end().base(), E.begin().base())
6732
- ```
6733
 
6734
  However, in either case `E` is evaluated only once.
6735
- - Otherwise, equivalent to `reverse_view{E}`.
6736
 
6737
  [*Example 1*:
6738
 
6739
  ``` cpp
6740
  vector<int> is {0,1,2,3,4};
@@ -6774,10 +7740,17 @@ namespace std::ranges {
6774
  }
6775
 
6776
  constexpr auto size() const requires sized_range<const V> {
6777
  return ranges::size(base_);
6778
  }
 
 
 
 
 
 
 
6779
  };
6780
 
6781
  template<class R>
6782
  reverse_view(R&&) -> reverse_view<views::all_t<R>>;
6783
  }
@@ -6878,10 +7851,15 @@ namespace std::ranges {
6878
  constexpr auto end() requires (!simple-view<V>) { return ranges::cend(base_); }
6879
  constexpr auto end() const requires range<const V> { return ranges::cend(base_); }
6880
 
6881
  constexpr auto size() requires sized_range<V> { return ranges::size(base_); }
6882
  constexpr auto size() const requires sized_range<const V> { return ranges::size(base_); }
 
 
 
 
 
6883
  };
6884
 
6885
  template<class R>
6886
  as_const_view(R&&) -> as_const_view<views::all_t<R>>;
6887
  }
@@ -7002,10 +7980,16 @@ namespace std::ranges {
7002
  { return ranges::size(base_); }
7003
 
7004
  constexpr auto size() const requires sized_range<const V>
7005
  { return ranges::size(base_); }
7006
 
 
 
 
 
 
 
7007
  private:
7008
  // [range.elements.iterator], class template elements_view::iterator
7009
  template<bool> class iterator; // exposition only
7010
 
7011
  // [range.elements.sentinel], class template elements_view::sentinel
@@ -7394,13 +8378,13 @@ friend constexpr range_difference_t<maybe-const<OtherConst, V>>
7394
  #### Overview <a id="range.enumerate.overview">[[range.enumerate.overview]]</a>
7395
 
7396
  `enumerate_view` is a view whose elements represent both the position
7397
  and value from a sequence of elements.
7398
 
7399
- The name `views::enumerate` denotes a range adaptor object. Given a
7400
- subexpression `E`, the expression `views::enumerate(E)` is
7401
- expression-equivalent to
7402
  `enumerate_view<views::all_t<decltype((E))>>(E)`.
7403
 
7404
  [*Example 1*:
7405
 
7406
  ``` cpp
@@ -7436,27 +8420,32 @@ namespace std::ranges {
7436
  { return iterator<false>(ranges::begin(base_), 0); }
7437
  constexpr auto begin() const requires range-with-movable-references<const V>
7438
  { return iterator<true>(ranges::begin(base_), 0); }
7439
 
7440
  constexpr auto end() requires (!simple-view<V>) {
7441
- if constexpr (common_range<V> && sized_range<V>)
7442
  return iterator<false>(ranges::end(base_), ranges::distance(base_));
7443
  else
7444
  return sentinel<false>(ranges::end(base_));
7445
  }
7446
  constexpr auto end() const requires range-with-movable-references<const V> {
7447
- if constexpr (common_range<const V> && sized_range<const V>)
7448
  return iterator<true>(ranges::end(base_), ranges::distance(base_));
7449
  else
7450
  return sentinel<true>(ranges::end(base_));
7451
  }
7452
 
7453
  constexpr auto size() requires sized_range<V>
7454
  { return ranges::size(base_); }
7455
  constexpr auto size() const requires sized_range<const V>
7456
  { return ranges::size(base_); }
7457
 
 
 
 
 
 
7458
  constexpr V base() const & requires copy_constructible<V> { return base_; }
7459
  constexpr V base() && { return std::move(base_); }
7460
  };
7461
 
7462
  template<class R>
@@ -7532,11 +8521,11 @@ namespace std::ranges {
7532
  requires random_access_range<Base>;
7533
  friend constexpr iterator operator+(difference_type x, const iterator& y)
7534
  requires random_access_range<Base>;
7535
  friend constexpr iterator operator-(const iterator& x, difference_type y)
7536
  requires random_access_range<Base>;
7537
- friend constexpr difference_type operator-(const iterator& x, const iterator& y);
7538
 
7539
  friend constexpr auto iter_move(const iterator& i)
7540
  noexcept(noexcept(ranges::iter_move(i.current_)) &&
7541
  is_nothrow_move_constructible_v<range_rvalue_reference_t<Base>>) {
7542
  return tuple<difference_type,
@@ -7714,11 +8703,11 @@ auto temp = x;
7714
  temp -= y;
7715
  return temp;
7716
  ```
7717
 
7718
  ``` cpp
7719
- friend constexpr difference_type operator-(const iterator& x, const iterator& y);
7720
  ```
7721
 
7722
  *Effects:* Equivalent to: `return x.`*`pos_`*` - y.`*`pos_`*`;`
7723
 
7724
  #### Class template `enumerate_view::sentinel` <a id="range.enumerate.sentinel">[[range.enumerate.sentinel]]</a>
@@ -7925,20 +8914,10 @@ return apply([](auto... sizes) {
7925
 
7926
  #### Class template `zip_view::iterator` <a id="range.zip.iterator">[[range.zip.iterator]]</a>
7927
 
7928
  ``` cpp
7929
  namespace std::ranges {
7930
- template<bool Const, class... Views>
7931
- concept all-random-access = // exposition only
7932
- (random_access_range<maybe-const<Const, Views>> && ...);
7933
- template<bool Const, class... Views>
7934
- concept all-bidirectional = // exposition only
7935
- (bidirectional_range<maybe-const<Const, Views>> && ...);
7936
- template<bool Const, class... Views>
7937
- concept all-forward = // exposition only
7938
- (forward_range<maybe-const<Const, Views>> && ...);
7939
-
7940
  template<input_range... Views>
7941
  requires (view<Views> && ...) && (sizeof...(Views) > 0)
7942
  template<bool Const>
7943
  class zip_view<Views...>::iterator {
7944
  tuple<iterator_t<maybe-const<Const, Views>>...> current_; // exposition only
@@ -8305,11 +9284,11 @@ template<bool OtherConst>
8305
  iterator_t<maybe-const<OtherConst, Views>>> && ...)
8306
  friend constexpr common_type_t<range_difference_t<maybe-const<OtherConst, Views>>...>
8307
  operator-(const sentinel& y, const iterator<OtherConst>& x);
8308
  ```
8309
 
8310
- *Effects:* Equivalent to `return -(x - y);`
8311
 
8312
  ### Zip transform view <a id="range.zip.transform">[[range.zip.transform]]</a>
8313
 
8314
  #### Overview <a id="range.zip.transform.overview">[[range.zip.transform.overview]]</a>
8315
 
@@ -8440,11 +9419,11 @@ namespace std::ranges {
8440
 
8441
  constexpr iterator(Parent& parent, ziperator<Const> inner); // exposition only
8442
 
8443
  public:
8444
  using iterator_category = see belownc; // not always present
8445
- using iterator_concept = typename ziperator<Const>::iterator_concept;
8446
  using value_type =
8447
  remove_cvref_t<invoke_result_t<maybe-const<Const, F>&,
8448
  range_reference_t<maybe-const<Const, Views>>...>>;
8449
  using difference_type = range_difference_t<Base>;
8450
 
@@ -8743,11 +9722,12 @@ resulting view is empty.
8743
  The name `views::adjacent<N>` denotes a range adaptor object
8744
  [[range.adaptor.object]]. Given a subexpression `E` and a constant
8745
  expression `N`, the expression `views::adjacent<N>(E)` is
8746
  expression-equivalent to
8747
 
8748
- - `((void)E, auto(views::empty<tuple<>>))` if `N` is equal to `0`,
 
8749
  - otherwise, `adjacent_view<views::all_t<decltype((E))>, N>(E)`.
8750
 
8751
  [*Example 1*:
8752
 
8753
  ``` cpp
@@ -8811,10 +9791,13 @@ namespace std::ranges {
8811
  }
8812
  }
8813
 
8814
  constexpr auto size() requires sized_range<V>;
8815
  constexpr auto size() const requires sized_range<const V>;
 
 
 
8816
  };
8817
  }
8818
  ```
8819
 
8820
  ``` cpp
@@ -8836,10 +9819,25 @@ using CT = common_type_t<ST, size_t>;
8836
  auto sz = static_cast<CT>(ranges::size(base_));
8837
  sz -= std::min<CT>(sz, N - 1);
8838
  return static_cast<ST>(sz);
8839
  ```
8840
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8841
  #### Class template `adjacent_view::iterator` <a id="range.adjacent.iterator">[[range.adjacent.iterator]]</a>
8842
 
8843
  ``` cpp
8844
  namespace std::ranges {
8845
  template<forward_range V, size_t N>
@@ -9232,13 +10230,14 @@ resulting view is empty.
9232
 
9233
  The name `views::adjacent_transform<N>` denotes a range adaptor object
9234
  [[range.adaptor.object]]. Given subexpressions `E` and `F` and a
9235
  constant expression `N`:
9236
 
9237
- - If `N` is equal to `0`, `views::adjacent_transform<N>(E, F)` is
9238
- expression-equivalent to `((void)E, views::zip_transform(F))`, except
9239
- that the evaluations of `E` and `F` are indeterminately sequenced.
 
9240
  - Otherwise, the expression `views::adjacent_transform<N>(E, F)` is
9241
  expression-equivalent to
9242
  `adjacent_transform_view<views::all_t<decltype((E))>, decay_t<decltype((F))>, N>(E, F)`.
9243
 
9244
  [*Example 1*:
@@ -9279,11 +10278,11 @@ namespace std::ranges {
9279
 
9280
  public:
9281
  adjacent_transform_view() = default;
9282
  constexpr explicit adjacent_transform_view(V base, F fun);
9283
 
9284
- constexpr V base() const & requires copy_constructible<InnerView> { return inner_.base(); }
9285
  constexpr V base() && { return std::move(inner_).base(); }
9286
 
9287
  constexpr auto begin() {
9288
  return iterator<false>(*this, inner_.begin());
9289
  }
@@ -9317,10 +10316,18 @@ namespace std::ranges {
9317
  }
9318
 
9319
  constexpr auto size() const requires sized_range<const InnerView> {
9320
  return inner_.size();
9321
  }
 
 
 
 
 
 
 
 
9322
  };
9323
  }
9324
  ```
9325
 
9326
  ``` cpp
@@ -9347,11 +10354,11 @@ namespace std::ranges {
9347
 
9348
  constexpr iterator(Parent& parent, inner-iterator<Const> inner); // exposition only
9349
 
9350
  public:
9351
  using iterator_category = see below;
9352
- using iterator_concept = typename inner-iterator<Const>::iterator_concept;
9353
  using value_type =
9354
  remove_cvref_t<invoke_result_t<maybe-const<Const, F>&,
9355
  REPEAT(range_reference_t<Base>, N)...>>;
9356
  using difference_type = range_difference_t<Base>;
9357
 
@@ -9621,11 +10628,11 @@ constexpr sentinel(sentinel<!Const> i)
9621
  template<bool OtherConst>
9622
  requires sentinel_for<inner-sentinel<Const>, inner-iterator<OtherConst>>
9623
  friend constexpr bool operator==(const iterator<OtherConst>& x, const sentinel& y);
9624
  ```
9625
 
9626
- *Effects:* Equivalent to `return x.`*`inner_`*` == y.`*`inner_`*`;`
9627
 
9628
  ``` cpp
9629
  template<bool OtherConst>
9630
  requires sized_sentinel_for<inner-sentinel<Const>, inner-iterator<OtherConst>>
9631
  friend constexpr range_difference_t<maybe-const<OtherConst, InnerView>>
@@ -9635,11 +10642,11 @@ template<bool OtherConst>
9635
  requires sized_sentinel_for<inner-sentinel<Const>, inner-iterator<OtherConst>>
9636
  friend constexpr range_difference_t<maybe-const<OtherConst, InnerView>>
9637
  operator-(const sentinel& x, const iterator<OtherConst>& y);
9638
  ```
9639
 
9640
- *Effects:* Equivalent to `return x.`*`inner_`*` - y.`*`inner_`*`;`
9641
 
9642
  ### Chunk view <a id="range.chunk">[[range.chunk]]</a>
9643
 
9644
  #### Overview <a id="range.chunk.overview">[[range.chunk.overview]]</a>
9645
 
@@ -9708,10 +10715,13 @@ namespace std::ranges {
9708
  constexpr outer-iterator begin();
9709
  constexpr default_sentinel_t end() const noexcept;
9710
 
9711
  constexpr auto size() requires sized_range<V>;
9712
  constexpr auto size() const requires sized_range<const V>;
 
 
 
9713
  };
9714
 
9715
  template<class R>
9716
  chunk_view(R&&, range_difference_t<R>) -> chunk_view<views::all_t<R>>;
9717
  }
@@ -9753,10 +10763,22 @@ constexpr auto size() const requires sized_range<const V>;
9753
 
9754
  ``` cpp
9755
  return to-unsigned-like(div-ceil(ranges::distance(base_), n_));
9756
  ```
9757
 
 
 
 
 
 
 
 
 
 
 
 
 
9758
  #### Class `chunk_view::outer-iterator` <a id="range.chunk.outer.iter">[[range.chunk.outer.iter]]</a>
9759
 
9760
  ``` cpp
9761
  namespace std::ranges {
9762
  template<view V>
@@ -9872,10 +10894,12 @@ namespace std::ranges {
9872
  constexpr inner-iterator begin() const noexcept;
9873
  constexpr default_sentinel_t end() const noexcept;
9874
 
9875
  constexpr auto size() const
9876
  requires sized_sentinel_for<sentinel_t<V>, iterator_t<V>>;
 
 
9877
  };
9878
  }
9879
  ```
9880
 
9881
  ``` cpp
@@ -9906,10 +10930,20 @@ constexpr auto size() const
9906
  ``` cpp
9907
  return to-unsigned-like(ranges::min(parent_->remainder_,
9908
  ranges::end(parent_->base_) - *parent_->current_));
9909
  ```
9910
 
 
 
 
 
 
 
 
 
 
 
9911
  #### Class `chunk_view::inner-iterator` <a id="range.chunk.inner.iter">[[range.chunk.inner.iter]]</a>
9912
 
9913
  ``` cpp
9914
  namespace std::ranges {
9915
  template<view V>
@@ -10084,10 +11118,13 @@ namespace std::ranges {
10084
  }
10085
  }
10086
 
10087
  constexpr auto size() requires sized_range<V>;
10088
  constexpr auto size() const requires sized_range<const V>;
 
 
 
10089
  };
10090
  }
10091
  ```
10092
 
10093
  ``` cpp
@@ -10108,10 +11145,22 @@ constexpr auto size() const requires sized_range<const V>;
10108
 
10109
  ``` cpp
10110
  return to-unsigned-like(div-ceil(ranges::distance(base_), n_));
10111
  ```
10112
 
 
 
 
 
 
 
 
 
 
 
 
 
10113
  #### Class template `chunk_view::iterator` for forward ranges <a id="range.chunk.fwd.iter">[[range.chunk.fwd.iter]]</a>
10114
 
10115
  ``` cpp
10116
  namespace std::ranges {
10117
  template<view V>
@@ -10484,10 +11533,13 @@ namespace std::ranges {
10484
  requires (!(simple-view<V> && slide-caches-nothing<const V>));
10485
  constexpr auto end() const requires slide-caches-nothing<const V>;
10486
 
10487
  constexpr auto size() requires sized_range<V>;
10488
  constexpr auto size() const requires sized_range<const V>;
 
 
 
10489
  };
10490
 
10491
  template<class R>
10492
  slide_view(R&&, range_difference_t<R>) -> slide_view<views::all_t<R>>;
10493
  }
@@ -10571,10 +11623,24 @@ constexpr auto size() const requires sized_range<const V>;
10571
  auto sz = ranges::distance(base_) - n_ + 1;
10572
  if (sz < 0) sz = 0;
10573
  return to-unsigned-like(sz);
10574
  ```
10575
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10576
  #### Class template `slide_view::iterator` <a id="range.slide.iterator">[[range.slide.iterator]]</a>
10577
 
10578
  ``` cpp
10579
  namespace std::ranges {
10580
  template<forward_range V>
@@ -11238,10 +12304,13 @@ namespace std::ranges {
11238
  }
11239
  }
11240
 
11241
  constexpr auto size() requires sized_range<V>;
11242
  constexpr auto size() const requires sized_range<const V>;
 
 
 
11243
  };
11244
 
11245
  template<class R>
11246
  stride_view(R&&, range_difference_t<R>) -> stride_view<views::all_t<R>>;
11247
  }
@@ -11271,10 +12340,22 @@ constexpr auto size() const requires sized_range<const V>;
11271
 
11272
  ``` cpp
11273
  return to-unsigned-like(div-ceil(ranges::distance(base_), stride_));
11274
  ```
11275
 
 
 
 
 
 
 
 
 
 
 
 
 
11276
  #### Class template `stride_view::iterator` <a id="range.stride.iterator">[[range.stride.iterator]]</a>
11277
 
11278
  ``` cpp
11279
  namespace std::ranges {
11280
  template<input_range V>
@@ -11432,11 +12513,11 @@ return *this;
11432
 
11433
  ``` cpp
11434
  constexpr void operator++(int);
11435
  ```
11436
 
11437
- *Effects:* Equivalent to: `++*this;`
11438
 
11439
  ``` cpp
11440
  constexpr iterator operator++(int) requires forward_range<Base>;
11441
  ```
11442
 
@@ -11674,11 +12755,11 @@ namespace std::ranges {
11674
  concept cartesian-product-is-bidirectional = // exposition only
11675
  (bidirectional_range<maybe-const<Const, First>> && ... &&
11676
  (bidirectional_range<maybe-const<Const, Vs>>
11677
  && cartesian-product-common-arg<maybe-const<Const, Vs>>));
11678
 
11679
- template<class First, class... Vs>
11680
  concept cartesian-product-is-common = // exposition only
11681
  cartesian-product-common-arg<First>;
11682
 
11683
  template<class... Vs>
11684
  concept cartesian-product-is-sized = // exposition only
@@ -12217,10 +13298,500 @@ ranges::iter_swap(std::get<i>(l.current_), std::get<i>(r.current_))
12217
  the following expressions:
12218
 
12219
  - `noexcept(ranges::iter_swap(std::get<`i`>(l.`*`current_`*`), std::get<`i`>(r.`*`current_`*`)))`
12220
  for every integer 0 ≤ i ≤ `sizeof...(Vs)`.
12221
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12222
  ## Range generators <a id="coro.generator">[[coro.generator]]</a>
12223
 
12224
  ### Overview <a id="coroutine.generator.overview">[[coroutine.generator.overview]]</a>
12225
 
12226
  Class template `generator` presents a view of the elements yielded by
@@ -12252,29 +13823,29 @@ void f() {
12252
  ### Header `<generator>` synopsis <a id="generator.syn">[[generator.syn]]</a>
12253
 
12254
  ``` cpp
12255
  namespace std {
12256
  // [coro.generator.class], class template generator
12257
- template<class Ref, class V = void, class Allocator = void>
12258
  class generator;
12259
 
12260
  namespace pmr {
12261
- template<class R, class V = void>
12262
- using generator = std::generator<R, V, polymorphic_allocator<>>;
12263
  }
12264
  }
12265
  ```
12266
 
12267
  ### Class template `generator` <a id="coro.generator.class">[[coro.generator.class]]</a>
12268
 
12269
  ``` cpp
12270
  namespace std {
12271
- template<class Ref, class V = void, class Allocator = void>
12272
- class generator : public ranges::view_interface<generator<Ref, V, Allocator>> {
12273
  private:
12274
- using value = conditional_t<is_void_v<V>, remove_cvref_t<Ref>, V>; // exposition only
12275
- using reference = conditional_t<is_void_v<V>, Ref&&, Ref>; // exposition only
12276
 
12277
  // [coro.generator.iterator], class generator::iterator
12278
  class iterator; // exposition only
12279
 
12280
  public:
@@ -12333,11 +13904,11 @@ undefined.
12333
  generator(generator&& other) noexcept;
12334
  ```
12335
 
12336
  *Effects:* Initializes *coroutine\_* with
12337
  `exchange(other.`*`coroutine_`*`, {})` and *active\_* with
12338
- `exchange(other.active_, nullptr)`.
12339
 
12340
  [*Note 1*: Iterators previously obtained from `other` are not
12341
  invalidated; they become iterators into `*this`. — *end note*]
12342
 
12343
  ``` cpp
@@ -12397,12 +13968,12 @@ default_sentinel_t end() const noexcept;
12397
 
12398
  ### Class `generator::promise_type` <a id="coro.generator.promise">[[coro.generator.promise]]</a>
12399
 
12400
  ``` cpp
12401
  namespace std {
12402
- template<class Ref, class V, class Allocator>
12403
- class generator<Ref, V, Allocator>::promise_type {
12404
  public:
12405
  generator get_return_object() noexcept;
12406
 
12407
  suspend_always initial_suspend() const noexcept { return {}; }
12408
  auto final_suspend() noexcept;
@@ -12414,29 +13985,30 @@ namespace std {
12414
  constructible_from<remove_cvref_t<yielded>, const remove_reference_t<yielded>&>;
12415
 
12416
  template<class R2, class V2, class Alloc2, class Unused>
12417
  requires same_as<typename generator<R2, V2, Alloc2>::yielded, yielded>
12418
  auto yield_value(ranges::elements_of<generator<R2, V2, Alloc2>&&, Unused> g) noexcept;
 
 
 
12419
 
12420
  template<ranges::input_range R, class Alloc>
12421
  requires convertible_to<ranges::range_reference_t<R>, yielded>
12422
- auto yield_value(ranges::elements_of<R, Alloc> r) noexcept;
12423
 
12424
  void await_transform() = delete;
12425
 
12426
  void return_void() const noexcept {}
12427
  void unhandled_exception();
12428
 
12429
  void* operator new(size_t size)
12430
  requires same_as<Allocator, void> || default_initializable<Allocator>;
12431
 
12432
  template<class Alloc, class... Args>
12433
- requires same_as<Allocator, void> || convertible_to<const Alloc&, Allocator>
12434
  void* operator new(size_t size, allocator_arg_t, const Alloc& alloc, const Args&...);
12435
 
12436
  template<class This, class Alloc, class... Args>
12437
- requires same_as<Allocator, void> || convertible_to<const Alloc&, Allocator>
12438
  void* operator new(size_t size, const This&, allocator_arg_t, const Alloc& alloc,
12439
  const Args&...);
12440
 
12441
  void operator delete(void* pointer, size_t size) noexcept;
12442
 
@@ -12503,10 +14075,13 @@ object.
12503
 
12504
  ``` cpp
12505
  template<class R2, class V2, class Alloc2, class Unused>
12506
  requires same_as<typename generator<R2, V2, Alloc2>::yielded, yielded>
12507
  auto yield_value(ranges::elements_of<generator<R2, V2, Alloc2>&&, Unused> g) noexcept;
 
 
 
12508
  ```
12509
 
12510
  *Preconditions:* A handle referring to the coroutine whose promise
12511
  object is `*this` is at the top of `*`*`active_`* of some `generator`
12512
  object `x`. The coroutine referred to by `g.range.`*`coroutine_`* is
@@ -12519,24 +14094,24 @@ into which `g.range` is moved, whose member `await_ready` returns
12519
  execution of the coroutine referred to by `g.range.`*`coroutine_`*, and
12520
  whose member `await_resume` evaluates `rethrow_exception(`*`except_`*`)`
12521
  if `bool(`*`except_`*`)` is `true`. If `bool(`*`except_`*`)` is `false`,
12522
  the `await_resume` member has no effects.
12523
 
12524
- *Remarks:* A *yield-expression* that calls this function has type `void`
12525
- [[expr.yield]].
12526
 
12527
  ``` cpp
12528
  template<ranges::input_range R, class Alloc>
12529
  requires convertible_to<ranges::range_reference_t<R>, yielded>
12530
- auto yield_value(ranges::elements_of<R, Alloc> r) noexcept;
12531
  ```
12532
 
12533
  *Effects:* Equivalent to:
12534
 
12535
  ``` cpp
12536
  auto nested = [](allocator_arg_t, Alloc, ranges::iterator_t<R> i, ranges::sentinel_t<R> s)
12537
- -> generator<yielded, ranges::range_value_t<R>, Alloc> {
12538
  for (; i != s; ++i) {
12539
  co_yield static_cast<yielded>(*i);
12540
  }
12541
  };
12542
  return yield_value(ranges::elements_of(nested(
@@ -12561,15 +14136,13 @@ is `*this` is the sole element of `*x.`*`active_`*, equivalent to
12561
  ``` cpp
12562
  void* operator new(size_t size)
12563
  requires same_as<Allocator, void> || default_initializable<Allocator>;
12564
 
12565
  template<class Alloc, class... Args>
12566
- requires same_as<Allocator, void> || convertible_to<const Alloc&, Allocator>
12567
  void* operator new(size_t size, allocator_arg_t, const Alloc& alloc, const Args&...);
12568
 
12569
  template<class This, class Alloc, class... Args>
12570
- requires same_as<Allocator, void> || convertible_to<const Alloc&, Allocator>
12571
  void* operator new(size_t size, const This&, allocator_arg_t, const Alloc& alloc,
12572
  const Args&...);
12573
  ```
12574
 
12575
  Let `A` be
@@ -12580,11 +14153,14 @@ Let `A` be
12580
 
12581
  Let `B` be `allocator_traits<A>::template rebind_alloc<U>` where `U` is
12582
  an unspecified type whose size and alignment are both
12583
  \_\_STDCPP_DEFAULT_NEW_ALIGNMENT\_\_.
12584
 
12585
- *Mandates:* `allocator_traits<B>::pointer` is a pointer type.
 
 
 
12586
 
12587
  *Effects:* Initializes an allocator `b` of type `B` with `A(alloc)`, for
12588
  the overloads with a function parameter `alloc`, and with `A()`
12589
  otherwise. Uses `b` to allocate storage for the smallest array of `U`
12590
  sufficient to provide storage for a coroutine state of size `size`, and
@@ -12606,12 +14182,12 @@ allocator equivalent to that used to allocate it.
12606
 
12607
  ### Class `generator::iterator` <a id="coro.generator.iterator">[[coro.generator.iterator]]</a>
12608
 
12609
  ``` cpp
12610
  namespace std {
12611
- template<class Ref, class V, class Allocator>
12612
- class generator<Ref, V, Allocator>::iterator {
12613
  public:
12614
  using value_type = value;
12615
  using difference_type = ptrdiff_t;
12616
 
12617
  iterator(iterator&& other) noexcept;
@@ -12678,10 +14254,11 @@ friend bool operator==(const iterator& i, default_sentinel_t);
12678
  ```
12679
 
12680
  *Effects:* Equivalent to: `return i.`*`coroutine_`*`.done();`
12681
 
12682
  <!-- Link reference definitions -->
 
12683
  [basic.lookup.argdep]: basic.md#basic.lookup.argdep
12684
  [concepts.equality]: concepts.md#concepts.equality
12685
  [containers]: containers.md#containers
12686
  [conv.rval]: expr.md#conv.rval
12687
  [coro.generator]: #coro.generator
@@ -12695,10 +14272,11 @@ friend bool operator==(const iterator& i, default_sentinel_t);
12695
  [dcl.init.general]: dcl.md#dcl.init.general
12696
  [expr.await]: expr.md#expr.await
12697
  [expr.const]: expr.md#expr.const
12698
  [expr.yield]: expr.md#expr.yield
12699
  [generator.syn]: #generator.syn
 
12700
  [iterator.concept.bidir]: iterators.md#iterator.concept.bidir
12701
  [iterator.concept.forward]: iterators.md#iterator.concept.forward
12702
  [iterator.concept.iterator]: iterators.md#iterator.concept.iterator
12703
  [iterator.concept.output]: iterators.md#iterator.concept.output
12704
  [iterator.concept.random.access]: iterators.md#iterator.concept.random.access
@@ -12730,16 +14308,22 @@ friend bool operator==(const iterator& i, default_sentinel_t);
12730
  [range.adjacent.transform.sentinel]: #range.adjacent.transform.sentinel
12731
  [range.adjacent.transform.view]: #range.adjacent.transform.view
12732
  [range.adjacent.view]: #range.adjacent.view
12733
  [range.all]: #range.all
12734
  [range.all.general]: #range.all.general
 
12735
  [range.as.const]: #range.as.const
12736
  [range.as.const.overview]: #range.as.const.overview
12737
  [range.as.const.view]: #range.as.const.view
12738
  [range.as.rvalue]: #range.as.rvalue
12739
  [range.as.rvalue.overview]: #range.as.rvalue.overview
12740
  [range.as.rvalue.view]: #range.as.rvalue.view
 
 
 
 
 
12741
  [range.cartesian]: #range.cartesian
12742
  [range.cartesian.iterator]: #range.cartesian.iterator
12743
  [range.cartesian.overview]: #range.cartesian.overview
12744
  [range.cartesian.view]: #range.cartesian.view
12745
  [range.chunk]: #range.chunk
@@ -12755,10 +14339,14 @@ friend bool operator==(const iterator& i, default_sentinel_t);
12755
  [range.chunk.view.fwd]: #range.chunk.view.fwd
12756
  [range.chunk.view.input]: #range.chunk.view.input
12757
  [range.common]: #range.common
12758
  [range.common.overview]: #range.common.overview
12759
  [range.common.view]: #range.common.view
 
 
 
 
12760
  [range.counted]: #range.counted
12761
  [range.dangling]: #range.dangling
12762
  [range.drop]: #range.drop
12763
  [range.drop.overview]: #range.drop.overview
12764
  [range.drop.view]: #range.drop.view
@@ -12816,10 +14404,11 @@ friend bool operator==(const iterator& i, default_sentinel_t);
12816
  [range.owning.view]: #range.owning.view
12817
  [range.prim.cdata]: #range.prim.cdata
12818
  [range.prim.data]: #range.prim.data
12819
  [range.prim.empty]: #range.prim.empty
12820
  [range.prim.size]: #range.prim.size
 
12821
  [range.prim.ssize]: #range.prim.ssize
12822
  [range.range]: #range.range
12823
  [range.ref.view]: #range.ref.view
12824
  [range.refinements]: #range.refinements
12825
  [range.repeat]: #range.repeat
@@ -12860,10 +14449,14 @@ friend bool operator==(const iterator& i, default_sentinel_t);
12860
  [range.take.view]: #range.take.view
12861
  [range.take.while]: #range.take.while
12862
  [range.take.while.overview]: #range.take.while.overview
12863
  [range.take.while.sentinel]: #range.take.while.sentinel
12864
  [range.take.while.view]: #range.take.while.view
 
 
 
 
12865
  [range.transform]: #range.transform
12866
  [range.transform.iterator]: #range.transform.iterator
12867
  [range.transform.overview]: #range.transform.overview
12868
  [range.transform.sentinel]: #range.transform.sentinel
12869
  [range.transform.view]: #range.transform.view
 
21
 
22
 
23
  ## Header `<ranges>` synopsis <a id="ranges.syn">[[ranges.syn]]</a>
24
 
25
  ``` cpp
26
+ // mostly freestanding
27
  #include <compare> // see [compare.syn]
28
  #include <initializer_list> // see [initializer.list.syn]
29
  #include <iterator> // see [iterator.synopsis]
30
 
31
  namespace std::ranges {
32
  inline namespace unspecified {
33
  // [range.access], range access
34
+ inline constexpr unspecified begin = unspecified;
35
+ inline constexpr unspecified end = unspecified;
36
+ inline constexpr unspecified cbegin = unspecified;
37
+ inline constexpr unspecified cend = unspecified;
38
+ inline constexpr unspecified rbegin = unspecified;
39
+ inline constexpr unspecified rend = unspecified;
40
+ inline constexpr unspecified crbegin = unspecified;
41
+ inline constexpr unspecified crend = unspecified;
42
 
43
+ inline constexpr unspecified size = unspecified;
44
+ inline constexpr unspecified reserve_hint = unspecified;
45
+ inline constexpr unspecified ssize = unspecified;
46
+ inline constexpr unspecified empty = unspecified;
47
+ inline constexpr unspecified data = unspecified;
48
+ inline constexpr unspecified cdata = unspecified;
49
  }
50
 
51
  // [range.range], ranges
52
  template<class T>
53
+ concept range = see below;
54
 
55
  template<class T>
56
+ constexpr bool enable_borrowed_range = false;
57
 
58
  template<class T>
59
+ concept borrowed_range = see below;
60
 
61
  template<class T>
62
+ using iterator_t = decltype(ranges::begin(declval<T&>()));
63
  template<range R>
64
+ using sentinel_t = decltype(ranges::end(declval<R&>()));
65
  template<range R>
66
+ using const_iterator_t = decltype(ranges::cbegin(declval<R&>()));
67
  template<range R>
68
+ using const_sentinel_t = decltype(ranges::cend(declval<R&>()));
69
  template<range R>
70
+ using range_difference_t = iter_difference_t<iterator_t<R>>;
71
  template<sized_range R>
72
+ using range_size_t = decltype(ranges::size(declval<R&>()));
73
  template<range R>
74
+ using range_value_t = iter_value_t<iterator_t<R>>;
75
  template<range R>
76
+ using range_reference_t = iter_reference_t<iterator_t<R>>;
77
  template<range R>
78
+ using range_const_reference_t = iter_const_reference_t<iterator_t<R>>;
79
  template<range R>
80
+ using range_rvalue_reference_t = iter_rvalue_reference_t<iterator_t<R>>;
81
  template<range R>
82
+ using range_common_reference_t = iter_common_reference_t<iterator_t<R>>;
83
 
84
  // [range.sized], sized ranges
85
  template<class>
86
+ constexpr bool disable_sized_range = false;
87
 
88
  template<class T>
89
+ concept approximately_sized_range = see below;
90
+
91
+ template<class T>
92
+ concept sized_range = see below;
93
 
94
  // [range.view], views
95
  template<class T>
96
+ constexpr bool enable_view = see below;
97
 
98
+ struct view_base {};
99
 
100
  template<class T>
101
+ concept view = see below;
102
 
103
  // [range.refinements], other range refinements
104
  template<class R, class T>
105
+ concept output_range = see below;
106
 
107
  template<class T>
108
+ concept input_range = see below;
109
 
110
  template<class T>
111
+ concept forward_range = see below;
112
 
113
  template<class T>
114
+ concept bidirectional_range = see below;
115
 
116
  template<class T>
117
+ concept random_access_range = see below;
118
 
119
  template<class T>
120
+ concept contiguous_range = see below;
121
 
122
  template<class T>
123
+ concept common_range = see below;
124
 
125
  template<class T>
126
+ concept viewable_range = see below;
127
 
128
  template<class T>
129
+ concept constant_range = see below;
130
+
131
+ template<class T>
132
+ concept sized-random-access-range = see belownc; // exposition only
133
 
134
  // [view.interface], class template view_interface
135
  template<class D>
136
  requires is_class_v<D> && same_as<D, remove_cv_t<D>>
137
+ class view_interface;
138
 
139
  // [range.subrange], sub-ranges
140
+ enum class subrange_kind : bool { unsized, sized };
141
 
142
  template<input_or_output_iterator I, sentinel_for<I> S = I, subrange_kind K = see below>
143
  requires (K == subrange_kind::sized || !sized_sentinel_for<S, I>)
144
+ class subrange;
145
 
146
  template<class I, class S, subrange_kind K>
147
+ constexpr bool \libspec{enable_borrowed_range}{subrange}<subrange<I, S, K>> = true;
148
 
149
  template<size_t N, class I, class S, subrange_kind K>
150
  requires ((N == 0 && copyable<I>) || N == 1)
151
+ constexpr auto get(const subrange<I, S, K>& r);
152
 
153
  template<size_t N, class I, class S, subrange_kind K>
154
  requires (N < 2)
155
+ constexpr auto get(subrange<I, S, K>&& r);
156
  }
157
 
158
  namespace std {
159
+ using ranges::get;
160
  }
161
 
162
  namespace std::ranges {
163
  // [range.dangling], dangling iterator handling
164
+ struct dangling;
165
 
166
  // [range.elementsof], class template elements_of
167
  template<range R, class Allocator = allocator<byte>>
168
+ struct elements_of; // hosted
169
 
170
  template<range R>
171
+ using borrowed_iterator_t = see below;
172
 
173
  template<range R>
174
+ using borrowed_subrange_t = see below;
175
 
176
  // [range.utility.conv], range conversions
177
  template<class C, input_range R, class... Args> requires (!view<C>)
178
+ constexpr C to(R&& r, Args&&... args);
179
  template<template<class...> class C, input_range R, class... Args>
180
+ constexpr auto to(R&& r, Args&&... args);
181
  template<class C, class... Args> requires (!view<C>)
182
+ constexpr auto to(Args&&... args);
183
  template<template<class...> class C, class... Args>
184
+ constexpr auto to(Args&&... args);
185
 
186
  // [range.empty], empty view
187
  template<class T>
188
  requires is_object_v<T>
189
+ class empty_view;
190
 
191
  template<class T>
192
+ constexpr bool \libspec{enable_borrowed_range}{empty_view}<empty_view<T>> = true;
193
 
194
  namespace views {
195
  template<class T>
196
+ constexpr empty_view<T> empty{};
197
  }
198
 
199
  // [range.single], single view
200
  template<move_constructible T>
201
  requires is_object_v<T>
202
+ class single_view;
203
 
204
+ namespace views { inline constexpr unspecified single = unspecified; }
205
 
206
  template<bool Const, class T>
207
  using maybe-const = conditional_t<Const, const T, T>; // exposition only
208
 
209
  // [range.iota], iota view
210
  template<weakly_incrementable W, semiregular Bound = unreachable_sentinel_t>
211
  requires weakly-equality-comparable-with<W, Bound> && copyable<W>
212
+ class iota_view;
213
 
214
  template<class W, class Bound>
215
+ constexpr bool \libspec{enable_borrowed_range}{iota_view}<iota_view<W, Bound>> = true;
216
 
217
+ namespace views {
218
+ inline constexpr unspecified iota = unspecified;
219
+ inline constexpr unspecified indices = unspecified;
220
+ }
221
 
222
  // [range.repeat], repeat view
223
  template<move_constructible T, semiregular Bound = unreachable_sentinel_t>
224
  requires see below
225
+ class repeat_view;
226
 
227
+ namespace views { inline constexpr unspecified repeat = unspecified; }
228
 
229
  // [range.istream], istream view
230
  template<movable Val, class CharT, class Traits = char_traits<CharT>>
231
  requires see below
232
+ class basic_istream_view; // hosted
233
  template<class Val>
234
+ using istream_view = basic_istream_view<Val, char>; // hosted
235
  template<class Val>
236
+ using wistream_view = basic_istream_view<Val, wchar_t>; // hosted
237
 
238
+ namespace views {
239
+ template<class T> constexpr unspecified istream = unspecified; // hosted
240
+ }
241
 
242
  // [range.adaptor.object], range adaptor objects
243
  template<class D>
244
  requires is_class_v<D> && same_as<D, remove_cv_t<D>>
245
+ class range_adaptor_closure { };
246
 
247
  // [range.all], all view
248
  namespace views {
249
+ inline constexpr unspecified all = unspecified;
250
 
251
  template<viewable_range R>
252
+ using all_t = decltype(all(declval<R>()));
253
  }
254
 
255
  // [range.ref.view], ref view
256
  template<range R>
257
  requires is_object_v<R>
258
+ class ref_view;
259
 
260
  template<class T>
261
+ constexpr bool \libspec{enable_borrowed_range}{ref_view}<ref_view<T>> = true;
262
 
263
  // [range.owning.view], owning view
264
  template<range R>
265
  requires see below
266
+ class owning_view;
267
 
268
  template<class T>
269
+ constexpr bool \libspec{enable_borrowed_range}{owning_view}<owning_view<T>> =
270
  enable_borrowed_range<T>;
271
 
272
  // [range.as.rvalue], as rvalue view
273
  template<view V>
274
  requires input_range<V>
275
+ class as_rvalue_view;
276
 
277
  template<class T>
278
+ constexpr bool \libspec{enable_borrowed_range}{as_rvalue_view}<as_rvalue_view<T>> =
279
  enable_borrowed_range<T>;
280
 
281
+ namespace views { inline constexpr unspecified as_rvalue = unspecified; }
282
 
283
  // [range.filter], filter view
284
  template<input_range V, indirect_unary_predicate<iterator_t<V>> Pred>
285
  requires view<V> && is_object_v<Pred>
286
+ class filter_view;
287
 
288
+ namespace views { inline constexpr unspecified filter = unspecified; }
289
 
290
  // [range.transform], transform view
291
  template<input_range V, move_constructible F>
292
  requires view<V> && is_object_v<F> &&
293
  regular_invocable<F&, range_reference_t<V>> &&
294
  can-reference<invoke_result_t<F&, range_reference_t<V>>>
295
+ class transform_view;
296
 
297
+ namespace views { inline constexpr unspecified transform = unspecified; }
298
 
299
  // [range.take], take view
300
+ template<view> class take_view;
301
 
302
  template<class T>
303
+ constexpr bool \libspec{enable_borrowed_range}{take_view}<take_view<T>> =
304
  enable_borrowed_range<T>;
305
 
306
+ namespace views { inline constexpr unspecified take = unspecified; }
307
 
308
  // [range.take.while], take while view
309
  template<view V, class Pred>
310
  requires input_range<V> && is_object_v<Pred> &&
311
  indirect_unary_predicate<const Pred, iterator_t<V>>
312
+ class take_while_view;
313
 
314
+ namespace views { inline constexpr unspecified take_while = unspecified; }
315
 
316
  // [range.drop], drop view
317
  template<view V>
318
+ class drop_view;
319
 
320
  template<class T>
321
+ constexpr bool \libspec{enable_borrowed_range}{drop_view}<drop_view<T>> =
322
  enable_borrowed_range<T>;
323
 
324
+ namespace views { inline constexpr unspecified drop = unspecified; }
325
 
326
  // [range.drop.while], drop while view
327
  template<view V, class Pred>
328
  requires input_range<V> && is_object_v<Pred> &&
329
  indirect_unary_predicate<const Pred, iterator_t<V>>
330
+ class drop_while_view;
331
 
332
  template<class T, class Pred>
333
+ constexpr bool \libspec{enable_borrowed_range}{drop_while_view}<drop_while_view<T, Pred>> =
334
  enable_borrowed_range<T>;
335
 
336
+ namespace views { inline constexpr unspecified drop_while = unspecified; }
337
 
338
  // [range.join], join view
339
  template<input_range V>
340
  requires view<V> && input_range<range_reference_t<V>>
341
+ class join_view;
342
 
343
+ namespace views { inline constexpr unspecified join = unspecified; }
344
 
345
  // [range.join.with], join with view
 
 
 
346
  template<input_range V, forward_range Pattern>
347
+ requires see below
348
+ class join_with_view;
 
 
349
 
350
+ namespace views { inline constexpr unspecified join_with = unspecified; }
351
 
352
  // [range.lazy.split], lazy split view
353
  template<class R>
354
  concept tiny-range = see below; // exposition only
355
 
356
  template<input_range V, forward_range Pattern>
357
  requires view<V> && view<Pattern> &&
358
  indirectly_comparable<iterator_t<V>, iterator_t<Pattern>, ranges::equal_to> &&
359
  (forward_range<V> || tiny-range<Pattern>)
360
+ class lazy_split_view;
361
 
362
  // [range.split], split view
363
  template<forward_range V, forward_range Pattern>
364
  requires view<V> && view<Pattern> &&
365
  indirectly_comparable<iterator_t<V>, iterator_t<Pattern>, ranges::equal_to>
366
+ class split_view;
367
 
368
  namespace views {
369
+ inline constexpr unspecified lazy_split = unspecified;
370
+ inline constexpr unspecified split = unspecified;
371
  }
372
 
373
+ // [range.concat], concat view
374
+ template<input_range... Views>
375
+ requires see below
376
+ class concat_view;
377
+
378
+ namespace views { inline constexpr unspecified concat = unspecified; }
379
+
380
  // [range.counted], counted view
381
+ namespace views { inline constexpr unspecified counted = unspecified; }
382
 
383
  // [range.common], common view
384
  template<view V>
385
  requires (!common_range<V> && copyable<iterator_t<V>>)
386
+ class common_view;
387
 
388
  template<class T>
389
+ constexpr bool \libspec{enable_borrowed_range}{common_view}<common_view<T>> =
390
  enable_borrowed_range<T>;
391
 
392
+ namespace views { inline constexpr unspecified common = unspecified; }
393
 
394
  // [range.reverse], reverse view
395
  template<view V>
396
  requires bidirectional_range<V>
397
+ class reverse_view;
398
 
399
  template<class T>
400
+ constexpr bool \libspec{enable_borrowed_range}{reverse_view}<reverse_view<T>> =
401
  enable_borrowed_range<T>;
402
 
403
+ namespace views { inline constexpr unspecified reverse = unspecified; }
404
 
405
  // [range.as.const], as const view
406
  template<input_range R>
407
+ constexpr auto& possibly-const-range(R& r) noexcept { // exposition only
408
+ if constexpr (input_range<const R>) {
409
  return const_cast<const R&>(r);
410
  } else {
411
  return r;
412
  }
413
  }
414
 
415
  template<view V>
416
  requires input_range<V>
417
+ class as_const_view;
418
 
419
  template<class T>
420
+ constexpr bool \libspec{enable_borrowed_range}{as_const_view}<as_const_view<T>> =
421
  enable_borrowed_range<T>;
422
 
423
+ namespace views { inline constexpr unspecified as_const = unspecified; }
424
 
425
  // [range.elements], elements view
426
  template<input_range V, size_t N>
427
  requires see below
428
+ class elements_view;
429
 
430
  template<class T, size_t N>
431
+ constexpr bool \libspec{enable_borrowed_range}{elements_view}<elements_view<T, N>> =
432
  enable_borrowed_range<T>;
433
 
434
  template<class R>
435
+ using keys_view = elements_view<R, 0>;
436
  template<class R>
437
+ using values_view = elements_view<R, 1>;
438
 
439
  namespace views {
440
  template<size_t N>
441
+ constexpr unspecified elements = unspecified;
442
+ inline constexpr auto keys = elements<0>;
443
+ inline constexpr auto values = elements<1>;
444
  }
445
 
446
  // [range.enumerate], enumerate view
447
+ template<view V>
448
+ requires see below
449
+ class enumerate_view;
450
 
451
  template<class View>
452
+ constexpr bool \libspec{enable_borrowed_range}{enumerate_view}<enumerate_view<View>> =
453
  enable_borrowed_range<View>;
454
 
455
+ namespace views { inline constexpr unspecified enumerate = unspecified; }
456
 
457
  // [range.zip], zip view
458
  template<input_range... Views>
459
  requires (view<Views> && ...) && (sizeof...(Views) > 0)
460
+ class zip_view;
461
 
462
  template<class... Views>
463
+ constexpr bool \libspec{enable_borrowed_range}{zip_view}<zip_view<Views...>> =
464
  (enable_borrowed_range<Views> && ...);
465
 
466
+ namespace views { inline constexpr unspecified zip = unspecified; }
467
 
468
  // [range.zip.transform], zip transform view
469
  template<move_constructible F, input_range... Views>
470
  requires (view<Views> && ...) && (sizeof...(Views) > 0) && is_object_v<F> &&
471
  regular_invocable<F&, range_reference_t<Views>...> &&
472
  can-reference<invoke_result_t<F&, range_reference_t<Views>...>>
473
+ class zip_transform_view;
474
 
475
+ namespace views { inline constexpr unspecified zip_transform = unspecified; }
476
 
477
  // [range.adjacent], adjacent view
478
  template<forward_range V, size_t N>
479
  requires view<V> && (N > 0)
480
+ class adjacent_view;
481
 
482
  template<class V, size_t N>
483
+ constexpr bool \libspec{enable_borrowed_range}{adjacent_view}<adjacent_view<V, N>> =
484
  enable_borrowed_range<V>;
485
 
486
  namespace views {
487
  template<size_t N>
488
+ constexpr unspecified adjacent = unspecified;
489
+ inline constexpr auto pairwise = adjacent<2>;
490
  }
491
 
492
  // [range.adjacent.transform], adjacent transform view
493
  template<forward_range V, move_constructible F, size_t N>
494
  requires see below
495
+ class adjacent_transform_view;
496
 
497
  namespace views {
498
  template<size_t N>
499
+ constexpr unspecified adjacent_transform = unspecified;
500
+ inline constexpr auto pairwise_transform = adjacent_transform<2>;
501
  }
502
 
503
  // [range.chunk], chunk view
504
  template<view V>
505
  requires input_range<V>
506
+ class chunk_view;
507
 
508
  template<view V>
509
  requires forward_range<V>
510
+ class chunk_view<V>;
511
 
512
  template<class V>
513
+ constexpr bool \libspec{enable_borrowed_range}{chunk_view}<chunk_view<V>> =
514
  forward_range<V> && enable_borrowed_range<V>;
515
 
516
+ namespace views { inline constexpr unspecified chunk = unspecified; }
517
 
518
  // [range.slide], slide view
519
  template<forward_range V>
520
  requires view<V>
521
+ class slide_view;
522
 
523
  template<class V>
524
+ constexpr bool \libspec{enable_borrowed_range}{slide_view}<slide_view<V>> =
525
+ enable_borrowed_range<V>;
526
 
527
+ namespace views { inline constexpr unspecified slide = unspecified; }
528
 
529
  // [range.chunk.by], chunk by view
530
  template<forward_range V, indirect_binary_predicate<iterator_t<V>, iterator_t<V>> Pred>
531
  requires view<V> && is_object_v<Pred>
532
+ class chunk_by_view;
533
 
534
+ namespace views { inline constexpr unspecified chunk_by = unspecified; }
535
 
536
  // [range.stride], stride view
537
  template<input_range V>
538
  requires view<V>
539
+ class stride_view;
540
 
541
  template<class V>
542
+ constexpr bool \libspec{enable_borrowed_range}{stride_view}<stride_view<V>> =
543
  enable_borrowed_range<V>;
544
 
545
+ namespace views { inline constexpr unspecified stride = unspecified; }
546
 
547
  // [range.cartesian], cartesian product view
548
  template<input_range First, forward_range... Vs>
549
  requires (view<First> && ... && view<Vs>)
550
+ class cartesian_product_view;
551
 
552
+ namespace views { inline constexpr unspecified cartesian_product = unspecified; }
553
+
554
+ // [range.cache.latest], cache latest view
555
+ template<input_range V>
556
+ requires view<V>
557
+ class cache_latest_view;
558
+
559
+ namespace views { inline constexpr unspecified cache_latest = unspecified; }
560
+
561
+ // [range.to.input], to input view
562
+ template<input_range V>
563
+ requires view<V>
564
+ class to_input_view;
565
+
566
+ template<class V>
567
+ constexpr bool enable_borrowed_range<to_input_view<V>> =
568
+ enable_borrowed_range<V>;
569
+
570
+ namespace views { inline constexpr unspecified to_input = unspecified; }
571
  }
572
 
573
  namespace std {
574
+ namespace views = ranges::views;
575
 
576
+ template<class T> struct tuple_size;
577
+ template<size_t I, class T> struct tuple_element;
578
 
579
  template<class I, class S, ranges::subrange_kind K>
580
+ struct tuple_size<ranges::subrange<I, S, K>>
581
  : integral_constant<size_t, 2> {};
582
  template<class I, class S, ranges::subrange_kind K>
583
+ struct tuple_element<0, ranges::subrange<I, S, K>> {
584
+ using type = I;
585
  };
586
  template<class I, class S, ranges::subrange_kind K>
587
+ struct tuple_element<1, ranges::subrange<I, S, K>> {
588
+ using type = S;
589
  };
590
  template<class I, class S, ranges::subrange_kind K>
591
+ struct tuple_element<0, const ranges::subrange<I, S, K>> {
592
+ using type = I;
593
  };
594
  template<class I, class S, ranges::subrange_kind K>
595
+ struct tuple_element<1, const ranges::subrange<I, S, K>> {
596
+ using type = S;
597
  };
598
 
599
+ struct from_range_t { explicit from_range_t() = default; };
600
+ inline constexpr from_range_t from_range{};
601
  }
602
  ```
603
 
604
  Within this Clause, for an integer-like type `X`
605
  [[iterator.concept.winc]], `make-unsigned-like-t<X>` denotes
 
617
 
618
  ### General <a id="range.access.general">[[range.access.general]]</a>
619
 
620
  In addition to being available via inclusion of the `<ranges>` header,
621
  the customization point objects in [[range.access]] are available when
622
+ the header `<iterator>` is included.
623
 
624
  Within [[range.access]], the *reified object* of a subexpression `E`
625
  denotes
626
 
627
  - the same object as `E` if `E` is a glvalue, or
 
879
  `ranges::ssize(E)` is ill-formed. Otherwise let `D` be
880
  `make-signed-like-t<decltype(ranges::{}size(t))>`, or `ptrdiff_t` if it
881
  is wider than that type; `ranges::ssize(E)` is expression-equivalent to
882
  `static_cast<D>(ranges::size(t))`.
883
 
884
+ ### `ranges::reserve_hint` <a id="range.prim.size.hint">[[range.prim.size.hint]]</a>
885
+
886
+ The name `ranges::reserve_hint` denotes a customization point object
887
+ [[customization.point.object]].
888
+
889
+ Given a subexpression `E` with type `T`, let `t` be an lvalue that
890
+ denotes the reified object for `E`. Then:
891
+
892
+ - If `ranges::size(E)` is a valid expression, `ranges::reserve_hint(E)`
893
+ is expression-equivalent to `ranges::size(E)`.
894
+ - Otherwise, if `auto(t.reserve_hint())` is a valid expression of
895
+ integer-like type [[iterator.concept.winc]], `ranges::reserve_hint(E)`
896
+ is expression-equivalent to `auto(t.reserve_hint())`.
897
+ - Otherwise, if `T` is a class or enumeration type and
898
+ `auto(reserve_hint(t))` is a valid expression of integer-like type
899
+ where the meaning of `reserve_hint` is established as-if by performing
900
+ argument-dependent lookup only [[basic.lookup.argdep]], then
901
+ `ranges::reserve_hint(E)` is expression-equivalent to that expression.
902
+ - Otherwise, `ranges::reserve_hint(E)` is ill-formed.
903
+
904
+ [*Note 1*: Diagnosable ill-formed cases above result in substitution
905
+ failure when `ranges::reserve_hint(E)` appears in the immediate context
906
+ of a template instantiation. — *end note*]
907
+
908
+ [*Note 2*: Whenever `ranges::reserve_hint(E)` is a valid expression,
909
+ its type is integer-like. — *end note*]
910
+
911
  ### `ranges::empty` <a id="range.prim.empty">[[range.prim.empty]]</a>
912
 
913
  The name `ranges::empty` denotes a customization point object
914
  [[customization.point.object]].
915
 
 
966
 
967
  ### `ranges::cdata` <a id="range.prim.cdata">[[range.prim.cdata]]</a>
968
 
969
  ``` cpp
970
  template<class T>
971
+ constexpr auto as-const-pointer(const T* p) noexcept { return p; } // exposition only
972
  ```
973
 
974
  The name `ranges::cdata` denotes a customization point object
975
  [[customization.point.object]]. Given a subexpression `E` with type `T`,
976
  let `t` be an lvalue that denotes the reified object for `E`. Then:
 
1024
  ranges::begin(t); // sometimes equality-preserving (see below)
1025
  ranges::end(t);
1026
  };
1027
  ```
1028
 
 
 
 
 
1029
  Given an expression `t` such that `decltype((t))` is `T&`, `T` models
1030
  `range` only if
1031
 
1032
  - \[`ranges::begin(t)`, `ranges::end(t)`) denotes a
1033
  range [[iterator.requirements.general]],
 
1081
  - `S`’s iterators do not have validity tied to the lifetime of an `S`
1082
  object because they are “borrowed” from some other range.
1083
 
1084
  — *end example*]
1085
 
1086
+ ### Approximately sized ranges <a id="range.approximately.sized">[[range.approximately.sized]]</a>
1087
+
1088
+ The `approximately_sized_range` concept refines `range` with the
1089
+ requirement that an approximation of the number of elements in the range
1090
+ can be determined in amortized constant time using
1091
+ `ranges::reserve_hint`.
1092
+
1093
+ ``` cpp
1094
+ template<class T>
1095
+ concept approximately_sized_range =
1096
+ range<T> && requires(T& t) { ranges::reserve_hint(t); };
1097
+ ```
1098
+
1099
+ Given an lvalue `t` of type `remove_reference_t<T>`, `T` models
1100
+ `approximately_sized_range` only if
1101
+
1102
+ - `ranges::reserve_hint(t)` is amortized 𝑂(1), does not modify `t`, and
1103
+ has a value that is not negative and is representable in
1104
+ `range_difference_t<T>`, and
1105
+ - if `iterator_t<T>` models `forward_iterator`,
1106
+ `ranges::reserve_hint(t)` is well-defined regardless of the evaluation
1107
+ of `ranges::begin(t)`. \[*Note 1*: `ranges::reserve_hint(t)` is
1108
+ otherwise not required to be well-defined after evaluating
1109
+ `ranges::begin(t)`. For example, it is possible for
1110
+ `ranges::reserve_hint(t)` to be well-defined for an whose iterator
1111
+ type does not model `forward_iterator` only if evaluated before the
1112
+ first call to `ranges::begin(t)`. — *end note*]
1113
+
1114
  ### Sized ranges <a id="range.sized">[[range.sized]]</a>
1115
 
1116
+ The `sized_range` concept refines `approximately_sized_range` with the
1117
+ requirement that the number of elements in the range can be determined
1118
+ in amortized constant time using `ranges::size`.
1119
 
1120
  ``` cpp
1121
  template<class T>
1122
  concept sized_range =
1123
+ approximately_sized_range<T> && requires(T& t) { ranges::size(t); };
1124
  ```
1125
 
1126
  Given an lvalue `t` of type `remove_reference_t<T>`, `T` models
1127
  `sized_range` only if
1128
 
 
1144
  *Remarks:* Pursuant to [[namespace.std]], users may specialize
1145
  `disable_sized_range` for cv-unqualified program-defined types. Such
1146
  specializations shall be usable in constant expressions [[expr.const]]
1147
  and have type `const bool`.
1148
 
1149
+ [*Note 1*: `disable_sized_range` allows use of `range` types with the
1150
  library that satisfy but do not in fact model
1151
  `sized_range`. — *end note*]
1152
 
1153
  ### Views <a id="range.view">[[range.view]]</a>
1154
 
 
1160
  template<class T>
1161
  concept view =
1162
  range<T> && movable<T> && enable_view<T>;
1163
  ```
1164
 
1165
+ `T` models `view` only if
1166
 
1167
  - `T` has 𝑂(1) move construction; and
1168
  - move assignment of an object of type `T` is no more complex than
1169
  destruction followed by move construction; and
1170
  - if N copies and/or moves are made from an object of type `T` that
 
1208
  only if `T` has exactly one public base class `view_interface<U>` for
1209
  some type `U` and `T` has no base classes of type `view_interface<V>`
1210
  for any other type `V`.
1211
 
1212
  *Remarks:* Pursuant to [[namespace.std]], users may specialize
1213
+ `enable_view` to `true` for cv-unqualified program-defined types that
1214
+ model `view`, and `false` for types that do not. Such specializations
1215
  shall be usable in constant expressions [[expr.const]] and have type
1216
  `const bool`.
1217
 
1218
  ### Other range refinements <a id="range.refinements">[[range.refinements]]</a>
1219
 
 
1299
  template<class T>
1300
  concept constant_range =
1301
  input_range<T> && constant-iterator<iterator_t<T>>;
1302
  ```
1303
 
1304
+ The exposition-only concept `sized-random-access-range` specifies the
1305
+ requirements of a `range` type that is sized and allows random access to
1306
+ its elements.
1307
+
1308
+ ``` cpp
1309
+ template<class T>
1310
+ concept sized-random-access-range = // exposition only
1311
+ random_access_range<T> && sized_range<T>;
1312
+ ```
1313
+
1314
+ [*Note 1*: This concept constrains some parallel algorithm overloads;
1315
+ see [[algorithms]]. — *end note*]
1316
+
1317
  ## Range utilities <a id="range.utility">[[range.utility]]</a>
1318
 
1319
  ### General <a id="range.utility.general">[[range.utility.general]]</a>
1320
 
1321
  The components in [[range.utility]] are general utilities for
1322
  representing and manipulating ranges.
1323
 
1324
  ### Helper concepts <a id="range.utility.helpers">[[range.utility.helpers]]</a>
1325
 
1326
+ Many of the types in [[range.utility]] are specified in terms of the
1327
+ following exposition-only concepts:
1328
 
1329
  ``` cpp
1330
  template<class R>
1331
  concept simple-view = // exposition only
1332
  view<R> && range<const R> &&
1333
  same_as<iterator_t<R>, iterator_t<const R>> &&
1334
  same_as<sentinel_t<R>, sentinel_t<const R>>;
1335
 
1336
  template<class I>
1337
  concept has-arrow = // exposition only
1338
+ input_iterator<I> && (is_pointer_v<I> || requires(const I i) { i.operator->(); });
1339
 
1340
  template<class T, class U>
1341
  concept different-from = // exposition only
1342
  !same_as<remove_cvref_t<T>, remove_cvref_t<U>>;
1343
 
 
1451
  ``` cpp
1452
  constexpr decltype(auto) front() requires forward_range<D>;
1453
  constexpr decltype(auto) front() const requires forward_range<const D>;
1454
  ```
1455
 
1456
+ `!empty()` is `true`.
1457
 
1458
  *Effects:* Equivalent to: `return *ranges::begin(`*`derived`*`());`
1459
 
1460
  ``` cpp
1461
  constexpr decltype(auto) back() requires bidirectional_range<D> && common_range<D>;
1462
  constexpr decltype(auto) back() const
1463
  requires bidirectional_range<const D> && common_range<const D>;
1464
  ```
1465
 
1466
+ `!empty()` is `true`.
1467
 
1468
  *Effects:* Equivalent to:
1469
  `return *ranges::prev(ranges::end(`*`derived`*`()));`
1470
 
1471
  ### Sub-ranges <a id="range.subrange">[[range.subrange]]</a>
 
1532
  template<different-from<subrange> PairLike>
1533
  requires pair-like-convertible-from<PairLike, const I&, const S&>
1534
  constexpr operator PairLike() const;
1535
 
1536
  constexpr I begin() const requires copyable<I>;
1537
+ constexpr I begin() requires (!copyable<I>);
1538
  constexpr S end() const;
1539
 
1540
  constexpr bool empty() const;
1541
  constexpr make-unsigned-like-t<iter_difference_t<I>> size() const
1542
  requires (K == subrange_kind::sized);
1543
 
1544
+ constexpr subrange next(iter_difference_t<I> n = 1) const &
1545
  requires forward_iterator<I>;
1546
+ constexpr subrange next(iter_difference_t<I> n = 1) &&;
1547
+ constexpr subrange prev(iter_difference_t<I> n = 1) const
1548
  requires bidirectional_iterator<I>;
1549
  constexpr subrange& advance(iter_difference_t<I> n);
1550
  };
1551
 
1552
  template<input_or_output_iterator I, sentinel_for<I> S>
 
1625
  ```
1626
 
1627
  *Effects:* Equivalent to: `return `*`begin_`*`;`
1628
 
1629
  ``` cpp
1630
+ constexpr I begin() requires (!copyable<I>);
1631
  ```
1632
 
1633
  *Effects:* Equivalent to: `return std::move(`*`begin_`*`);`
1634
 
1635
  ``` cpp
 
1654
  - If *StoreSize* is `true`, equivalent to: `return `*`size_`*`;`
1655
  - Otherwise, equivalent to:
1656
  `return `*`to-unsigned-like`*`(`*`end_`*` - `*`begin_`*`);`
1657
 
1658
  ``` cpp
1659
+ constexpr subrange next(iter_difference_t<I> n = 1) const &
1660
  requires forward_iterator<I>;
1661
  ```
1662
 
1663
  *Effects:* Equivalent to:
1664
 
 
1667
  tmp.advance(n);
1668
  return tmp;
1669
  ```
1670
 
1671
  ``` cpp
1672
+ constexpr subrange next(iter_difference_t<I> n = 1) &&;
1673
  ```
1674
 
1675
  *Effects:* Equivalent to:
1676
 
1677
  ``` cpp
1678
  advance(n);
1679
  return std::move(*this);
1680
  ```
1681
 
1682
  ``` cpp
1683
+ constexpr subrange prev(iter_difference_t<I> n = 1) const
1684
  requires bidirectional_iterator<I>;
1685
  ```
1686
 
1687
  *Effects:* Equivalent to:
1688
 
 
1846
  { c.capacity() } -> same_as<decltype(n)>;
1847
  { c.max_size() } -> same_as<decltype(n)>;
1848
  };
1849
  ```
1850
 
1851
+ Let *`container-appendable`* be defined as follows:
1852
 
1853
  ``` cpp
1854
  template<class Container, class Ref>
1855
+ constexpr bool container-appendable = // exposition only
1856
  requires(Container& c, Ref&& ref) {
1857
+ requires (requires { c.emplace_back(std::forward<Ref>(ref)); } ||
1858
+ requires { c.push_back(std::forward<Ref>(ref)); } ||
1859
+ requires { c.emplace(c.end(), std::forward<Ref>(ref)); } ||
1860
  requires { c.insert(c.end(), std::forward<Ref>(ref)); });
1861
  };
1862
  ```
1863
 
1864
+ Let *`container-append`* be defined as follows:
1865
 
1866
  ``` cpp
1867
+ template<class Container>
1868
+ constexpr auto container-append(Container& c) { // exposition only
1869
+ return [&c]<class Ref>(Ref&& ref) {
1870
+ if constexpr (requires { c.emplace_back(declval<Ref>()); })
1871
+ c.emplace_back(std::forward<Ref>(ref));
1872
+ else if constexpr (requires { c.push_back(declval<Ref>()); })
1873
+ c.push_back(std::forward<Ref>(ref));
1874
+ else if constexpr (requires { c.emplace(c.end(), declval<Ref>()); })
1875
+ c.emplace(c.end(), std::forward<Ref>(ref));
1876
  else
1877
+ c.insert(c.end(), std::forward<Ref>(ref));
1878
+ };
1879
  }
1880
  ```
1881
 
1882
  #### `ranges::to` <a id="range.utility.conv.to">[[range.utility.conv.to]]</a>
1883
 
 
1913
  ``` cpp
1914
  C(ranges::begin(r), ranges::end(r), std::forward<Args>(args)...)
1915
  ```
1916
  - Otherwise, if
1917
  - `constructible_from<C, Args...>` is `true`, and
1918
+ - *`container-appendable`*`<C, range_reference_t<R>>` is `true`:
1919
 
1920
  ``` cpp
1921
  C c(std::forward<Args>(args)...);
1922
+ if constexpr (approximately_sized_range<R> && reservable-container<C>)
1923
+ c.reserve(static_cast<range_size_t<C>>(ranges::reserve_hint(r)));
1924
+ ranges::for_each(r, container-append(c));
1925
  ```
1926
+ - Otherwise, the program is ill-formed.
1927
  - Otherwise, if `input_range<range_reference_t<R>>` is `true`:
1928
  ``` cpp
1929
+ to<C>(ref_view(r) | views::transform([](auto&& elem) {
1930
  return to<range_value_t<C>>(std::forward<decltype(elem)>(elem));
1931
  }), std::forward<Args>(args)...);
1932
  ```
1933
  - Otherwise, the program is ill-formed.
1934
 
 
2079
 
2080
  constexpr T* begin() noexcept;
2081
  constexpr const T* begin() const noexcept;
2082
  constexpr T* end() noexcept;
2083
  constexpr const T* end() const noexcept;
2084
+ static constexpr bool empty() noexcept;
2085
  static constexpr size_t size() noexcept;
2086
  constexpr T* data() noexcept;
2087
  constexpr const T* data() const noexcept;
2088
  };
2089
 
 
2125
  constexpr const T* end() const noexcept;
2126
  ```
2127
 
2128
  *Effects:* Equivalent to: `return data() + 1;`
2129
 
2130
+ ``` cpp
2131
+ static constexpr bool empty() noexcept;
2132
+ ```
2133
+
2134
+ *Effects:* Equivalent to: `return false;`
2135
+
2136
  ``` cpp
2137
  static constexpr size_t size() noexcept;
2138
  ```
2139
 
2140
  *Effects:* Equivalent to: `return 1;`
 
2154
  an initial value.
2155
 
2156
  The name `views::iota` denotes a customization point object
2157
  [[customization.point.object]]. Given subexpressions `E` and `F`, the
2158
  expressions `views::iota(E)` and `views::iota(E, F)` are
2159
+ expression-equivalent to `iota_view<decay_t<decltype((E))>>(E)` and
2160
+ `iota_view(E, F)`, respectively.
2161
 
2162
  [*Example 1*:
2163
 
2164
  ``` cpp
2165
  for (int i : views::iota(1, 10))
2166
  cout << i << ' '; // prints 1 2 3 4 5 6 7 8 9
2167
  ```
2168
 
2169
  — *end example*]
2170
 
2171
+ The name `views::indices` denotes a customization point object
2172
+ [[customization.point.object]]. Given subexpression `E`, let `T` be
2173
+ `remove_cvref_t<decltype((E))>`. `views::indices(E)` is
2174
+ expression-equivalent to `views::iota(T(0), E)` if `is-integer-like<T>`
2175
+ is `true`, and ill-formed otherwise.
2176
+
2177
  #### Class template `iota_view` <a id="range.iota.view">[[range.iota.view]]</a>
2178
 
2179
  ``` cpp
2180
  namespace std::ranges {
2181
  template<class I>
 
2205
 
2206
  constexpr iterator begin() const;
2207
  constexpr auto end() const;
2208
  constexpr iterator end() const requires same_as<W, Bound>;
2209
 
2210
+ constexpr bool empty() const;
2211
  constexpr auto size() const requires see below;
2212
  };
2213
 
2214
  template<class W, class Bound>
2215
  requires (!is-integer-like<W> || !is-integer-like<Bound> ||
 
2353
  constexpr iterator end() const requires same_as<W, Bound>;
2354
  ```
2355
 
2356
  *Effects:* Equivalent to: `return `*`iterator`*`{`*`bound_`*`};`
2357
 
2358
+ ``` cpp
2359
+ constexpr bool empty() const;
2360
+ ```
2361
+
2362
+ *Effects:* Equivalent to: `return `*`value_`*` == `*`bound_`*`;`
2363
+
2364
  ``` cpp
2365
  constexpr auto size() const requires see below;
2366
  ```
2367
 
2368
  *Effects:* Equivalent to:
 
2725
  the same value.
2726
 
2727
  The name `views::repeat` denotes a customization point object
2728
  [[customization.point.object]]. Given subexpressions `E` and `F`, the
2729
  expressions `views::repeat(E)` and `views::repeat(E, F)` are
2730
+ expression-equivalent to `repeat_view<decay_t<decltype((E))>>(E)` and
2731
+ `repeat_view(E, F)`, respectively.
2732
 
2733
  [*Example 1*:
2734
 
2735
  ``` cpp
2736
  for (int i : views::repeat(17, 4))
 
2777
  constexpr unreachable_sentinel_t end() const noexcept;
2778
 
2779
  constexpr auto size() const requires (!same_as<Bound, unreachable_sentinel_t>);
2780
  };
2781
 
2782
+ template<class T, class Bound = unreachable_sentinel_t>
2783
+ repeat_view(T, Bound = Bound()) -> repeat_view<T, Bound>;
2784
  }
2785
  ```
2786
 
2787
  ``` cpp
2788
  constexpr explicit repeat_view(const T& value, Bound bound = Bound())
 
3341
  - Otherwise, `movable-box<T>` should store only a `T` if either `T`
3342
  models `movable` or `is_nothrow_move_constructible_v<T>` is `true`.
3343
 
3344
  ### Non-propagating cache <a id="range.nonprop.cache">[[range.nonprop.cache]]</a>
3345
 
3346
+ Some types in [[range.adaptors]] are specified in terms of an
3347
  exposition-only class template *`non-propagating-{}cache`*.
3348
  `non-propagating-cache<T>` behaves exactly like `optional<T>` with the
3349
  following differences:
3350
 
3351
  - `non-propagating-cache<T>` constrains its type parameter `T` with
 
3420
 
3421
  template<class T>
3422
  constexpr T& as-lvalue(T&& t) { // exposition only
3423
  return static_cast<T&>(t);
3424
  }
3425
+
3426
+ template<bool Const, class... Views>
3427
+ concept all-random-access = // exposition only
3428
+ (random_access_range<maybe-const<Const, Views>> && ...);
3429
+ template<bool Const, class... Views>
3430
+ concept all-bidirectional = // exposition only
3431
+ (bidirectional_range<maybe-const<Const, Views>> && ...);
3432
+ template<bool Const, class... Views>
3433
+ concept all-forward = // exposition only
3434
+ (forward_range<maybe-const<Const, Views>> && ...);
3435
  }
3436
  ```
3437
 
3438
  ### All view <a id="range.all">[[range.all]]</a>
3439
 
 
3477
  { return ranges::empty(*r_); }
3478
 
3479
  constexpr auto size() const requires sized_range<R>
3480
  { return ranges::size(*r_); }
3481
 
3482
+ constexpr auto reserve_hint() const requires approximately_sized_range<R>
3483
+ { return ranges::reserve_hint(*r_); }
3484
+
3485
  constexpr auto data() const requires contiguous_range<R>
3486
  { return ranges::data(*r_); }
3487
  };
3488
 
3489
  template<class R>
 
3553
  constexpr auto size() requires sized_range<R>
3554
  { return ranges::size(r_); }
3555
  constexpr auto size() const requires sized_range<const R>
3556
  { return ranges::size(r_); }
3557
 
3558
+ constexpr auto reserve_hint() requires approximately_sized_range<R>
3559
+ { return ranges::reserve_hint(r_); }
3560
+ constexpr auto reserve_hint() const requires approximately_sized_range<const R>
3561
+ { return ranges::reserve_hint(r_); }
3562
+
3563
  constexpr auto data() requires contiguous_range<R>
3564
  { return ranges::data(r_); }
3565
  constexpr auto data() const requires contiguous_range<const R>
3566
  { return ranges::data(r_); }
3567
  };
 
3586
  The name `views::as_rvalue` denotes a range adaptor object
3587
  [[range.adaptor.object]]. Let `E` be an expression and let `T` be
3588
  `decltype((E))`. The expression `views::as_rvalue(E)` is
3589
  expression-equivalent to:
3590
 
3591
+ - `views::all(E)` if `T` models `input_range` and
3592
  `same_as<range_rvalue_reference_t<T>, range_reference_t<T>>` is
3593
  `true`.
3594
  - Otherwise, `as_rvalue_view(E)`.
3595
 
3596
  [*Example 1*:
 
3640
  }
3641
  }
3642
 
3643
  constexpr auto size() requires sized_range<V> { return ranges::size(base_); }
3644
  constexpr auto size() const requires sized_range<const V> { return ranges::size(base_); }
3645
+
3646
+ constexpr auto reserve_hint() requires approximately_sized_range<V>
3647
+ { return ranges::reserve_hint(base_); }
3648
+ constexpr auto reserve_hint() const requires approximately_sized_range<const V>
3649
+ { return ranges::reserve_hint(base_); }
3650
  };
3651
 
3652
  template<class R>
3653
  as_rvalue_view(R&&) -> as_rvalue_view<views::all_t<R>>;
3654
  }
 
4032
  regular_invocable<const F&, range_reference_t<const V>>;
4033
 
4034
  constexpr auto size() requires sized_range<V> { return ranges::size(base_); }
4035
  constexpr auto size() const requires sized_range<const V>
4036
  { return ranges::size(base_); }
4037
+
4038
+ constexpr auto reserve_hint() requires approximately_sized_range<V>
4039
+ { return ranges::reserve_hint(base_); }
4040
+ constexpr auto reserve_hint() const requires approximately_sized_range<const V>
4041
+ { return ranges::reserve_hint(base_); }
4042
  };
4043
 
4044
  template<class R, class F>
4045
  transform_view(R&&, F) -> transform_view<views::all_t<R>, F>;
4046
  }
 
4620
 
4621
  constexpr auto size() const requires sized_range<const V> {
4622
  auto n = ranges::size(base_);
4623
  return ranges::min(n, static_cast<decltype(n)>(count_));
4624
  }
4625
+
4626
+ constexpr auto reserve_hint() {
4627
+ if constexpr (approximately_sized_range<V>) {
4628
+ auto n = static_cast<range_difference_t<V>>(ranges::reserve_hint(base_));
4629
+ return to-unsigned-like(ranges::min(n, count_));
4630
+ }
4631
+ return to-unsigned-like(count_);
4632
+ }
4633
+
4634
+ constexpr auto reserve_hint() const {
4635
+ if constexpr (approximately_sized_range<const V>) {
4636
+ auto n = static_cast<range_difference_t<const V>>(ranges::reserve_hint(base_));
4637
+ return to-unsigned-like(ranges::min(n, count_));
4638
+ }
4639
+ return to-unsigned-like(count_);
4640
+ }
4641
  };
4642
 
4643
  template<class R>
4644
  take_view(R&&, range_difference_t<R>)
4645
  -> take_view<views::all_t<R>>;
 
4889
  then
4890
  `U(ranges::begin(E) + std::min<D>(ranges::distance(E), F), ranges::end(E))`,
4891
  except that `E` is evaluated only once, where `U` is
4892
  `span<typename T::element_type>` if `T` is a specialization of `span`
4893
  and `T` otherwise.
4894
+ - Otherwise, if `T` is a specialization of `subrange` that models
4895
+ `random_access_range` and `sized_range`, then
4896
  `T(ranges::begin(E) + std::min<D>(ranges::distance(E), F), ranges::{}end(E),
4897
  to-unsigned-like(ranges::distance(E) -
4898
  std::min<D>(ranges::distance(E), F)))`, except that `E` and `F` are
4899
  each evaluated only once.
4900
  - Otherwise, if `T` is a specialization of `repeat_view`
 
4955
  const auto s = ranges::size(base_);
4956
  const auto c = static_cast<decltype(s)>(count_);
4957
  return s < c ? 0 : s - c;
4958
  }
4959
 
4960
+ constexpr auto reserve_hint() requires approximately_sized_range<V> {
4961
+ const auto s = static_cast<range_difference_t<V>>(ranges::reserve_hint(base_));
4962
+ return to-unsigned-like(s < count_ ? 0 : s - count_);
4963
+ }
4964
+
4965
+ constexpr auto reserve_hint() const requires approximately_sized_range<const V> {
4966
+ const auto s = static_cast<range_difference_t<const V>>(ranges::reserve_hint(base_));
4967
+ return to-unsigned-like(s < count_ ? 0 : s - count_);
4968
+ }
4969
+
4970
  private:
4971
  V base_ = V(); // exposition only
4972
  range_difference_t<V> count_ = 0; // exposition only
4973
  };
4974
 
 
5471
  noexcept(noexcept(ranges::iter_swap(*x.inner_, *y.inner_)))
5472
  requires indirectly_swappable<InnerIter>;
5473
  ```
5474
 
5475
  *Effects:* Equivalent to:
5476
+ `ranges::iter_swap(*x.`*`inner_`*`, *y.`*`inner_`*`);`
5477
 
5478
  #### Class template `join_view::sentinel` <a id="range.join.sentinel">[[range.join.sentinel]]</a>
5479
 
5480
  ``` cpp
5481
  namespace std::ranges {
 
5550
 
5551
  #### Class template `join_with_view` <a id="range.join.with.view">[[range.join.with.view]]</a>
5552
 
5553
  ``` cpp
5554
  namespace std::ranges {
 
 
 
 
 
 
5555
  template<class R>
5556
  concept bidirectional-common = bidirectional_range<R> && common_range<R>; // exposition only
5557
 
5558
  template<input_range V, forward_range Pattern>
5559
  requires view<V> && input_range<range_reference_t<V>>
5560
  && view<Pattern>
5561
+ && concatable<range_reference_t<V>, Pattern>
5562
  class join_with_view : public view_interface<join_with_view<V, Pattern>> {
5563
  using InnerRng = range_reference_t<V>; // exposition only
5564
 
5565
  V base_ = V(); // exposition only
5566
  non-propagating-cache<iterator_t<V>> outer_it_; // exposition only, present only
 
5602
  }
5603
  constexpr auto begin() const
5604
  requires forward_range<const V> &&
5605
  forward_range<const Pattern> &&
5606
  is_reference_v<range_reference_t<const V>> &&
5607
+ input_range<range_reference_t<const V>> &&
5608
+ concatable<range_reference_t<const V>, const Pattern> {
5609
  return iterator<true>{*this, ranges::begin(base_)};
5610
  }
5611
 
5612
  constexpr auto end() {
5613
  if constexpr (forward_range<V> &&
 
5618
  return sentinel<simple-view<V> && simple-view<Pattern>>{*this};
5619
  }
5620
  constexpr auto end() const
5621
  requires forward_range<const V> && forward_range<const Pattern> &&
5622
  is_reference_v<range_reference_t<const V>> &&
5623
+ input_range<range_reference_t<const V>> &&
5624
+ concatable<range_reference_t<const V>, const Pattern> {
5625
  using InnerConstRng = range_reference_t<const V>;
5626
  if constexpr (forward_range<InnerConstRng> &&
5627
  common_range<const V> && common_range<InnerConstRng>)
5628
  return iterator<true>{*this, ranges::end(base_)};
5629
  else
 
5661
 
5662
  ``` cpp
5663
  namespace std::ranges {
5664
  template<input_range V, forward_range Pattern>
5665
  requires view<V> && input_range<range_reference_t<V>>
5666
+ && view<Pattern> && concatable<range_reference_t<V>, Pattern>
5667
  template<bool Const>
5668
  class join_with_view<V, Pattern>::iterator {
5669
  using Parent = maybe-const<Const, join_with_view>; // exposition only
5670
  using Base = maybe-const<Const, V>; // exposition only
5671
  using InnerBase = range_reference_t<Base>; // exposition only
 
5764
  iter_reference_t<PatternIter>>>
5765
  ```
5766
 
5767
  is `false`, `iterator_category` denotes `input_iterator_tag`.
5768
  - Otherwise, if *OUTERC*, *INNERC*, and *PATTERNC* each model
5769
+ `derived_from<bidirectional_iterator_tag>` and *`InnerBase`* and
5770
  *`PatternBase`* each model `common_range`, `iterator_category` denotes
5771
  `bidirectional_iterator_tag`.
5772
  - Otherwise, if *OUTERC*, *INNERC*, and *PATTERNC* each model
5773
  `derived_from<forward_iterator_tag>`, `iterator_category` denotes
5774
  `forward_iterator_tag`.
 
5832
  ``` cpp
5833
  while (true) {
5834
  if (inner_it_.index() == 0) {
5835
  if (std::get<0>(inner_it_) != ranges::end(parent_->pattern_))
5836
  break;
5837
+ inner_it_.template emplace<1>(ranges::begin(update-inner()));
5838
  } else {
5839
  if (std::get<1>(inner_it_) != ranges::end(get-inner()))
5840
  break;
5841
  if (++outer() == ranges::end(parent_->base_)) {
5842
  if constexpr (ref-is-glvalue)
5843
+ inner_it_.template emplace<0>();
5844
  break;
5845
  }
5846
+ inner_it_.template emplace<0>(ranges::begin(parent_->pattern_));
5847
  }
5848
  }
5849
  ```
5850
 
5851
  [*Note 1*: `join_with_view` iterators use the *satisfy* function to
 
5862
  first overload, also initializes *outer_it\_* with `std::move(outer)`.
5863
  Then, equivalent to:
5864
 
5865
  ``` cpp
5866
  if (outer() != ranges::end(parent_->base_)) {
5867
+ inner_it_.template emplace<1>(ranges::begin(update-inner()));
5868
  satisfy();
5869
  }
5870
  ```
5871
 
5872
  ``` cpp
 
5879
  *Effects:* Initializes *outer_it\_* with `std::move(i.`*`outer_it_`*`)`
5880
  and *parent\_* with `i.`*`parent_`*. Then, equivalent to:
5881
 
5882
  ``` cpp
5883
  if (i.inner_it_.index() == 0)
5884
+ inner_it_.template emplace<0>(std::get<0>(std::move(i.inner_it_)));
5885
  else
5886
+ inner_it_.template emplace<1>(std::get<1>(std::move(i.inner_it_)));
5887
  ```
5888
 
5889
  [*Note 2*: `Const` can only be `true` when *Base* models
5890
  `forward_range`. — *end note*]
5891
 
 
5941
  *Effects:* Equivalent to:
5942
 
5943
  ``` cpp
5944
  if (outer_it_ == ranges::end(parent_->base_)) {
5945
  auto&& inner = *--outer_it_;
5946
+ inner_it_.template emplace<1>(ranges::end(inner));
5947
  }
5948
 
5949
  while (true) {
5950
  if (inner_it_.index() == 0) {
5951
  auto& it = std::get<0>(inner_it_);
5952
  if (it == ranges::begin(parent_->pattern_)) {
5953
  auto&& inner = *--outer_it_;
5954
+ inner_it_.template emplace<1>(ranges::end(inner));
5955
  } else {
5956
  break;
5957
  }
5958
  } else {
5959
  auto& it = std::get<1>(inner_it_);
5960
  auto&& inner = *outer_it_;
5961
  if (it == ranges::begin(inner)) {
5962
+ inner_it_.template emplace<0>(ranges::end(parent_->pattern_));
5963
  } else {
5964
  break;
5965
  }
5966
  }
5967
  }
 
5999
 
6000
  ``` cpp
6001
  namespace std::ranges {
6002
  template<input_range V, forward_range Pattern>
6003
  requires view<V> && input_range<range_reference_t<V>>
6004
+ && view<Pattern> && concatable<range_reference_t<V>, Pattern>
6005
  template<bool Const>
6006
  class join_with_view<V, Pattern>::sentinel {
6007
  using Parent = maybe-const<Const, join_with_view>; // exposition only
6008
  using Base = maybe-const<Const, V>; // exposition only
6009
  sentinel_t<Base> end_ = sentinel_t<Base>(); // exposition only
 
6248
  ``` cpp
6249
  constexpr outer-iterator(outer-iterator<!Const> i)
6250
  requires Const && convertible_to<iterator_t<V>, iterator_t<Base>>;
6251
  ```
6252
 
6253
+ *Effects:* Initializes *parent\_* with `i.`*`parent_`*, *current\_* with
6254
+ `std::move(i.`*`current_`*`)`, and *trailing_empty\_* with
6255
+ `i.`*`trailing_empty_`*.
6256
 
6257
  ``` cpp
6258
  constexpr value_type operator*() const;
6259
  ```
6260
 
 
6329
  struct lazy_split_view<V, Pattern>::outer-iterator<Const>::value_type
6330
  : view_interface<value_type> {
6331
  private:
6332
  outer-iterator i_ = outer-iterator(); // exposition only
6333
 
6334
+ constexpr explicit value_type(outer-iterator i); // exposition only
 
 
6335
 
6336
+ public:
6337
  constexpr inner-iterator<Const> begin() const;
6338
  constexpr default_sentinel_t end() const noexcept;
6339
  };
6340
  }
6341
  ```
 
6373
  using Base = maybe-const<Const, V>; // exposition only
6374
  outer-iterator<Const> i_ = outer-iterator<Const>(); // exposition only
6375
  bool incremented_ = false; // exposition only
6376
 
6377
  public:
6378
+ using iterator_concept = outer-iterator<Const>::iterator_concept;
6379
 
6380
  using iterator_category = see belownc; // present only if Base
6381
  // models forward_range
6382
  using value_type = range_value_t<Base>;
6383
  using difference_type = range_difference_t<Base>;
 
6668
 
6669
  ``` cpp
6670
  constexpr iterator_t<V> base() const;
6671
  ```
6672
 
6673
+ *Effects:* Equivalent to: `return `*`cur_`*`;`
6674
 
6675
  ``` cpp
6676
  constexpr value_type operator*() const;
6677
  ```
6678
 
6679
+ *Effects:* Equivalent to: `return {`*`cur_`*`, `*`next_`*`.begin()};`
6680
 
6681
  ``` cpp
6682
  constexpr iterator& operator++();
6683
  ```
6684
 
 
6753
  ```
6754
 
6755
  *Effects:* Equivalent to:
6756
  `return x.`*`cur_`*` == y.`*`end_`*` && !x.`*`trailing_empty_`*`;`
6757
 
6758
+ ### Concat view <a id="range.concat">[[range.concat]]</a>
6759
+
6760
+ #### Overview <a id="range.concat.overview">[[range.concat.overview]]</a>
6761
+
6762
+ `concat_view` presents a view that concatenates all the underlying
6763
+ ranges.
6764
+
6765
+ The name `views::concat` denotes a customization point object
6766
+ [[customization.point.object]]. Given a pack of subexpressions `Es...`,
6767
+ the expression `views::concat(Es...)` is expression-equivalent to
6768
+
6769
+ - `views::all(Es...)` if `Es` is a pack with only one element whose type
6770
+ models `input_range`,
6771
+ - otherwise, `concat_view(Es...)`.
6772
+
6773
+ [*Example 1*:
6774
+
6775
+ ``` cpp
6776
+ vector<int> v1{1, 2, 3}, v2{4, 5}, v3{};
6777
+ array a{6, 7, 8};
6778
+ auto s = views::single(9);
6779
+ for (auto&& i : views::concat(v1, v2, v3, a, s)) {
6780
+ print("{} ", i); // prints 1 2 3 4 5 6 7 8 9
6781
+ }
6782
+ ```
6783
+
6784
+ — *end example*]
6785
+
6786
+ #### Class template `concat_view` <a id="range.concat.view">[[range.concat.view]]</a>
6787
+
6788
+ ``` cpp
6789
+ namespace std::ranges {
6790
+ template<class... Rs>
6791
+ using concat-reference-t = common_reference_t<range_reference_t<Rs>...>; // exposition only
6792
+ template<class... Rs>
6793
+ using concat-value-t = common_type_t<range_value_t<Rs>...>; // exposition only
6794
+ template<class... Rs>
6795
+ using concat-rvalue-reference-t = // exposition only
6796
+ common_reference_t<range_rvalue_reference_t<Rs>...>;
6797
+
6798
+ template<class... Rs>
6799
+ concept concat-indirectly-readable = see below; // exposition only
6800
+ template<class... Rs>
6801
+ concept concatable = see below; // exposition only
6802
+ template<bool Const, class... Rs>
6803
+ concept concat-is-random-access = see below; // exposition only
6804
+ template<bool Const, class... Rs>
6805
+ concept concat-is-bidirectional = see below; // exposition only
6806
+
6807
+ template<input_range... Views>
6808
+ requires (view<Views> && ...) && (sizeof...(Views) > 0) &&
6809
+ concatable<Views...>
6810
+ class concat_view : public view_interface<concat_view<Views...>> {
6811
+
6812
+ tuple<Views...> views_; // exposition only
6813
+
6814
+ // [range.concat.iterator], class template concat_view::iterator
6815
+ template<bool> class iterator; // exposition only
6816
+
6817
+ public:
6818
+ constexpr concat_view() = default;
6819
+ constexpr explicit concat_view(Views... views);
6820
+
6821
+ constexpr iterator<false> begin() requires (!(simple-view<Views> && ...));
6822
+ constexpr iterator<true> begin() const
6823
+ requires (range<const Views> && ...) && concatable<const Views...>;
6824
+
6825
+ constexpr auto end() requires (!(simple-view<Views> && ...));
6826
+ constexpr auto end() const
6827
+ requires (range<const Views> && ...) && concatable<const Views...>;
6828
+
6829
+ constexpr auto size() requires (sized_range<Views> && ...);
6830
+ constexpr auto size() const requires (sized_range<const Views> && ...);
6831
+ };
6832
+
6833
+ template<class... R>
6834
+ concat_view(R&&...) -> concat_view<views::all_t<R>...>;
6835
+ }
6836
+ ```
6837
+
6838
+ ``` cpp
6839
+ template<class... Rs>
6840
+ concept concat-indirectly-readable = see below; // exposition only
6841
+ ```
6842
+
6843
+ The exposition-only `concat-indirectly-readable` concept is equivalent
6844
+ to:
6845
+
6846
+ ``` cpp
6847
+ template<class Ref, class RRef, class It>
6848
+ concept concat-indirectly-readable-impl = // exposition only
6849
+ requires (const It it) {
6850
+ { *it } -> convertible_to<Ref>;
6851
+ { ranges::iter_move(it) } -> convertible_to<RRef>;
6852
+ };
6853
+
6854
+ template<class... Rs>
6855
+ concept concat-indirectly-readable = // exposition only
6856
+ common_reference_with<concat-reference-t<Rs...>&&,
6857
+ concat-value-t<Rs...>&> &&
6858
+ common_reference_with<concat-reference-t<Rs...>&&,
6859
+ concat-rvalue-reference-t<Rs...>&&> &&
6860
+ common_reference_with<concat-rvalue-reference-t<Rs...>&&,
6861
+ concat-value-t<Rs...> const&> &&
6862
+ (concat-indirectly-readable-impl<concat-reference-t<Rs...>,
6863
+ concat-rvalue-reference-t<Rs...>,
6864
+ iterator_t<Rs>> && ...);
6865
+ ```
6866
+
6867
+ ``` cpp
6868
+ template<class... Rs>
6869
+ concept concatable = see below; // exposition only
6870
+ ```
6871
+
6872
+ The exposition-only `concatable` concept is equivalent to:
6873
+
6874
+ ``` cpp
6875
+ template<class... Rs>
6876
+ concept concatable = requires { // exposition only
6877
+ typename concat-reference-t<Rs...>;
6878
+ typename concat-value-t<Rs...>;
6879
+ typename concat-rvalue-reference-t<Rs...>;
6880
+ } && concat-indirectly-readable<Rs...>;
6881
+ ```
6882
+
6883
+ ``` cpp
6884
+ template<bool Const, class... Rs>
6885
+ concept concat-is-random-access = see below; // exposition only
6886
+ ```
6887
+
6888
+ Let `Fs` be the pack that consists of all elements of `Rs` except the
6889
+ last element, then *`concat-is-random-access`* is equivalent to:
6890
+
6891
+ ``` cpp
6892
+ template<bool Const, class... Rs>
6893
+ concept concat-is-random-access = // exposition only
6894
+ all-random-access<Const, Rs...> &&
6895
+ (common_range<maybe-const<Const, Fs>> && ...);
6896
+ ```
6897
+
6898
+ ``` cpp
6899
+ template<bool Const, class... Rs>
6900
+ concept concat-is-bidirectional = see below; // exposition only
6901
+ ```
6902
+
6903
+ Let `Fs` be the pack that consists of all elements of `Rs` except the
6904
+ last element, then *`concat-is-bidirectional`* is equivalent to:
6905
+
6906
+ ``` cpp
6907
+ template<bool Const, class... Rs>
6908
+ concept concat-is-bidirectional = // exposition only
6909
+ all-bidirectional<Const, Rs...> &&
6910
+ (common_range<maybe-const<Const, Fs>> && ...);
6911
+ ```
6912
+
6913
+ ``` cpp
6914
+ constexpr explicit concat_view(Views... views);
6915
+ ```
6916
+
6917
+ *Effects:* Initializes *views\_* with `std::move(views)...`.
6918
+
6919
+ ``` cpp
6920
+ constexpr iterator<false> begin() requires (!(simple-view<Views> && ...));
6921
+ constexpr iterator<true> begin() const
6922
+ requires (range<const Views> && ...) && concatable<const Views...>;
6923
+ ```
6924
+
6925
+ *Effects:* Let *is-const* be `true` for the const-qualified overload,
6926
+ and `false` otherwise. Equivalent to:
6927
+
6928
+ ``` cpp
6929
+ iterator<is-const> it(this, in_place_index<0>, ranges::begin(std::get<0>(views_)));
6930
+ it.template satisfy<0>();
6931
+ return it;
6932
+ ```
6933
+
6934
+ ``` cpp
6935
+ constexpr auto end() requires (!(simple-view<Views> && ...));
6936
+ constexpr auto end() const
6937
+ requires (range<const Views> && ...) && concatable<const Views...>;
6938
+ ```
6939
+
6940
+ *Effects:* Let *is-const* be `true` for the const-qualified overload,
6941
+ and `false` otherwise. Equivalent to:
6942
+
6943
+ ``` cpp
6944
+ constexpr auto N = sizeof...(Views);
6945
+ if constexpr (common_range<maybe-const<is-const, Views...[N - 1]>>) {
6946
+ return iterator<is-const>(this, in_place_index<N - 1>,
6947
+ ranges::end(std::get<N - 1>(views_)));
6948
+ } else {
6949
+ return default_sentinel;
6950
+ }
6951
+ ```
6952
+
6953
+ ``` cpp
6954
+ constexpr auto size() requires (sized_range<Views> && ...);
6955
+ constexpr auto size() const requires (sized_range<const Views> && ...);
6956
+ ```
6957
+
6958
+ *Effects:* Equivalent to:
6959
+
6960
+ ``` cpp
6961
+ return apply(
6962
+ [](auto... sizes) {
6963
+ using CT = make-unsigned-like-t<common_type_t<decltype(sizes)...>>;
6964
+ return (CT(sizes) + ...);
6965
+ },
6966
+ tuple-transform(ranges::size, views_));
6967
+ ```
6968
+
6969
+ #### Class `concat_view::iterator` <a id="range.concat.iterator">[[range.concat.iterator]]</a>
6970
+
6971
+ ``` cpp
6972
+ namespace std::ranges {
6973
+ template<input_range... Views>
6974
+ requires (view<Views> && ...) && (sizeof...(Views) > 0) &&
6975
+ concatable<Views...>
6976
+ template<bool Const>
6977
+ class concat_view<Views...>::iterator {
6978
+
6979
+ public:
6980
+ using iterator_category = see below; // not always present
6981
+ using iterator_concept = see below;
6982
+ using value_type = concat-value-t<maybe-const<Const, Views>...>;
6983
+ using difference_type = common_type_t<range_difference_t<maybe-const<Const, Views>>...>;
6984
+
6985
+ private:
6986
+ using base-iter = // exposition only
6987
+ variant<iterator_t<maybe-const<Const, Views>>...>;
6988
+
6989
+ maybe-const<Const, concat_view>* parent_ = nullptr; // exposition only
6990
+ base-iter it_; // exposition only
6991
+
6992
+ template<size_t N>
6993
+ constexpr void satisfy(); // exposition only
6994
+ template<size_t N>
6995
+ constexpr void prev(); // exposition only
6996
+
6997
+ template<size_t N>
6998
+ constexpr void advance-fwd(difference_type offset, // exposition only
6999
+ difference_type steps);
7000
+ template<size_t N>
7001
+ constexpr void advance-bwd(difference_type offset, // exposition only
7002
+ difference_type steps);
7003
+
7004
+ template<class... Args>
7005
+ constexpr explicit iterator(maybe-const<Const, concat_view>* parent, // exposition only
7006
+ Args&&... args)
7007
+ requires constructible_from<base-iter, Args&&...>;
7008
+
7009
+ public:
7010
+ iterator() = default;
7011
+
7012
+ constexpr iterator(iterator<!Const> i)
7013
+ requires Const && (convertible_to<iterator_t<Views>, iterator_t<const Views>> && ...);
7014
+
7015
+ constexpr decltype(auto) operator*() const;
7016
+ constexpr iterator& operator++();
7017
+ constexpr void operator++(int);
7018
+ constexpr iterator operator++(int)
7019
+ requires all-forward<Const, Views...>;
7020
+ constexpr iterator& operator--()
7021
+ requires concat-is-bidirectional<Const, Views...>;
7022
+ constexpr iterator operator--(int)
7023
+ requires concat-is-bidirectional<Const, Views...>;
7024
+ constexpr iterator& operator+=(difference_type n)
7025
+ requires concat-is-random-access<Const, Views...>;
7026
+ constexpr iterator& operator-=(difference_type n)
7027
+ requires concat-is-random-access<Const, Views...>;
7028
+ constexpr decltype(auto) operator[](difference_type n) const
7029
+ requires concat-is-random-access<Const, Views...>;
7030
+
7031
+ friend constexpr bool operator==(const iterator& x, const iterator& y)
7032
+ requires (equality_comparable<iterator_t<maybe-const<Const, Views>>> && ...);
7033
+ friend constexpr bool operator==(const iterator& it, default_sentinel_t);
7034
+ friend constexpr bool operator<(const iterator& x, const iterator& y)
7035
+ requires all-random-access<Const, Views...>;
7036
+ friend constexpr bool operator>(const iterator& x, const iterator& y)
7037
+ requires all-random-access<Const, Views...>;
7038
+ friend constexpr bool operator<=(const iterator& x, const iterator& y)
7039
+ requires all-random-access<Const, Views...>;
7040
+ friend constexpr bool operator>=(const iterator& x, const iterator& y)
7041
+ requires all-random-access<Const, Views...>;
7042
+ friend constexpr auto operator<=>(const iterator& x, const iterator& y)
7043
+ requires (all-random-access<Const, Views...> &&
7044
+ (three_way_comparable<iterator_t<maybe-const<Const, Views>>> && ...));
7045
+ friend constexpr iterator operator+(const iterator& it, difference_type n)
7046
+ requires concat-is-random-access<Const, Views...>;
7047
+ friend constexpr iterator operator+(difference_type n, const iterator& it)
7048
+ requires concat-is-random-access<Const, Views...>;
7049
+ friend constexpr iterator operator-(const iterator& it, difference_type n)
7050
+ requires concat-is-random-access<Const, Views...>;
7051
+ friend constexpr difference_type operator-(const iterator& x, const iterator& y)
7052
+ requires concat-is-random-access<Const, Views...>;
7053
+ friend constexpr difference_type operator-(const iterator& x, default_sentinel_t)
7054
+ requires see below;
7055
+ friend constexpr difference_type operator-(default_sentinel_t, const iterator& x)
7056
+ requires see below;
7057
+ friend constexpr decltype(auto) iter_move(const iterator& it) noexcept(see below);
7058
+ friend constexpr void iter_swap(const iterator& x, const iterator& y) noexcept(see below)
7059
+ requires see below;
7060
+ };
7061
+ }
7062
+ ```
7063
+
7064
+ `iterator::iterator_concept` is defined as follows:
7065
+
7066
+ - If `concat-is-random-access<Const, Views...>` is modeled, then
7067
+ `iterator_concept` denotes `random_access_iterator_tag`.
7068
+ - Otherwise, if `concat-is-bidirectional<Const, Views...>` is modeled,
7069
+ then `iterator_concept` denotes `bidirectional_iterator_tag`.
7070
+ - Otherwise, if `all-forward<Const, Views...>` is modeled, then
7071
+ `iterator_concept` denotes `forward_iterator_tag`.
7072
+ - Otherwise, `iterator_concept` denotes `input_iterator_tag`.
7073
+
7074
+ The member *typedef-name* `iterator_category` is defined if and only if
7075
+ `all-forward<Const, Views...>` is modeled. In that case,
7076
+ `iterator::iterator_category` is defined as follows:
7077
+
7078
+ - If `is_reference_v<concat-reference-t<maybe-const<Const, Views>...>>`
7079
+ is `false`, then `iterator_category` denotes `input_iterator_tag`.
7080
+ - Otherwise, let `Cs` denote the pack of types
7081
+ `iterator_traits<iterator_t<maybe-const<Const, Views>>>::iterator_category...`.
7082
+ - If
7083
+ `(derived_from<Cs, random_access_iterator_tag> && ...) && concat-is-random-ac-{cess}<Const, Views...>`
7084
+ is `true`, `iterator_category` denotes `random_access_iterator_tag`.
7085
+ - Otherwise, if
7086
+ `(derived_from<Cs, bidirectional_iterator_tag> && ...) && concat-is-{bidirectional}<Const, Views...>`
7087
+ is `true`, `iterator_category` denotes `bidirectional_iterator_tag`.
7088
+ - Otherwise, if `(derived_from<Cs, forward_iterator_tag> && ...)` is
7089
+ `true`, `iterator_category` denotes `forward_iterator_tag`.
7090
+ - Otherwise, `iterator_category` denotes `input_iterator_tag`.
7091
+
7092
+ ``` cpp
7093
+ template<size_t N>
7094
+ constexpr void satisfy();
7095
+ ```
7096
+
7097
+ *Effects:* Equivalent to:
7098
+
7099
+ ``` cpp
7100
+ if constexpr (N < (sizeof...(Views) - 1)) {
7101
+ if (std::get<N>(it_) == ranges::end(std::get<N>(parent_->views_))) {
7102
+ it_.template emplace<N + 1>(ranges::begin(std::get<N + 1>(parent_->views_)));
7103
+ satisfy<N + 1>();
7104
+ }
7105
+ }
7106
+ ```
7107
+
7108
+ ``` cpp
7109
+ template<size_t N>
7110
+ constexpr void prev();
7111
+ ```
7112
+
7113
+ *Effects:* Equivalent to:
7114
+
7115
+ ``` cpp
7116
+ if constexpr (N == 0) {
7117
+ --std::get<0>(it_);
7118
+ } else {
7119
+ if (std::get<N>(it_) == ranges::begin(std::get<N>(parent_->views_))) {
7120
+ it_.template emplace<N - 1>(ranges::end(std::get<N - 1>(parent_->views_)));
7121
+ prev<N - 1>();
7122
+ } else {
7123
+ --std::get<N>(it_);
7124
+ }
7125
+ }
7126
+ ```
7127
+
7128
+ ``` cpp
7129
+ template<size_t N>
7130
+ constexpr void advance-fwd(difference_type offset, difference_type steps);
7131
+ ```
7132
+
7133
+ *Effects:* Equivalent to:
7134
+
7135
+ ``` cpp
7136
+ using underlying_diff_type = iter_difference_t<variant_alternative_t<N, base-iter>>;
7137
+ if constexpr (N == sizeof...(Views) - 1) {
7138
+ std::get<N>(it_) += static_cast<underlying_diff_type>(steps);
7139
+ } else {
7140
+ auto n_size = ranges::distance(std::get<N>(parent_->views_));
7141
+ if (offset + steps < n_size) {
7142
+ std::get<N>(it_) += static_cast<underlying_diff_type>(steps);
7143
+ } else {
7144
+ it_.template emplace<N + 1>(ranges::begin(std::get<N + 1>(parent_->views_)));
7145
+ advance-fwd<N + 1>(0, offset + steps - n_size);
7146
+ }
7147
+ }
7148
+ ```
7149
+
7150
+ ``` cpp
7151
+ template<size_t N>
7152
+ constexpr void advance-bwd(difference_type offset, difference_type steps);
7153
+ ```
7154
+
7155
+ *Effects:* Equivalent to:
7156
+
7157
+ ``` cpp
7158
+ using underlying_diff_type = iter_difference_t<variant_alternative_t<N, base-iter>>;
7159
+ if constexpr (N == 0) {
7160
+ std::get<N>(it_) -= static_cast<underlying_diff_type>(steps);
7161
+ } else {
7162
+ if (offset >= steps) {
7163
+ std::get<N>(it_) -= static_cast<underlying_diff_type>(steps);
7164
+ } else {
7165
+ auto prev_size = ranges::distance(std::get<N - 1>(parent_->views_));
7166
+ it_.template emplace<N - 1>(ranges::end(std::get<N - 1>(parent_->views_)));
7167
+ advance-bwd<N - 1>(prev_size, steps - offset);
7168
+ }
7169
+ }
7170
+ ```
7171
+
7172
+ ``` cpp
7173
+ template<class... Args>
7174
+ constexpr explicit iterator(maybe-const<Const, concat_view>* parent,
7175
+ Args&&... args)
7176
+ requires constructible_from<base-iter, Args&&...>;
7177
+ ```
7178
+
7179
+ *Effects:* Initializes *parent\_* with `parent`, and initializes *it\_*
7180
+ with `std::forward<Args>(args)...`.
7181
+
7182
+ ``` cpp
7183
+ constexpr iterator(iterator<!Const> it)
7184
+ requires Const &&
7185
+ (convertible_to<iterator_t<Views>, iterator_t<const Views>> && ...);
7186
+ ```
7187
+
7188
+ *Preconditions:* `it.`*`it_`*`.valueless_by_exception()` is `false`.
7189
+
7190
+ *Effects:* Initializes *parent\_* with `it.`*`parent_`*, and let i be
7191
+ `it.`*`it_`*`.index()`, initializes *it\_* with
7192
+ *`base-iter`*`(in_place_index<`i`>, std::get<`i`>(std::move(it.`*`it_`*`)))`.
7193
+
7194
+ ``` cpp
7195
+ constexpr decltype(auto) operator*() const;
7196
+ ```
7197
+
7198
+ *Preconditions:* *`it_`*`.valueless_by_exception()` is `false`.
7199
+
7200
+ *Effects:* Equivalent to:
7201
+
7202
+ ``` cpp
7203
+ using reference = concat-reference-t<maybe-const<Const, Views>...>;
7204
+ return std::visit([](auto&& it) -> reference { return *it; },
7205
+ it_);
7206
+ ```
7207
+
7208
+ ``` cpp
7209
+ constexpr iterator& operator++();
7210
+ ```
7211
+
7212
+ *Preconditions:* *`it_`*`.valueless_by_exception()` is `false`.
7213
+
7214
+ *Effects:* Let i be *`it_`*`.index()`. Equivalent to:
7215
+
7216
+ ``` cpp
7217
+ ++std::get<i>(it_);
7218
+ satisfy<i>();
7219
+ return *this;
7220
+ ```
7221
+
7222
+ ``` cpp
7223
+ constexpr void operator++(int);
7224
+ ```
7225
+
7226
+ *Effects:* Equivalent to:
7227
+
7228
+ ``` cpp
7229
+ ++*this;
7230
+ ```
7231
+
7232
+ ``` cpp
7233
+ constexpr iterator operator++(int)
7234
+ requires all-forward<Const, Views...>;
7235
+ ```
7236
+
7237
+ *Effects:* Equivalent to:
7238
+
7239
+ ``` cpp
7240
+ auto tmp = *this;
7241
+ ++*this;
7242
+ return tmp;
7243
+ ```
7244
+
7245
+ ``` cpp
7246
+ constexpr iterator& operator--()
7247
+ requires concat-is-bidirectional<Const, Views...>;
7248
+ ```
7249
+
7250
+ *Preconditions:* *`it_`*`.valueless_by_exception()` is `false`.
7251
+
7252
+ *Effects:* Let i be *`it_`*`.index()`. Equivalent to:
7253
+
7254
+ ``` cpp
7255
+ prev<i>();
7256
+ return *this;
7257
+ ```
7258
+
7259
+ ``` cpp
7260
+ constexpr iterator operator--(int)
7261
+ requires concat-is-bidirectional<Const, Views...>;
7262
+ ```
7263
+
7264
+ *Effects:* Equivalent to:
7265
+
7266
+ ``` cpp
7267
+ auto tmp = *this;
7268
+ --*this;
7269
+ return tmp;
7270
+ ```
7271
+
7272
+ ``` cpp
7273
+ constexpr iterator& operator+=(difference_type n)
7274
+ requires concat-is-random-access<Const, Views...>;
7275
+ ```
7276
+
7277
+ *Preconditions:* *`it_`*`.valueless_by_exception()` is `false`.
7278
+
7279
+ *Effects:* Let i be *`it_`*`.index()`. Equivalent to:
7280
+
7281
+ ``` cpp
7282
+ if (n > 0) {
7283
+ advance-fwd<i>(std::get<i>(it_) - ranges::begin(std::get<i>(parent_->views_)), n);
7284
+ } else if (n < 0) {
7285
+ advance-bwd<i>(std::get<i>(it_) - ranges::begin(std::get<i>(parent_->views_)), -n);
7286
+ }
7287
+ return *this;
7288
+ ```
7289
+
7290
+ ``` cpp
7291
+ constexpr iterator& operator-=(difference_type n)
7292
+ requires concat-is-random-access<Const, Views...>;
7293
+ ```
7294
+
7295
+ *Effects:* Equivalent to:
7296
+
7297
+ ``` cpp
7298
+ *this += -n;
7299
+ return *this;
7300
+ ```
7301
+
7302
+ ``` cpp
7303
+ constexpr decltype(auto) operator[](difference_type n) const
7304
+ requires concat-is-random-access<Const, Views...>;
7305
+ ```
7306
+
7307
+ *Effects:* Equivalent to:
7308
+
7309
+ ``` cpp
7310
+ return *((*this) + n);
7311
+ ```
7312
+
7313
+ ``` cpp
7314
+ friend constexpr bool operator==(const iterator& x, const iterator& y)
7315
+ requires (equality_comparable<iterator_t<maybe-const<Const, Views>>> && ...);
7316
+ ```
7317
+
7318
+ *Preconditions:* `x.`*`it_`*`.valueless_by_exception()` and
7319
+ `y.`*`it_`*`.valueless_by_exception()` are each `false`.
7320
+
7321
+ *Effects:* Equivalent to:
7322
+
7323
+ ``` cpp
7324
+ return x.it_ == y.it_;
7325
+ ```
7326
+
7327
+ ``` cpp
7328
+ friend constexpr bool operator==(const iterator& it, default_sentinel_t);
7329
+ ```
7330
+
7331
+ *Preconditions:* `it.`*`it_`*`.valueless_by_exception()` is `false`.
7332
+
7333
+ *Effects:* Equivalent to:
7334
+
7335
+ ``` cpp
7336
+ constexpr auto last_idx = sizeof...(Views) - 1;
7337
+ return it.it_.index() == last_idx &&
7338
+ std::get<last_idx>(it.it_) == ranges::end(std::get<last_idx>(it.parent_->views_));
7339
+ ```
7340
+
7341
+ ``` cpp
7342
+ friend constexpr bool operator<(const iterator& x, const iterator& y)
7343
+ requires all-random-access<Const, Views...>;
7344
+ friend constexpr bool operator>(const iterator& x, const iterator& y)
7345
+ requires all-random-access<Const, Views...>;
7346
+ friend constexpr bool operator<=(const iterator& x, const iterator& y)
7347
+ requires all-random-access<Const, Views...>;
7348
+ friend constexpr bool operator>=(const iterator& x, const iterator& y)
7349
+ requires all-random-access<Const, Views...>;
7350
+ friend constexpr auto operator<=>(const iterator& x, const iterator& y)
7351
+ requires (all-random-access<Const, Views...> &&
7352
+ (three_way_comparable<iterator_t<maybe-const<Const, Views>>> && ...));
7353
+ ```
7354
+
7355
+ *Preconditions:* `x.`*`it_`*`.valueless_by_exception()` and
7356
+ `y.`*`it_`*`.valueless_by_exception()` are each `false`.
7357
+
7358
+ Let op be the operator.
7359
+
7360
+ *Effects:* Equivalent to:
7361
+
7362
+ ``` cpp
7363
+ return x.it_ op y.it_;
7364
+ ```
7365
+
7366
+ ``` cpp
7367
+ friend constexpr iterator operator+(const iterator& it, difference_type n)
7368
+ requires concat-is-random-access<Const, Views...>;
7369
+ ```
7370
+
7371
+ *Effects:* Equivalent to:
7372
+
7373
+ ``` cpp
7374
+ auto temp = it;
7375
+ temp += n;
7376
+ return temp;
7377
+ ```
7378
+
7379
+ ``` cpp
7380
+ friend constexpr iterator operator+(difference_type n, const iterator& it)
7381
+ requires concat-is-random-access<Const, Views...>;
7382
+ ```
7383
+
7384
+ *Effects:* Equivalent to:
7385
+
7386
+ ``` cpp
7387
+ return it + n;
7388
+ ```
7389
+
7390
+ ``` cpp
7391
+ friend constexpr iterator operator-(const iterator& it, difference_type n)
7392
+ requires concat-is-random-access<Const, Views...>;
7393
+ ```
7394
+
7395
+ *Effects:* Equivalent to:
7396
+
7397
+ ``` cpp
7398
+ auto temp = it;
7399
+ temp -= n;
7400
+ return temp;
7401
+ ```
7402
+
7403
+ ``` cpp
7404
+ friend constexpr difference_type operator-(const iterator& x, const iterator& y)
7405
+ requires concat-is-random-access<Const, Views...>;
7406
+ ```
7407
+
7408
+ *Preconditions:* `x.`*`it_`*`.valueless_by_exception()` and
7409
+ `y.`*`it_`*`.valueless_by_exception()` are each `false`.
7410
+
7411
+ *Effects:* Let i_`x` denote `x.`*`it_`*`.index()` and i_`y` denote
7412
+ `y.`*`it_`*`.index()`.
7413
+
7414
+ - If i_`x`` > `i_`y`, let d_`y` be
7415
+ `ranges::distance(std::get<`i_`y``>(y.`*`it_`*`), ranges::end(std::get<`i_`y``>(y.`*`parent_`*`->`*`views_`*`)))`,
7416
+ d_`x` be
7417
+ `ranges::distance(ranges::begin(std::get<`i_`x``>(x.`*`parent_`*`->`*`views_`*`)), std::get<`i_`x``>(x.`*`it_`*`))`.
7418
+ Let s denote the sum of the sizes of all the ranges
7419
+ `std::get<`i`>(x.`*`parent_`*`->`*`views_`*`)` for every integer i in
7420
+ the range \[i_`y`` + 1`, i_`x`) if there is any, and `0` otherwise, of
7421
+ type `difference_type`, equivalent to:
7422
+ ``` cpp
7423
+ return $d_y$ + s + $d_x$;
7424
+ ```
7425
+ - otherwise, if i_`x`` < `i_`y` is `true`, equivalent to:
7426
+ ``` cpp
7427
+ return -(y - x);
7428
+ ```
7429
+ - otherwise, equivalent to:
7430
+ ``` cpp
7431
+ return std::get<$i_x$>(x.it_) - std::get<$i_y$>(y.it_);
7432
+ ```
7433
+
7434
+ ``` cpp
7435
+ friend constexpr difference_type operator-(const iterator& x, default_sentinel_t)
7436
+ requires see below;
7437
+ ```
7438
+
7439
+ *Preconditions:* `x.`*`it_`*`.valueless_by_exception()` is `false`.
7440
+
7441
+ *Effects:* Let i_`x` denote `x.`*`it_`*`.index()`, d_`x` be
7442
+ `ranges::distance(std::get<`i_`x``>(x.`*`it_`*`), ranges::end(std::get<`i_`x``>(x.`*`parent_`*`->`*`views_`*`)))`.
7443
+ Let s denote the sum of the sizes of all the ranges
7444
+ `std::get<`i`>(x.`*`parent_`*`->`*`views_`*`)` for every integer i in
7445
+ the range \[i_`x`` + 1`, `sizeof...(Views)`) if there is any, and `0`
7446
+ otherwise, of type difference_type, equivalent to:
7447
+
7448
+ ``` cpp
7449
+ return -($d_x$ + s);
7450
+ ```
7451
+
7452
+ *Remarks:* Let `Fs` be the pack that consists of all elements of `Views`
7453
+ except the first element, the expression in the *requires-clause* is
7454
+ equivalent to:
7455
+
7456
+ ``` cpp
7457
+ (sized_sentinel_for<sentinel_t<maybe-const<Const, Views>>,
7458
+ iterator_t<maybe-const<Const, Views>>> && ...) &&
7459
+ (sized_range<maybe-const<Const, Fs>> && ...)
7460
+ ```
7461
+
7462
+ ``` cpp
7463
+ friend constexpr difference_type operator-(default_sentinel_t, const iterator& x)
7464
+ requires see below;
7465
+ ```
7466
+
7467
+ *Effects:* Equivalent to:
7468
+
7469
+ ``` cpp
7470
+ return -(x - default_sentinel);
7471
+ ```
7472
+
7473
+ *Remarks:* Let `Fs` be the pack that consists of all elements of `Views`
7474
+ except the first element, the expression in the *requires-clause* is
7475
+ equivalent to:
7476
+
7477
+ ``` cpp
7478
+ (sized_sentinel_for<sentinel_t<maybe-const<Const, Views>>,
7479
+ iterator_t<maybe-const<Const, Views>>> && ...) &&
7480
+ (sized_range<maybe-const<Const, Fs>> && ...)
7481
+ ```
7482
+
7483
+ ``` cpp
7484
+ friend constexpr decltype(auto) iter_move(const iterator& it) noexcept(see below);
7485
+ ```
7486
+
7487
+ *Preconditions:* `it.`*`it_`*`.valueless_by_exception()` is `false`.
7488
+
7489
+ *Effects:* Equivalent to:
7490
+
7491
+ ``` cpp
7492
+ return std::visit([](const auto& i)
7493
+ -> concat-rvalue-reference-t<maybe-const<Const, Views>...> {
7494
+ return ranges::iter_move(i);
7495
+ },
7496
+ it.it_);
7497
+ ```
7498
+
7499
+ *Remarks:* The exception specification is equivalent to:
7500
+
7501
+ ``` cpp
7502
+ ((is_nothrow_invocable_v<decltype(ranges::iter_move),
7503
+ const iterator_t<maybe-const<Const, Views>>&> &&
7504
+ is_nothrow_convertible_v<range_rvalue_reference_t<maybe-const<Const, Views>>,
7505
+ concat-rvalue-reference-t<maybe-const<Const, Views>...>>) &&
7506
+ ...)
7507
+ ```
7508
+
7509
+ ``` cpp
7510
+ friend constexpr void iter_swap(const iterator& x, const iterator& y) noexcept(see below)
7511
+ requires see below;
7512
+ ```
7513
+
7514
+ *Preconditions:* `x.`*`it_`*`.valueless_by_exception()` and
7515
+ `y.`*`it_`*`.valueless_by_exception()` are each `false`.
7516
+
7517
+ *Effects:* Equivalent to:
7518
+
7519
+ ``` cpp
7520
+ std::visit([&](const auto& it1, const auto& it2) {
7521
+ if constexpr (is_same_v<decltype(it1), decltype(it2)>) {
7522
+ ranges::iter_swap(it1, it2);
7523
+ } else {
7524
+ ranges::swap(*x, *y);
7525
+ }
7526
+ },
7527
+ x.it_, y.it_);
7528
+ ```
7529
+
7530
+ *Remarks:* The exception specification is equivalent to
7531
+
7532
+ ``` cpp
7533
+ (noexcept(ranges::swap(*x, *y)) && ... && noexcept(ranges::iter_swap(its, its)))
7534
+ ```
7535
+
7536
+ where `its` is a pack of lvalues of type
7537
+ `const iterator_t<`*`maybe-const`*`<Const, Views>>` respectively.
7538
+
7539
+ The expression in the *requires-clause* is equivalent to
7540
+
7541
+ ``` cpp
7542
+ swappable_with<iter_reference_t<iterator>, iter_reference_t<iterator>> &&
7543
+ (... && indirectly_swappable<iterator_t<maybe-const<Const, Views>>>)
7544
+ ```
7545
+
7546
  ### Counted view <a id="range.counted">[[range.counted]]</a>
7547
 
7548
  A counted view presents a view of the elements of the counted range
7549
  [[iterator.requirements.general]] `i`+\[0, `n`) for an iterator `i` and
7550
  non-negative integer `n`.
 
7621
  constexpr explicit common_view(V r);
7622
 
7623
  constexpr V base() const & requires copy_constructible<V> { return base_; }
7624
  constexpr V base() && { return std::move(base_); }
7625
 
7626
+ constexpr auto begin() requires (!simple-view<V>) {
7627
  if constexpr (random_access_range<V> && sized_range<V>)
7628
  return ranges::begin(base_);
7629
  else
7630
  return common_iterator<iterator_t<V>, sentinel_t<V>>(ranges::begin(base_));
7631
  }
 
7635
  return ranges::begin(base_);
7636
  else
7637
  return common_iterator<iterator_t<const V>, sentinel_t<const V>>(ranges::begin(base_));
7638
  }
7639
 
7640
+ constexpr auto end() requires (!simple-view<V>) {
7641
  if constexpr (random_access_range<V> && sized_range<V>)
7642
  return ranges::begin(base_) + ranges::distance(base_);
7643
  else
7644
  return common_iterator<iterator_t<V>, sentinel_t<V>>(ranges::end(base_));
7645
  }
 
7655
  return ranges::size(base_);
7656
  }
7657
  constexpr auto size() const requires sized_range<const V> {
7658
  return ranges::size(base_);
7659
  }
7660
+
7661
+ constexpr auto reserve_hint() requires approximately_sized_range<V> {
7662
+ return ranges::reserve_hint(base_);
7663
+ }
7664
+ constexpr auto reserve_hint() const requires approximately_sized_range<const V> {
7665
+ return ranges::reserve_hint(base_);
7666
+ }
7667
  };
7668
 
7669
  template<class R>
7670
  common_view(R&&) -> common_view<views::all_t<R>>;
7671
  }
 
7687
  The name `views::reverse` denotes a range adaptor object
7688
  [[range.adaptor.object]]. Given a subexpression `E`, the expression
7689
  `views::reverse(E)` is expression-equivalent to:
7690
 
7691
  - If the type of `E` is a (possibly cv-qualified) specialization of
7692
+ `reverse_view`, then `E.base()`.
7693
  - Otherwise, if the type of `E` is cv
7694
  `subrange<reverse_iterator<I>, reverse_iterator<I>, K>` for some
7695
  iterator type `I` and value `K` of type `subrange_kind`,
7696
+ - if `K` is `subrange_kind::sized`, then
7697
+ `subrange<I, I, K>(E.end().base(), E.begin().base(), E.size())`;
7698
+ - otherwise, `subrange<I, I, K>(E.end().base(), E.begin().base())`.
 
 
 
 
 
7699
 
7700
  However, in either case `E` is evaluated only once.
7701
+ - Otherwise, `reverse_view{E}`.
7702
 
7703
  [*Example 1*:
7704
 
7705
  ``` cpp
7706
  vector<int> is {0,1,2,3,4};
 
7740
  }
7741
 
7742
  constexpr auto size() const requires sized_range<const V> {
7743
  return ranges::size(base_);
7744
  }
7745
+
7746
+ constexpr auto reserve_hint() requires approximately_sized_range<V> {
7747
+ return ranges::reserve_hint(base_);
7748
+ }
7749
+ constexpr auto reserve_hint() const requires approximately_sized_range<const V> {
7750
+ return ranges::reserve_hint(base_);
7751
+ }
7752
  };
7753
 
7754
  template<class R>
7755
  reverse_view(R&&) -> reverse_view<views::all_t<R>>;
7756
  }
 
7851
  constexpr auto end() requires (!simple-view<V>) { return ranges::cend(base_); }
7852
  constexpr auto end() const requires range<const V> { return ranges::cend(base_); }
7853
 
7854
  constexpr auto size() requires sized_range<V> { return ranges::size(base_); }
7855
  constexpr auto size() const requires sized_range<const V> { return ranges::size(base_); }
7856
+
7857
+ constexpr auto reserve_hint() requires approximately_sized_range<V>
7858
+ { return ranges::reserve_hint(base_); }
7859
+ constexpr auto reserve_hint() const requires approximately_sized_range<const V>
7860
+ { return ranges::reserve_hint(base_); }
7861
  };
7862
 
7863
  template<class R>
7864
  as_const_view(R&&) -> as_const_view<views::all_t<R>>;
7865
  }
 
7980
  { return ranges::size(base_); }
7981
 
7982
  constexpr auto size() const requires sized_range<const V>
7983
  { return ranges::size(base_); }
7984
 
7985
+ constexpr auto reserve_hint() requires approximately_sized_range<V>
7986
+ { return ranges::reserve_hint(base_); }
7987
+
7988
+ constexpr auto reserve_hint() const requires approximately_sized_range<const V>
7989
+ { return ranges::reserve_hint(base_); }
7990
+
7991
  private:
7992
  // [range.elements.iterator], class template elements_view::iterator
7993
  template<bool> class iterator; // exposition only
7994
 
7995
  // [range.elements.sentinel], class template elements_view::sentinel
 
8378
  #### Overview <a id="range.enumerate.overview">[[range.enumerate.overview]]</a>
8379
 
8380
  `enumerate_view` is a view whose elements represent both the position
8381
  and value from a sequence of elements.
8382
 
8383
+ The name `views::enumerate` denotes a range adaptor object
8384
+ [[range.adaptor.object]]. Given a subexpression `E`, the expression
8385
+ `views::enumerate(E)` is expression-equivalent to
8386
  `enumerate_view<views::all_t<decltype((E))>>(E)`.
8387
 
8388
  [*Example 1*:
8389
 
8390
  ``` cpp
 
8420
  { return iterator<false>(ranges::begin(base_), 0); }
8421
  constexpr auto begin() const requires range-with-movable-references<const V>
8422
  { return iterator<true>(ranges::begin(base_), 0); }
8423
 
8424
  constexpr auto end() requires (!simple-view<V>) {
8425
+ if constexpr (forward_range<V> && common_range<V> && sized_range<V>)
8426
  return iterator<false>(ranges::end(base_), ranges::distance(base_));
8427
  else
8428
  return sentinel<false>(ranges::end(base_));
8429
  }
8430
  constexpr auto end() const requires range-with-movable-references<const V> {
8431
+ if constexpr (forward_range<const V> && common_range<const V> && sized_range<const V>)
8432
  return iterator<true>(ranges::end(base_), ranges::distance(base_));
8433
  else
8434
  return sentinel<true>(ranges::end(base_));
8435
  }
8436
 
8437
  constexpr auto size() requires sized_range<V>
8438
  { return ranges::size(base_); }
8439
  constexpr auto size() const requires sized_range<const V>
8440
  { return ranges::size(base_); }
8441
 
8442
+ constexpr auto reserve_hint() requires approximately_sized_range<V>
8443
+ { return ranges::reserve_hint(base_); }
8444
+ constexpr auto reserve_hint() const requires approximately_sized_range<const V>
8445
+ { return ranges::reserve_hint(base_); }
8446
+
8447
  constexpr V base() const & requires copy_constructible<V> { return base_; }
8448
  constexpr V base() && { return std::move(base_); }
8449
  };
8450
 
8451
  template<class R>
 
8521
  requires random_access_range<Base>;
8522
  friend constexpr iterator operator+(difference_type x, const iterator& y)
8523
  requires random_access_range<Base>;
8524
  friend constexpr iterator operator-(const iterator& x, difference_type y)
8525
  requires random_access_range<Base>;
8526
+ friend constexpr difference_type operator-(const iterator& x, const iterator& y) noexcept;
8527
 
8528
  friend constexpr auto iter_move(const iterator& i)
8529
  noexcept(noexcept(ranges::iter_move(i.current_)) &&
8530
  is_nothrow_move_constructible_v<range_rvalue_reference_t<Base>>) {
8531
  return tuple<difference_type,
 
8703
  temp -= y;
8704
  return temp;
8705
  ```
8706
 
8707
  ``` cpp
8708
+ friend constexpr difference_type operator-(const iterator& x, const iterator& y) noexcept;
8709
  ```
8710
 
8711
  *Effects:* Equivalent to: `return x.`*`pos_`*` - y.`*`pos_`*`;`
8712
 
8713
  #### Class template `enumerate_view::sentinel` <a id="range.enumerate.sentinel">[[range.enumerate.sentinel]]</a>
 
8914
 
8915
  #### Class template `zip_view::iterator` <a id="range.zip.iterator">[[range.zip.iterator]]</a>
8916
 
8917
  ``` cpp
8918
  namespace std::ranges {
 
 
 
 
 
 
 
 
 
 
8919
  template<input_range... Views>
8920
  requires (view<Views> && ...) && (sizeof...(Views) > 0)
8921
  template<bool Const>
8922
  class zip_view<Views...>::iterator {
8923
  tuple<iterator_t<maybe-const<Const, Views>>...> current_; // exposition only
 
9284
  iterator_t<maybe-const<OtherConst, Views>>> && ...)
9285
  friend constexpr common_type_t<range_difference_t<maybe-const<OtherConst, Views>>...>
9286
  operator-(const sentinel& y, const iterator<OtherConst>& x);
9287
  ```
9288
 
9289
+ *Effects:* Equivalent to: `return -(x - y);`
9290
 
9291
  ### Zip transform view <a id="range.zip.transform">[[range.zip.transform]]</a>
9292
 
9293
  #### Overview <a id="range.zip.transform.overview">[[range.zip.transform.overview]]</a>
9294
 
 
9419
 
9420
  constexpr iterator(Parent& parent, ziperator<Const> inner); // exposition only
9421
 
9422
  public:
9423
  using iterator_category = see belownc; // not always present
9424
+ using iterator_concept = ziperator<Const>::iterator_concept;
9425
  using value_type =
9426
  remove_cvref_t<invoke_result_t<maybe-const<Const, F>&,
9427
  range_reference_t<maybe-const<Const, Views>>...>>;
9428
  using difference_type = range_difference_t<Base>;
9429
 
 
9722
  The name `views::adjacent<N>` denotes a range adaptor object
9723
  [[range.adaptor.object]]. Given a subexpression `E` and a constant
9724
  expression `N`, the expression `views::adjacent<N>(E)` is
9725
  expression-equivalent to
9726
 
9727
+ - `((void)E, auto(views::empty<tuple<>>))` if `N` is equal to `0` and
9728
+ `decltype((E))` models `forward_range`,
9729
  - otherwise, `adjacent_view<views::all_t<decltype((E))>, N>(E)`.
9730
 
9731
  [*Example 1*:
9732
 
9733
  ``` cpp
 
9791
  }
9792
  }
9793
 
9794
  constexpr auto size() requires sized_range<V>;
9795
  constexpr auto size() const requires sized_range<const V>;
9796
+
9797
+ constexpr auto reserve_hint() requires approximately_sized_range<V>;
9798
+ constexpr auto reserve_hint() const requires approximately_sized_range<const V>;
9799
  };
9800
  }
9801
  ```
9802
 
9803
  ``` cpp
 
9819
  auto sz = static_cast<CT>(ranges::size(base_));
9820
  sz -= std::min<CT>(sz, N - 1);
9821
  return static_cast<ST>(sz);
9822
  ```
9823
 
9824
+ ``` cpp
9825
+ constexpr auto reserve_hint() requires approximately_sized_range<V>;
9826
+ constexpr auto reserve_hint() const requires approximately_sized_range<const V>;
9827
+ ```
9828
+
9829
+ *Effects:* Equivalent to:
9830
+
9831
+ ``` cpp
9832
+ using DT = range_difference_t<decltype((base_))>;
9833
+ using CT = common_type_t<DT, size_t>;
9834
+ auto sz = static_cast<CT>(ranges::reserve_hint(base_));
9835
+ sz -= std::min<CT>(sz, N - 1);
9836
+ return to-unsigned-like(sz);
9837
+ ```
9838
+
9839
  #### Class template `adjacent_view::iterator` <a id="range.adjacent.iterator">[[range.adjacent.iterator]]</a>
9840
 
9841
  ``` cpp
9842
  namespace std::ranges {
9843
  template<forward_range V, size_t N>
 
10230
 
10231
  The name `views::adjacent_transform<N>` denotes a range adaptor object
10232
  [[range.adaptor.object]]. Given subexpressions `E` and `F` and a
10233
  constant expression `N`:
10234
 
10235
+ - If `N` is equal to `0` and `decltype((E))` models `forward_range`,
10236
+ `views::adjacent_transform<N>(E, F)` is expression-equivalent to
10237
+ `((void)E, views::zip_transform(F))`, except that the evaluations of
10238
+ `E` and `F` are indeterminately sequenced.
10239
  - Otherwise, the expression `views::adjacent_transform<N>(E, F)` is
10240
  expression-equivalent to
10241
  `adjacent_transform_view<views::all_t<decltype((E))>, decay_t<decltype((F))>, N>(E, F)`.
10242
 
10243
  [*Example 1*:
 
10278
 
10279
  public:
10280
  adjacent_transform_view() = default;
10281
  constexpr explicit adjacent_transform_view(V base, F fun);
10282
 
10283
+ constexpr V base() const & requires copy_constructible<V> { return inner_.base(); }
10284
  constexpr V base() && { return std::move(inner_).base(); }
10285
 
10286
  constexpr auto begin() {
10287
  return iterator<false>(*this, inner_.begin());
10288
  }
 
10316
  }
10317
 
10318
  constexpr auto size() const requires sized_range<const InnerView> {
10319
  return inner_.size();
10320
  }
10321
+
10322
+ constexpr auto reserve_hint() requires approximately_sized_range<InnerView> {
10323
+ return inner_.reserve_hint();
10324
+ }
10325
+
10326
+ constexpr auto reserve_hint() const requires approximately_sized_range<const InnerView> {
10327
+ return inner_.reserve_hint();
10328
+ }
10329
  };
10330
  }
10331
  ```
10332
 
10333
  ``` cpp
 
10354
 
10355
  constexpr iterator(Parent& parent, inner-iterator<Const> inner); // exposition only
10356
 
10357
  public:
10358
  using iterator_category = see below;
10359
+ using iterator_concept = inner-iterator<Const>::iterator_concept;
10360
  using value_type =
10361
  remove_cvref_t<invoke_result_t<maybe-const<Const, F>&,
10362
  REPEAT(range_reference_t<Base>, N)...>>;
10363
  using difference_type = range_difference_t<Base>;
10364
 
 
10628
  template<bool OtherConst>
10629
  requires sentinel_for<inner-sentinel<Const>, inner-iterator<OtherConst>>
10630
  friend constexpr bool operator==(const iterator<OtherConst>& x, const sentinel& y);
10631
  ```
10632
 
10633
+ *Effects:* Equivalent to: `return x.`*`inner_`*` == y.`*`inner_`*`;`
10634
 
10635
  ``` cpp
10636
  template<bool OtherConst>
10637
  requires sized_sentinel_for<inner-sentinel<Const>, inner-iterator<OtherConst>>
10638
  friend constexpr range_difference_t<maybe-const<OtherConst, InnerView>>
 
10642
  requires sized_sentinel_for<inner-sentinel<Const>, inner-iterator<OtherConst>>
10643
  friend constexpr range_difference_t<maybe-const<OtherConst, InnerView>>
10644
  operator-(const sentinel& x, const iterator<OtherConst>& y);
10645
  ```
10646
 
10647
+ *Effects:* Equivalent to: `return x.`*`inner_`*` - y.`*`inner_`*`;`
10648
 
10649
  ### Chunk view <a id="range.chunk">[[range.chunk]]</a>
10650
 
10651
  #### Overview <a id="range.chunk.overview">[[range.chunk.overview]]</a>
10652
 
 
10715
  constexpr outer-iterator begin();
10716
  constexpr default_sentinel_t end() const noexcept;
10717
 
10718
  constexpr auto size() requires sized_range<V>;
10719
  constexpr auto size() const requires sized_range<const V>;
10720
+
10721
+ constexpr auto reserve_hint() requires approximately_sized_range<V>;
10722
+ constexpr auto reserve_hint() const requires approximately_sized_range<const V>;
10723
  };
10724
 
10725
  template<class R>
10726
  chunk_view(R&&, range_difference_t<R>) -> chunk_view<views::all_t<R>>;
10727
  }
 
10763
 
10764
  ``` cpp
10765
  return to-unsigned-like(div-ceil(ranges::distance(base_), n_));
10766
  ```
10767
 
10768
+ ``` cpp
10769
+ constexpr auto reserve_hint() requires approximately_sized_range<V>;
10770
+ constexpr auto reserve_hint() const requires approximately_sized_range<const V>;
10771
+ ```
10772
+
10773
+ *Effects:* Equivalent to:
10774
+
10775
+ ``` cpp
10776
+ auto s = static_cast<range_difference_t<decltype((base_))>>(ranges::reserve_hint(base_));
10777
+ return to-unsigned-like(div-ceil(s, n_));
10778
+ ```
10779
+
10780
  #### Class `chunk_view::outer-iterator` <a id="range.chunk.outer.iter">[[range.chunk.outer.iter]]</a>
10781
 
10782
  ``` cpp
10783
  namespace std::ranges {
10784
  template<view V>
 
10894
  constexpr inner-iterator begin() const noexcept;
10895
  constexpr default_sentinel_t end() const noexcept;
10896
 
10897
  constexpr auto size() const
10898
  requires sized_sentinel_for<sentinel_t<V>, iterator_t<V>>;
10899
+
10900
+ constexpr auto reserve_hint() const noexcept;
10901
  };
10902
  }
10903
  ```
10904
 
10905
  ``` cpp
 
10930
  ``` cpp
10931
  return to-unsigned-like(ranges::min(parent_->remainder_,
10932
  ranges::end(parent_->base_) - *parent_->current_));
10933
  ```
10934
 
10935
+ ``` cpp
10936
+ constexpr auto reserve_hint() const noexcept;
10937
+ ```
10938
+
10939
+ *Effects:* Equivalent to:
10940
+
10941
+ ``` cpp
10942
+ return to-unsigned-like(parent_->remainder_);
10943
+ ```
10944
+
10945
  #### Class `chunk_view::inner-iterator` <a id="range.chunk.inner.iter">[[range.chunk.inner.iter]]</a>
10946
 
10947
  ``` cpp
10948
  namespace std::ranges {
10949
  template<view V>
 
11118
  }
11119
  }
11120
 
11121
  constexpr auto size() requires sized_range<V>;
11122
  constexpr auto size() const requires sized_range<const V>;
11123
+
11124
+ constexpr auto reserve_hint() requires approximately_sized_range<V>;
11125
+ constexpr auto reserve_hint() const requires approximately_sized_range<const V>;
11126
  };
11127
  }
11128
  ```
11129
 
11130
  ``` cpp
 
11145
 
11146
  ``` cpp
11147
  return to-unsigned-like(div-ceil(ranges::distance(base_), n_));
11148
  ```
11149
 
11150
+ ``` cpp
11151
+ constexpr auto reserve_hint() requires approximately_sized_range<V>;
11152
+ constexpr auto reserve_hint() const requires approximately_sized_range<const V>;
11153
+ ```
11154
+
11155
+ *Effects:* Equivalent to:
11156
+
11157
+ ``` cpp
11158
+ auto s = static_cast<range_difference_t<decltype((base_))>>(ranges::reserve_hint(base_));
11159
+ return to-unsigned-like(div-ceil(s, n_));
11160
+ ```
11161
+
11162
  #### Class template `chunk_view::iterator` for forward ranges <a id="range.chunk.fwd.iter">[[range.chunk.fwd.iter]]</a>
11163
 
11164
  ``` cpp
11165
  namespace std::ranges {
11166
  template<view V>
 
11533
  requires (!(simple-view<V> && slide-caches-nothing<const V>));
11534
  constexpr auto end() const requires slide-caches-nothing<const V>;
11535
 
11536
  constexpr auto size() requires sized_range<V>;
11537
  constexpr auto size() const requires sized_range<const V>;
11538
+
11539
+ constexpr auto reserve_hint() requires approximately_sized_range<V>;
11540
+ constexpr auto reserve_hint() const requires approximately_sized_range<const V>;
11541
  };
11542
 
11543
  template<class R>
11544
  slide_view(R&&, range_difference_t<R>) -> slide_view<views::all_t<R>>;
11545
  }
 
11623
  auto sz = ranges::distance(base_) - n_ + 1;
11624
  if (sz < 0) sz = 0;
11625
  return to-unsigned-like(sz);
11626
  ```
11627
 
11628
+ ``` cpp
11629
+ constexpr auto reserve_hint() requires approximately_sized_range<V>;
11630
+ constexpr auto reserve_hint() const requires approximately_sized_range<const V>;
11631
+ ```
11632
+
11633
+ *Effects:* Equivalent to:
11634
+
11635
+ ``` cpp
11636
+ auto sz = static_cast<range_difference_t<decltype((base_))>>(ranges::reserve_hint(base_)) -
11637
+ n_ + 1;
11638
+ if (sz < 0) sz = 0;
11639
+ return to-unsigned-like(sz);
11640
+ ```
11641
+
11642
  #### Class template `slide_view::iterator` <a id="range.slide.iterator">[[range.slide.iterator]]</a>
11643
 
11644
  ``` cpp
11645
  namespace std::ranges {
11646
  template<forward_range V>
 
12304
  }
12305
  }
12306
 
12307
  constexpr auto size() requires sized_range<V>;
12308
  constexpr auto size() const requires sized_range<const V>;
12309
+
12310
+ constexpr auto reserve_hint() requires approximately_sized_range<V>;
12311
+ constexpr auto reserve_hint() const requires approximately_sized_range<const V>;
12312
  };
12313
 
12314
  template<class R>
12315
  stride_view(R&&, range_difference_t<R>) -> stride_view<views::all_t<R>>;
12316
  }
 
12340
 
12341
  ``` cpp
12342
  return to-unsigned-like(div-ceil(ranges::distance(base_), stride_));
12343
  ```
12344
 
12345
+ ``` cpp
12346
+ constexpr auto reserve_hint() requires approximately_sized_range<V>;
12347
+ constexpr auto reserve_hint() const requires approximately_sized_range<const V>;
12348
+ ```
12349
+
12350
+ *Effects:* Equivalent to:
12351
+
12352
+ ``` cpp
12353
+ auto s = static_cast<range_difference_t<decltype((base_))>>(ranges::reserve_hint(base_));
12354
+ return to-unsigned-like(div-ceil(s, stride_));
12355
+ ```
12356
+
12357
  #### Class template `stride_view::iterator` <a id="range.stride.iterator">[[range.stride.iterator]]</a>
12358
 
12359
  ``` cpp
12360
  namespace std::ranges {
12361
  template<input_range V>
 
12513
 
12514
  ``` cpp
12515
  constexpr void operator++(int);
12516
  ```
12517
 
12518
+ *Effects:* Equivalent to `++*this;`
12519
 
12520
  ``` cpp
12521
  constexpr iterator operator++(int) requires forward_range<Base>;
12522
  ```
12523
 
 
12755
  concept cartesian-product-is-bidirectional = // exposition only
12756
  (bidirectional_range<maybe-const<Const, First>> && ... &&
12757
  (bidirectional_range<maybe-const<Const, Vs>>
12758
  && cartesian-product-common-arg<maybe-const<Const, Vs>>));
12759
 
12760
+ template<class First, class...>
12761
  concept cartesian-product-is-common = // exposition only
12762
  cartesian-product-common-arg<First>;
12763
 
12764
  template<class... Vs>
12765
  concept cartesian-product-is-sized = // exposition only
 
13298
  the following expressions:
13299
 
13300
  - `noexcept(ranges::iter_swap(std::get<`i`>(l.`*`current_`*`), std::get<`i`>(r.`*`current_`*`)))`
13301
  for every integer 0 ≤ i ≤ `sizeof...(Vs)`.
13302
 
13303
+ ### Cache latest view <a id="range.cache.latest">[[range.cache.latest]]</a>
13304
+
13305
+ #### Overview <a id="range.cache.latest.overview">[[range.cache.latest.overview]]</a>
13306
+
13307
+ `cache_latest_view` caches the last-accessed element of its underlying
13308
+ sequence so that the element does not have to be recomputed on repeated
13309
+ access.
13310
+
13311
+ [*Note 1*: This is useful if computation of the element to produce is
13312
+ expensive. — *end note*]
13313
+
13314
+ The name `views::cache_latest` denotes a range adaptor object
13315
+ [[range.adaptor.object]]. Let `E` be an expression. The expression
13316
+ `views::cache_latest(E)` is expression-equivalent to
13317
+ `cache_latest_view(E)`.
13318
+
13319
+ #### Class template `cache_latest_view` <a id="range.cache.latest.view">[[range.cache.latest.view]]</a>
13320
+
13321
+ ``` cpp
13322
+ namespace std::ranges {
13323
+ template<input_range V>
13324
+ requires view<V>
13325
+ class cache_latest_view : public view_interface<cache_latest_view<V>> {
13326
+ V base_ = V(); // exposition only
13327
+ using cache-t = conditional_t<is_reference_v<range_reference_t<V>>, // exposition only
13328
+ add_pointer_t<range_reference_t<V>>,
13329
+ range_reference_t<V>>;
13330
+
13331
+ non-propagating-cache<cache-t> cache_; // exposition only
13332
+
13333
+ // [range.cache.latest.iterator], class cache_latest_view::iterator
13334
+ class iterator; // exposition only
13335
+ // [range.cache.latest.sentinel], class cache_latest_view::sentinel
13336
+ class sentinel; // exposition only
13337
+
13338
+ public:
13339
+ cache_latest_view() requires default_initializable<V> = default;
13340
+ constexpr explicit cache_latest_view(V base);
13341
+
13342
+ constexpr V base() const & requires copy_constructible<V> { return base_; }
13343
+ constexpr V base() && { return std::move(base_); }
13344
+
13345
+ constexpr auto begin();
13346
+ constexpr auto end();
13347
+
13348
+ constexpr auto size() requires sized_range<V>;
13349
+ constexpr auto size() const requires sized_range<const V>;
13350
+
13351
+ constexpr auto reserve_hint() requires approximately_sized_range<V>;
13352
+ constexpr auto reserve_hint() const requires approximately_sized_range<const V>;
13353
+ };
13354
+
13355
+ template<class R>
13356
+ cache_latest_view(R&&) -> cache_latest_view<views::all_t<R>>;
13357
+ }
13358
+ ```
13359
+
13360
+ ``` cpp
13361
+ constexpr explicit cache_latest_view(V base);
13362
+ ```
13363
+
13364
+ *Effects:* Initializes *base\_* with `std::move(base)`.
13365
+
13366
+ ``` cpp
13367
+ constexpr auto begin();
13368
+ ```
13369
+
13370
+ *Effects:* Equivalent to: `return `*`iterator`*`(*this);`
13371
+
13372
+ ``` cpp
13373
+ constexpr auto end();
13374
+ ```
13375
+
13376
+ *Effects:* Equivalent to: `return `*`sentinel`*`(*this);`
13377
+
13378
+ ``` cpp
13379
+ constexpr auto size() requires sized_range<V>;
13380
+ constexpr auto size() const requires sized_range<const V>;
13381
+ ```
13382
+
13383
+ *Effects:* Equivalent to: `return ranges::size(`*`base_`*`);`
13384
+
13385
+ ``` cpp
13386
+ constexpr auto reserve_hint() requires approximately_sized_range<V>;
13387
+ constexpr auto reserve_hint() const requires approximately_sized_range<const V>;
13388
+ ```
13389
+
13390
+ *Effects:* Equivalent to: `return ranges::reserve_hint(`*`base_`*`);`
13391
+
13392
+ #### Class `cache_latest_view::iterator` <a id="range.cache.latest.iterator">[[range.cache.latest.iterator]]</a>
13393
+
13394
+ ``` cpp
13395
+ namespace std::ranges {
13396
+ template<input_range V>
13397
+ requires view<V>
13398
+ class cache_latest_view<V>::iterator {
13399
+ cache_latest_view* parent_; // exposition only
13400
+ iterator_t<V> current_; // exposition only
13401
+
13402
+ constexpr explicit iterator(cache_latest_view& parent); // exposition only
13403
+
13404
+ public:
13405
+ using difference_type = range_difference_t<V>;
13406
+ using value_type = range_value_t<V>;
13407
+ using iterator_concept = input_iterator_tag;
13408
+
13409
+ iterator(iterator&&) = default;
13410
+ iterator& operator=(iterator&&) = default;
13411
+
13412
+ constexpr iterator_t<V> base() &&;
13413
+ constexpr const iterator_t<V>& base() const & noexcept;
13414
+
13415
+ constexpr range_reference_t<V>& operator*() const;
13416
+
13417
+ constexpr iterator& operator++();
13418
+ constexpr void operator++(int);
13419
+
13420
+ friend constexpr range_rvalue_reference_t<V> iter_move(const iterator& i)
13421
+ noexcept(noexcept(ranges::iter_move(i.current_)));
13422
+
13423
+ friend constexpr void iter_swap(const iterator& x, const iterator& y)
13424
+ noexcept(noexcept(ranges::iter_swap(x.current_, y.current_)))
13425
+ requires indirectly_swappable<iterator_t<V>>;
13426
+ };
13427
+ }
13428
+ ```
13429
+
13430
+ ``` cpp
13431
+ constexpr explicit iterator(cache_latest_view& parent);
13432
+ ```
13433
+
13434
+ *Effects:* Initializes *current\_* with
13435
+ `ranges::begin(parent.`*`base_`*`)` and *parent\_* with
13436
+ `addressof(parent)`.
13437
+
13438
+ ``` cpp
13439
+ constexpr iterator_t<V> base() &&;
13440
+ ```
13441
+
13442
+ *Returns:* `std::move(`*`current_`*`)`.
13443
+
13444
+ ``` cpp
13445
+ constexpr const iterator_t<V>& base() const & noexcept;
13446
+ ```
13447
+
13448
+ *Returns:* *current\_*.
13449
+
13450
+ ``` cpp
13451
+ constexpr iterator& operator++();
13452
+ ```
13453
+
13454
+ *Effects:* Equivalent to:
13455
+
13456
+ ``` cpp
13457
+ parent_->cache_.reset();
13458
+ ++current_;
13459
+ return *this;
13460
+ ```
13461
+
13462
+ ``` cpp
13463
+ constexpr void operator++(int);
13464
+ ```
13465
+
13466
+ *Effects:* Equivalent to: `++*this`.
13467
+
13468
+ ``` cpp
13469
+ constexpr range_reference_t<V>& operator*() const;
13470
+ ```
13471
+
13472
+ *Effects:* Equivalent to:
13473
+
13474
+ ``` cpp
13475
+ if constexpr (is_reference_v<range_reference_t<V>>) {
13476
+ if (!parent_->cache_) {
13477
+ parent_->cache_ = addressof(as-lvalue(*current_));
13478
+ }
13479
+ return **parent_->cache_;
13480
+ } else {
13481
+ if (!parent_->cache_) {
13482
+ parent_->cache_.emplace-deref(current_);
13483
+ }
13484
+ return *parent_->cache_;
13485
+ }
13486
+ ```
13487
+
13488
+ [*Note 1*: Evaluations of `operator*` on the same iterator object can
13489
+ conflict [[intro.races]]. — *end note*]
13490
+
13491
+ ``` cpp
13492
+ friend constexpr range_rvalue_reference_t<V> iter_move(const iterator& i)
13493
+ noexcept(noexcept(ranges::iter_move(i.current_)));
13494
+ ```
13495
+
13496
+ *Effects:* Equivalent to: `return ranges::iter_move(i.`*`current_`*`);`
13497
+
13498
+ ``` cpp
13499
+ friend constexpr void iter_swap(const iterator& x, const iterator& y)
13500
+ noexcept(noexcept(ranges::iter_swap(x.current_, y.current_)))
13501
+ requires indirectly_swappable<iterator_t<V>>;
13502
+ ```
13503
+
13504
+ *Effects:* Equivalent to
13505
+ `ranges::iter_swap(x.`*`current_`*`, y.`*`current_`*`)`.
13506
+
13507
+ #### Class `cache_latest_view::sentinel` <a id="range.cache.latest.sentinel">[[range.cache.latest.sentinel]]</a>
13508
+
13509
+ ``` cpp
13510
+ namespace std::ranges {
13511
+ template<input_range V>
13512
+ requires view<V>
13513
+ class cache_latest_view<V>::sentinel {
13514
+ sentinel_t<V> end_ = sentinel_t<V>(); // exposition only
13515
+
13516
+ constexpr explicit sentinel(cache_latest_view& parent); // exposition only
13517
+
13518
+ public:
13519
+ sentinel() = default;
13520
+
13521
+ constexpr sentinel_t<V> base() const;
13522
+
13523
+ friend constexpr bool operator==(const iterator& x, const sentinel& y);
13524
+
13525
+ friend constexpr range_difference_t<V> operator-(const iterator& x, const sentinel& y)
13526
+ requires sized_sentinel_for<sentinel_t<V>, iterator_t<V>>;
13527
+ friend constexpr range_difference_t<V> operator-(const sentinel& x, const iterator& y)
13528
+ requires sized_sentinel_for<sentinel_t<V>, iterator_t<V>>;
13529
+ };
13530
+ }
13531
+ ```
13532
+
13533
+ ``` cpp
13534
+ constexpr explicit sentinel(cache_latest_view& parent);
13535
+ ```
13536
+
13537
+ *Effects:* Initializes *end\_* with `ranges::end(parent.`*`base_`*`)`.
13538
+
13539
+ ``` cpp
13540
+ constexpr sentinel_t<V> base() const;
13541
+ ```
13542
+
13543
+ *Returns:* *end\_*.
13544
+
13545
+ ``` cpp
13546
+ friend constexpr bool operator==(const iterator& x, const sentinel& y);
13547
+ ```
13548
+
13549
+ *Returns:* `x.`*`current_`*` == y.`*`end_`*.
13550
+
13551
+ ``` cpp
13552
+ friend constexpr range_difference_t<V> operator-(const iterator& x, const sentinel& y)
13553
+ requires sized_sentinel_for<sentinel_t<V>, iterator_t<V>>;
13554
+ ```
13555
+
13556
+ *Returns:* `x.`*`current_`*` - y.`*`end_`*.
13557
+
13558
+ ``` cpp
13559
+ friend constexpr range_difference_t<V> operator-(const sentinel& x, const iterator& y)
13560
+ requires sized_sentinel_for<sentinel_t<V>, iterator_t<V>>;
13561
+ ```
13562
+
13563
+ *Returns:* `x.`*`end_`*` - y.`*`current_`*.
13564
+
13565
+ ### To input view <a id="range.to.input">[[range.to.input]]</a>
13566
+
13567
+ #### Overview <a id="range.to.input.overview">[[range.to.input.overview]]</a>
13568
+
13569
+ `to_input_view` presents a view of an underlying sequence as an
13570
+ input-only non-common range.
13571
+
13572
+ [*Note 1*: This is useful to avoid overhead that can be necessary to
13573
+ provide support for the operations needed for greater iterator
13574
+ strength. — *end note*]
13575
+
13576
+ The name `views::to_input` denotes a range adaptor object
13577
+ [[range.adaptor.object]]. Let `E` be an expression and let `T` be
13578
+ `decltype((E))`. The expression `views::to_input(E)` is
13579
+ expression-equivalent to:
13580
+
13581
+ - `views::all(E)` if `T` models `input_range`, does not satisfy
13582
+ `common_range`, and does not satisfy `forward_range`.
13583
+ - Otherwise, `to_input_view(E)`.
13584
+
13585
+ #### Class template `to_input_view` <a id="range.to.input.view">[[range.to.input.view]]</a>
13586
+
13587
+ ``` cpp
13588
+ namespace std::ranges {
13589
+ template<input_range V>
13590
+ requires view<V>
13591
+ class to_input_view : public view_interface<to_input_view<V>> {
13592
+ V base_ = V(); // exposition only
13593
+
13594
+ // [range.to.input.iterator], class template to_input_view::iterator
13595
+ template<bool Const> class iterator; // exposition only
13596
+
13597
+ public:
13598
+ to_input_view() requires default_initializable<V> = default;
13599
+ constexpr explicit to_input_view(V base);
13600
+
13601
+ constexpr V base() const & requires copy_constructible<V> { return base_; }
13602
+ constexpr V base() && { return std::move(base_); }
13603
+
13604
+ constexpr auto begin() requires (!simple-view<V>);
13605
+ constexpr auto begin() const requires range<const V>;
13606
+
13607
+ constexpr auto end() requires (!simple-view<V>);
13608
+ constexpr auto end() const requires range<const V>;
13609
+
13610
+ constexpr auto size() requires sized_range<V>;
13611
+ constexpr auto size() const requires sized_range<const V>;
13612
+
13613
+ constexpr auto reserve_hint() requires approximately_sized_range<V>;
13614
+ constexpr auto reserve_hint() const requires approximately_sized_range<const V>;
13615
+ };
13616
+
13617
+ template<class R>
13618
+ to_input_view(R&&) -> to_input_view<views::all_t<R>>;
13619
+ }
13620
+ ```
13621
+
13622
+ ``` cpp
13623
+ constexpr explicit to_input_view(V base);
13624
+ ```
13625
+
13626
+ *Effects:* Initializes *base\_* with `std::move(base)`.
13627
+
13628
+ ``` cpp
13629
+ constexpr auto begin() requires (!simple-view<V>);
13630
+ ```
13631
+
13632
+ *Effects:* Equivalent to:
13633
+ `return `*`iterator`*`<false>(ranges::begin(`*`base_`*`));`
13634
+
13635
+ ``` cpp
13636
+ constexpr auto begin() const requires range<const V>;
13637
+ ```
13638
+
13639
+ *Effects:* Equivalent to:
13640
+ `return `*`iterator`*`<true>(ranges::begin(`*`base_`*`));`
13641
+
13642
+ ``` cpp
13643
+ constexpr auto end() requires (!simple-view<V>);
13644
+ constexpr auto end() const requires range<const V>;
13645
+ ```
13646
+
13647
+ *Effects:* Equivalent to: `return ranges::end(`*`base_`*`);`
13648
+
13649
+ ``` cpp
13650
+ constexpr auto size() requires sized_range<V>;
13651
+ constexpr auto size() const requires sized_range<const V>;
13652
+ ```
13653
+
13654
+ *Effects:* Equivalent to: `return ranges::size(`*`base_`*`);`
13655
+
13656
+ ``` cpp
13657
+ constexpr auto reserve_hint() requires approximately_sized_range<V>;
13658
+ constexpr auto reserve_hint() const requires approximately_sized_range<const V>;
13659
+ ```
13660
+
13661
+ *Effects:* Equivalent to: `return ranges::reserve_hint(`*`base_`*`);`
13662
+
13663
+ #### Class template `to_input_view::iterator` <a id="range.to.input.iterator">[[range.to.input.iterator]]</a>
13664
+
13665
+ ``` cpp
13666
+ namespace std::ranges {
13667
+ template<input_range V>
13668
+ requires view<V>
13669
+ template<bool Const>
13670
+ class to_input_view<V>::iterator {
13671
+ using Base = maybe-const<Const, V>; // exposition only
13672
+
13673
+ iterator_t<Base> current_ = iterator_t<Base>(); // exposition only
13674
+
13675
+ constexpr explicit iterator(iterator_t<Base> current); // exposition only
13676
+
13677
+ public:
13678
+ using difference_type = range_difference_t<Base>;
13679
+ using value_type = range_value_t<Base>;
13680
+ using iterator_concept = input_iterator_tag;
13681
+
13682
+ iterator() requires default_initializable<iterator_t<Base>> = default;
13683
+
13684
+ iterator(iterator&&) = default;
13685
+ iterator& operator=(iterator&&) = default;
13686
+
13687
+ constexpr iterator(iterator<!Const> i)
13688
+ requires Const && convertible_to<iterator_t<V>, iterator_t<Base>>;
13689
+
13690
+ constexpr iterator_t<Base> base() &&;
13691
+ constexpr const iterator_t<Base>& base() const & noexcept;
13692
+
13693
+ constexpr decltype(auto) operator*() const { return *current_; }
13694
+
13695
+ constexpr iterator& operator++();
13696
+ constexpr void operator++(int);
13697
+
13698
+ friend constexpr bool operator==(const iterator& x, const sentinel_t<Base>& y);
13699
+
13700
+ friend constexpr difference_type operator-(const sentinel_t<Base>& y, const iterator& x)
13701
+ requires sized_sentinel_for<sentinel_t<Base>, iterator_t<Base>>;
13702
+ friend constexpr difference_type operator-(const iterator& x, const sentinel_t<Base>& y)
13703
+ requires sized_sentinel_for<sentinel_t<Base>, iterator_t<Base>>;
13704
+
13705
+ friend constexpr range_rvalue_reference_t<Base> iter_move(const iterator& i)
13706
+ noexcept(noexcept(ranges::iter_move(i.current_)));
13707
+
13708
+ friend constexpr void iter_swap(const iterator& x, const iterator& y)
13709
+ noexcept(noexcept(ranges::iter_swap(x.current_, y.current_)))
13710
+ requires indirectly_swappable<iterator_t<Base>>;
13711
+ };
13712
+ }
13713
+ ```
13714
+
13715
+ ``` cpp
13716
+ constexpr explicit iterator(iterator_t<Base> current);
13717
+ ```
13718
+
13719
+ *Effects:* Initializes *current\_* with `std::move(current)`.
13720
+
13721
+ ``` cpp
13722
+ constexpr iterator(iterator<!Const> i)
13723
+ requires Const && convertible_to<iterator_t<V>, iterator_t<Base>>;
13724
+ ```
13725
+
13726
+ *Effects:* Initializes *current\_* with `std::move(i.`*`current_`*`)`.
13727
+
13728
+ ``` cpp
13729
+ constexpr iterator_t<Base> base() &&;
13730
+ ```
13731
+
13732
+ *Returns:* `std::move(`*`current_`*`)`.
13733
+
13734
+ ``` cpp
13735
+ constexpr const iterator_t<Base>& base() const & noexcept;
13736
+ ```
13737
+
13738
+ *Returns:* *current\_*.
13739
+
13740
+ ``` cpp
13741
+ constexpr iterator& operator++();
13742
+ ```
13743
+
13744
+ *Effects:* Equivalent to:
13745
+
13746
+ ``` cpp
13747
+ ++current_;
13748
+ return *this;
13749
+ ```
13750
+
13751
+ ``` cpp
13752
+ constexpr void operator++(int);
13753
+ ```
13754
+
13755
+ *Effects:* Equivalent to: `++*this;`
13756
+
13757
+ ``` cpp
13758
+ friend constexpr bool operator==(const iterator& x, const sentinel_t<Base>& y);
13759
+ ```
13760
+
13761
+ *Returns:* `x.`*`current_`*` == y`.
13762
+
13763
+ ``` cpp
13764
+ friend constexpr difference_type operator-(const sentinel_t<Base>& y, const iterator& x)
13765
+ requires sized_sentinel_for<sentinel_t<Base>, iterator_t<Base>>;
13766
+ ```
13767
+
13768
+ *Returns:* `y - x.`*`current_`*.
13769
+
13770
+ ``` cpp
13771
+ friend constexpr difference_type operator-(const iterator& x, const sentinel_t<Base>& y)
13772
+ requires sized_sentinel_for<sentinel_t<Base>, iterator_t<Base>>;
13773
+ ```
13774
+
13775
+ *Returns:* `x.`*`current_`*` - y`.
13776
+
13777
+ ``` cpp
13778
+ friend constexpr range_rvalue_reference_t<Base> iter_move(const iterator& i)
13779
+ noexcept(noexcept(ranges::iter_move(i.current_)));
13780
+ ```
13781
+
13782
+ *Effects:* Equivalent to: `return ranges::iter_move(i.`*`current_`*`);`
13783
+
13784
+ ``` cpp
13785
+ friend constexpr void iter_swap(const iterator& x, const iterator& y)
13786
+ noexcept(noexcept(ranges::iter_swap(x.current_, y.current_)))
13787
+ requires indirectly_swappable<iterator_t<Base>>;
13788
+ ```
13789
+
13790
+ *Effects:* Equivalent to:
13791
+ `ranges::iter_swap(x.`*`current_`*`, y.`*`current_`*`);`
13792
+
13793
  ## Range generators <a id="coro.generator">[[coro.generator]]</a>
13794
 
13795
  ### Overview <a id="coroutine.generator.overview">[[coroutine.generator.overview]]</a>
13796
 
13797
  Class template `generator` presents a view of the elements yielded by
 
13823
  ### Header `<generator>` synopsis <a id="generator.syn">[[generator.syn]]</a>
13824
 
13825
  ``` cpp
13826
  namespace std {
13827
  // [coro.generator.class], class template generator
13828
+ template<class Ref, class Val = void, class Allocator = void>
13829
  class generator;
13830
 
13831
  namespace pmr {
13832
+ template<class Ref, class Val = void>
13833
+ using generator = std::generator<Ref, Val, polymorphic_allocator<>>;
13834
  }
13835
  }
13836
  ```
13837
 
13838
  ### Class template `generator` <a id="coro.generator.class">[[coro.generator.class]]</a>
13839
 
13840
  ``` cpp
13841
  namespace std {
13842
+ template<class Ref, class Val = void, class Allocator = void>
13843
+ class generator : public ranges::view_interface<generator<Ref, Val, Allocator>> {
13844
  private:
13845
+ using value = conditional_t<is_void_v<Val>, remove_cvref_t<Ref>, Val>; // exposition only
13846
+ using reference = conditional_t<is_void_v<Val>, Ref&&, Ref>; // exposition only
13847
 
13848
  // [coro.generator.iterator], class generator::iterator
13849
  class iterator; // exposition only
13850
 
13851
  public:
 
13904
  generator(generator&& other) noexcept;
13905
  ```
13906
 
13907
  *Effects:* Initializes *coroutine\_* with
13908
  `exchange(other.`*`coroutine_`*`, {})` and *active\_* with
13909
+ `exchange(other.`*`active_`*`, nullptr)`.
13910
 
13911
  [*Note 1*: Iterators previously obtained from `other` are not
13912
  invalidated; they become iterators into `*this`. — *end note*]
13913
 
13914
  ``` cpp
 
13968
 
13969
  ### Class `generator::promise_type` <a id="coro.generator.promise">[[coro.generator.promise]]</a>
13970
 
13971
  ``` cpp
13972
  namespace std {
13973
+ template<class Ref, class Val, class Allocator>
13974
+ class generator<Ref, Val, Allocator>::promise_type {
13975
  public:
13976
  generator get_return_object() noexcept;
13977
 
13978
  suspend_always initial_suspend() const noexcept { return {}; }
13979
  auto final_suspend() noexcept;
 
13985
  constructible_from<remove_cvref_t<yielded>, const remove_reference_t<yielded>&>;
13986
 
13987
  template<class R2, class V2, class Alloc2, class Unused>
13988
  requires same_as<typename generator<R2, V2, Alloc2>::yielded, yielded>
13989
  auto yield_value(ranges::elements_of<generator<R2, V2, Alloc2>&&, Unused> g) noexcept;
13990
+ template<class R2, class V2, class Alloc2, class Unused>
13991
+ requires same_as<typename generator<R2, V2, Alloc2>::yielded, yielded>
13992
+ auto yield_value(ranges::elements_of<generator<R2, V2, Alloc2>&, Unused> g) noexcept;
13993
 
13994
  template<ranges::input_range R, class Alloc>
13995
  requires convertible_to<ranges::range_reference_t<R>, yielded>
13996
+ auto yield_value(ranges::elements_of<R, Alloc> r);
13997
 
13998
  void await_transform() = delete;
13999
 
14000
  void return_void() const noexcept {}
14001
  void unhandled_exception();
14002
 
14003
  void* operator new(size_t size)
14004
  requires same_as<Allocator, void> || default_initializable<Allocator>;
14005
 
14006
  template<class Alloc, class... Args>
 
14007
  void* operator new(size_t size, allocator_arg_t, const Alloc& alloc, const Args&...);
14008
 
14009
  template<class This, class Alloc, class... Args>
 
14010
  void* operator new(size_t size, const This&, allocator_arg_t, const Alloc& alloc,
14011
  const Args&...);
14012
 
14013
  void operator delete(void* pointer, size_t size) noexcept;
14014
 
 
14075
 
14076
  ``` cpp
14077
  template<class R2, class V2, class Alloc2, class Unused>
14078
  requires same_as<typename generator<R2, V2, Alloc2>::yielded, yielded>
14079
  auto yield_value(ranges::elements_of<generator<R2, V2, Alloc2>&&, Unused> g) noexcept;
14080
+ template<class R2, class V2, class Alloc2, class Unused>
14081
+ requires same_as<typename generator<R2, V2, Alloc2>::yielded, yielded>
14082
+ auto yield_value(ranges::elements_of<generator<R2, V2, Alloc2>&, Unused> g) noexcept;
14083
  ```
14084
 
14085
  *Preconditions:* A handle referring to the coroutine whose promise
14086
  object is `*this` is at the top of `*`*`active_`* of some `generator`
14087
  object `x`. The coroutine referred to by `g.range.`*`coroutine_`* is
 
14094
  execution of the coroutine referred to by `g.range.`*`coroutine_`*, and
14095
  whose member `await_resume` evaluates `rethrow_exception(`*`except_`*`)`
14096
  if `bool(`*`except_`*`)` is `true`. If `bool(`*`except_`*`)` is `false`,
14097
  the `await_resume` member has no effects.
14098
 
14099
+ *Remarks:* A *yield-expression* that calls one of these functions has
14100
+ type `void` [[expr.yield]].
14101
 
14102
  ``` cpp
14103
  template<ranges::input_range R, class Alloc>
14104
  requires convertible_to<ranges::range_reference_t<R>, yielded>
14105
+ auto yield_value(ranges::elements_of<R, Alloc> r);
14106
  ```
14107
 
14108
  *Effects:* Equivalent to:
14109
 
14110
  ``` cpp
14111
  auto nested = [](allocator_arg_t, Alloc, ranges::iterator_t<R> i, ranges::sentinel_t<R> s)
14112
+ -> generator<yielded, void, Alloc> {
14113
  for (; i != s; ++i) {
14114
  co_yield static_cast<yielded>(*i);
14115
  }
14116
  };
14117
  return yield_value(ranges::elements_of(nested(
 
14136
  ``` cpp
14137
  void* operator new(size_t size)
14138
  requires same_as<Allocator, void> || default_initializable<Allocator>;
14139
 
14140
  template<class Alloc, class... Args>
 
14141
  void* operator new(size_t size, allocator_arg_t, const Alloc& alloc, const Args&...);
14142
 
14143
  template<class This, class Alloc, class... Args>
 
14144
  void* operator new(size_t size, const This&, allocator_arg_t, const Alloc& alloc,
14145
  const Args&...);
14146
  ```
14147
 
14148
  Let `A` be
 
14153
 
14154
  Let `B` be `allocator_traits<A>::template rebind_alloc<U>` where `U` is
14155
  an unspecified type whose size and alignment are both
14156
  \_\_STDCPP_DEFAULT_NEW_ALIGNMENT\_\_.
14157
 
14158
+ *Mandates:* `allocator_traits<B>::pointer` is a pointer type. For the
14159
+ overloads with a template parameter `Alloc`,
14160
+ `same_as<Allocator, void> || convertible_to<const Alloc&, Allocator>` is
14161
+ modeled.
14162
 
14163
  *Effects:* Initializes an allocator `b` of type `B` with `A(alloc)`, for
14164
  the overloads with a function parameter `alloc`, and with `A()`
14165
  otherwise. Uses `b` to allocate storage for the smallest array of `U`
14166
  sufficient to provide storage for a coroutine state of size `size`, and
 
14182
 
14183
  ### Class `generator::iterator` <a id="coro.generator.iterator">[[coro.generator.iterator]]</a>
14184
 
14185
  ``` cpp
14186
  namespace std {
14187
+ template<class Ref, class Val, class Allocator>
14188
+ class generator<Ref, Val, Allocator>::iterator {
14189
  public:
14190
  using value_type = value;
14191
  using difference_type = ptrdiff_t;
14192
 
14193
  iterator(iterator&& other) noexcept;
 
14254
  ```
14255
 
14256
  *Effects:* Equivalent to: `return i.`*`coroutine_`*`.done();`
14257
 
14258
  <!-- Link reference definitions -->
14259
+ [algorithms]: algorithms.md#algorithms
14260
  [basic.lookup.argdep]: basic.md#basic.lookup.argdep
14261
  [concepts.equality]: concepts.md#concepts.equality
14262
  [containers]: containers.md#containers
14263
  [conv.rval]: expr.md#conv.rval
14264
  [coro.generator]: #coro.generator
 
14272
  [dcl.init.general]: dcl.md#dcl.init.general
14273
  [expr.await]: expr.md#expr.await
14274
  [expr.const]: expr.md#expr.const
14275
  [expr.yield]: expr.md#expr.yield
14276
  [generator.syn]: #generator.syn
14277
+ [intro.races]: basic.md#intro.races
14278
  [iterator.concept.bidir]: iterators.md#iterator.concept.bidir
14279
  [iterator.concept.forward]: iterators.md#iterator.concept.forward
14280
  [iterator.concept.iterator]: iterators.md#iterator.concept.iterator
14281
  [iterator.concept.output]: iterators.md#iterator.concept.output
14282
  [iterator.concept.random.access]: iterators.md#iterator.concept.random.access
 
14308
  [range.adjacent.transform.sentinel]: #range.adjacent.transform.sentinel
14309
  [range.adjacent.transform.view]: #range.adjacent.transform.view
14310
  [range.adjacent.view]: #range.adjacent.view
14311
  [range.all]: #range.all
14312
  [range.all.general]: #range.all.general
14313
+ [range.approximately.sized]: #range.approximately.sized
14314
  [range.as.const]: #range.as.const
14315
  [range.as.const.overview]: #range.as.const.overview
14316
  [range.as.const.view]: #range.as.const.view
14317
  [range.as.rvalue]: #range.as.rvalue
14318
  [range.as.rvalue.overview]: #range.as.rvalue.overview
14319
  [range.as.rvalue.view]: #range.as.rvalue.view
14320
+ [range.cache.latest]: #range.cache.latest
14321
+ [range.cache.latest.iterator]: #range.cache.latest.iterator
14322
+ [range.cache.latest.overview]: #range.cache.latest.overview
14323
+ [range.cache.latest.sentinel]: #range.cache.latest.sentinel
14324
+ [range.cache.latest.view]: #range.cache.latest.view
14325
  [range.cartesian]: #range.cartesian
14326
  [range.cartesian.iterator]: #range.cartesian.iterator
14327
  [range.cartesian.overview]: #range.cartesian.overview
14328
  [range.cartesian.view]: #range.cartesian.view
14329
  [range.chunk]: #range.chunk
 
14339
  [range.chunk.view.fwd]: #range.chunk.view.fwd
14340
  [range.chunk.view.input]: #range.chunk.view.input
14341
  [range.common]: #range.common
14342
  [range.common.overview]: #range.common.overview
14343
  [range.common.view]: #range.common.view
14344
+ [range.concat]: #range.concat
14345
+ [range.concat.iterator]: #range.concat.iterator
14346
+ [range.concat.overview]: #range.concat.overview
14347
+ [range.concat.view]: #range.concat.view
14348
  [range.counted]: #range.counted
14349
  [range.dangling]: #range.dangling
14350
  [range.drop]: #range.drop
14351
  [range.drop.overview]: #range.drop.overview
14352
  [range.drop.view]: #range.drop.view
 
14404
  [range.owning.view]: #range.owning.view
14405
  [range.prim.cdata]: #range.prim.cdata
14406
  [range.prim.data]: #range.prim.data
14407
  [range.prim.empty]: #range.prim.empty
14408
  [range.prim.size]: #range.prim.size
14409
+ [range.prim.size.hint]: #range.prim.size.hint
14410
  [range.prim.ssize]: #range.prim.ssize
14411
  [range.range]: #range.range
14412
  [range.ref.view]: #range.ref.view
14413
  [range.refinements]: #range.refinements
14414
  [range.repeat]: #range.repeat
 
14449
  [range.take.view]: #range.take.view
14450
  [range.take.while]: #range.take.while
14451
  [range.take.while.overview]: #range.take.while.overview
14452
  [range.take.while.sentinel]: #range.take.while.sentinel
14453
  [range.take.while.view]: #range.take.while.view
14454
+ [range.to.input]: #range.to.input
14455
+ [range.to.input.iterator]: #range.to.input.iterator
14456
+ [range.to.input.overview]: #range.to.input.overview
14457
+ [range.to.input.view]: #range.to.input.view
14458
  [range.transform]: #range.transform
14459
  [range.transform.iterator]: #range.transform.iterator
14460
  [range.transform.overview]: #range.transform.overview
14461
  [range.transform.sentinel]: #range.transform.sentinel
14462
  [range.transform.view]: #range.transform.view