]>
git.ipfire.org Git - thirdparty/gcc.git/blob - libstdc++-v3/testsuite/std/ranges/access/cend.cc
1 // Copyright (C) 2019-2023 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 <utility> // as_const
23 #include <testsuite_hooks.h>
24 #include <testsuite_iterators.h>
26 static_assert(__gnu_test::is_customization_point_object(std::ranges::cend
));
35 static_assert(same_as
<decltype(std::ranges::cend(a
)), const int*>);
36 static_assert(noexcept(std::ranges::cend(a
)));
37 VERIFY( std::ranges::cend(a
) == (a
+ 2) );
42 int a
[4] = { 0, 1, 2, 3 };
44 const int* begin() const { return nullptr; }
45 friend const int* begin(const R
&& r
) noexcept
{ return nullptr; }
47 // Should be ignored because it doesn't return a sentinel for int*
48 const long* end() const { return nullptr; }
50 friend int* end(R
& r
) { return r
.a
+ 0; }
51 friend int* end(R
&& r
) { return r
.a
+ 1; }
52 friend const int* end(const R
& r
) noexcept
{ return r
.a
+ 2; }
53 friend const int* end(const R
&& r
) noexcept
{ return r
.a
+ 3; }
56 struct RV
// view on an R
60 friend const int* begin(RV
& rv
) { return rv
.r
.begin(); }
61 friend int* end(RV
& rv
) { return end(rv
.r
); }
62 friend const int* begin(const RV
& rv
) noexcept
{ return rv
.r
.begin(); }
63 friend const int* end(const RV
& rv
) noexcept
{ return end(std::as_const(rv
.r
)); }
66 // Allow ranges::end to work with RV&&
67 template<> constexpr bool std::ranges::enable_borrowed_range
<RV
> = true;
74 VERIFY( std::ranges::cend(r
) == std::ranges::end(c
) );
75 VERIFY( std::ranges::cend(c
) == std::ranges::end(c
) );
79 VERIFY( std::ranges::cend(std::move(v
)) == std::ranges::end(c
) );
80 VERIFY( std::ranges::cend(std::move(cv
)) == std::ranges::end(c
) );
87 int a
[4] = { 0, 1, 2, 3 };
89 const void* begin() const; // return type not an iterator
91 friend int* end(RR
&) { throw 1; }
92 short* end() noexcept
{ return &s
; }
94 friend const long* begin(const RR
&) noexcept
;
95 const long* end() const { return &l
; }
97 friend int* begin(RR
&&) noexcept
;
98 friend int* end(RR
&& r
) { return r
.a
+ 1; }
100 friend const int* begin(const RR
&&) noexcept
;
101 friend const int* end(const RR
&& r
) noexcept
{ return r
.a
+ 3; }
104 // N.B. this is a lie, begin/end on an RR rvalue will return a dangling pointer.
105 template<> constexpr bool std::ranges::enable_borrowed_range
<RR
> = true;
112 VERIFY( std::ranges::cend(r
) == std::ranges::end(c
) );
113 VERIFY( std::ranges::cend(c
) == std::ranges::end(c
) );
115 VERIFY( std::ranges::cend(std::move(r
)) == std::ranges::end(c
) );
116 VERIFY( std::ranges::cend(std::move(c
)) == std::ranges::end(c
) );