From Jason Turner

[iterator.synopsis]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpb68z1qfy/{from.md → to.md} +287 -35
tmp/tmpb68z1qfy/{from.md → to.md} RENAMED
@@ -1,60 +1,275 @@
1
  ## Header `<iterator>` synopsis <a id="iterator.synopsis">[[iterator.synopsis]]</a>
2
 
3
  ``` cpp
 
 
 
4
  namespace std {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
  // [iterator.primitives], primitives
6
- template<class Iterator> struct iterator_traits;
7
- template<class T> struct iterator_traits<T*>;
8
- template<class T> struct iterator_traits<const T*>;
9
-
10
  struct input_iterator_tag { };
11
  struct output_iterator_tag { };
12
  struct forward_iterator_tag: public input_iterator_tag { };
13
  struct bidirectional_iterator_tag: public forward_iterator_tag { };
14
  struct random_access_iterator_tag: public bidirectional_iterator_tag { };
 
15
 
16
  // [iterator.operations], iterator operations
17
  template<class InputIterator, class Distance>
18
- constexpr void advance(InputIterator& i, Distance n);
 
19
  template<class InputIterator>
20
  constexpr typename iterator_traits<InputIterator>::difference_type
21
  distance(InputIterator first, InputIterator last);
22
  template<class InputIterator>
23
- constexpr InputIterator next(InputIterator x,
 
24
  typename iterator_traits<InputIterator>::difference_type n = 1);
25
  template<class BidirectionalIterator>
26
- constexpr BidirectionalIterator prev(BidirectionalIterator x,
 
27
  typename iterator_traits<BidirectionalIterator>::difference_type n = 1);
28
 
29
- // [predef.iterators], predefined iterators
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
  template<class Iterator> class reverse_iterator;
31
 
32
  template<class Iterator1, class Iterator2>
33
  constexpr bool operator==(
34
  const reverse_iterator<Iterator1>& x,
35
  const reverse_iterator<Iterator2>& y);
36
- template <class Iterator1, class Iterator2>
37
- constexpr bool operator<(
38
- const reverse_iterator<Iterator1>& x,
39
- const reverse_iterator<Iterator2>& y);
40
  template<class Iterator1, class Iterator2>
41
  constexpr bool operator!=(
42
  const reverse_iterator<Iterator1>& x,
43
  const reverse_iterator<Iterator2>& y);
 
 
 
 
44
  template<class Iterator1, class Iterator2>
45
  constexpr bool operator>(
46
  const reverse_iterator<Iterator1>& x,
47
  const reverse_iterator<Iterator2>& y);
48
- template <class Iterator1, class Iterator2>
49
- constexpr bool operator>=(
50
- const reverse_iterator<Iterator1>& x,
51
- const reverse_iterator<Iterator2>& y);
52
  template<class Iterator1, class Iterator2>
53
  constexpr bool operator<=(
54
  const reverse_iterator<Iterator1>& x,
55
  const reverse_iterator<Iterator2>& y);
 
 
 
 
 
 
 
 
56
 
57
  template<class Iterator1, class Iterator2>
58
  constexpr auto operator-(
59
  const reverse_iterator<Iterator1>& x,
60
  const reverse_iterator<Iterator2>& y) -> decltype(y.base() - x.base());
@@ -65,74 +280,109 @@ namespace std {
65
  const reverse_iterator<Iterator>& x);
66
 
67
  template<class Iterator>
68
  constexpr reverse_iterator<Iterator> make_reverse_iterator(Iterator i);
69
 
 
 
 
 
 
 
70
  template<class Container> class back_insert_iterator;
71
  template<class Container>
72
- back_insert_iterator<Container> back_inserter(Container& x);
73
 
74
  template<class Container> class front_insert_iterator;
75
  template<class Container>
76
- front_insert_iterator<Container> front_inserter(Container& x);
77
 
78
  template<class Container> class insert_iterator;
79
  template<class Container>
80
- insert_iterator<Container> inserter(Container& x, typename Container::iterator i);
 
81
 
 
82
  template<class Iterator> class move_iterator;
 
83
  template<class Iterator1, class Iterator2>
84
  constexpr bool operator==(
85
  const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
86
- template <class Iterator1, class Iterator2>
87
- constexpr bool operator!=(
88
- const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
89
  template<class Iterator1, class Iterator2>
90
  constexpr bool operator<(
91
  const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
92
- template <class Iterator1, class Iterator2>
93
- constexpr bool operator<=(
94
- const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
95
  template<class Iterator1, class Iterator2>
96
  constexpr bool operator>(
97
  const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
 
 
 
98
  template<class Iterator1, class Iterator2>
99
  constexpr bool operator>=(
100
  const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
 
 
 
 
101
 
102
  template<class Iterator1, class Iterator2>
103
  constexpr auto operator-(
104
  const move_iterator<Iterator1>& x,
105
  const move_iterator<Iterator2>& y) -> decltype(x.base() - y.base());
106
  template<class Iterator>
107
  constexpr move_iterator<Iterator> operator+(
108
  typename move_iterator<Iterator>::difference_type n, const move_iterator<Iterator>& x);
 
109
  template<class Iterator>
110
  constexpr move_iterator<Iterator> make_move_iterator(Iterator i);
111
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
112
  // [stream.iterators], stream iterators
113
  template<class T, class charT = char, class traits = char_traits<charT>,
114
  class Distance = ptrdiff_t>
115
  class istream_iterator;
116
  template<class T, class charT, class traits, class Distance>
117
  bool operator==(const istream_iterator<T,charT,traits,Distance>& x,
118
  const istream_iterator<T,charT,traits,Distance>& y);
119
- template <class T, class charT, class traits, class Distance>
120
- bool operator!=(const istream_iterator<T,charT,traits,Distance>& x,
121
- const istream_iterator<T,charT,traits,Distance>& y);
122
 
123
  template<class T, class charT = char, class traits = char_traits<charT>>
124
  class ostream_iterator;
125
 
126
  template<class charT, class traits = char_traits<charT>>
127
  class istreambuf_iterator;
128
  template<class charT, class traits>
129
  bool operator==(const istreambuf_iterator<charT,traits>& a,
130
  const istreambuf_iterator<charT,traits>& b);
131
- template <class charT, class traits>
132
- bool operator!=(const istreambuf_iterator<charT,traits>& a,
133
- const istreambuf_iterator<charT,traits>& b);
134
 
135
  template<class charT, class traits = char_traits<charT>>
136
  class ostreambuf_iterator;
137
 
138
  // [iterator.range], range access
@@ -155,16 +405,18 @@ namespace std {
155
  template<class E> constexpr reverse_iterator<const E*> rbegin(initializer_list<E> il);
156
  template<class E> constexpr reverse_iterator<const E*> rend(initializer_list<E> il);
157
  template<class C> constexpr auto crbegin(const C& c) -> decltype(std::rbegin(c));
158
  template<class C> constexpr auto crend(const C& c) -> decltype(std::rend(c));
159
 
160
- // [iterator.container], container access
161
  template<class C> constexpr auto size(const C& c) -> decltype(c.size());
162
  template<class T, size_t N> constexpr size_t size(const T (&array)[N]) noexcept;
163
- template <class C> constexpr auto empty(const C& c) -> decltype(c.empty());
164
- template <class T, size_t N> constexpr bool empty(const T (&array)[N]) noexcept;
165
- template <class E> constexpr bool empty(initializer_list<E> il) noexcept;
 
 
 
166
  template<class C> constexpr auto data(C& c) -> decltype(c.data());
167
  template<class C> constexpr auto data(const C& c) -> decltype(c.data());
168
  template<class T, size_t N> constexpr T* data(T (&array)[N]) noexcept;
169
  template<class E> constexpr const E* data(initializer_list<E> il) noexcept;
170
  }
 
1
  ## Header `<iterator>` synopsis <a id="iterator.synopsis">[[iterator.synopsis]]</a>
2
 
3
  ``` cpp
4
+ #include <compare> // see [compare.syn]
5
+ #include <concepts> // see [concepts.syn]
6
+
7
  namespace std {
8
+ template<class T> using with-reference = T&; // exposition only
9
+ template<class T> concept can-reference // exposition only
10
+ = requires { typename with-reference<T>; };
11
+ template<class T> concept dereferenceable // exposition only
12
+ = requires(T& t) {
13
+ { *t } -> can-reference; // not required to be equality-preserving
14
+ };
15
+
16
+ // [iterator.assoc.types], associated types
17
+ // [incrementable.traits], incrementable traits
18
+ template<class> struct incrementable_traits;
19
+ template<class T>
20
+ using iter_difference_t = see below;
21
+
22
+ // [readable.traits], indirectly readable traits
23
+ template<class> struct indirectly_readable_traits;
24
+ template<class T>
25
+ using iter_value_t = see below;
26
+
27
+ // [iterator.traits], iterator traits
28
+ template<class I> struct iterator_traits;
29
+ template<class T> requires is_object_v<T> struct iterator_traits<T*>;
30
+
31
+ template<dereferenceable T>
32
+ using iter_reference_t = decltype(*declval<T&>());
33
+
34
+ namespace ranges {
35
+ // [iterator.cust], customization points
36
+ inline namespace unspecified {
37
+ // [iterator.cust.move], ranges::iter_move
38
+ inline constexpr unspecified iter_move = unspecified;
39
+
40
+ // [iterator.cust.swap], ranges::iter_swap
41
+ inline constexpr unspecified iter_swap = unspecified;
42
+ }
43
+ }
44
+
45
+ template<dereferenceable T>
46
+ requires requires(T& t) {
47
+ { ranges::iter_move(t) } -> can-reference;
48
+ }
49
+ using iter_rvalue_reference_t
50
+ = decltype(ranges::iter_move(declval<T&>()));
51
+
52
+ // [iterator.concepts], iterator concepts
53
+ // [iterator.concept.readable], concept indirectly_readable
54
+ template<class In>
55
+ concept indirectly_readable = see below;
56
+
57
+ template<indirectly_readable T>
58
+ using iter_common_reference_t =
59
+ common_reference_t<iter_reference_t<T>, iter_value_t<T>&>;
60
+
61
+ // [iterator.concept.writable], concept indirectly_writable
62
+ template<class Out, class T>
63
+ concept indirectly_writable = see below;
64
+
65
+ // [iterator.concept.winc], concept weakly_incrementable
66
+ template<class I>
67
+ concept weakly_incrementable = see below;
68
+
69
+ // [iterator.concept.inc], concept incrementable
70
+ template<class I>
71
+ concept incrementable = see below;
72
+
73
+ // [iterator.concept.iterator], concept input_or_output_iterator
74
+ template<class I>
75
+ concept input_or_output_iterator = see below;
76
+
77
+ // [iterator.concept.sentinel], concept sentinel_for
78
+ template<class S, class I>
79
+ concept sentinel_for = see below;
80
+
81
+ // [iterator.concept.sizedsentinel], concept sized_sentinel_for
82
+ template<class S, class I>
83
+ inline constexpr bool disable_sized_sentinel_for = false;
84
+
85
+ template<class S, class I>
86
+ concept sized_sentinel_for = see below;
87
+
88
+ // [iterator.concept.input], concept input_iterator
89
+ template<class I>
90
+ concept input_iterator = see below;
91
+
92
+ // [iterator.concept.output], concept output_iterator
93
+ template<class I, class T>
94
+ concept output_iterator = see below;
95
+
96
+ // [iterator.concept.forward], concept forward_iterator
97
+ template<class I>
98
+ concept forward_iterator = see below;
99
+
100
+ // [iterator.concept.bidir], concept bidirectional_iterator
101
+ template<class I>
102
+ concept bidirectional_iterator = see below;
103
+
104
+ // [iterator.concept.random.access], concept random_access_iterator
105
+ template<class I>
106
+ concept random_access_iterator = see below;
107
+
108
+ // [iterator.concept.contiguous], concept contiguous_iterator
109
+ template<class I>
110
+ concept contiguous_iterator = see below;
111
+
112
+ // [indirectcallable], indirect callable requirements
113
+ // [indirectcallable.indirectinvocable], indirect callables
114
+ template<class F, class I>
115
+ concept indirectly_unary_invocable = see below;
116
+
117
+ template<class F, class I>
118
+ concept indirectly_regular_unary_invocable = see below;
119
+
120
+ template<class F, class I>
121
+ concept indirect_unary_predicate = see below;
122
+
123
+ template<class F, class I1, class I2>
124
+ concept indirect_binary_predicate = see below;
125
+
126
+ template<class F, class I1, class I2 = I1>
127
+ concept indirect_equivalence_relation = see below;
128
+
129
+ template<class F, class I1, class I2 = I1>
130
+ concept indirect_strict_weak_order = see below;
131
+
132
+ template<class F, class... Is>
133
+ requires (indirectly_readable<Is> && ...) && invocable<F, iter_reference_t<Is>...>
134
+ using indirect_result_t = invoke_result_t<F, iter_reference_t<Is>...>;
135
+
136
+ // [projected], projected
137
+ template<indirectly_readable I, indirectly_regular_unary_invocable<I> Proj>
138
+ struct projected;
139
+
140
+ template<weakly_incrementable I, class Proj>
141
+ struct incrementable_traits<projected<I, Proj>>;
142
+
143
+ // [alg.req], common algorithm requirements
144
+ // [alg.req.ind.move], concept indirectly_movable
145
+ template<class In, class Out>
146
+ concept indirectly_movable = see below;
147
+
148
+ template<class In, class Out>
149
+ concept indirectly_movable_storable = see below;
150
+
151
+ // [alg.req.ind.copy], concept indirectly_copyable
152
+ template<class In, class Out>
153
+ concept indirectly_copyable = see below;
154
+
155
+ template<class In, class Out>
156
+ concept indirectly_copyable_storable = see below;
157
+
158
+ // [alg.req.ind.swap], concept indirectly_swappable
159
+ template<class I1, class I2 = I1>
160
+ concept indirectly_swappable = see below;
161
+
162
+ // [alg.req.ind.cmp], concept indirectly_comparable
163
+ template<class I1, class I2, class R, class P1 = identity, class P2 = identity>
164
+ concept indirectly_comparable = see below;
165
+
166
+ // [alg.req.permutable], concept permutable
167
+ template<class I>
168
+ concept permutable = see below;
169
+
170
+ // [alg.req.mergeable], concept mergeable
171
+ template<class I1, class I2, class Out,
172
+ class R = ranges::less, class P1 = identity, class P2 = identity>
173
+ concept mergeable = see below;
174
+
175
+ // [alg.req.sortable], concept sortable
176
+ template<class I, class R = ranges::less, class P = identity>
177
+ concept sortable = see below;
178
+
179
  // [iterator.primitives], primitives
180
+ // [std.iterator.tags], iterator tags
 
 
 
181
  struct input_iterator_tag { };
182
  struct output_iterator_tag { };
183
  struct forward_iterator_tag: public input_iterator_tag { };
184
  struct bidirectional_iterator_tag: public forward_iterator_tag { };
185
  struct random_access_iterator_tag: public bidirectional_iterator_tag { };
186
+ struct contiguous_iterator_tag: public random_access_iterator_tag { };
187
 
188
  // [iterator.operations], iterator operations
189
  template<class InputIterator, class Distance>
190
+ constexpr void
191
+ advance(InputIterator& i, Distance n);
192
  template<class InputIterator>
193
  constexpr typename iterator_traits<InputIterator>::difference_type
194
  distance(InputIterator first, InputIterator last);
195
  template<class InputIterator>
196
+ constexpr InputIterator
197
+ next(InputIterator x,
198
  typename iterator_traits<InputIterator>::difference_type n = 1);
199
  template<class BidirectionalIterator>
200
+ constexpr BidirectionalIterator
201
+ prev(BidirectionalIterator x,
202
  typename iterator_traits<BidirectionalIterator>::difference_type n = 1);
203
 
204
+ // [range.iter.ops], range iterator operations
205
+ namespace ranges {
206
+ // [range.iter.op.advance], ranges::advance
207
+ template<input_or_output_iterator I>
208
+ constexpr void advance(I& i, iter_difference_t<I> n);
209
+ template<input_or_output_iterator I, sentinel_for<I> S>
210
+ constexpr void advance(I& i, S bound);
211
+ template<input_or_output_iterator I, sentinel_for<I> S>
212
+ constexpr iter_difference_t<I> advance(I& i, iter_difference_t<I> n, S bound);
213
+
214
+ // [range.iter.op.distance], ranges::distance
215
+ template<input_or_output_iterator I, sentinel_for<I> S>
216
+ constexpr iter_difference_t<I> distance(I first, S last);
217
+ template<range R>
218
+ constexpr range_difference_t<R> distance(R&& r);
219
+
220
+ // [range.iter.op.next], ranges::next
221
+ template<input_or_output_iterator I>
222
+ constexpr I next(I x);
223
+ template<input_or_output_iterator I>
224
+ constexpr I next(I x, iter_difference_t<I> n);
225
+ template<input_or_output_iterator I, sentinel_for<I> S>
226
+ constexpr I next(I x, S bound);
227
+ template<input_or_output_iterator I, sentinel_for<I> S>
228
+ constexpr I next(I x, iter_difference_t<I> n, S bound);
229
+
230
+ // [range.iter.op.prev], ranges::prev
231
+ template<bidirectional_iterator I>
232
+ constexpr I prev(I x);
233
+ template<bidirectional_iterator I>
234
+ constexpr I prev(I x, iter_difference_t<I> n);
235
+ template<bidirectional_iterator I>
236
+ constexpr I prev(I x, iter_difference_t<I> n, I bound);
237
+ }
238
+
239
+ // [predef.iterators], predefined iterators and sentinels
240
+ // [reverse.iterators], reverse iterators
241
  template<class Iterator> class reverse_iterator;
242
 
243
  template<class Iterator1, class Iterator2>
244
  constexpr bool operator==(
245
  const reverse_iterator<Iterator1>& x,
246
  const reverse_iterator<Iterator2>& y);
 
 
 
 
247
  template<class Iterator1, class Iterator2>
248
  constexpr bool operator!=(
249
  const reverse_iterator<Iterator1>& x,
250
  const reverse_iterator<Iterator2>& y);
251
+ template<class Iterator1, class Iterator2>
252
+ constexpr bool operator<(
253
+ const reverse_iterator<Iterator1>& x,
254
+ const reverse_iterator<Iterator2>& y);
255
  template<class Iterator1, class Iterator2>
256
  constexpr bool operator>(
257
  const reverse_iterator<Iterator1>& x,
258
  const reverse_iterator<Iterator2>& y);
 
 
 
 
259
  template<class Iterator1, class Iterator2>
260
  constexpr bool operator<=(
261
  const reverse_iterator<Iterator1>& x,
262
  const reverse_iterator<Iterator2>& y);
263
+ template<class Iterator1, class Iterator2>
264
+ constexpr bool operator>=(
265
+ const reverse_iterator<Iterator1>& x,
266
+ const reverse_iterator<Iterator2>& y);
267
+ template<class Iterator1, three_way_comparable_with<Iterator1> Iterator2>
268
+ constexpr compare_three_way_result_t<Iterator1, Iterator2>
269
+ operator<=>(const reverse_iterator<Iterator1>& x,
270
+ const reverse_iterator<Iterator2>& y);
271
 
272
  template<class Iterator1, class Iterator2>
273
  constexpr auto operator-(
274
  const reverse_iterator<Iterator1>& x,
275
  const reverse_iterator<Iterator2>& y) -> decltype(y.base() - x.base());
 
280
  const reverse_iterator<Iterator>& x);
281
 
282
  template<class Iterator>
283
  constexpr reverse_iterator<Iterator> make_reverse_iterator(Iterator i);
284
 
285
+ template<class Iterator1, class Iterator2>
286
+ requires (!sized_sentinel_for<Iterator1, Iterator2>)
287
+ inline constexpr bool disable_sized_sentinel_for<reverse_iterator<Iterator1>,
288
+ reverse_iterator<Iterator2>> = true;
289
+
290
+ // [insert.iterators], insert iterators
291
  template<class Container> class back_insert_iterator;
292
  template<class Container>
293
+ constexpr back_insert_iterator<Container> back_inserter(Container& x);
294
 
295
  template<class Container> class front_insert_iterator;
296
  template<class Container>
297
+ constexpr front_insert_iterator<Container> front_inserter(Container& x);
298
 
299
  template<class Container> class insert_iterator;
300
  template<class Container>
301
+ constexpr insert_iterator<Container>
302
+ inserter(Container& x, ranges::iterator_t<Container> i);
303
 
304
+ // [move.iterators], move iterators and sentinels
305
  template<class Iterator> class move_iterator;
306
+
307
  template<class Iterator1, class Iterator2>
308
  constexpr bool operator==(
309
  const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
 
 
 
310
  template<class Iterator1, class Iterator2>
311
  constexpr bool operator<(
312
  const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
 
 
 
313
  template<class Iterator1, class Iterator2>
314
  constexpr bool operator>(
315
  const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
316
+ template<class Iterator1, class Iterator2>
317
+ constexpr bool operator<=(
318
+ const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
319
  template<class Iterator1, class Iterator2>
320
  constexpr bool operator>=(
321
  const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
322
+ template<class Iterator1, three_way_comparable_with<Iterator1> Iterator2>
323
+ constexpr compare_three_way_result_t<Iterator1, Iterator2>
324
+ operator<=>(const move_iterator<Iterator1>& x,
325
+ const move_iterator<Iterator2>& y);
326
 
327
  template<class Iterator1, class Iterator2>
328
  constexpr auto operator-(
329
  const move_iterator<Iterator1>& x,
330
  const move_iterator<Iterator2>& y) -> decltype(x.base() - y.base());
331
  template<class Iterator>
332
  constexpr move_iterator<Iterator> operator+(
333
  typename move_iterator<Iterator>::difference_type n, const move_iterator<Iterator>& x);
334
+
335
  template<class Iterator>
336
  constexpr move_iterator<Iterator> make_move_iterator(Iterator i);
337
 
338
+ template<semiregular S> class move_sentinel;
339
+
340
+ // [iterators.common], common iterators
341
+ template<input_or_output_iterator I, sentinel_for<I> S>
342
+ requires (!same_as<I, S> && copyable<I>)
343
+ class common_iterator;
344
+
345
+ template<class I, class S>
346
+ struct incrementable_traits<common_iterator<I, S>>;
347
+
348
+ template<input_iterator I, class S>
349
+ struct iterator_traits<common_iterator<I, S>>;
350
+
351
+ // [default.sentinels], default sentinels
352
+ struct default_sentinel_t;
353
+ inline constexpr default_sentinel_t default_sentinel{};
354
+
355
+ // [iterators.counted], counted iterators
356
+ template<input_or_output_iterator I> class counted_iterator;
357
+
358
+ template<class I>
359
+ struct incrementable_traits<counted_iterator<I>>;
360
+
361
+ template<input_iterator I>
362
+ struct iterator_traits<counted_iterator<I>>;
363
+
364
+ // [unreachable.sentinels], unreachable sentinels
365
+ struct unreachable_sentinel_t;
366
+ inline constexpr unreachable_sentinel_t unreachable_sentinel{};
367
+
368
  // [stream.iterators], stream iterators
369
  template<class T, class charT = char, class traits = char_traits<charT>,
370
  class Distance = ptrdiff_t>
371
  class istream_iterator;
372
  template<class T, class charT, class traits, class Distance>
373
  bool operator==(const istream_iterator<T,charT,traits,Distance>& x,
374
  const istream_iterator<T,charT,traits,Distance>& y);
 
 
 
375
 
376
  template<class T, class charT = char, class traits = char_traits<charT>>
377
  class ostream_iterator;
378
 
379
  template<class charT, class traits = char_traits<charT>>
380
  class istreambuf_iterator;
381
  template<class charT, class traits>
382
  bool operator==(const istreambuf_iterator<charT,traits>& a,
383
  const istreambuf_iterator<charT,traits>& b);
 
 
 
384
 
385
  template<class charT, class traits = char_traits<charT>>
386
  class ostreambuf_iterator;
387
 
388
  // [iterator.range], range access
 
405
  template<class E> constexpr reverse_iterator<const E*> rbegin(initializer_list<E> il);
406
  template<class E> constexpr reverse_iterator<const E*> rend(initializer_list<E> il);
407
  template<class C> constexpr auto crbegin(const C& c) -> decltype(std::rbegin(c));
408
  template<class C> constexpr auto crend(const C& c) -> decltype(std::rend(c));
409
 
 
410
  template<class C> constexpr auto size(const C& c) -> decltype(c.size());
411
  template<class T, size_t N> constexpr size_t size(const T (&array)[N]) noexcept;
412
+ template<class C> constexpr auto ssize(const C& c)
413
+ -> common_type_t<ptrdiff_t, make_signed_t<decltype(c.size())>>;
414
+ template<class T, ptrdiff_t N> constexpr ptrdiff_t ssize(const T (&array)[N]) noexcept;
415
+ template<class C> [[nodiscard]] constexpr auto empty(const C& c) -> decltype(c.empty());
416
+ template<class T, size_t N> [[nodiscard]] constexpr bool empty(const T (&array)[N]) noexcept;
417
+ template<class E> [[nodiscard]] constexpr bool empty(initializer_list<E> il) noexcept;
418
  template<class C> constexpr auto data(C& c) -> decltype(c.data());
419
  template<class C> constexpr auto data(const C& c) -> decltype(c.data());
420
  template<class T, size_t N> constexpr T* data(T (&array)[N]) noexcept;
421
  template<class E> constexpr const E* data(initializer_list<E> il) noexcept;
422
  }