@@ -101,11 +101,12 @@ struct Iter {
101
101
template <std::size_t X, std::size_t Y>
102
102
friend difference_type operator -(Iter<X> a, Iter<Y> b);
103
103
104
- friend bool operator ==(Iter a, Iter b) = default ;
104
+ friend bool operator ==(Iter a, Iter b) { return a. ptr_ == b. ptr_ ; } ;
105
105
friend bool operator <(Iter a, Iter b) { return a.ptr_ < b.ptr_ ; }
106
106
friend bool operator >(Iter a, Iter b) { return a.ptr_ > b.ptr_ ; }
107
107
friend bool operator <=(Iter a, Iter b) { return a.ptr_ <= b.ptr_ ; }
108
108
friend bool operator >=(Iter a, Iter b) { return a.ptr_ >= b.ptr_ ; }
109
+ friend auto operator <=>(Iter a, Iter b) { return a.ptr_ <=> b.ptr_ ; }
109
110
};
110
111
111
112
template <std::size_t X>
@@ -132,6 +133,7 @@ template <std::size_t N>
132
133
struct Range : std::ranges::view_base {
133
134
using iterator = Iter<N>;
134
135
using const_iterator = Iter<N>;
136
+ using sentinel = sentinel_wrapper<iterator>;
135
137
136
138
int * data_;
137
139
std::size_t size_;
@@ -189,6 +191,22 @@ int main() {
189
191
}
190
192
}
191
193
194
+ {
195
+ // valueless by exception test operator== with a sentinel
196
+ flag = false ;
197
+ Range<0 > r1;
198
+ Range<1 > r2;
199
+ auto cv = std::views::concat (r1, r2);
200
+ auto iter1 = cv.begin ();
201
+ auto iter2 = std::ranges::next (cv.begin (), 4 );
202
+ flag = true ;
203
+ try {
204
+ iter1 = std::move (iter2);
205
+ } catch (...) {
206
+ TEST_LIBCPP_ASSERT_FAILURE ([=] { (void )(iter1 == std::default_sentinel); }(), " valueless by exception" );
207
+ }
208
+ }
209
+
192
210
{
193
211
// valueless by exception test operator--
194
212
flag = false ;
@@ -202,7 +220,7 @@ int main() {
202
220
try {
203
221
iter1 = std::move (iter2);
204
222
} catch (...) {
205
- TEST_LIBCPP_ASSERT_FAILURE ([&] { iter1-- ; }(), " valueless by exception" );
223
+ TEST_LIBCPP_ASSERT_FAILURE ([&] { --iter1 ; }(), " valueless by exception" );
206
224
}
207
225
}
208
226
@@ -240,6 +258,108 @@ int main() {
240
258
}
241
259
}
242
260
261
+ {
262
+ // valueless by exception test operator>
263
+ flag = false ;
264
+ Range<0 > r1;
265
+ Range<1 > r2;
266
+
267
+ auto cv = std::views::concat (r1, r2);
268
+ auto iter1 = cv.begin ();
269
+ auto iter2 = std::ranges::next (cv.begin (), 4 );
270
+ flag = true ;
271
+ try {
272
+ iter1 = std::move (iter2);
273
+ } catch (...) {
274
+ TEST_LIBCPP_ASSERT_FAILURE ([&] { (void )(iter1 > iter2); }(), " valueless by exception" );
275
+ }
276
+ }
277
+
278
+ {
279
+ // valueless by exception test operator>=
280
+ flag = false ;
281
+ Range<0 > r1;
282
+ Range<1 > r2;
283
+
284
+ auto cv = std::views::concat (r1, r2);
285
+ auto iter1 = cv.begin ();
286
+ auto iter2 = std::ranges::next (cv.begin (), 4 );
287
+ flag = true ;
288
+ try {
289
+ iter1 = std::move (iter2);
290
+ } catch (...) {
291
+ TEST_LIBCPP_ASSERT_FAILURE ([&] { (void )(iter1 >= iter2); }(), " valueless by exception" );
292
+ }
293
+ }
294
+
295
+ {
296
+ // valueless by exception test operator<
297
+ flag = false ;
298
+ Range<0 > r1;
299
+ Range<1 > r2;
300
+
301
+ auto cv = std::views::concat (r1, r2);
302
+ auto iter1 = cv.begin ();
303
+ auto iter2 = std::ranges::next (cv.begin (), 4 );
304
+ flag = true ;
305
+ try {
306
+ iter1 = std::move (iter2);
307
+ } catch (...) {
308
+ TEST_LIBCPP_ASSERT_FAILURE ([&] { (void )(iter1 < iter2); }(), " valueless by exception" );
309
+ }
310
+ }
311
+
312
+ {
313
+ // valueless by exception test operator<=
314
+ flag = false ;
315
+ Range<0 > r1;
316
+ Range<1 > r2;
317
+
318
+ auto cv = std::views::concat (r1, r2);
319
+ auto iter1 = cv.begin ();
320
+ auto iter2 = std::ranges::next (cv.begin (), 4 );
321
+ flag = true ;
322
+ try {
323
+ iter1 = std::move (iter2);
324
+ } catch (...) {
325
+ TEST_LIBCPP_ASSERT_FAILURE ([&] { (void )(iter1 <= iter2); }(), " valueless by exception" );
326
+ }
327
+ }
328
+
329
+ {
330
+ // valueless by exception test operator- between two iterators
331
+ flag = false ;
332
+ Range<0 > r1;
333
+ Range<1 > r2;
334
+
335
+ auto cv = std::views::concat (r1, r2);
336
+ auto iter1 = cv.begin ();
337
+ auto iter2 = std::ranges::next (cv.begin (), 4 );
338
+ flag = true ;
339
+ try {
340
+ iter1 = std::move (iter2);
341
+ } catch (...) {
342
+ TEST_LIBCPP_ASSERT_FAILURE ([&] { (void )(iter1 - iter2); }(), " valueless by exception" );
343
+ }
344
+ }
345
+
346
+ {
347
+ // valueless by exception test operator- with a constant
348
+ flag = false ;
349
+ Range<0 > r1;
350
+ Range<1 > r2;
351
+
352
+ auto cv = std::views::concat (r1, r2);
353
+ auto iter1 = cv.begin ();
354
+ auto iter2 = std::ranges::next (cv.begin (), 4 );
355
+ flag = true ;
356
+ try {
357
+ iter1 = std::move (iter2);
358
+ } catch (...) {
359
+ TEST_LIBCPP_ASSERT_FAILURE ([&] { (void )(iter1 - 1 ); }(), " valueless by exception" );
360
+ }
361
+ }
362
+
243
363
{
244
364
// valueless by exception test constructor
245
365
flag = false ;
0 commit comments