]> git.ipfire.org Git - thirdparty/gcc.git/blob - libstdc++-v3/testsuite/std/ranges/access/cend.cc
Update copyright years.
[thirdparty/gcc.git] / libstdc++-v3 / testsuite / std / ranges / access / cend.cc
1 // Copyright (C) 2019-2021 Free Software Foundation, Inc.
2 //
3 // This file is part of the GNU ISO C++ Library. This library is free
4 // software; you can redistribute it and/or modify it under the
5 // terms of the GNU General Public License as published by the
6 // Free Software Foundation; either version 3, or (at your option)
7 // any later version.
8
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13
14 // You should have received a copy of the GNU General Public License along
15 // with this library; see the file COPYING3. If not see
16 // <http://www.gnu.org/licenses/>.
17
18 // { dg-options "-std=gnu++2a" }
19 // { dg-do run { target c++2a } }
20
21 #include <ranges>
22 #include <testsuite_hooks.h>
23
24 using std::same_as;
25
26 void
27 test01()
28 {
29 int a[2] = {};
30
31 static_assert(same_as<decltype(std::ranges::cend(a)), const int*>);
32 static_assert(noexcept(std::ranges::cend(a)));
33 VERIFY( std::ranges::cend(a) == (a + 2) );
34 }
35
36 struct R
37 {
38 int a[4] = { 0, 1, 2, 3 };
39
40 const int* begin() const { return nullptr; }
41 friend const int* begin(const R&& r) noexcept { return nullptr; }
42
43 // Should be ignored because it doesn't return a sentinel for int*
44 const long* end() const { return nullptr; }
45
46 friend int* end(R& r) { return r.a + 0; }
47 friend int* end(R&& r) { return r.a + 1; }
48 friend const int* end(const R& r) noexcept { return r.a + 2; }
49 friend const int* end(const R&& r) noexcept { return r.a + 3; }
50 };
51
52 struct RV // view on an R
53 {
54 R& r;
55
56 friend const int* begin(RV& rv) { return rv.r.begin(); }
57 friend int* end(RV& rv) { return end(rv.r); }
58 friend const int* begin(const RV& rv) noexcept { return rv.r.begin(); }
59 friend const int* end(const RV& rv) noexcept { return end(std::as_const(rv.r)); }
60 };
61
62 // Allow ranges::end to work with RV&&
63 template<> constexpr bool std::ranges::enable_borrowed_range<RV> = true;
64
65 void
66 test03()
67 {
68 R r;
69 const R& c = r;
70 VERIFY( std::ranges::cend(r) == std::ranges::end(c) );
71 VERIFY( std::ranges::cend(c) == std::ranges::end(c) );
72
73 RV v{r};
74 const RV cv{r};
75 VERIFY( std::ranges::cend(std::move(v)) == std::ranges::end(c) );
76 VERIFY( std::ranges::cend(std::move(cv)) == std::ranges::end(c) );
77 }
78
79 struct RR
80 {
81 short s = 0;
82 long l = 0;
83 int a[4] = { 0, 1, 2, 3 };
84
85 const void* begin() const; // return type not an iterator
86
87 friend int* end(RR&) { throw 1; }
88 short* end() noexcept { return &s; }
89
90 friend const long* begin(const RR&) noexcept;
91 const long* end() const { return &l; }
92
93 friend int* begin(RR&&) noexcept;
94 friend int* end(RR&& r) { return r.a + 1; }
95
96 friend const int* begin(const RR&&) noexcept;
97 friend const int* end(const RR&& r) noexcept { return r.a + 3; }
98 };
99
100 // N.B. this is a lie, begin/end on an RR rvalue will return a dangling pointer.
101 template<> constexpr bool std::ranges::enable_borrowed_range<RR> = true;
102
103 void
104 test04()
105 {
106 RR r;
107 const RR& c = r;
108 VERIFY( std::ranges::cend(r) == std::ranges::end(c) );
109 VERIFY( std::ranges::cend(c) == std::ranges::end(c) );
110
111 VERIFY( std::ranges::cend(std::move(r)) == std::ranges::end(c) );
112 VERIFY( std::ranges::cend(std::move(c)) == std::ranges::end(c) );
113 }
114
115 int
116 main()
117 {
118 test01();
119 test03();
120 test04();
121 }