Author: Nikolas Klauser Date: 2022-08-02T21:48:48-07:00 New Revision: 36fb543094a5a39e099eae96ab8b213cd8288f1a
URL: https://github.com/llvm/llvm-project/commit/36fb543094a5a39e099eae96ab8b213cd8288f1a DIFF: https://github.com/llvm/llvm-project/commit/36fb543094a5a39e099eae96ab8b213cd8288f1a.diff LOG: [libc++] Fix reverse_iterator::iterator_concept Fixes https://github.com/llvm/llvm-project/issues/56504 Reviewed By: ldionne, Mordante, huixie90, #libc Spies: libcxx-commits, hewillk Differential Revision: https://reviews.llvm.org/D129794 (cherry picked from commit 7912b1f8e7c845a97411cbfc176db56861cdf116) Added: Modified: libcxx/include/__iterator/reverse_iterator.h libcxx/test/std/iterators/predef.iterators/reverse.iterators/types.compile.pass.cpp libcxx/test/support/test_iterators.h Removed: ################################################################################ diff --git a/libcxx/include/__iterator/reverse_iterator.h b/libcxx/include/__iterator/reverse_iterator.h index 5c344c2ee3104..abc8896c0adb2 100644 --- a/libcxx/include/__iterator/reverse_iterator.h +++ b/libcxx/include/__iterator/reverse_iterator.h @@ -70,9 +70,7 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP 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 diff erence_type = iter_ diff erence_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 f8c9ce72daa9d..20c3a15e90df9 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 a1eef1a2a10ab..b98c35b1d0c6d 100644 --- a/libcxx/test/support/test_iterators.h +++ b/libcxx/test/support/test_iterators.h @@ -223,6 +223,96 @@ class random_access_iterator }; #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 diff erence_type = typename std::iterator_traits<It>:: diff erence_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[]( diff erence_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+=( diff erence_type n) { + it_ += n; + return *this; + } + constexpr cpp20_random_access_iterator& operator-=( diff erence_type n) { + it_ -= n; + return *this; + } + friend constexpr cpp20_random_access_iterator operator+(cpp20_random_access_iterator x, diff erence_type n) { + x += n; + return x; + } + friend constexpr cpp20_random_access_iterator operator+( diff erence_type n, cpp20_random_access_iterator x) { + x += n; + return x; + } + friend constexpr cpp20_random_access_iterator operator-(cpp20_random_access_iterator x, diff erence_type n) { + x -= n; + return x; + } + friend constexpr diff erence_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; _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits