[libcxx-commits] [libcxx] 7912b1f - [libc++] Fix reverse_iterator::iterator_concept

Nikolas Klauser via libcxx-commits libcxx-commits at lists.llvm.org
Sat Jul 30 01:54:04 PDT 2022


Author: Nikolas Klauser
Date: 2022-07-30T10:53:59+02:00
New Revision: 7912b1f8e7c845a97411cbfc176db56861cdf116

URL: https://github.com/llvm/llvm-project/commit/7912b1f8e7c845a97411cbfc176db56861cdf116
DIFF: https://github.com/llvm/llvm-project/commit/7912b1f8e7c845a97411cbfc176db56861cdf116.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

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;
 


        


More information about the libcxx-commits mailing list