]> git.ipfire.org Git - thirdparty/gcc.git/blame - libstdc++-v3/testsuite/std/ranges/access/end.cc
Update copyright years.
[thirdparty/gcc.git] / libstdc++-v3 / testsuite / std / ranges / access / end.cc
CommitLineData
a945c346 1// Copyright (C) 2019-2024 Free Software Foundation, Inc.
6d0dff49
JW
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
d4ac20b0 18// { dg-do run { target c++20 } }
6d0dff49 19
328b52d6 20#include <ranges>
261d5a4a 21#include <utility> // as_const
6d0dff49
JW
22#include <testsuite_hooks.h>
23#include <testsuite_iterators.h>
24
b9e35ee6
JW
25static_assert(__gnu_test::is_customization_point_object(std::ranges::end));
26
6d0dff49
JW
27using std::same_as;
28
29void
30test01()
31{
32 int a[2] = {};
33
5cd2e126
JW
34 // t + extent_v<T> if E is of array type T.
35
6d0dff49
JW
36 static_assert(same_as<decltype(std::ranges::end(a)), decltype(a + 2)>);
37 static_assert(noexcept(std::ranges::end(a)));
38 VERIFY( std::ranges::end(a) == (a + 2) );
39}
40
41void
42test02()
43{
44 using __gnu_test::test_range;
45 using __gnu_test::random_access_iterator_wrapper;
46 using __gnu_test::input_iterator_wrapper;
47 using __gnu_test::output_iterator_wrapper;
48
49 int a[] = { 0, 1 };
50
5cd2e126
JW
51 // Otherwise, decay-copy(t.end()) if it is a valid expression
52 // and its type S models sentinel_for<decltype(ranges::begin(E))>.
53
6d0dff49
JW
54 test_range<int, random_access_iterator_wrapper> r(a);
55 static_assert(same_as<decltype(std::ranges::end(r)), decltype(r.end())>);
5cd2e126 56 VERIFY( std::ranges::end(r) == std::ranges::next(r.begin(), 2) );
6d0dff49
JW
57
58 test_range<int, input_iterator_wrapper> i(a);
59 static_assert(same_as<decltype(std::ranges::end(i)), decltype(i.end())>);
5cd2e126 60 VERIFY( std::ranges::end(i) == std::ranges::next(i.begin(), 2) );
6d0dff49
JW
61
62 test_range<int, output_iterator_wrapper> o(a);
63 static_assert(same_as<decltype(std::ranges::end(o)), decltype(o.end())>);
64 VERIFY( std::ranges::end(o) == std::ranges::next(o.begin(), 2) );
65}
66
67struct R
68{
69 int a[4] = { 0, 1, 2, 3 };
70
b3ffa117
JW
71 const int* begin() const;
72 friend int* begin(R&&) noexcept;
73 friend const int* begin(const R&&) noexcept;
6d0dff49
JW
74
75 // Should be ignored because it doesn't return a sentinel for int*
b3ffa117 76 const long* end() const;
6d0dff49
JW
77
78 friend int* end(R& r) { return r.a + 0; }
79 friend int* end(R&& r) { return r.a + 1; }
80 friend const int* end(const R& r) noexcept { return r.a + 2; }
81 friend const int* end(const R&& r) noexcept { return r.a + 3; }
82};
83
b5b2e387
JW
84struct RV // view on an R
85{
86 R& r;
87
88 const int* begin() const;
89
90 friend int* end(RV& v) noexcept { return end(v.r); }
91 friend const int* end(const RV& v) { return end(std::as_const(v.r)); }
92};
93
94// Allow ranges::begin to work with RV&&
15411a64 95template<> constexpr bool std::ranges::enable_borrowed_range<RV> = true;
b5b2e387 96
6d0dff49
JW
97void
98test03()
99{
100 R r;
101 const R& c = r;
102
5cd2e126
JW
103 // Otherwise, decay-copy(end(t)) if it is a valid expression
104 // and its type S models sentinel_for<decltype(ranges::begin(E))>.
105
6d0dff49
JW
106 static_assert(same_as<decltype(std::ranges::end(r)), decltype(end(r))>);
107 static_assert(!noexcept(std::ranges::end(r)));
108 VERIFY( std::ranges::end(r) == end(r) );
109
6d0dff49
JW
110 static_assert(same_as<decltype(std::ranges::end(c)), decltype(end(c))>);
111 static_assert(noexcept(std::ranges::end(c)));
112 VERIFY( std::ranges::end(c) == end(c) );
113
b5b2e387
JW
114 RV v{r};
115 static_assert(same_as<decltype(std::ranges::end(std::move(v))),
116 decltype(end(r))>);
117 static_assert(noexcept(std::ranges::end(std::move(v))));
118 VERIFY( std::ranges::end(std::move(v)) == end(r) );
119
120 const RV cv{r};
121 static_assert(same_as<decltype(std::ranges::end(std::move(cv))),
122 decltype(end(c))>);
123 static_assert(!noexcept(std::ranges::end(std::move(cv))));
124 VERIFY( std::ranges::end(std::move(cv)) == end(c) );
6d0dff49
JW
125}
126
127struct RR
128{
129 short s = 0;
130 long l = 0;
131 int a[4] = { 0, 1, 2, 3 };
132
b3ffa117 133 const void* begin() const; // return type not an iterator
6d0dff49 134
b3ffa117 135 friend const short* begin(RR&) noexcept;
6d0dff49 136 short* end() noexcept { return &s; }
b3ffa117
JW
137
138 friend const long* begin(const RR&) noexcept;
6d0dff49
JW
139 const long* end() const { return &l; }
140
b3ffa117
JW
141 friend const int* begin(RR&&) noexcept;
142 friend int* end(RR&) { throw 1; } // not valid for rvalues
6d0dff49 143 friend int* end(RR&& r) { return r.a + 1; }
b3ffa117
JW
144
145 friend const int* begin(const RR&&) noexcept;
146 friend const int* end(const RR&) { throw 1; } // not valid for rvalues
6d0dff49
JW
147 friend const int* end(const RR&& r) noexcept { return r.a + 3; }
148};
149
b5b2e387 150// N.B. this is a lie, end on an RR rvalue will return a dangling pointer.
15411a64 151template<> constexpr bool std::ranges::enable_borrowed_range<RR> = true;
b5b2e387 152
6d0dff49
JW
153void
154test04()
155{
156 RR r;
157 const RR& c = r;
158 VERIFY( std::ranges::end(r) == &r.s );
159 static_assert(noexcept(std::ranges::end(r)));
160
b5b2e387
JW
161 VERIFY( std::ranges::end(std::move(r)) == &r.s );
162 static_assert(noexcept(std::ranges::end(std::move(r))));
6d0dff49
JW
163
164 VERIFY( std::ranges::end(c) == &r.l );
165 static_assert(!noexcept(std::ranges::end(c)));
166
b5b2e387
JW
167 VERIFY( std::ranges::end(std::move(c)) == &r.l );
168 static_assert(!noexcept(std::ranges::end(std::move(c))));
6d0dff49
JW
169}
170
171int
172main()
173{
174 test01();
175 test02();
176 test03();
177 test04();
178}