aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3
diff options
context:
space:
mode:
Diffstat (limited to 'libstdc++-v3')
-rw-r--r--libstdc++-v3/testsuite/std/ranges/access/cbegin.cc13
-rw-r--r--libstdc++-v3/testsuite/std/ranges/access/cdata.cc38
-rw-r--r--libstdc++-v3/testsuite/std/ranges/access/cend.cc29
-rw-r--r--libstdc++-v3/testsuite/std/ranges/access/crbegin.cc40
-rw-r--r--libstdc++-v3/testsuite/std/ranges/access/crend.cc33
-rw-r--r--libstdc++-v3/testsuite/std/ranges/adaptors/take.cc2
-rw-r--r--libstdc++-v3/testsuite/std/ranges/adaptors/take_while.cc2
-rw-r--r--libstdc++-v3/testsuite/std/ranges/adaptors/transform.cc4
8 files changed, 154 insertions, 7 deletions
diff --git a/libstdc++-v3/testsuite/std/ranges/access/cbegin.cc b/libstdc++-v3/testsuite/std/ranges/access/cbegin.cc
index 1037604..3667b0d 100644
--- a/libstdc++-v3/testsuite/std/ranges/access/cbegin.cc
+++ b/libstdc++-v3/testsuite/std/ranges/access/cbegin.cc
@@ -48,6 +48,10 @@ struct R
friend int* begin(R&&); // this function is not defined
friend const int* begin(const R& r) noexcept { return r.a + 2; }
friend const int* begin(const R&&); // this function is not defined
+
+#if __cpp_lib_ranges_as_const
+ friend const int* end(const R&) noexcept; // C++23 requires this.
+#endif
};
struct RV // view on an R
@@ -56,6 +60,10 @@ struct RV // view on an R
friend int* begin(RV&); // this function is not defined
friend const int* begin(const RV& rv) noexcept { return begin(std::as_const(rv.r)); }
+
+#if __cpp_lib_ranges_as_const
+ friend const int* end(const RV&) noexcept; // C++23 requires this.
+#endif
};
// Allow ranges::begin to work with RV&&
@@ -88,6 +96,11 @@ struct RR
friend int* begin(RR&& r) { return r.a + 1; }
friend const int* begin(const RR& r) { return r.a + 2; }
friend const int* begin(const RR&& r) noexcept { return r.a + 3; }
+
+#if __cpp_lib_ranges_as_const
+ short* end() noexcept { return &s + 1; } // C++23 requires this.
+ const long* end() const { return &l + 1; } // C++23 requires this.
+#endif
};
// N.B. this is a lie, cbegin on an RR rvalue will return a dangling pointer.
diff --git a/libstdc++-v3/testsuite/std/ranges/access/cdata.cc b/libstdc++-v3/testsuite/std/ranges/access/cdata.cc
index f0f45ee..d69b04c 100644
--- a/libstdc++-v3/testsuite/std/ranges/access/cdata.cc
+++ b/libstdc++-v3/testsuite/std/ranges/access/cdata.cc
@@ -41,15 +41,43 @@ test01()
static_assert( has_cdata<R&> );
static_assert( has_cdata<const R&> );
R r;
- const R& c = r;
+#if ! __cpp_lib_ranges_as_const
VERIFY( std::ranges::cdata(r) == (R*)nullptr );
static_assert( noexcept(std::ranges::cdata(r)) );
+#else
+ // constant_range<const R> is not satisfied, so cdata(r) == data(r).
+ VERIFY( std::ranges::cdata(r) == &r.j );
+ static_assert( ! noexcept(std::ranges::cdata(r)) );
+#endif
+ const R& c = r;
VERIFY( std::ranges::cdata(c) == (R*)nullptr );
static_assert( noexcept(std::ranges::cdata(c)) );
// not lvalues and not borrowed ranges
static_assert( !has_cdata<R> );
static_assert( !has_cdata<const R> );
+
+ struct R2
+ {
+ // These overloads mean that range<R2> and range<const R2> are satisfied.
+ int* begin();
+ int* end();
+ const int* begin() const;
+ const int* end() const;
+
+ int i = 0;
+ int j = 0;
+ int* data() { return &j; }
+ const R2* data() const noexcept { return nullptr; }
+ };
+ static_assert( has_cdata<R2&> );
+ static_assert( has_cdata<const R2&> );
+ R2 r2;
+ VERIFY( std::ranges::cdata(r2) == (R2*)nullptr );
+ static_assert( noexcept(std::ranges::cdata(r2)) );
+ const R2& c2 = r2;
+ VERIFY( std::ranges::cdata(c2) == (R2*)nullptr );
+ static_assert( noexcept(std::ranges::cdata(c2)) );
}
void
@@ -71,6 +99,14 @@ struct R3
friend long* begin(R3&& r); // not defined
friend const long* begin(const R3& r) { return &r.l; }
friend const short* begin(const R3&&); // not defined
+
+#if __cpp_lib_ranges_as_const
+ // C++23 needs these so that range<R3> is satisfied and so that
+ // possibly-const-range<R3> is not the same type as R3.
+ friend long* begin(R3&);
+ friend long* end(R3&);
+ friend const long* end(const R3& r);
+#endif
};
template<> constexpr bool std::ranges::enable_borrowed_range<R3> = true;
diff --git a/libstdc++-v3/testsuite/std/ranges/access/cend.cc b/libstdc++-v3/testsuite/std/ranges/access/cend.cc
index f47bd9d..3726ebb 100644
--- a/libstdc++-v3/testsuite/std/ranges/access/cend.cc
+++ b/libstdc++-v3/testsuite/std/ranges/access/cend.cc
@@ -42,7 +42,7 @@ struct R
int a[4] = { 0, 1, 2, 3 };
const int* begin() const { return nullptr; }
- friend const int* begin(const R&& r) noexcept { return nullptr; }
+ friend const int* begin(const R&&) noexcept { return nullptr; }
// Should be ignored because it doesn't return a sentinel for int*
const long* end() const { return nullptr; }
@@ -53,6 +53,15 @@ struct R
friend const int* end(const R&& r) noexcept { return r.a + 3; }
};
+#if __cpp_lib_ranges_as_const
+struct R2 : R
+{
+ // This overload means constant_range<const R2> will be satisfied:
+ friend const int* begin(const R2&) noexcept;
+ friend const int* end(const R2& r2) noexcept { return r2.a + 2; }
+};
+#endif
+
struct RV // view on an R
{
R& r;
@@ -71,12 +80,28 @@ test03()
{
R r;
const R& c = r;
+#if ! __cpp_lib_ranges_as_const
VERIFY( std::ranges::cend(r) == std::ranges::end(c) );
+#else
+ // constant_range<const R> is not satisfied, so cend(r) == end(r) instead.
+ VERIFY( std::ranges::cend(r) == std::ranges::end(r) );
+ R2 r2;
+ const R& c2 = r2;
+ // But constant_range<const R2> is satisfied, so cend(r2) == end(c2).
+ VERIFY( std::ranges::cend(r2) == std::ranges::end(c2) );
+ VERIFY( std::ranges::cend(r2) == std::ranges::end((const R&)c2) );
+#endif
VERIFY( std::ranges::cend(c) == std::ranges::end(c) );
RV v{r};
- const RV cv{r};
+#if ! __cpp_lib_ranges_as_const
VERIFY( std::ranges::cend(std::move(v)) == std::ranges::end(c) );
+#else
+ // constant_range<RV> is already satisfied, so cend(v) == end(r) instead.
+ VERIFY( std::ranges::cend(std::move(v)) == std::ranges::end(r) );
+#endif
+
+ const RV cv{r};
VERIFY( std::ranges::cend(std::move(cv)) == std::ranges::end(c) );
}
diff --git a/libstdc++-v3/testsuite/std/ranges/access/crbegin.cc b/libstdc++-v3/testsuite/std/ranges/access/crbegin.cc
index db58d95..95b4607f 100644
--- a/libstdc++-v3/testsuite/std/ranges/access/crbegin.cc
+++ b/libstdc++-v3/testsuite/std/ranges/access/crbegin.cc
@@ -37,13 +37,33 @@ struct R1V // view on an R1
{
R1& r;
- friend const long* rbegin(R1V&); // this is not defined
+ friend const long* rbegin(R1V&) { return nullptr; }
friend const int* rbegin(const R1V& rv) noexcept { return rv.r.rbegin(); }
};
// Allow ranges::end to work with R1V&&
template<> constexpr bool std::ranges::enable_borrowed_range<R1V> = true;
+#if __cpp_lib_ranges_as_const
+struct R1VC // view on an R1
+{
+ R1& r;
+
+ friend const long* rbegin(R1VC&); // this is not defined
+ friend const int* rbegin(const R1VC& rv) noexcept { return rv.r.rbegin(); }
+
+ // The following ensure that the following are satisfied:
+ // constant_range<const R1VC> && ! constant_range<R1VC>
+ friend int* begin(R1VC&);
+ friend int* end(R1VC&);
+ friend const int* begin(const R1VC&);
+ friend const int* end(const R1VC&);
+};
+
+// Allow ranges::end to work with R1VC&&
+template<> constexpr bool std::ranges::enable_borrowed_range<R1VC> = true;
+#endif
+
void
test01()
{
@@ -53,8 +73,24 @@ test01()
VERIFY( std::ranges::crbegin(c) == std::ranges::rbegin(c) );
R1V v{r};
- const R1V cv{r};
+#if ! __cpp_lib_ranges_as_const
+ VERIFY( std::ranges::crbegin(v) == std::ranges::rbegin(c) );
VERIFY( std::ranges::crbegin(std::move(v)) == std::ranges::rbegin(c) );
+#else
+ // constant_range<const R1V> is not satisfied, so crbegin(v) == rbegin(v).
+ VERIFY( std::ranges::crbegin(v) == (long*)nullptr );
+ VERIFY( std::ranges::crbegin(std::move(v)) == (long*)nullptr );
+ R1VC v2{r};
+ // But constant_range<const R1VC> is satisfied:
+ VERIFY( std::ranges::crbegin(v2) == std::ranges::rbegin(c) );
+ VERIFY( std::ranges::crbegin(std::move(v2)) == std::ranges::rbegin(c) );
+ const R1VC cv2{r};
+ VERIFY( std::ranges::crbegin(cv2) == std::ranges::rbegin(c) );
+ VERIFY( std::ranges::crbegin(std::move(cv2)) == std::ranges::rbegin(c) );
+#endif
+
+ const R1V cv{r};
+ VERIFY( std::ranges::crbegin(cv) == std::ranges::rbegin(c) );
VERIFY( std::ranges::crbegin(std::move(cv)) == std::ranges::rbegin(c) );
}
diff --git a/libstdc++-v3/testsuite/std/ranges/access/crend.cc b/libstdc++-v3/testsuite/std/ranges/access/crend.cc
index a7e033f..2e4c0f3 100644
--- a/libstdc++-v3/testsuite/std/ranges/access/crend.cc
+++ b/libstdc++-v3/testsuite/std/ranges/access/crend.cc
@@ -86,18 +86,47 @@ struct R3
friend const int* rend(const R3& r) { return &r.i; }
};
-// N.B. this is a lie, rend on an R3 rvalue will return a dangling pointer.
-template<> constexpr bool std::ranges::enable_borrowed_range<R3> = true;
+struct R4
+{
+ int i = 0;
+
+ // These members mean that range<R4> and range<const R4> are satisfied.
+ const short* begin() const { return 0; }
+ const short* end() const { return 0; }
+
+ const int* rbegin() const noexcept { return &i + 1; }
+ const long* rend() const noexcept { return nullptr; } // not a sentinel for rbegin()
+
+ friend const long* rbegin(const R4&) noexcept { return nullptr; }
+ friend const int* rend(const R4& r) { return &r.i; }
+};
void
test03()
{
R3 r;
const R3& c = r;
+#if ! __cpp_lib_ranges_as_const
VERIFY( std::ranges::crend(r) == std::ranges::rend(c) );
static_assert( !noexcept(std::ranges::crend(r)) );
+#else
+ // constant_range<const R3> is not satisfied, so crend(r) is equivalent
+ // to const_sentinel{rend(r)}, which is ill-formed because range<R3>
+ // is not satisfied.
+ static_assert( not std::ranges::range<R3> );
+ static_assert( not std::ranges::range<const R3> );
+#endif
VERIFY( std::ranges::crend(c) == std::ranges::rend(c) );
static_assert( !noexcept(std::ranges::crend(c)) );
+
+ R4 r4;
+ const R4& c4 = r4;
+ auto b = std::ranges::rbegin(r4);
+ auto s0 = std::ranges::rend(r4);
+ static_assert( std::ranges::__access::__adl_rend<R4&> );
+ auto s = std::ranges::crend(r4);
+ auto s2 = std::ranges::rend(c4);
+ // VERIFY( std::ranges::crend(r4) == std::ranges::rend(c4) );
}
void
diff --git a/libstdc++-v3/testsuite/std/ranges/adaptors/take.cc b/libstdc++-v3/testsuite/std/ranges/adaptors/take.cc
index 290b5c2..a1f6068 100644
--- a/libstdc++-v3/testsuite/std/ranges/adaptors/take.cc
+++ b/libstdc++-v3/testsuite/std/ranges/adaptors/take.cc
@@ -94,8 +94,10 @@ test05()
// Verify that _Sentinel<false> is implicitly convertible to _Sentinel<true>.
static_assert(!ranges::common_range<decltype(v)>);
+#if ! __cpp_lib_ranges_as_const
static_assert(!std::same_as<decltype(ranges::end(v)),
decltype(ranges::cend(v))>);
+#endif
auto b = ranges::cend(v);
b = ranges::end(v);
}
diff --git a/libstdc++-v3/testsuite/std/ranges/adaptors/take_while.cc b/libstdc++-v3/testsuite/std/ranges/adaptors/take_while.cc
index 4606077..098091e 100644
--- a/libstdc++-v3/testsuite/std/ranges/adaptors/take_while.cc
+++ b/libstdc++-v3/testsuite/std/ranges/adaptors/take_while.cc
@@ -64,8 +64,10 @@ test03()
// Verify that _Sentinel<false> is implicitly convertible to _Sentinel<true>.
static_assert(!ranges::common_range<decltype(v)>);
+#if ! __cpp_lib_ranges_as_const
static_assert(!std::same_as<decltype(ranges::end(v)),
decltype(ranges::cend(v))>);
+#endif
auto b = ranges::cend(v);
b = ranges::end(v);
}
diff --git a/libstdc++-v3/testsuite/std/ranges/adaptors/transform.cc b/libstdc++-v3/testsuite/std/ranges/adaptors/transform.cc
index 9d52cb0..d9801d5 100644
--- a/libstdc++-v3/testsuite/std/ranges/adaptors/transform.cc
+++ b/libstdc++-v3/testsuite/std/ranges/adaptors/transform.cc
@@ -108,16 +108,20 @@ test05()
auto r = ranges::subrange{i, std::default_sentinel};
auto v = r | views::transform(std::negate{});
+#if ! __cpp_lib_ranges_as_const
// Verify that _Iterator<false> is implicitly convertible to _Iterator<true>.
static_assert(!std::same_as<decltype(ranges::begin(v)),
decltype(ranges::cbegin(v))>);
+#endif
auto a = ranges::cbegin(v);
a = ranges::begin(v);
+#if ! __cpp_lib_ranges_as_const
// Verify that _Sentinel<false> is implicitly convertible to _Sentinel<true>.
static_assert(!ranges::common_range<decltype(v)>);
static_assert(!std::same_as<decltype(ranges::end(v)),
decltype(ranges::cend(v))>);
+#endif
auto b = ranges::cend(v);
b = ranges::end(v);
}