diff options
-rw-r--r-- | libcxx/include/__iterator/reverse_iterator.h | 4 | ||||
-rw-r--r-- | libcxx/test/std/iterators/predef.iterators/reverse.iterators/types.compile.pass.cpp | 1 | ||||
-rw-r--r-- | libcxx/test/support/test_iterators.h | 92 |
3 files changed, 93 insertions, 4 deletions
diff --git a/libcxx/include/__iterator/reverse_iterator.h b/libcxx/include/__iterator/reverse_iterator.h index 5c344c2ee310..abc8896c0adb 100644 --- a/libcxx/include/__iterator/reverse_iterator.h +++ b/libcxx/include/__iterator/reverse_iterator.h @@ -70,9 +70,7 @@ public: typename iterator_traits<_Iter>::iterator_category>; using pointer = typename iterator_traits<_Iter>::pointer; #if _LIBCPP_STD_VER > 17 - using iterator_concept = _If<__is_cpp17_random_access_iterator<_Iter>::value, - random_access_iterator_tag, - bidirectional_iterator_tag>; + using iterator_concept = _If<random_access_iterator<_Iter>, 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>; diff --git a/libcxx/test/std/iterators/predef.iterators/reverse.iterators/types.compile.pass.cpp b/libcxx/test/std/iterators/predef.iterators/reverse.iterators/types.compile.pass.cpp index f8c9ce72daa9..20c3a15e90df 100644 --- a/libcxx/test/std/iterators/predef.iterators/reverse.iterators/types.compile.pass.cpp +++ b/libcxx/test/std/iterators/predef.iterators/reverse.iterators/types.compile.pass.cpp @@ -116,6 +116,7 @@ void test_all() { test<contiguous_iterator<char*>>(); static_assert(std::is_same_v<typename std::reverse_iterator<bidirectional_iterator<char*>>::iterator_concept, std::bidirectional_iterator_tag>); static_assert(std::is_same_v<typename std::reverse_iterator<random_access_iterator<char*>>::iterator_concept, std::random_access_iterator_tag>); + static_assert(std::is_same_v<typename std::reverse_iterator<cpp20_random_access_iterator<char*>>::iterator_concept, std::random_access_iterator_tag>); static_assert(std::is_same_v<typename std::reverse_iterator<contiguous_iterator<char*>>::iterator_concept, std::random_access_iterator_tag>); static_assert(std::is_same_v<typename std::reverse_iterator<char*>::iterator_concept, std::random_access_iterator_tag>); #endif diff --git a/libcxx/test/support/test_iterators.h b/libcxx/test/support/test_iterators.h index a1eef1a2a10a..b98c35b1d0c6 100644 --- a/libcxx/test/support/test_iterators.h +++ b/libcxx/test/support/test_iterators.h @@ -223,6 +223,96 @@ public: }; #if TEST_STD_VER > 17 + +template <std::random_access_iterator It> +class cpp20_random_access_iterator { + It it_; + + template <std::random_access_iterator> + friend class cpp20_random_access_iterator; + +public: + using iterator_category = std::input_iterator_tag; + using iterator_concept = std::random_access_iterator_tag; + using value_type = typename std::iterator_traits<It>::value_type; + using difference_type = typename std::iterator_traits<It>::difference_type; + + constexpr cpp20_random_access_iterator() : it_() {} + constexpr explicit cpp20_random_access_iterator(It it) : it_(it) {} + + template <class U> + constexpr cpp20_random_access_iterator(const cpp20_random_access_iterator<U>& u) : it_(u.it_) {} + + template <class U> + constexpr cpp20_random_access_iterator(cpp20_random_access_iterator<U>&& u) : it_(u.it_) { + u.it_ = U(); + } + + constexpr decltype(auto) operator*() const { return *it_; } + constexpr decltype(auto) operator[](difference_type n) const { return it_[n]; } + + constexpr cpp20_random_access_iterator& operator++() { + ++it_; + return *this; + } + constexpr cpp20_random_access_iterator& operator--() { + --it_; + return *this; + } + constexpr cpp20_random_access_iterator operator++(int) { return cpp20_random_access_iterator(it_++); } + constexpr cpp20_random_access_iterator operator--(int) { return cpp20_random_access_iterator(it_--); } + + constexpr cpp20_random_access_iterator& operator+=(difference_type n) { + it_ += n; + return *this; + } + constexpr cpp20_random_access_iterator& operator-=(difference_type n) { + it_ -= n; + return *this; + } + friend constexpr cpp20_random_access_iterator operator+(cpp20_random_access_iterator x, difference_type n) { + x += n; + return x; + } + friend constexpr cpp20_random_access_iterator operator+(difference_type n, cpp20_random_access_iterator x) { + x += n; + return x; + } + friend constexpr cpp20_random_access_iterator operator-(cpp20_random_access_iterator x, difference_type n) { + x -= n; + return x; + } + friend constexpr difference_type operator-(cpp20_random_access_iterator x, cpp20_random_access_iterator y) { + return x.it_ - y.it_; + } + + friend constexpr bool operator==(const cpp20_random_access_iterator& x, const cpp20_random_access_iterator& y) { + return x.it_ == y.it_; + } + friend constexpr bool operator!=(const cpp20_random_access_iterator& x, const cpp20_random_access_iterator& y) { + return x.it_ != y.it_; + } + friend constexpr bool operator<(const cpp20_random_access_iterator& x, const cpp20_random_access_iterator& y) { + return x.it_ < y.it_; + } + friend constexpr bool operator<=(const cpp20_random_access_iterator& x, const cpp20_random_access_iterator& y) { + return x.it_ <= y.it_; + } + friend constexpr bool operator>(const cpp20_random_access_iterator& x, const cpp20_random_access_iterator& y) { + return x.it_ > y.it_; + } + friend constexpr bool operator>=(const cpp20_random_access_iterator& x, const cpp20_random_access_iterator& y) { + return x.it_ >= y.it_; + } + + friend constexpr It base(const cpp20_random_access_iterator& i) { return i.it_; } + + template <class T> + void operator,(T const&) = delete; +}; + +static_assert(std::random_access_iterator<cpp20_random_access_iterator<int*>>); + template <class It> class contiguous_iterator { @@ -857,7 +947,7 @@ class Iterator { // on plain swap instead of ranges::iter_swap. // This class is useful for testing that if algorithms support proxy iterator // properly, i.e. calling ranges::iter_swap and ranges::iter_move instead of -// plain swap and std::move +// plain swap and std::move. template <class T> struct Proxy; |