1 // Copyright (C) 2019 Free Software Foundation, Inc.
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)
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.
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/>.
18 // { dg-options "-std=gnu++2a" }
19 // { dg-do run { target c++2a } }
22 #include <testsuite_hooks.h>
23 #include <testsuite_iterators.h>
32 static_assert(same_as
<decltype(std::ranges::end(a
)), decltype(a
+ 2)>);
33 static_assert(noexcept(std::ranges::end(a
)));
34 VERIFY( std::ranges::end(a
) == (a
+ 2) );
40 using __gnu_test::test_range
;
41 using __gnu_test::random_access_iterator_wrapper
;
42 using __gnu_test::input_iterator_wrapper
;
43 using __gnu_test::output_iterator_wrapper
;
47 test_range
<int, random_access_iterator_wrapper
> r(a
);
48 static_assert(same_as
<decltype(std::ranges::end(r
)), decltype(r
.end())>);
49 VERIFY( std::ranges::end(r
) == r
.end() );
51 test_range
<int, input_iterator_wrapper
> i(a
);
52 static_assert(same_as
<decltype(std::ranges::end(i
)), decltype(i
.end())>);
53 VERIFY( std::ranges::end(i
) == i
.end() );
55 test_range
<int, output_iterator_wrapper
> o(a
);
56 static_assert(same_as
<decltype(std::ranges::end(o
)), decltype(o
.end())>);
57 VERIFY( std::ranges::end(o
) == std::ranges::next(o
.begin(), 2) );
62 int a
[4] = { 0, 1, 2, 3 };
64 const int* begin() const;
65 friend int* begin(R
&&) noexcept
;
66 friend const int* begin(const R
&&) noexcept
;
68 // Should be ignored because it doesn't return a sentinel for int*
69 const long* end() const;
71 friend int* end(R
& r
) { return r
.a
+ 0; }
72 friend int* end(R
&& r
) { return r
.a
+ 1; }
73 friend const int* end(const R
& r
) noexcept
{ return r
.a
+ 2; }
74 friend const int* end(const R
&& r
) noexcept
{ return r
.a
+ 3; }
77 struct RV
// view on an R
81 const int* begin() const;
83 friend int* end(RV
& v
) noexcept
{ return end(v
.r
); }
84 friend const int* end(const RV
& v
) { return end(std::as_const(v
.r
)); }
87 // Allow ranges::begin to work with RV&&
88 template<> constexpr bool std::ranges::enable_safe_range
<RV
> = true;
96 static_assert(same_as
<decltype(std::ranges::end(r
)), decltype(end(r
))>);
97 static_assert(!noexcept(std::ranges::end(r
)));
98 VERIFY( std::ranges::end(r
) == end(r
) );
100 static_assert(same_as
<decltype(std::ranges::end(c
)), decltype(end(c
))>);
101 static_assert(noexcept(std::ranges::end(c
)));
102 VERIFY( std::ranges::end(c
) == end(c
) );
105 static_assert(same_as
<decltype(std::ranges::end(std::move(v
))),
107 static_assert(noexcept(std::ranges::end(std::move(v
))));
108 VERIFY( std::ranges::end(std::move(v
)) == end(r
) );
111 static_assert(same_as
<decltype(std::ranges::end(std::move(cv
))),
113 static_assert(!noexcept(std::ranges::end(std::move(cv
))));
114 VERIFY( std::ranges::end(std::move(cv
)) == end(c
) );
121 int a
[4] = { 0, 1, 2, 3 };
123 const void* begin() const; // return type not an iterator
125 friend const short* begin(RR
&) noexcept
;
126 short* end() noexcept
{ return &s
; }
128 friend const long* begin(const RR
&) noexcept
;
129 const long* end() const { return &l
; }
131 friend const int* begin(RR
&&) noexcept
;
132 friend int* end(RR
&) { throw 1; } // not valid for rvalues
133 friend int* end(RR
&& r
) { return r
.a
+ 1; }
135 friend const int* begin(const RR
&&) noexcept
;
136 friend const int* end(const RR
&) { throw 1; } // not valid for rvalues
137 friend const int* end(const RR
&& r
) noexcept
{ return r
.a
+ 3; }
140 // N.B. this is a lie, end on an RR rvalue will return a dangling pointer.
141 template<> constexpr bool std::ranges::enable_safe_range
<RR
> = true;
148 VERIFY( std::ranges::end(r
) == &r
.s
);
149 static_assert(noexcept(std::ranges::end(r
)));
151 VERIFY( std::ranges::end(std::move(r
)) == &r
.s
);
152 static_assert(noexcept(std::ranges::end(std::move(r
))));
154 VERIFY( std::ranges::end(c
) == &r
.l
);
155 static_assert(!noexcept(std::ranges::end(c
)));
157 VERIFY( std::ranges::end(std::move(c
)) == &r
.l
);
158 static_assert(!noexcept(std::ranges::end(std::move(c
))));