[libcxx-commits] [libcxx] 1bbf3a3 - [libc++] Fix `reverse_iterator` when underlying is c++20 `bidirectional_iterator` but not `Cpp17BidirectionalIterator` (#112100)
via libcxx-commits
libcxx-commits at lists.llvm.org
Sat Oct 19 03:09:28 PDT 2024
Author: Hui
Date: 2024-10-19T11:09:25+01:00
New Revision: 1bbf3a37056761ec407031431e28f856428566f0
URL: https://github.com/llvm/llvm-project/commit/1bbf3a37056761ec407031431e28f856428566f0
DIFF: https://github.com/llvm/llvm-project/commit/1bbf3a37056761ec407031431e28f856428566f0.diff
LOG: [libc++] Fix `reverse_iterator` when underlying is c++20 `bidirectional_iterator` but not `Cpp17BidirectionalIterator` (#112100)
`reverse_iterator` supports either c++20 `bidirectional_iterator` or
`Cpp17BidirectionalIterator `
http://eel.is/c++draft/reverse.iter.requirements
The current `reverse_iterator` uses `std::prev` in its `operator->`,
which only supports the `Cpp17BidirectionalIterator` properly.
If the underlying iterator is c++20 `bidirectional_iterator` but does
not satisfy the named requirement `Cpp17BidirectionalIterator`,
(examples are `zip_view::iterator`, `flat_map::iterator`), the current
`std::prev` silently compiles but does a no-op and returns the same
iterator back. So `reverse_iterator::operator->` will silently give a
wrong answer.
Even if we fix the behaviour of `std::prev`, at best, we could fail to
compile the code. But this is not ok, because we need to support this
kind of iterators in `reverse_iterator`.
The solution is simply to not use `std::prev`.
---------
Co-authored-by: Louis Dionne <ldionne.2 at gmail.com>
Added:
Modified:
libcxx/include/__iterator/reverse_iterator.h
libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cmp/equal.pass.cpp
libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cmp/greater-equal.pass.cpp
libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cmp/greater.pass.cpp
libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cmp/less-equal.pass.cpp
libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cmp/less.pass.cpp
libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cmp/not-equal.pass.cpp
libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cons/assign.pass.cpp
libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cons/ctor.default.pass.cpp
libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cons/ctor.iter.pass.cpp
libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cons/ctor.reverse_iterator.pass.cpp
libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.conv/base.pass.cpp
libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.elem/arrow.pass.cpp
libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.elem/bracket.pass.cpp
libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.elem/dereference.pass.cpp
libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.nav/decrement-assign.pass.cpp
libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.nav/increment-assign.pass.cpp
libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.nav/minus.pass.cpp
libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.nav/plus.pass.cpp
libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.nav/postdecrement.pass.cpp
libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.nav/postincrement.pass.cpp
libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.nav/predecrement.pass.cpp
libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.nav/preincrement.pass.cpp
libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.nonmember/make_reverse_iterator.pass.cpp
libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.nonmember/minus.pass.cpp
libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.nonmember/plus.pass.cpp
Removed:
################################################################################
diff --git a/libcxx/include/__iterator/reverse_iterator.h b/libcxx/include/__iterator/reverse_iterator.h
index 50c0f21eaa286b..5e88d86ad5e9b2 100644
--- a/libcxx/include/__iterator/reverse_iterator.h
+++ b/libcxx/include/__iterator/reverse_iterator.h
@@ -136,10 +136,12 @@ class _LIBCPP_TEMPLATE_VIS reverse_iterator
_LIBCPP_HIDE_FROM_ABI constexpr pointer operator->() const
requires is_pointer_v<_Iter> || requires(const _Iter __i) { __i.operator->(); }
{
+ _Iter __tmp = current;
+ --__tmp;
if constexpr (is_pointer_v<_Iter>) {
- return std::prev(current);
+ return __tmp;
} else {
- return std::prev(current).operator->();
+ return __tmp.operator->();
}
}
#else
diff --git a/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cmp/equal.pass.cpp b/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cmp/equal.pass.cpp
index fcf8d88fcf62be..6fe575ebdd9a0d 100644
--- a/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cmp/equal.pass.cpp
+++ b/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cmp/equal.pass.cpp
@@ -33,6 +33,10 @@ TEST_CONSTEXPR_CXX17 bool tests() {
test(bidirectional_iterator<const char*>(s), bidirectional_iterator<const char*>(s+1), false);
test(random_access_iterator<const char*>(s), random_access_iterator<const char*>(s), true);
test(random_access_iterator<const char*>(s), random_access_iterator<const char*>(s+1), false);
+#if TEST_STD_VER >= 20
+ test(cpp20_random_access_iterator<const char*>(s), cpp20_random_access_iterator<const char*>(s), true);
+ test(cpp20_random_access_iterator<const char*>(s), cpp20_random_access_iterator<const char*>(s + 1), false);
+#endif
test(s, s, true);
test(s, s+1, false);
return true;
diff --git a/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cmp/greater-equal.pass.cpp b/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cmp/greater-equal.pass.cpp
index fdcd02abb0d8ed..b2bfdb56d646ed 100644
--- a/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cmp/greater-equal.pass.cpp
+++ b/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cmp/greater-equal.pass.cpp
@@ -32,6 +32,11 @@ TEST_CONSTEXPR_CXX17 bool tests() {
test(random_access_iterator<const char*>(s), random_access_iterator<const char*>(s), true);
test(random_access_iterator<const char*>(s), random_access_iterator<const char*>(s+1), true);
test(random_access_iterator<const char*>(s+1), random_access_iterator<const char*>(s), false);
+#if TEST_STD_VER >= 20
+ test(cpp20_random_access_iterator<const char*>(s), cpp20_random_access_iterator<const char*>(s), true);
+ test(cpp20_random_access_iterator<const char*>(s), cpp20_random_access_iterator<const char*>(s + 1), true);
+ test(cpp20_random_access_iterator<const char*>(s + 1), cpp20_random_access_iterator<const char*>(s), false);
+#endif
test(s, s, true);
test(s, s+1, true);
test(s+1, s, false);
diff --git a/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cmp/greater.pass.cpp b/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cmp/greater.pass.cpp
index dce331e519646f..38f9258de31f5e 100644
--- a/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cmp/greater.pass.cpp
+++ b/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cmp/greater.pass.cpp
@@ -32,6 +32,11 @@ TEST_CONSTEXPR_CXX17 bool tests() {
test(random_access_iterator<const char*>(s), random_access_iterator<const char*>(s), false);
test(random_access_iterator<const char*>(s), random_access_iterator<const char*>(s+1), true);
test(random_access_iterator<const char*>(s+1), random_access_iterator<const char*>(s), false);
+#if TEST_STD_VER >= 20
+ test(cpp20_random_access_iterator<const char*>(s), cpp20_random_access_iterator<const char*>(s), false);
+ test(cpp20_random_access_iterator<const char*>(s), cpp20_random_access_iterator<const char*>(s + 1), true);
+ test(cpp20_random_access_iterator<const char*>(s + 1), cpp20_random_access_iterator<const char*>(s), false);
+#endif
test(s, s, false);
test(s, s+1, true);
test(s+1, s, false);
diff --git a/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cmp/less-equal.pass.cpp b/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cmp/less-equal.pass.cpp
index e9cea6250a7645..a57930b111314d 100644
--- a/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cmp/less-equal.pass.cpp
+++ b/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cmp/less-equal.pass.cpp
@@ -32,6 +32,11 @@ TEST_CONSTEXPR_CXX17 bool tests() {
test(random_access_iterator<const char*>(s), random_access_iterator<const char*>(s), true);
test(random_access_iterator<const char*>(s), random_access_iterator<const char*>(s+1), false);
test(random_access_iterator<const char*>(s+1), random_access_iterator<const char*>(s), true);
+#if TEST_STD_VER >= 20
+ test(cpp20_random_access_iterator<const char*>(s), cpp20_random_access_iterator<const char*>(s), true);
+ test(cpp20_random_access_iterator<const char*>(s), cpp20_random_access_iterator<const char*>(s + 1), false);
+ test(cpp20_random_access_iterator<const char*>(s + 1), cpp20_random_access_iterator<const char*>(s), true);
+#endif
test(s, s, true);
test(s, s+1, false);
test(s+1, s, true);
diff --git a/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cmp/less.pass.cpp b/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cmp/less.pass.cpp
index b66147cf3a03c3..4cd3f249d033e1 100644
--- a/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cmp/less.pass.cpp
+++ b/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cmp/less.pass.cpp
@@ -32,6 +32,11 @@ TEST_CONSTEXPR_CXX17 bool tests() {
test(random_access_iterator<const char*>(s), random_access_iterator<const char*>(s), false);
test(random_access_iterator<const char*>(s), random_access_iterator<const char*>(s+1), false);
test(random_access_iterator<const char*>(s+1), random_access_iterator<const char*>(s), true);
+#if TEST_STD_VER >= 20
+ test(cpp20_random_access_iterator<const char*>(s), cpp20_random_access_iterator<const char*>(s), false);
+ test(cpp20_random_access_iterator<const char*>(s), cpp20_random_access_iterator<const char*>(s + 1), false);
+ test(cpp20_random_access_iterator<const char*>(s + 1), cpp20_random_access_iterator<const char*>(s), true);
+#endif
test(s, s, false);
test(s, s+1, false);
test(s+1, s, true);
diff --git a/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cmp/not-equal.pass.cpp b/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cmp/not-equal.pass.cpp
index 37a6ff1302ce77..509ac297c3cba6 100644
--- a/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cmp/not-equal.pass.cpp
+++ b/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cmp/not-equal.pass.cpp
@@ -33,6 +33,10 @@ TEST_CONSTEXPR_CXX17 bool tests() {
test(bidirectional_iterator<const char*>(s), bidirectional_iterator<const char*>(s+1), true);
test(random_access_iterator<const char*>(s), random_access_iterator<const char*>(s), false);
test(random_access_iterator<const char*>(s), random_access_iterator<const char*>(s+1), true);
+#if TEST_STD_VER >= 20
+ test(cpp20_random_access_iterator<const char*>(s), cpp20_random_access_iterator<const char*>(s), false);
+ test(cpp20_random_access_iterator<const char*>(s), cpp20_random_access_iterator<const char*>(s + 1), true);
+#endif
test(s, s, false);
test(s, s+1, true);
return true;
diff --git a/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cons/assign.pass.cpp b/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cons/assign.pass.cpp
index 0e5123a49e2b56..f9d2efa7c2a8cc 100644
--- a/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cons/assign.pass.cpp
+++ b/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cons/assign.pass.cpp
@@ -59,6 +59,9 @@ TEST_CONSTEXPR_CXX17 bool tests() {
Derived d;
test<bidirectional_iterator<Base*> >(bidirectional_iterator<Derived*>(&d));
test<random_access_iterator<const Base*> >(random_access_iterator<Derived*>(&d));
+#if TEST_STD_VER >= 20
+ test<cpp20_random_access_iterator<const Base*> >(cpp20_random_access_iterator<Derived*>(&d));
+#endif
test<Base*>(&d);
char c = '\0';
diff --git a/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cons/ctor.default.pass.cpp b/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cons/ctor.default.pass.cpp
index fcb96de91d1a02..90047b19f5a63a 100644
--- a/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cons/ctor.default.pass.cpp
+++ b/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cons/ctor.default.pass.cpp
@@ -26,6 +26,9 @@ TEST_CONSTEXPR_CXX17 void test() {
TEST_CONSTEXPR_CXX17 bool tests() {
test<bidirectional_iterator<const char*> >();
test<random_access_iterator<char*> >();
+#if TEST_STD_VER >= 20
+ test<cpp20_random_access_iterator<char*> >();
+#endif
test<char*>();
test<const char*>();
return true;
diff --git a/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cons/ctor.iter.pass.cpp b/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cons/ctor.iter.pass.cpp
index 801b2cf879ce5b..72e77b08564219 100644
--- a/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cons/ctor.iter.pass.cpp
+++ b/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cons/ctor.iter.pass.cpp
@@ -28,6 +28,9 @@ TEST_CONSTEXPR_CXX17 bool tests() {
const char s[] = "123";
test(bidirectional_iterator<const char*>(s));
test(random_access_iterator<const char*>(s));
+#if TEST_STD_VER >= 20
+ test(cpp20_random_access_iterator<const char*>(s));
+#endif
test(s);
return true;
}
diff --git a/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cons/ctor.reverse_iterator.pass.cpp b/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cons/ctor.reverse_iterator.pass.cpp
index 8f315e83f6d7b4..fa967b45b1d9f8 100644
--- a/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cons/ctor.reverse_iterator.pass.cpp
+++ b/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cons/ctor.reverse_iterator.pass.cpp
@@ -33,6 +33,9 @@ TEST_CONSTEXPR_CXX17 bool tests() {
Derived d;
test<bidirectional_iterator<Base*> >(bidirectional_iterator<Derived*>(&d));
test<random_access_iterator<const Base*> >(random_access_iterator<Derived*>(&d));
+#if TEST_STD_VER >= 20
+ test<cpp20_random_access_iterator<const Base*> >(cpp20_random_access_iterator<Derived*>(&d));
+#endif
test<Base*>(&d);
return true;
}
diff --git a/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.conv/base.pass.cpp b/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.conv/base.pass.cpp
index 4fb33f54260457..35ed17583c8555 100644
--- a/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.conv/base.pass.cpp
+++ b/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.conv/base.pass.cpp
@@ -18,20 +18,28 @@
#include "test_macros.h"
#include "test_iterators.h"
-TEST_CONSTEXPR_CXX17 bool test() {
- typedef bidirectional_iterator<int*> Iter;
- int i = 0;
- Iter iter(&i);
- std::reverse_iterator<Iter> const reverse(iter);
- std::reverse_iterator<Iter>::iterator_type base = reverse.base();
- assert(base == Iter(&i));
- return true;
+template <class Iter>
+TEST_CONSTEXPR_CXX17 void test() {
+ int i = 0;
+ Iter iter(&i);
+ std::reverse_iterator<Iter> const reverse(iter);
+ typename std::reverse_iterator<Iter>::iterator_type base = reverse.base();
+ assert(base == Iter(&i));
+}
+
+TEST_CONSTEXPR_CXX17 bool tests() {
+ test<bidirectional_iterator<int*> >();
+ test<random_access_iterator<int*> >();
+#if TEST_STD_VER >= 20
+ test<cpp20_random_access_iterator<int*>>();
+#endif
+ return true;
}
int main(int, char**) {
- test();
+ tests();
#if TEST_STD_VER > 14
- static_assert(test(), "");
+ static_assert(tests(), "");
#endif
- return 0;
+ return 0;
}
diff --git a/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.elem/arrow.pass.cpp b/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.elem/arrow.pass.cpp
index 15d18d9145ef0c..665a1a89223bc4 100644
--- a/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.elem/arrow.pass.cpp
+++ b/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.elem/arrow.pass.cpp
@@ -24,6 +24,55 @@
#include "test_macros.h"
+#if TEST_STD_VER >= 20
+// C++20 bidirectional_iterator that does not satisfy the Cpp17BidirectionalIterator named requirement.
+template <class It>
+class cpp20_bidirectional_iterator_with_arrow {
+ It it_;
+
+public:
+ using iterator_category = std::input_iterator_tag;
+ using iterator_concept = std::bidirectional_iterator_tag;
+ using value_type = std::iterator_traits<It>::value_type;
+ using
diff erence_type = std::iterator_traits<It>::
diff erence_type;
+
+ cpp20_bidirectional_iterator_with_arrow() : it_() {}
+ explicit cpp20_bidirectional_iterator_with_arrow(It it) : it_(it) {}
+
+ decltype(auto) operator*() const { return *it_; }
+
+ auto operator->() const {
+ if constexpr (std::is_pointer_v<It>) {
+ return it_;
+ } else {
+ return it_.operator->();
+ }
+ }
+
+ cpp20_bidirectional_iterator_with_arrow& operator++() {
+ ++it_;
+ return *this;
+ }
+ cpp20_bidirectional_iterator_with_arrow& operator--() {
+ --it_;
+ return *this;
+ }
+ cpp20_bidirectional_iterator_with_arrow operator++(int) { return cpp20_bidirectional_iterator_with_arrow(it_++); }
+ cpp20_bidirectional_iterator_with_arrow operator--(int) { return cpp20_bidirectional_iterator_with_arrow(it_--); }
+
+ friend bool
+ operator==(const cpp20_bidirectional_iterator_with_arrow& x, const cpp20_bidirectional_iterator_with_arrow& y) {
+ return x.it_ == y.it_;
+ }
+ friend bool
+ operator!=(const cpp20_bidirectional_iterator_with_arrow& x, const cpp20_bidirectional_iterator_with_arrow& y) {
+ return x.it_ != y.it_;
+ }
+
+ friend It base(const cpp20_bidirectional_iterator_with_arrow& i) { return i.it_; }
+};
+#endif
+
class A
{
int data_;
@@ -113,6 +162,16 @@ int main(int, char**)
static_assert(it1->get() == gC.get(), "");
}
+#endif
+#if TEST_STD_VER >= 20
+ {
+ // The underlying iterator models c++20 bidirectional_iterator,
+ // but does not satisfy c++17 BidirectionalIterator named requirement
+ B data[] = {1, 2, 3};
+ cpp20_bidirectional_iterator_with_arrow<B*> iter(data + 3);
+ auto ri = std::make_reverse_iterator(iter);
+ assert(ri->get() == 3);
+ }
#endif
{
((void)gC);
diff --git a/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.elem/bracket.pass.cpp b/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.elem/bracket.pass.cpp
index 37a857ceefa83d..8b45bfa09b4fe7 100644
--- a/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.elem/bracket.pass.cpp
+++ b/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.elem/bracket.pass.cpp
@@ -33,6 +33,10 @@ TEST_CONSTEXPR_CXX17 bool tests() {
const char* s = "1234567890";
test(random_access_iterator<const char*>(s+5), 4, '1');
test(random_access_iterator<const char*>(s+5), 0, '5');
+#if TEST_STD_VER >= 20
+ test(cpp20_random_access_iterator<const char*>(s + 5), 4, '1');
+ test(cpp20_random_access_iterator<const char*>(s + 5), 0, '5');
+#endif
test(s+5, 4, '1');
test(s+5, 0, '5');
return true;
diff --git a/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.elem/dereference.pass.cpp b/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.elem/dereference.pass.cpp
index 292c6da9a7733e..c3a489085c68b0 100644
--- a/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.elem/dereference.pass.cpp
+++ b/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.elem/dereference.pass.cpp
@@ -21,6 +21,7 @@
#include <cassert>
#include "test_macros.h"
+#include "test_iterators.h"
class A
{
@@ -47,6 +48,10 @@ int main(int, char**)
{
A a;
test(&a+1, A());
+ test(random_access_iterator<A*>(&a + 1), A());
+#if TEST_STD_VER >= 20
+ test(cpp20_random_access_iterator<A*>(&a + 1), A());
+#endif
#if TEST_STD_VER > 14
{
diff --git a/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.nav/decrement-assign.pass.cpp b/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.nav/decrement-assign.pass.cpp
index 8c83ec1e9389f9..91c2d9363619bf 100644
--- a/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.nav/decrement-assign.pass.cpp
+++ b/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.nav/decrement-assign.pass.cpp
@@ -30,6 +30,9 @@ TEST_CONSTEXPR_CXX17 void test(It i, typename std::iterator_traits<It>::
diff eren
TEST_CONSTEXPR_CXX17 bool tests() {
const char* s = "1234567890";
test(random_access_iterator<const char*>(s+5), 5, random_access_iterator<const char*>(s+10));
+#if TEST_STD_VER >= 20
+ test(cpp20_random_access_iterator<const char*>(s + 5), 5, cpp20_random_access_iterator<const char*>(s + 10));
+#endif
test(s+5, 5, s+10);
return true;
}
diff --git a/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.nav/increment-assign.pass.cpp b/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.nav/increment-assign.pass.cpp
index e32fac9fc24fe1..2a2746f2cc52bd 100644
--- a/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.nav/increment-assign.pass.cpp
+++ b/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.nav/increment-assign.pass.cpp
@@ -29,7 +29,10 @@ TEST_CONSTEXPR_CXX17 void test(It i, typename std::iterator_traits<It>::
diff eren
TEST_CONSTEXPR_CXX17 bool tests() {
char const* s = "1234567890";
- test(random_access_iterator<const char*>(s+5), 5, random_access_iterator<const char*>(s));
+ test(random_access_iterator<const char*>(s + 5), 5, random_access_iterator<const char*>(s));
+#if TEST_STD_VER >= 20
+ test(cpp20_random_access_iterator<const char*>(s + 5), 5, cpp20_random_access_iterator<const char*>(s));
+#endif
test(s+5, 5, s);
return true;
}
diff --git a/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.nav/minus.pass.cpp b/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.nav/minus.pass.cpp
index f2474dd7669f2c..759cacad94e24c 100644
--- a/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.nav/minus.pass.cpp
+++ b/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.nav/minus.pass.cpp
@@ -28,7 +28,10 @@ TEST_CONSTEXPR_CXX17 void test(It i, typename std::iterator_traits<It>::
diff eren
TEST_CONSTEXPR_CXX17 bool tests() {
const char* s = "1234567890";
- test(random_access_iterator<const char*>(s+5), 5, random_access_iterator<const char*>(s+10));
+ test(random_access_iterator<const char*>(s + 5), 5, random_access_iterator<const char*>(s + 10));
+#if TEST_STD_VER >= 20
+ test(cpp20_random_access_iterator<const char*>(s + 5), 5, cpp20_random_access_iterator<const char*>(s + 10));
+#endif
test(s+5, 5, s+10);
return true;
}
diff --git a/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.nav/plus.pass.cpp b/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.nav/plus.pass.cpp
index 5673425e796757..24fa84e4f37c8b 100644
--- a/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.nav/plus.pass.cpp
+++ b/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.nav/plus.pass.cpp
@@ -28,7 +28,10 @@ TEST_CONSTEXPR_CXX17 void test(It i, typename std::iterator_traits<It>::
diff eren
TEST_CONSTEXPR_CXX17 bool tests() {
const char* s = "1234567890";
- test(random_access_iterator<const char*>(s+5), 5, random_access_iterator<const char*>(s));
+ test(random_access_iterator<const char*>(s + 5), 5, random_access_iterator<const char*>(s));
+#if TEST_STD_VER >= 20
+ test(cpp20_random_access_iterator<const char*>(s + 5), 5, cpp20_random_access_iterator<const char*>(s));
+#endif
test(s+5, 5, s);
return true;
}
diff --git a/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.nav/postdecrement.pass.cpp b/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.nav/postdecrement.pass.cpp
index 24bedad314b7e8..f0551b5efece09 100644
--- a/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.nav/postdecrement.pass.cpp
+++ b/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.nav/postdecrement.pass.cpp
@@ -30,6 +30,9 @@ TEST_CONSTEXPR_CXX17 bool tests() {
const char* s = "123";
test(bidirectional_iterator<const char*>(s+1), bidirectional_iterator<const char*>(s+2));
test(random_access_iterator<const char*>(s+1), random_access_iterator<const char*>(s+2));
+#if TEST_STD_VER >= 20
+ test(cpp20_random_access_iterator<const char*>(s + 1), cpp20_random_access_iterator<const char*>(s + 2));
+#endif
test(s+1, s+2);
return true;
}
diff --git a/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.nav/postincrement.pass.cpp b/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.nav/postincrement.pass.cpp
index e15bfb2fd15096..f1d3ea21a5b860 100644
--- a/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.nav/postincrement.pass.cpp
+++ b/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.nav/postincrement.pass.cpp
@@ -30,6 +30,9 @@ TEST_CONSTEXPR_CXX17 bool tests() {
const char* s = "123";
test(bidirectional_iterator<const char*>(s+1), bidirectional_iterator<const char*>(s));
test(random_access_iterator<const char*>(s+1), random_access_iterator<const char*>(s));
+#if TEST_STD_VER >= 20
+ test(cpp20_random_access_iterator<const char*>(s + 1), cpp20_random_access_iterator<const char*>(s));
+#endif
test(s+1, s);
return true;
}
diff --git a/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.nav/predecrement.pass.cpp b/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.nav/predecrement.pass.cpp
index 2fbd530a085dcc..5a2ac785703672 100644
--- a/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.nav/predecrement.pass.cpp
+++ b/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.nav/predecrement.pass.cpp
@@ -30,6 +30,9 @@ TEST_CONSTEXPR_CXX17 bool tests() {
const char* s = "123";
test(bidirectional_iterator<const char*>(s+1), bidirectional_iterator<const char*>(s+2));
test(random_access_iterator<const char*>(s+1), random_access_iterator<const char*>(s+2));
+#if TEST_STD_VER >= 20
+ test(cpp20_random_access_iterator<const char*>(s + 1), cpp20_random_access_iterator<const char*>(s + 2));
+#endif
test(s+1, s+2);
return true;
}
diff --git a/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.nav/preincrement.pass.cpp b/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.nav/preincrement.pass.cpp
index 5efc8a39e22aa8..6087eedd2449f2 100644
--- a/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.nav/preincrement.pass.cpp
+++ b/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.nav/preincrement.pass.cpp
@@ -30,6 +30,9 @@ TEST_CONSTEXPR_CXX17 bool tests() {
const char* s = "123";
test(bidirectional_iterator<const char*>(s+1), bidirectional_iterator<const char*>(s));
test(random_access_iterator<const char*>(s+1), random_access_iterator<const char*>(s));
+#if TEST_STD_VER >= 20
+ test(cpp20_random_access_iterator<const char*>(s + 1), cpp20_random_access_iterator<const char*>(s));
+#endif
test(s+1, s);
return true;
}
diff --git a/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.nonmember/make_reverse_iterator.pass.cpp b/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.nonmember/make_reverse_iterator.pass.cpp
index 401eecb2a3b838..4a4e474a550835 100644
--- a/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.nonmember/make_reverse_iterator.pass.cpp
+++ b/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.nonmember/make_reverse_iterator.pass.cpp
@@ -22,24 +22,34 @@
#include "test_iterators.h"
template <class It>
-TEST_CONSTEXPR_CXX17 void test(It i) {
- const std::reverse_iterator<It> r = std::make_reverse_iterator(i);
- assert(r.base() == i);
+TEST_CONSTEXPR_CXX17 void test_one(It i) {
+ const std::reverse_iterator<It> r = std::make_reverse_iterator(i);
+ assert(r.base() == i);
+}
+
+template <class It>
+TEST_CONSTEXPR_CXX17 void test() {
+ const char* s = "1234567890";
+ It b(s);
+ It e(s + 10);
+ while (b != e)
+ test_one(b++);
}
TEST_CONSTEXPR_CXX17 bool tests() {
- const char* s = "1234567890";
- random_access_iterator<const char*> b(s);
- random_access_iterator<const char*> e(s+10);
- while (b != e)
- test (b++);
- return true;
+ test<const char*>();
+ test<bidirectional_iterator<const char*>>();
+ test<random_access_iterator<const char*>>();
+#if TEST_STD_VER >= 20
+ test<cpp20_random_access_iterator<const char*>>();
+#endif
+ return true;
}
int main(int, char**) {
- tests();
+ tests();
#if TEST_STD_VER > 14
- static_assert(tests(), "");
+ static_assert(tests(), "");
#endif
- return 0;
+ return 0;
}
diff --git a/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.nonmember/minus.pass.cpp b/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.nonmember/minus.pass.cpp
index f7f74d145d73c6..676f6e1b491695 100644
--- a/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.nonmember/minus.pass.cpp
+++ b/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.nonmember/minus.pass.cpp
@@ -23,45 +23,63 @@
#include "test_macros.h"
#include "test_iterators.h"
-template <class, class, class = void> struct HasMinus : std::false_type {};
-template <class R1, class R2> struct HasMinus<R1, R2, decltype((R1() - R2(), void()))> : std::true_type {};
+template <class, class, class = void>
+struct HasMinus : std::false_type {};
+template <class R1, class R2>
+struct HasMinus<R1, R2, decltype((R1() - R2(), void()))> : std::true_type {};
+
+// Test non-subtractable base iterator types
+static_assert(HasMinus<std::reverse_iterator<int*>, std::reverse_iterator<int*> >::value, "");
+static_assert(HasMinus<std::reverse_iterator<int*>, std::reverse_iterator<const int*> >::value, "");
+
+#if TEST_STD_VER >= 11
+static_assert(!HasMinus<std::reverse_iterator<int*>, std::reverse_iterator<char*> >::value, "");
+static_assert(!HasMinus<std::reverse_iterator<bidirectional_iterator<int*> >,
+ std::reverse_iterator<bidirectional_iterator<int*> > >::value,
+ "");
+#endif
template <class It1, class It2>
-TEST_CONSTEXPR_CXX17 void test(It1 l, It2 r, std::ptr
diff _t x) {
- const std::reverse_iterator<It1> r1(l);
- const std::reverse_iterator<It2> r2(r);
- assert((r1 - r2) == x);
+TEST_CONSTEXPR_CXX17 void test_one(It1 l, It2 r, std::ptr
diff _t x) {
+ const std::reverse_iterator<It1> r1(l);
+ const std::reverse_iterator<It2> r2(r);
+ assert((r1 - r2) == x);
}
-TEST_CONSTEXPR_CXX17 bool tests() {
- using PC = const char*;
- char s[3] = {0};
-
- // Test same base iterator type
- test(s, s, 0);
- test(s, s+1, 1);
- test(s+1, s, -1);
+template <class Iter>
+TEST_CONSTEXPR_CXX17 void test() {
+ // Test same base iterator type
+ char s[3] = {0};
- // Test
diff erent (but subtractable) base iterator types
- test(PC(s), s, 0);
- test(PC(s), s+1, 1);
- test(PC(s+1), s, -1);
+ test_one(Iter(s), Iter(s), 0);
+ test_one(Iter(s), Iter(s + 1), 1);
+ test_one(Iter(s + 1), Iter(s), -1);
+}
- // Test non-subtractable base iterator types
- static_assert( HasMinus<std::reverse_iterator<int*>, std::reverse_iterator<int*> >::value, "");
- static_assert( HasMinus<std::reverse_iterator<int*>, std::reverse_iterator<const int*> >::value, "");
-#if TEST_STD_VER >= 11
- static_assert(!HasMinus<std::reverse_iterator<int*>, std::reverse_iterator<char*> >::value, "");
- static_assert(!HasMinus<std::reverse_iterator<bidirectional_iterator<int*> >, std::reverse_iterator<bidirectional_iterator<int*> > >::value, "");
+TEST_CONSTEXPR_CXX17 bool tests() {
+ {
+ test<char*>();
+ test<random_access_iterator<char*> >();
+#if TEST_STD_VER >= 20
+ test<cpp20_random_access_iterator<char*>>();
#endif
+ }
+ {
+ // Test
diff erent (but subtractable) base iterator types
+ using PC = const char*;
+ char s[3] = {0};
+ test_one(PC(s), s, 0);
+ test_one(PC(s), s + 1, 1);
+ test_one(PC(s + 1), s, -1);
+ }
- return true;
+ return true;
}
int main(int, char**) {
- tests();
+ tests();
#if TEST_STD_VER > 14
- static_assert(tests(), "");
+ static_assert(tests(), "");
#endif
- return 0;
+ return 0;
}
diff --git a/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.nonmember/plus.pass.cpp b/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.nonmember/plus.pass.cpp
index aeb9f89dd48725..9ead123781bc86 100644
--- a/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.nonmember/plus.pass.cpp
+++ b/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.nonmember/plus.pass.cpp
@@ -29,6 +29,9 @@ TEST_CONSTEXPR_CXX17 void test(It i, typename std::iterator_traits<It>::
diff eren
TEST_CONSTEXPR_CXX17 bool tests() {
const char* s = "1234567890";
test(random_access_iterator<const char*>(s+5), 5, random_access_iterator<const char*>(s));
+#if TEST_STD_VER >= 20
+ test(cpp20_random_access_iterator<const char*>(s + 5), 5, cpp20_random_access_iterator<const char*>(s));
+#endif
test(s+5, 5, s);
return true;
}
More information about the libcxx-commits
mailing list