@@ -316,172 +316,6 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator<_Ite
316
316
}
317
317
#endif
318
318
319
- #if _LIBCPP_STD_VER <= 17
320
- template <class _Iter >
321
- using __unconstrained_reverse_iterator = reverse_iterator<_Iter>;
322
- #else
323
-
324
- // __unconstrained_reverse_iterator allows us to use reverse iterators in the implementation of algorithms by working
325
- // around a language issue in C++20.
326
- // In C++20, when a reverse iterator wraps certain C++20-hostile iterators, calling comparison operators on it will
327
- // result in a compilation error. However, calling comparison operators on the pristine hostile iterator is not
328
- // an error. Thus, we cannot use reverse_iterators in the implementation of an algorithm that accepts a
329
- // C++20-hostile iterator. This class is an internal workaround -- it is a copy of reverse_iterator with
330
- // tweaks to make it support hostile iterators.
331
- //
332
- // A C++20-hostile iterator is one that defines a comparison operator where one of the arguments is an exact match
333
- // and the other requires an implicit conversion, for example:
334
- // friend bool operator==(const BaseIter&, const DerivedIter&);
335
- //
336
- // C++20 rules for rewriting equality operators create another overload of this function with parameters reversed:
337
- // friend bool operator==(const DerivedIter&, const BaseIter&);
338
- //
339
- // This creates an ambiguity in overload resolution.
340
- //
341
- // Clang treats this ambiguity differently in different contexts. When operator== is actually called in the function
342
- // body, the code is accepted with a warning. When a concept requires operator== to be a valid expression, however,
343
- // it evaluates to false. Thus, the implementation of reverse_iterator::operator== can actually call operator== on its
344
- // base iterators, but the constraints on reverse_iterator::operator== prevent it from being considered during overload
345
- // resolution. This class simply removes the problematic constraints from comparison functions.
346
- template <class _Iter >
347
- class __unconstrained_reverse_iterator {
348
- _Iter __iter_;
349
-
350
- public:
351
- static_assert (__has_bidirectional_iterator_category<_Iter>::value || bidirectional_iterator<_Iter>);
352
-
353
- using iterator_type = _Iter;
354
- using iterator_category =
355
- _If<__has_random_access_iterator_category<_Iter>::value,
356
- random_access_iterator_tag,
357
- __iterator_category_type<_Iter>>;
358
- using pointer = __iterator_pointer_type<_Iter>;
359
- using value_type = iter_value_t <_Iter>;
360
- using difference_type = iter_difference_t <_Iter>;
361
- using reference = iter_reference_t <_Iter>;
362
-
363
- _LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator () = default;
364
- _LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator (const __unconstrained_reverse_iterator&) = default;
365
- _LIBCPP_HIDE_FROM_ABI constexpr explicit __unconstrained_reverse_iterator (_Iter __iter) : __iter_(__iter) {}
366
-
367
- _LIBCPP_HIDE_FROM_ABI constexpr _Iter base () const { return __iter_; }
368
- _LIBCPP_HIDE_FROM_ABI constexpr reference operator *() const {
369
- auto __tmp = __iter_;
370
- return *--__tmp;
371
- }
372
-
373
- _LIBCPP_HIDE_FROM_ABI constexpr pointer operator ->() const {
374
- if constexpr (is_pointer_v<_Iter>) {
375
- return std::prev (__iter_);
376
- } else {
377
- return std::prev (__iter_).operator ->();
378
- }
379
- }
380
-
381
- _LIBCPP_HIDE_FROM_ABI friend constexpr iter_rvalue_reference_t <_Iter>
382
- iter_move (const __unconstrained_reverse_iterator& __i) noexcept (
383
- is_nothrow_copy_constructible_v<_Iter>&& noexcept (ranges::iter_move(--std::declval<_Iter&>()))) {
384
- auto __tmp = __i.base ();
385
- return ranges::iter_move (--__tmp);
386
- }
387
-
388
- _LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator& operator ++() {
389
- --__iter_;
390
- return *this ;
391
- }
392
-
393
- _LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator operator ++(int ) {
394
- auto __tmp = *this ;
395
- --__iter_;
396
- return __tmp;
397
- }
398
-
399
- _LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator& operator --() {
400
- ++__iter_;
401
- return *this ;
402
- }
403
-
404
- _LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator operator --(int ) {
405
- auto __tmp = *this ;
406
- ++__iter_;
407
- return __tmp;
408
- }
409
-
410
- _LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator& operator +=(difference_type __n) {
411
- __iter_ -= __n;
412
- return *this ;
413
- }
414
-
415
- _LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator& operator -=(difference_type __n) {
416
- __iter_ += __n;
417
- return *this ;
418
- }
419
-
420
- _LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator operator +(difference_type __n) const {
421
- return __unconstrained_reverse_iterator (__iter_ - __n);
422
- }
423
-
424
- _LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator operator -(difference_type __n) const {
425
- return __unconstrained_reverse_iterator (__iter_ + __n);
426
- }
427
-
428
- _LIBCPP_HIDE_FROM_ABI constexpr difference_type operator -(const __unconstrained_reverse_iterator& __other) const {
429
- return __other.__iter_ - __iter_;
430
- }
431
-
432
- _LIBCPP_HIDE_FROM_ABI constexpr auto operator [](difference_type __n) const { return *(*this + __n); }
433
-
434
- // Deliberately unconstrained unlike the comparison functions in `reverse_iterator` -- see the class comment for the
435
- // rationale.
436
- _LIBCPP_HIDE_FROM_ABI friend constexpr bool
437
- operator ==(const __unconstrained_reverse_iterator& __lhs, const __unconstrained_reverse_iterator& __rhs) {
438
- return __lhs.base () == __rhs.base ();
439
- }
440
-
441
- _LIBCPP_HIDE_FROM_ABI friend constexpr bool
442
- operator !=(const __unconstrained_reverse_iterator& __lhs, const __unconstrained_reverse_iterator& __rhs) {
443
- return __lhs.base () != __rhs.base ();
444
- }
445
-
446
- _LIBCPP_HIDE_FROM_ABI friend constexpr bool
447
- operator <(const __unconstrained_reverse_iterator& __lhs, const __unconstrained_reverse_iterator& __rhs) {
448
- return __lhs.base () > __rhs.base ();
449
- }
450
-
451
- _LIBCPP_HIDE_FROM_ABI friend constexpr bool
452
- operator >(const __unconstrained_reverse_iterator& __lhs, const __unconstrained_reverse_iterator& __rhs) {
453
- return __lhs.base () < __rhs.base ();
454
- }
455
-
456
- _LIBCPP_HIDE_FROM_ABI friend constexpr bool
457
- operator <=(const __unconstrained_reverse_iterator& __lhs, const __unconstrained_reverse_iterator& __rhs) {
458
- return __lhs.base () >= __rhs.base ();
459
- }
460
-
461
- _LIBCPP_HIDE_FROM_ABI friend constexpr bool
462
- operator >=(const __unconstrained_reverse_iterator& __lhs, const __unconstrained_reverse_iterator& __rhs) {
463
- return __lhs.base () <= __rhs.base ();
464
- }
465
- };
466
-
467
- #endif // _LIBCPP_STD_VER <= 17
468
-
469
- template <template <class > class _RevIter1 , template <class > class _RevIter2 , class _Iter >
470
- struct __unwrap_reverse_iter_impl {
471
- using _UnwrappedIter = decltype(__unwrap_iter_impl<_Iter>::__unwrap(std::declval<_Iter>()));
472
- using _ReverseWrapper = _RevIter1<_RevIter2<_Iter> >;
473
-
474
- static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _ReverseWrapper
475
- __rewrap (_ReverseWrapper __orig_iter, _UnwrappedIter __unwrapped_iter) {
476
- return _ReverseWrapper (
477
- _RevIter2<_Iter>(__unwrap_iter_impl<_Iter>::__rewrap (__orig_iter.base ().base (), __unwrapped_iter)));
478
- }
479
-
480
- static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _UnwrappedIter __unwrap (_ReverseWrapper __i) _NOEXCEPT {
481
- return __unwrap_iter_impl<_Iter>::__unwrap (__i.base ().base ());
482
- }
483
- };
484
-
485
319
#if _LIBCPP_STD_VER >= 20
486
320
template <ranges::bidirectional_range _Range>
487
321
_LIBCPP_HIDE_FROM_ABI constexpr ranges::subrange<reverse_iterator<ranges::iterator_t <_Range>>,
@@ -493,24 +327,20 @@ __reverse_range(_Range&& __range) {
493
327
#endif
494
328
495
329
template <class _Iter , bool __b>
496
- struct __unwrap_iter_impl <reverse_iterator<reverse_iterator<_Iter> >, __b>
497
- : __unwrap_reverse_iter_impl<reverse_iterator, reverse_iterator, _Iter> {};
498
-
499
- #if _LIBCPP_STD_VER >= 20
500
-
501
- template <class _Iter , bool __b>
502
- struct __unwrap_iter_impl <reverse_iterator<__unconstrained_reverse_iterator<_Iter>>, __b>
503
- : __unwrap_reverse_iter_impl<reverse_iterator, __unconstrained_reverse_iterator, _Iter> {};
504
-
505
- template <class _Iter , bool __b>
506
- struct __unwrap_iter_impl <__unconstrained_reverse_iterator<reverse_iterator<_Iter>>, __b>
507
- : __unwrap_reverse_iter_impl<__unconstrained_reverse_iterator, reverse_iterator, _Iter> {};
330
+ struct __unwrap_iter_impl <reverse_iterator<reverse_iterator<_Iter> >, __b> {
331
+ using _UnwrappedIter = decltype(__unwrap_iter_impl<_Iter>::__unwrap(std::declval<_Iter>()));
332
+ using _ReverseWrapper = reverse_iterator<reverse_iterator<_Iter> >;
508
333
509
- template <class _Iter , bool __b>
510
- struct __unwrap_iter_impl <__unconstrained_reverse_iterator<__unconstrained_reverse_iterator<_Iter>>, __b>
511
- : __unwrap_reverse_iter_impl<__unconstrained_reverse_iterator, __unconstrained_reverse_iterator, _Iter> {};
334
+ static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _ReverseWrapper
335
+ __rewrap (_ReverseWrapper __orig_iter, _UnwrappedIter __unwrapped_iter) {
336
+ return _ReverseWrapper (
337
+ reverse_iterator<_Iter>(__unwrap_iter_impl<_Iter>::__rewrap (__orig_iter.base ().base (), __unwrapped_iter)));
338
+ }
512
339
513
- #endif // _LIBCPP_STD_VER >= 20
340
+ static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _UnwrappedIter __unwrap (_ReverseWrapper __i) _NOEXCEPT {
341
+ return __unwrap_iter_impl<_Iter>::__unwrap (__i.base ().base ());
342
+ }
343
+ };
514
344
515
345
_LIBCPP_END_NAMESPACE_STD
516
346
0 commit comments