aboutsummaryrefslogtreecommitdiff
path: root/libcxx/include/__iterator/reverse_iterator.h
diff options
context:
space:
mode:
Diffstat (limited to 'libcxx/include/__iterator/reverse_iterator.h')
-rw-r--r--libcxx/include/__iterator/reverse_iterator.h175
1 files changed, 155 insertions, 20 deletions
diff --git a/libcxx/include/__iterator/reverse_iterator.h b/libcxx/include/__iterator/reverse_iterator.h
index 449eb529aa98..89bda19effef 100644
--- a/libcxx/include/__iterator/reverse_iterator.h
+++ b/libcxx/include/__iterator/reverse_iterator.h
@@ -10,16 +10,25 @@
#ifndef _LIBCPP___ITERATOR_REVERSE_ITERATOR_H
#define _LIBCPP___ITERATOR_REVERSE_ITERATOR_H
+#include <__algorithm/unwrap_iter.h>
#include <__compare/compare_three_way_result.h>
#include <__compare/three_way_comparable.h>
+#include <__concepts/convertible_to.h>
#include <__config>
+#include <__iterator/concepts.h>
+#include <__iterator/incrementable_traits.h>
+#include <__iterator/iter_move.h>
+#include <__iterator/iter_swap.h>
#include <__iterator/iterator.h>
#include <__iterator/iterator_traits.h>
+#include <__iterator/prev.h>
+#include <__iterator/readable_traits.h>
#include <__memory/addressof.h>
+#include <__utility/move.h>
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
+# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -41,22 +50,31 @@ private:
_Iter __t; // no longer used as of LWG #2360, not removed due to ABI break
#endif
+#if _LIBCPP_STD_VER > 17
+ static_assert(__is_cpp17_bidirectional_iterator<_Iter>::value || bidirectional_iterator<_Iter>,
+ "reverse_iterator<It> requires It to be a bidirectional iterator.");
+#endif // _LIBCPP_STD_VER > 17
+
protected:
_Iter current;
public:
- typedef _Iter iterator_type;
- typedef typename iterator_traits<_Iter>::difference_type difference_type;
- typedef typename iterator_traits<_Iter>::reference reference;
- typedef typename iterator_traits<_Iter>::pointer pointer;
- typedef _If<__is_cpp17_random_access_iterator<_Iter>::value,
- random_access_iterator_tag,
- typename iterator_traits<_Iter>::iterator_category> iterator_category;
- typedef typename iterator_traits<_Iter>::value_type value_type;
+ using iterator_type = _Iter;
+ using iterator_category = _If<__is_cpp17_random_access_iterator<_Iter>::value,
+ random_access_iterator_tag,
+ typename iterator_traits<_Iter>::iterator_category>;
+ using pointer = typename iterator_traits<_Iter>::pointer;
#if _LIBCPP_STD_VER > 17
- typedef _If<__is_cpp17_random_access_iterator<_Iter>::value,
- random_access_iterator_tag,
- bidirectional_iterator_tag> iterator_concept;
+ using iterator_concept = _If<__is_cpp17_random_access_iterator<_Iter>::value,
+ random_access_iterator_tag,
+ bidirectional_iterator_tag>;
+ using value_type = iter_value_t<_Iter>;
+ using difference_type = iter_difference_t<_Iter>;
+ using reference = iter_reference_t<_Iter>;
+#else
+ using value_type = typename iterator_traits<_Iter>::value_type;
+ using difference_type = typename iterator_traits<_Iter>::difference_type;
+ using reference = typename iterator_traits<_Iter>::reference;
#endif
#ifndef _LIBCPP_ABI_NO_ITERATOR_BASES
@@ -114,32 +132,75 @@ public:
_Iter base() const {return current;}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
reference operator*() const {_Iter __tmp = current; return *--__tmp;}
+
+#if _LIBCPP_STD_VER > 17
+ _LIBCPP_INLINE_VISIBILITY
+ constexpr pointer operator->() const
+ requires is_pointer_v<_Iter> || requires(const _Iter i) { i.operator->(); }
+ {
+ if constexpr (is_pointer_v<_Iter>) {
+ return std::prev(current);
+ } else {
+ return std::prev(current).operator->();
+ }
+ }
+#else
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
- pointer operator->() const {return _VSTD::addressof(operator*());}
+ pointer operator->() const {
+ return std::addressof(operator*());
+ }
+#endif // _LIBCPP_STD_VER > 17
+
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
reverse_iterator& operator++() {--current; return *this;}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
- reverse_iterator operator++(int) {reverse_iterator __tmp(*this); --current; return __tmp;}
+ reverse_iterator operator++(int) {reverse_iterator __tmp(*this); --current; return __tmp;}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
reverse_iterator& operator--() {++current; return *this;}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
- reverse_iterator operator--(int) {reverse_iterator __tmp(*this); ++current; return __tmp;}
+ reverse_iterator operator--(int) {reverse_iterator __tmp(*this); ++current; return __tmp;}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
- reverse_iterator operator+ (difference_type __n) const {return reverse_iterator(current - __n);}
+ reverse_iterator operator+(difference_type __n) const {return reverse_iterator(current - __n);}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
reverse_iterator& operator+=(difference_type __n) {current -= __n; return *this;}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
- reverse_iterator operator- (difference_type __n) const {return reverse_iterator(current + __n);}
+ reverse_iterator operator-(difference_type __n) const {return reverse_iterator(current + __n);}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
reverse_iterator& operator-=(difference_type __n) {current += __n; return *this;}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
- reference operator[](difference_type __n) const {return *(*this + __n);}
+ reference operator[](difference_type __n) const {return *(*this + __n);}
+
+#if _LIBCPP_STD_VER > 17
+ _LIBCPP_HIDE_FROM_ABI friend constexpr
+ iter_rvalue_reference_t<_Iter> iter_move(const reverse_iterator& __i)
+ noexcept(is_nothrow_copy_constructible_v<_Iter> &&
+ noexcept(ranges::iter_move(--declval<_Iter&>()))) {
+ auto __tmp = __i.base();
+ return ranges::iter_move(--__tmp);
+ }
+
+ template <indirectly_swappable<_Iter> _Iter2>
+ _LIBCPP_HIDE_FROM_ABI friend constexpr
+ void iter_swap(const reverse_iterator& __x, const reverse_iterator<_Iter2>& __y)
+ noexcept(is_nothrow_copy_constructible_v<_Iter> &&
+ is_nothrow_copy_constructible_v<_Iter2> &&
+ noexcept(ranges::iter_swap(--declval<_Iter&>(), --declval<_Iter2&>()))) {
+ auto __xtmp = __x.base();
+ auto __ytmp = __y.base();
+ ranges::iter_swap(--__xtmp, --__ytmp);
+ }
+#endif // _LIBCPP_STD_VER > 17
};
template <class _Iter1, class _Iter2>
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
bool
operator==(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
+#if _LIBCPP_STD_VER > 17
+ requires requires {
+ { __x.base() == __y.base() } -> convertible_to<bool>;
+ }
+#endif // _LIBCPP_STD_VER > 17
{
return __x.base() == __y.base();
}
@@ -148,6 +209,11 @@ template <class _Iter1, class _Iter2>
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
bool
operator<(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
+#if _LIBCPP_STD_VER > 17
+ requires requires {
+ { __x.base() > __y.base() } -> convertible_to<bool>;
+ }
+#endif // _LIBCPP_STD_VER > 17
{
return __x.base() > __y.base();
}
@@ -156,6 +222,11 @@ template <class _Iter1, class _Iter2>
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
bool
operator!=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
+#if _LIBCPP_STD_VER > 17
+ requires requires {
+ { __x.base() != __y.base() } -> convertible_to<bool>;
+ }
+#endif // _LIBCPP_STD_VER > 17
{
return __x.base() != __y.base();
}
@@ -164,6 +235,11 @@ template <class _Iter1, class _Iter2>
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
bool
operator>(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
+#if _LIBCPP_STD_VER > 17
+ requires requires {
+ { __x.base() < __y.base() } -> convertible_to<bool>;
+ }
+#endif // _LIBCPP_STD_VER > 17
{
return __x.base() < __y.base();
}
@@ -172,6 +248,11 @@ template <class _Iter1, class _Iter2>
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
bool
operator>=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
+#if _LIBCPP_STD_VER > 17
+ requires requires {
+ { __x.base() <= __y.base() } -> convertible_to<bool>;
+ }
+#endif // _LIBCPP_STD_VER > 17
{
return __x.base() <= __y.base();
}
@@ -180,11 +261,16 @@ template <class _Iter1, class _Iter2>
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
bool
operator<=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
+#if _LIBCPP_STD_VER > 17
+ requires requires {
+ { __x.base() >= __y.base() } -> convertible_to<bool>;
+ }
+#endif // _LIBCPP_STD_VER > 17
{
return __x.base() >= __y.base();
}
-#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17
template <class _Iter1, three_way_comparable_with<_Iter1> _Iter2>
_LIBCPP_HIDE_FROM_ABI constexpr
compare_three_way_result_t<_Iter1, _Iter2>
@@ -192,7 +278,7 @@ operator<=>(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>&
{
return __y.base() <=> __x.base();
}
-#endif
+#endif // _LIBCPP_STD_VER > 17
#ifndef _LIBCPP_CXX03_LANG
template <class _Iter1, class _Iter2>
@@ -221,6 +307,12 @@ operator+(typename reverse_iterator<_Iter>::difference_type __n, const reverse_i
return reverse_iterator<_Iter>(__x.base() - __n);
}
+#if _LIBCPP_STD_VER > 17
+template <class _Iter1, class _Iter2>
+ requires (!sized_sentinel_for<_Iter1, _Iter2>)
+inline constexpr bool disable_sized_sentinel_for<reverse_iterator<_Iter1>, reverse_iterator<_Iter2>> = true;
+#endif // _LIBCPP_STD_VER > 17
+
#if _LIBCPP_STD_VER > 11
template <class _Iter>
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
@@ -230,6 +322,49 @@ reverse_iterator<_Iter> make_reverse_iterator(_Iter __i)
}
#endif
+template <class _Iter>
+using _ReverseWrapper = reverse_iterator<reverse_iterator<_Iter> >;
+
+template <class _Iter, bool __b>
+struct __unwrap_iter_impl<_ReverseWrapper<_Iter>, __b> {
+ static _LIBCPP_CONSTEXPR decltype(std::__unwrap_iter(std::declval<_Iter>()))
+ __apply(_ReverseWrapper<_Iter> __i) _NOEXCEPT {
+ return std::__unwrap_iter(__i.base().base());
+ }
+};
+
+template <class _OrigIter, class _UnwrappedIter>
+struct __rewrap_iter_impl<_ReverseWrapper<_OrigIter>, _UnwrappedIter> {
+ template <class _Iter>
+ struct _ReverseWrapperCount {
+ static _LIBCPP_CONSTEXPR const size_t value = 1;
+ };
+
+ template <class _Iter>
+ struct _ReverseWrapperCount<_ReverseWrapper<_Iter> > {
+ static _LIBCPP_CONSTEXPR const size_t value = 1 + _ReverseWrapperCount<_Iter>::value;
+ };
+
+ template <size_t _RewrapCount, class _OIter, class _UIter, __enable_if_t<_RewrapCount != 0, int> = 0>
+ _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR _ReverseWrapper<_OIter> __rewrap(_ReverseWrapper<_OIter> __iter1,
+ _UIter __iter2) {
+ return _ReverseWrapper<_OIter>(
+ reverse_iterator<_OIter>(__rewrap<_RewrapCount - 1>(__iter1.base().base(), __iter2)));
+ }
+
+ template <size_t _RewrapCount, class _OIter, class _UIter, __enable_if_t<_RewrapCount == 0, int> = 0>
+ _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR decltype(std::__rewrap_iter(std::declval<_OIter>(),
+ std::declval<_UIter>()))
+ __rewrap(_OIter __iter1, _UIter __iter2) {
+ return std::__rewrap_iter(__iter1, __iter2);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR _ReverseWrapper<_OrigIter> __apply(_ReverseWrapper<_OrigIter> __iter1,
+ _UnwrappedIter __iter2) {
+ return __rewrap<_ReverseWrapperCount<_OrigIter>::value>(__iter1, __iter2);
+ }
+};
+
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP___ITERATOR_REVERSE_ITERATOR_H