[libcxx-commits] [libcxx] [libcxx][test] Do not assume array::iterator is a pointer (PR #100603)

nicole mazzuca via libcxx-commits libcxx-commits at lists.llvm.org
Mon Jul 29 13:20:34 PDT 2024


https://github.com/strega-nil updated https://github.com/llvm/llvm-project/pull/100603

>From d08c22c154f65b9328c89eb09215dba2b86eeba0 Mon Sep 17 00:00:00 2001
From: Nicole Mazzuca <nicole at strega-nil.co>
Date: Thu, 25 Jul 2024 19:19:41 +0200
Subject: [PATCH 1/6] [libcxx] Do not assume array::iterator is a pointer

In the tests I added for `ranges::find_last{_if{_not}}`, I accidentally introduced an assumption
that `same_as<array<T, 0>::iterator, T*>`; this is a faulty assumption on MSVC-STL.
---
 .../alg.nonmodifying/alg.find.last/ranges.find_last.pass.cpp   | 3 ++-
 .../alg.find.last/ranges.find_last_if.pass.cpp                 | 3 ++-
 .../alg.find.last/ranges.find_last_if_not.pass.cpp             | 3 ++-
 3 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/libcxx/test/std/algorithms/alg.nonmodifying/alg.find.last/ranges.find_last.pass.cpp b/libcxx/test/std/algorithms/alg.nonmodifying/alg.find.last/ranges.find_last.pass.cpp
index 2a2b12fb2c288..036631b19f48a 100644
--- a/libcxx/test/std/algorithms/alg.nonmodifying/alg.find.last/ranges.find_last.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.nonmodifying/alg.find.last/ranges.find_last.pass.cpp
@@ -61,7 +61,8 @@ template <class It, class Sent = It>
 constexpr void test_iterators() {
   using ValueT    = std::iter_value_t<It>;
   auto make_range = [](auto& a) {
-    return std::ranges::subrange(It(std::ranges::begin(a)), Sent(It(std::ranges::end(a))));
+    return std::ranges::subrange(
+        It(std::to_address(std::ranges::begin(a))), Sent(It(std::to_address(std::ranges::end(a)))));
   };
   { // simple test
     {
diff --git a/libcxx/test/std/algorithms/alg.nonmodifying/alg.find.last/ranges.find_last_if.pass.cpp b/libcxx/test/std/algorithms/alg.nonmodifying/alg.find.last/ranges.find_last_if.pass.cpp
index a15f81bd4e481..427ef3539947f 100644
--- a/libcxx/test/std/algorithms/alg.nonmodifying/alg.find.last/ranges.find_last_if.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.nonmodifying/alg.find.last/ranges.find_last_if.pass.cpp
@@ -59,7 +59,8 @@ static_assert(!HasFindLastIfR<ForwardRangeNotSentinelEqualityComparableWith>);
 
 template <class It, class Sent>
 constexpr auto make_range(auto& a) {
-  return std::ranges::subrange(It(std::ranges::begin(a)), Sent(It(std::ranges::end(a))));
+  return std::ranges::subrange(
+      It(std::to_address(std::ranges::begin(a))), Sent(It(std::to_address(std::ranges::end(a)))));
 }
 
 template <template <class> class IteratorT, template <class> class SentinelT>
diff --git a/libcxx/test/std/algorithms/alg.nonmodifying/alg.find.last/ranges.find_last_if_not.pass.cpp b/libcxx/test/std/algorithms/alg.nonmodifying/alg.find.last/ranges.find_last_if_not.pass.cpp
index bb0e411acf0fa..f8357f9eecb93 100644
--- a/libcxx/test/std/algorithms/alg.nonmodifying/alg.find.last/ranges.find_last_if_not.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.nonmodifying/alg.find.last/ranges.find_last_if_not.pass.cpp
@@ -59,7 +59,8 @@ static_assert(!HasFindLastIfR<ForwardRangeNotSentinelEqualityComparableWith>);
 
 template <class It, class Sent>
 constexpr auto make_range(auto& a) {
-  return std::ranges::subrange(It(std::ranges::begin(a)), Sent(It(std::ranges::end(a))));
+  return std::ranges::subrange(
+      It(std::to_address(std::ranges::begin(a))), Sent(It(std::to_address(std::ranges::end(a)))));
 }
 
 template <template <class> class IteratorT, template <class> class SentinelT>

>From 04a67b5617d11a94627c5ee89f24e2fff9ce8eda Mon Sep 17 00:00:00 2001
From: Nicole Mazzuca <nicole at strega-nil.co>
Date: Thu, 25 Jul 2024 19:50:03 +0200
Subject: [PATCH 2/6] make sure to include <memory>

---
 .../alg.nonmodifying/alg.find.last/ranges.find_last.pass.cpp   | 3 ++-
 .../alg.find.last/ranges.find_last_if.pass.cpp                 | 1 +
 .../alg.find.last/ranges.find_last_if_not.pass.cpp             | 3 ++-
 3 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/libcxx/test/std/algorithms/alg.nonmodifying/alg.find.last/ranges.find_last.pass.cpp b/libcxx/test/std/algorithms/alg.nonmodifying/alg.find.last/ranges.find_last.pass.cpp
index 036631b19f48a..9da8c26db0f56 100644
--- a/libcxx/test/std/algorithms/alg.nonmodifying/alg.find.last/ranges.find_last.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.nonmodifying/alg.find.last/ranges.find_last.pass.cpp
@@ -25,6 +25,7 @@
 #include <algorithm>
 #include <array>
 #include <cassert>
+#include <memory>
 #include <ranges>
 #include <vector>
 
@@ -92,7 +93,7 @@ constexpr void test_iterators() {
       std::array<ValueT, 0> a = {};
 
       auto ret = std::ranges::find_last(make_range(a), 1).begin();
-      assert(ret == It(a.begin()));
+      assert(ret == It(a.data()));
     }
   }
 
diff --git a/libcxx/test/std/algorithms/alg.nonmodifying/alg.find.last/ranges.find_last_if.pass.cpp b/libcxx/test/std/algorithms/alg.nonmodifying/alg.find.last/ranges.find_last_if.pass.cpp
index 427ef3539947f..dc700c26ef2d9 100644
--- a/libcxx/test/std/algorithms/alg.nonmodifying/alg.find.last/ranges.find_last_if.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.nonmodifying/alg.find.last/ranges.find_last_if.pass.cpp
@@ -20,6 +20,7 @@
 #include <algorithm>
 #include <array>
 #include <cassert>
+#include <memory>
 #include <ranges>
 
 #include "almost_satisfies_types.h"
diff --git a/libcxx/test/std/algorithms/alg.nonmodifying/alg.find.last/ranges.find_last_if_not.pass.cpp b/libcxx/test/std/algorithms/alg.nonmodifying/alg.find.last/ranges.find_last_if_not.pass.cpp
index f8357f9eecb93..f2cd8f9759334 100644
--- a/libcxx/test/std/algorithms/alg.nonmodifying/alg.find.last/ranges.find_last_if_not.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.nonmodifying/alg.find.last/ranges.find_last_if_not.pass.cpp
@@ -20,6 +20,7 @@
 #include <algorithm>
 #include <array>
 #include <cassert>
+#include <memory>
 #include <ranges>
 
 #include "almost_satisfies_types.h"
@@ -100,7 +101,7 @@ constexpr void test_iterator_classes() {
       std::array<int, 0> a = {};
 
       auto ret = std::ranges::find_last_if_not(make_range<it, sent>(a), [](auto&&) { return false; }).begin();
-      assert(ret == it(a.begin()));
+      assert(ret == it(a.data()));
     }
   }
 

>From 92fda3690c8de225de53a6a275457f52949d9c38 Mon Sep 17 00:00:00 2001
From: Nicole Mazzuca <nicole at strega-nil.co>
Date: Fri, 26 Jul 2024 11:30:20 +0200
Subject: [PATCH 3/6] fix array<T, 0>::iterator under ABI_USE_WRAP_ITER

additionally, actually fix the rest of the tests now that I can actually
test them.
---
 libcxx/include/array                          |  29 ++---
 .../ranges.find_last_if.pass.cpp              |  21 ++--
 .../ranges.find_last_if_not.pass.cpp          |  21 ++--
 libcxx/test/support/test_iterators.h          | 100 ++++++++++++------
 4 files changed, 111 insertions(+), 60 deletions(-)

diff --git a/libcxx/include/array b/libcxx/include/array
index 6ffde852f4802..d691db008eed2 100644
--- a/libcxx/include/array
+++ b/libcxx/include/array
@@ -270,18 +270,23 @@ struct _LIBCPP_TEMPLATE_VIS array {
 template <class _Tp>
 struct _LIBCPP_TEMPLATE_VIS array<_Tp, 0> {
   // types:
-  typedef array __self;
-  typedef _Tp value_type;
-  typedef value_type& reference;
-  typedef const value_type& const_reference;
-  typedef value_type* iterator;
-  typedef const value_type* const_iterator;
-  typedef value_type* pointer;
-  typedef const value_type* const_pointer;
-  typedef size_t size_type;
-  typedef ptrdiff_t difference_type;
-  typedef std::reverse_iterator<iterator> reverse_iterator;
-  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+  using __self          = array;
+  using value_type      = _Tp;
+  using reference       = value_type&;
+  using const_reference = const value_type&;
+  using pointer         = value_type*;
+  using const_pointer   = const value_type*;
+#if defined(_LIBCPP_ABI_USE_WRAP_ITER_IN_STD_ARRAY)
+  using iterator       = __wrap_iter<pointer>;
+  using const_iterator = __wrap_iter<const_pointer>;
+#else
+  using iterator       = pointer;
+  using const_iterator = const_pointer;
+#endif
+  using size_type              = size_t;
+  using difference_type        = ptrdiff_t;
+  using reverse_iterator       = std::reverse_iterator<iterator>;
+  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
 
   typedef __conditional_t<is_const<_Tp>::value, const __empty, __empty> _EmptyType;
 
diff --git a/libcxx/test/std/algorithms/alg.nonmodifying/alg.find.last/ranges.find_last_if.pass.cpp b/libcxx/test/std/algorithms/alg.nonmodifying/alg.find.last/ranges.find_last_if.pass.cpp
index dc700c26ef2d9..e21abae29c778 100644
--- a/libcxx/test/std/algorithms/alg.nonmodifying/alg.find.last/ranges.find_last_if.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.nonmodifying/alg.find.last/ranges.find_last_if.pass.cpp
@@ -20,7 +20,6 @@
 #include <algorithm>
 #include <array>
 #include <cassert>
-#include <memory>
 #include <ranges>
 
 #include "almost_satisfies_types.h"
@@ -60,8 +59,7 @@ static_assert(!HasFindLastIfR<ForwardRangeNotSentinelEqualityComparableWith>);
 
 template <class It, class Sent>
 constexpr auto make_range(auto& a) {
-  return std::ranges::subrange(
-      It(std::to_address(std::ranges::begin(a))), Sent(It(std::to_address(std::ranges::end(a)))));
+  return std::ranges::subrange(It(std::ranges::begin(a)), Sent(It(std::ranges::end(a))));
 }
 
 template <template <class> class IteratorT, template <class> class SentinelT>
@@ -94,14 +92,14 @@ constexpr void test_iterator_classes() {
     {
       std::array<int, 0> a = {};
 
-      auto ret = std::ranges::find_last_if(it(a.data()), sent(it(a.data())), [](auto&&) { return true; }).begin();
-      assert(ret == it(a.data()));
+      auto ret = std::ranges::find_last_if(it(a.begin()), sent(it(a.end())), [](auto&&) { return true; }).begin();
+      assert(ret == it(a.end()));
     }
     {
       std::array<int, 0> a = {};
 
       auto ret = std::ranges::find_last_if(make_range<it, sent>(a), [](auto&&) { return true; }).begin();
-      assert(ret == it(a.begin()));
+      assert(ret == it(a.end()));
     }
   }
 
@@ -185,8 +183,17 @@ struct NonConstComparable {
   friend constexpr bool operator==(NonConstComparable&, const NonConstComparable&) { return true; }
 };
 
+// note: this should really use `std::const_iterator`
 template <class T>
-using add_const_to_ptr_t = std::add_pointer_t<std::add_const_t<std::remove_pointer_t<T>>>;
+struct add_const_to_ptr {
+  using type = T;
+};
+template <class T>
+struct add_const_to_ptr<T*> {
+  using type = const T*;
+};
+template <class T>
+using add_const_to_ptr_t = typename add_const_to_ptr<T>::type;
 
 constexpr bool test() {
   test_iterator_classes<std::type_identity_t, std::type_identity_t>();
diff --git a/libcxx/test/std/algorithms/alg.nonmodifying/alg.find.last/ranges.find_last_if_not.pass.cpp b/libcxx/test/std/algorithms/alg.nonmodifying/alg.find.last/ranges.find_last_if_not.pass.cpp
index f2cd8f9759334..677c5ac8229eb 100644
--- a/libcxx/test/std/algorithms/alg.nonmodifying/alg.find.last/ranges.find_last_if_not.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.nonmodifying/alg.find.last/ranges.find_last_if_not.pass.cpp
@@ -20,7 +20,6 @@
 #include <algorithm>
 #include <array>
 #include <cassert>
-#include <memory>
 #include <ranges>
 
 #include "almost_satisfies_types.h"
@@ -60,8 +59,7 @@ static_assert(!HasFindLastIfR<ForwardRangeNotSentinelEqualityComparableWith>);
 
 template <class It, class Sent>
 constexpr auto make_range(auto& a) {
-  return std::ranges::subrange(
-      It(std::to_address(std::ranges::begin(a))), Sent(It(std::to_address(std::ranges::end(a)))));
+  return std::ranges::subrange(It(std::ranges::begin(a)), Sent(It(std::ranges::end(a))));
 }
 
 template <template <class> class IteratorT, template <class> class SentinelT>
@@ -94,14 +92,14 @@ constexpr void test_iterator_classes() {
     {
       std::array<int, 0> a = {};
 
-      auto ret = std::ranges::find_last_if_not(it(a.data()), sent(it(a.data())), [](auto&&) { return false; }).begin();
-      assert(ret == it(a.data()));
+      auto ret = std::ranges::find_last_if_not(it(a.begin()), sent(it(a.end())), [](auto&&) { return false; }).begin();
+      assert(ret == it(a.end()));
     }
     {
       std::array<int, 0> a = {};
 
       auto ret = std::ranges::find_last_if_not(make_range<it, sent>(a), [](auto&&) { return false; }).begin();
-      assert(ret == it(a.data()));
+      assert(ret == it(a.end()));
     }
   }
 
@@ -185,8 +183,17 @@ struct NonConstComparable {
   friend constexpr bool operator!=(NonConstComparable&, const NonConstComparable&) { return false; }
 };
 
+// note: this should really use `std::const_iterator`
 template <class T>
-using add_const_to_ptr_t = std::add_pointer_t<std::add_const_t<std::remove_pointer_t<T>>>;
+struct add_const_to_ptr {
+  using type = T;
+};
+template <class T>
+struct add_const_to_ptr<T*> {
+  using type = const T*;
+};
+template <class T>
+using add_const_to_ptr_t = typename add_const_to_ptr<T>::type;
 
 constexpr bool test() {
   test_iterator_classes<std::type_identity_t, std::type_identity_t>();
diff --git a/libcxx/test/support/test_iterators.h b/libcxx/test/support/test_iterators.h
index 95d1b7df0007c..86b700c7ae4a1 100644
--- a/libcxx/test/support/test_iterators.h
+++ b/libcxx/test/support/test_iterators.h
@@ -339,59 +339,91 @@ cpp20_random_access_iterator(It) -> cpp20_random_access_iterator<It>;
 
 static_assert(std::random_access_iterator<cpp20_random_access_iterator<int*>>);
 
-template <class It>
-class contiguous_iterator
-{
-    static_assert(std::is_pointer_v<It>, "Things probably break in this case");
+template <std::contiguous_iterator It>
+class contiguous_iterator {
+  It it_;
 
-    It it_;
+  template <std::contiguous_iterator U>
+  friend class contiguous_iterator;
 
-    template <class U> friend class contiguous_iterator;
 public:
     typedef          std::contiguous_iterator_tag              iterator_category;
     typedef typename std::iterator_traits<It>::value_type      value_type;
     typedef typename std::iterator_traits<It>::difference_type difference_type;
     typedef It                                                 pointer;
     typedef typename std::iterator_traits<It>::reference       reference;
-    typedef typename std::remove_pointer<It>::type             element_type;
+    typedef value_type element_type;
 
-    TEST_CONSTEXPR_CXX14 It base() const {return it_;}
+    constexpr It base() const { return it_; }
 
-    TEST_CONSTEXPR_CXX14 contiguous_iterator() : it_() {}
-    TEST_CONSTEXPR_CXX14 explicit contiguous_iterator(It it) : it_(it) {}
+    constexpr contiguous_iterator() : it_() {}
+    constexpr explicit contiguous_iterator(It it) : it_(it) {}
 
     template <class U>
-    TEST_CONSTEXPR_CXX14 contiguous_iterator(const contiguous_iterator<U>& u) : it_(u.it_) {}
+    constexpr contiguous_iterator(const contiguous_iterator<U>& u) : it_(u.it_) {}
 
     template <class U, class = typename std::enable_if<std::is_default_constructible<U>::value>::type>
     constexpr contiguous_iterator(contiguous_iterator<U>&& u) : it_(u.it_) { u.it_ = U(); }
 
-    TEST_CONSTEXPR reference operator*() const {return *it_;}
-    TEST_CONSTEXPR pointer operator->() const {return it_;}
-    TEST_CONSTEXPR reference operator[](difference_type n) const {return it_[n];}
-
-    TEST_CONSTEXPR_CXX14 contiguous_iterator& operator++() {++it_; return *this;}
-    TEST_CONSTEXPR_CXX14 contiguous_iterator& operator--() {--it_; return *this;}
-    TEST_CONSTEXPR_CXX14 contiguous_iterator operator++(int) {return contiguous_iterator(it_++);}
-    TEST_CONSTEXPR_CXX14 contiguous_iterator operator--(int) {return contiguous_iterator(it_--);}
-
-    TEST_CONSTEXPR_CXX14 contiguous_iterator& operator+=(difference_type n) {it_ += n; return *this;}
-    TEST_CONSTEXPR_CXX14 contiguous_iterator& operator-=(difference_type n) {it_ -= n; return *this;}
-    friend TEST_CONSTEXPR_CXX14 contiguous_iterator operator+(contiguous_iterator x, difference_type n) {x += n; return x;}
-    friend TEST_CONSTEXPR_CXX14 contiguous_iterator operator+(difference_type n, contiguous_iterator x) {x += n; return x;}
-    friend TEST_CONSTEXPR_CXX14 contiguous_iterator operator-(contiguous_iterator x, difference_type n) {x -= n; return x;}
-    friend TEST_CONSTEXPR difference_type operator-(contiguous_iterator x, contiguous_iterator y) {return x.it_ - y.it_;}
-
-    friend TEST_CONSTEXPR bool operator==(const contiguous_iterator& x, const contiguous_iterator& y) {return x.it_ == y.it_;}
-    friend TEST_CONSTEXPR bool operator!=(const contiguous_iterator& x, const contiguous_iterator& y) {return x.it_ != y.it_;}
-    friend TEST_CONSTEXPR bool operator< (const contiguous_iterator& x, const contiguous_iterator& y) {return x.it_ <  y.it_;}
-    friend TEST_CONSTEXPR bool operator<=(const contiguous_iterator& x, const contiguous_iterator& y) {return x.it_ <= y.it_;}
-    friend TEST_CONSTEXPR bool operator> (const contiguous_iterator& x, const contiguous_iterator& y) {return x.it_ >  y.it_;}
-    friend TEST_CONSTEXPR bool operator>=(const contiguous_iterator& x, const contiguous_iterator& y) {return x.it_ >= y.it_;}
+    constexpr reference operator*() const { return *it_; }
+    constexpr pointer operator->() const { return it_; }
+    constexpr reference operator[](difference_type n) const { return it_[n]; }
+
+    constexpr contiguous_iterator& operator++() {
+      ++it_;
+      return *this;
+    }
+    constexpr contiguous_iterator& operator--() {
+      --it_;
+      return *this;
+    }
+    constexpr contiguous_iterator operator++(int) { return contiguous_iterator(it_++); }
+    constexpr contiguous_iterator operator--(int) { return contiguous_iterator(it_--); }
+
+    constexpr contiguous_iterator& operator+=(difference_type n) {
+      it_ += n;
+      return *this;
+    }
+    constexpr contiguous_iterator& operator-=(difference_type n) {
+      it_ -= n;
+      return *this;
+    }
+    friend constexpr contiguous_iterator operator+(contiguous_iterator x, difference_type n) {
+      x += n;
+      return x;
+    }
+    friend constexpr contiguous_iterator operator+(difference_type n, contiguous_iterator x) {
+      x += n;
+      return x;
+    }
+    friend constexpr contiguous_iterator operator-(contiguous_iterator x, difference_type n) {
+      x -= n;
+      return x;
+    }
+    friend constexpr difference_type operator-(contiguous_iterator x, contiguous_iterator y) { return x.it_ - y.it_; }
+
+    friend constexpr bool operator==(const contiguous_iterator& x, const contiguous_iterator& y) {
+      return x.it_ == y.it_;
+    }
+    friend constexpr bool operator!=(const contiguous_iterator& x, const contiguous_iterator& y) {
+      return x.it_ != y.it_;
+    }
+    friend constexpr bool operator<(const contiguous_iterator& x, const contiguous_iterator& y) {
+      return x.it_ < y.it_;
+    }
+    friend constexpr bool operator<=(const contiguous_iterator& x, const contiguous_iterator& y) {
+      return x.it_ <= y.it_;
+    }
+    friend constexpr bool operator>(const contiguous_iterator& x, const contiguous_iterator& y) {
+      return x.it_ > y.it_;
+    }
+    friend constexpr bool operator>=(const contiguous_iterator& x, const contiguous_iterator& y) {
+      return x.it_ >= y.it_;
+    }
 
     // Note no operator<=>, use three_way_contiguous_iterator for testing operator<=>
 
-    friend TEST_CONSTEXPR It base(const contiguous_iterator& i) { return i.it_; }
+    friend constexpr It base(const contiguous_iterator& i) { return i.it_; }
 
     template <class T>
     void operator,(T const &) = delete;

>From 135531ede0b55817ab1de772b48595ee16cd1217 Mon Sep 17 00:00:00 2001
From: Nicole Mazzuca <nicole at strega-nil.co>
Date: Sat, 27 Jul 2024 21:09:52 +0200
Subject: [PATCH 4/6] CRs - remove array changes

---
 libcxx/include/array                 | 29 ++++++++++++----------------
 libcxx/test/support/test_iterators.h | 28 ++++++++++++++-------------
 2 files changed, 27 insertions(+), 30 deletions(-)

diff --git a/libcxx/include/array b/libcxx/include/array
index d691db008eed2..6ffde852f4802 100644
--- a/libcxx/include/array
+++ b/libcxx/include/array
@@ -270,23 +270,18 @@ struct _LIBCPP_TEMPLATE_VIS array {
 template <class _Tp>
 struct _LIBCPP_TEMPLATE_VIS array<_Tp, 0> {
   // types:
-  using __self          = array;
-  using value_type      = _Tp;
-  using reference       = value_type&;
-  using const_reference = const value_type&;
-  using pointer         = value_type*;
-  using const_pointer   = const value_type*;
-#if defined(_LIBCPP_ABI_USE_WRAP_ITER_IN_STD_ARRAY)
-  using iterator       = __wrap_iter<pointer>;
-  using const_iterator = __wrap_iter<const_pointer>;
-#else
-  using iterator       = pointer;
-  using const_iterator = const_pointer;
-#endif
-  using size_type              = size_t;
-  using difference_type        = ptrdiff_t;
-  using reverse_iterator       = std::reverse_iterator<iterator>;
-  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
+  typedef array __self;
+  typedef _Tp value_type;
+  typedef value_type& reference;
+  typedef const value_type& const_reference;
+  typedef value_type* iterator;
+  typedef const value_type* const_iterator;
+  typedef value_type* pointer;
+  typedef const value_type* const_pointer;
+  typedef size_t size_type;
+  typedef ptrdiff_t difference_type;
+  typedef std::reverse_iterator<iterator> reverse_iterator;
+  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
 
   typedef __conditional_t<is_const<_Tp>::value, const __empty, __empty> _EmptyType;
 
diff --git a/libcxx/test/support/test_iterators.h b/libcxx/test/support/test_iterators.h
index 86b700c7ae4a1..abf0c76514acb 100644
--- a/libcxx/test/support/test_iterators.h
+++ b/libcxx/test/support/test_iterators.h
@@ -347,23 +347,25 @@ class contiguous_iterator {
   friend class contiguous_iterator;
 
 public:
-    typedef          std::contiguous_iterator_tag              iterator_category;
-    typedef typename std::iterator_traits<It>::value_type      value_type;
-    typedef typename std::iterator_traits<It>::difference_type difference_type;
-    typedef It                                                 pointer;
-    typedef typename std::iterator_traits<It>::reference       reference;
-    typedef value_type element_type;
+  using iterator_category = std::contiguous_iterator_tag;
+  using value_type        = typename std::iterator_traits<It>::value_type;
+  using difference_type   = typename std::iterator_traits<It>::difference_type;
+  using pointer           = typename std::iterator_traits<It>::pointer;
+  using reference         = typename std::iterator_traits<It>::reference;
+  using element_type      = value_type;
 
-    constexpr It base() const { return it_; }
+  constexpr It base() const { return it_; }
 
-    constexpr contiguous_iterator() : it_() {}
-    constexpr explicit contiguous_iterator(It it) : it_(it) {}
+  constexpr contiguous_iterator() : it_() {}
+  constexpr explicit contiguous_iterator(It it) : it_(it) {}
 
-    template <class U>
-    constexpr contiguous_iterator(const contiguous_iterator<U>& u) : it_(u.it_) {}
+  template <class U>
+  constexpr contiguous_iterator(const contiguous_iterator<U>& u) : it_(u.it_) {}
 
-    template <class U, class = typename std::enable_if<std::is_default_constructible<U>::value>::type>
-    constexpr contiguous_iterator(contiguous_iterator<U>&& u) : it_(u.it_) { u.it_ = U(); }
+  template <class U, class = typename std::enable_if<std::is_default_constructible<U>::value>::type>
+  constexpr contiguous_iterator(contiguous_iterator<U>&& u) : it_(u.it_) {
+    u.it_ = U();
+  }
 
     constexpr reference operator*() const { return *it_; }
     constexpr pointer operator->() const { return it_; }

>From ed1bc6de6fa676ff149b68fded710fae48e1a22b Mon Sep 17 00:00:00 2001
From: Nicole Mazzuca <nicole at strega-nil.co>
Date: Sat, 27 Jul 2024 21:31:26 +0200
Subject: [PATCH 5/6] format

---
 libcxx/test/support/test_iterators.h | 106 +++++++++++++--------------
 1 file changed, 51 insertions(+), 55 deletions(-)

diff --git a/libcxx/test/support/test_iterators.h b/libcxx/test/support/test_iterators.h
index abf0c76514acb..44bd4a597539d 100644
--- a/libcxx/test/support/test_iterators.h
+++ b/libcxx/test/support/test_iterators.h
@@ -367,68 +367,64 @@ class contiguous_iterator {
     u.it_ = U();
   }
 
-    constexpr reference operator*() const { return *it_; }
-    constexpr pointer operator->() const { return it_; }
-    constexpr reference operator[](difference_type n) const { return it_[n]; }
+  constexpr reference operator*() const { return *it_; }
+  constexpr pointer operator->() const { return it_; }
+  constexpr reference operator[](difference_type n) const { return it_[n]; }
 
-    constexpr contiguous_iterator& operator++() {
-      ++it_;
-      return *this;
-    }
-    constexpr contiguous_iterator& operator--() {
-      --it_;
-      return *this;
-    }
-    constexpr contiguous_iterator operator++(int) { return contiguous_iterator(it_++); }
-    constexpr contiguous_iterator operator--(int) { return contiguous_iterator(it_--); }
+  constexpr contiguous_iterator& operator++() {
+    ++it_;
+    return *this;
+  }
+  constexpr contiguous_iterator& operator--() {
+    --it_;
+    return *this;
+  }
+  constexpr contiguous_iterator operator++(int) { return contiguous_iterator(it_++); }
+  constexpr contiguous_iterator operator--(int) { return contiguous_iterator(it_--); }
 
-    constexpr contiguous_iterator& operator+=(difference_type n) {
-      it_ += n;
-      return *this;
-    }
-    constexpr contiguous_iterator& operator-=(difference_type n) {
-      it_ -= n;
-      return *this;
-    }
-    friend constexpr contiguous_iterator operator+(contiguous_iterator x, difference_type n) {
-      x += n;
-      return x;
-    }
-    friend constexpr contiguous_iterator operator+(difference_type n, contiguous_iterator x) {
-      x += n;
-      return x;
-    }
-    friend constexpr contiguous_iterator operator-(contiguous_iterator x, difference_type n) {
-      x -= n;
-      return x;
-    }
-    friend constexpr difference_type operator-(contiguous_iterator x, contiguous_iterator y) { return x.it_ - y.it_; }
+  constexpr contiguous_iterator& operator+=(difference_type n) {
+    it_ += n;
+    return *this;
+  }
+  constexpr contiguous_iterator& operator-=(difference_type n) {
+    it_ -= n;
+    return *this;
+  }
+  friend constexpr contiguous_iterator operator+(contiguous_iterator x, difference_type n) {
+    x += n;
+    return x;
+  }
+  friend constexpr contiguous_iterator operator+(difference_type n, contiguous_iterator x) {
+    x += n;
+    return x;
+  }
+  friend constexpr contiguous_iterator operator-(contiguous_iterator x, difference_type n) {
+    x -= n;
+    return x;
+  }
+  friend constexpr difference_type operator-(contiguous_iterator x, contiguous_iterator y) { return x.it_ - y.it_; }
 
-    friend constexpr bool operator==(const contiguous_iterator& x, const contiguous_iterator& y) {
-      return x.it_ == y.it_;
-    }
-    friend constexpr bool operator!=(const contiguous_iterator& x, const contiguous_iterator& y) {
-      return x.it_ != y.it_;
-    }
-    friend constexpr bool operator<(const contiguous_iterator& x, const contiguous_iterator& y) {
-      return x.it_ < y.it_;
-    }
-    friend constexpr bool operator<=(const contiguous_iterator& x, const contiguous_iterator& y) {
-      return x.it_ <= y.it_;
-    }
-    friend constexpr bool operator>(const contiguous_iterator& x, const contiguous_iterator& y) {
-      return x.it_ > y.it_;
-    }
-    friend constexpr bool operator>=(const contiguous_iterator& x, const contiguous_iterator& y) {
-      return x.it_ >= y.it_;
-    }
+  friend constexpr bool operator==(const contiguous_iterator& x, const contiguous_iterator& y) {
+    return x.it_ == y.it_;
+  }
+  friend constexpr bool operator!=(const contiguous_iterator& x, const contiguous_iterator& y) {
+    return x.it_ != y.it_;
+  }
+  friend constexpr bool operator<(const contiguous_iterator& x, const contiguous_iterator& y) { return x.it_ < y.it_; }
+  friend constexpr bool operator<=(const contiguous_iterator& x, const contiguous_iterator& y) {
+    return x.it_ <= y.it_;
+  }
+  friend constexpr bool operator>(const contiguous_iterator& x, const contiguous_iterator& y) { return x.it_ > y.it_; }
+  friend constexpr bool operator>=(const contiguous_iterator& x, const contiguous_iterator& y) {
+    return x.it_ >= y.it_;
+  }
 
     // Note no operator<=>, use three_way_contiguous_iterator for testing operator<=>
 
-    friend constexpr It base(const contiguous_iterator& i) { return i.it_; }
+  friend constexpr It base(const contiguous_iterator& i) { return i.it_; }
 
-    template <class T>
-    void operator,(T const &) = delete;
+  template <class T>
+  void operator,(T const&) = delete;
 };
 template <class It>
 contiguous_iterator(It) -> contiguous_iterator<It>;

>From 19d48194ef8e670586f41a43f5d2795cba50b20d Mon Sep 17 00:00:00 2001
From: Nicole Mazzuca <nicole at strega-nil.co>
Date: Mon, 29 Jul 2024 22:20:07 +0200
Subject: [PATCH 6/6] switch a note to a TODO

---
 .../alg.nonmodifying/alg.find.last/ranges.find_last_if.pass.cpp | 2 +-
 .../alg.find.last/ranges.find_last_if_not.pass.cpp              | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/libcxx/test/std/algorithms/alg.nonmodifying/alg.find.last/ranges.find_last_if.pass.cpp b/libcxx/test/std/algorithms/alg.nonmodifying/alg.find.last/ranges.find_last_if.pass.cpp
index e21abae29c778..107fcf900d3e4 100644
--- a/libcxx/test/std/algorithms/alg.nonmodifying/alg.find.last/ranges.find_last_if.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.nonmodifying/alg.find.last/ranges.find_last_if.pass.cpp
@@ -183,7 +183,7 @@ struct NonConstComparable {
   friend constexpr bool operator==(NonConstComparable&, const NonConstComparable&) { return true; }
 };
 
-// note: this should really use `std::const_iterator`
+// TODO: this should really use `std::const_iterator`
 template <class T>
 struct add_const_to_ptr {
   using type = T;
diff --git a/libcxx/test/std/algorithms/alg.nonmodifying/alg.find.last/ranges.find_last_if_not.pass.cpp b/libcxx/test/std/algorithms/alg.nonmodifying/alg.find.last/ranges.find_last_if_not.pass.cpp
index 677c5ac8229eb..6602ac569c679 100644
--- a/libcxx/test/std/algorithms/alg.nonmodifying/alg.find.last/ranges.find_last_if_not.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.nonmodifying/alg.find.last/ranges.find_last_if_not.pass.cpp
@@ -183,7 +183,7 @@ struct NonConstComparable {
   friend constexpr bool operator!=(NonConstComparable&, const NonConstComparable&) { return false; }
 };
 
-// note: this should really use `std::const_iterator`
+// TODO: this should really use `std::const_iterator`
 template <class T>
 struct add_const_to_ptr {
   using type = T;



More information about the libcxx-commits mailing list