Skip to content

Commit 4ea850b

Browse files
authored
[libc++] Remove __unconstrained_reverse_iterator (llvm#85582)
`__unconstrained_reverse_iterator` has outlived its usefullness, since the standard and subsequently the compilers have been fixed.
1 parent bc70f60 commit 4ea850b

27 files changed

+14
-1396
lines changed

libcxx/include/__algorithm/inplace_merge.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,8 @@ _LIBCPP_HIDE_FROM_ABI void __buffered_inplace_merge(
114114
for (_BidirectionalIterator __i = __middle; __i != __last;
115115
__d.template __incr<value_type>(), (void)++__i, (void)++__p)
116116
::new ((void*)__p) value_type(_IterOps<_AlgPolicy>::__iter_move(__i));
117-
typedef __unconstrained_reverse_iterator<_BidirectionalIterator> _RBi;
118-
typedef __unconstrained_reverse_iterator<value_type*> _Rv;
117+
typedef reverse_iterator<_BidirectionalIterator> _RBi;
118+
typedef reverse_iterator<value_type*> _Rv;
119119
typedef __invert<_Compare> _Inverted;
120120
std::__half_inplace_merge<_AlgPolicy>(
121121
_Rv(__p), _Rv(__buff), _RBi(__middle), _RBi(__first), _RBi(__last), _Inverted(__comp));

libcxx/include/__iterator/reverse_iterator.h

+12-182
Original file line numberDiff line numberDiff line change
@@ -316,172 +316,6 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator<_Ite
316316
}
317317
#endif
318318

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-
485319
#if _LIBCPP_STD_VER >= 20
486320
template <ranges::bidirectional_range _Range>
487321
_LIBCPP_HIDE_FROM_ABI constexpr ranges::subrange<reverse_iterator<ranges::iterator_t<_Range>>,
@@ -493,24 +327,20 @@ __reverse_range(_Range&& __range) {
493327
#endif
494328

495329
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> >;
508333

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+
}
512339

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+
};
514344

515345
_LIBCPP_END_NAMESPACE_STD
516346

libcxx/test/libcxx/iterators/predef.iterators/__unconstrained_reverse_iterator/reverse.iter.cmp/equal.pass.cpp

-47
This file was deleted.

libcxx/test/libcxx/iterators/predef.iterators/__unconstrained_reverse_iterator/reverse.iter.cmp/greater-equal.pass.cpp

-47
This file was deleted.

libcxx/test/libcxx/iterators/predef.iterators/__unconstrained_reverse_iterator/reverse.iter.cmp/greater.pass.cpp

-47
This file was deleted.

0 commit comments

Comments
 (0)