Fix handling of arrays in range access customization points
[official-gcc.git] / libstdc++-v3 / testsuite / std / ranges / access / begin.cc
blob100dcf69c6ec8538aa0958f2133b0bb55b1931a0
1 // Copyright (C) 2019 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.
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 } }
21 #include <iterator> // N.B. should be <ranges>
22 #include <testsuite_hooks.h>
23 #include <testsuite_iterators.h>
25 using std::same_as;
27 void
28 test01()
30 int a[2] = {};
32 static_assert(same_as<decltype(std::ranges::begin(a)), decltype(a + 0)>);
33 static_assert(noexcept(std::ranges::begin(a)));
34 VERIFY( std::ranges::begin(a) == (a + 0) );
36 constexpr long b[2] = { };
37 static_assert( std::ranges::begin(b) == (b + 0) );
39 struct Incomplete;
40 using A = Incomplete[]; // unbounded array of incomplete type
41 extern A& f();
42 static_assert( same_as<decltype(std::ranges::begin(f())), Incomplete*> );
45 void
46 test02()
48 using __gnu_test::test_range;
49 using __gnu_test::random_access_iterator_wrapper;
50 using __gnu_test::input_iterator_wrapper;
51 using __gnu_test::output_iterator_wrapper;
53 int a[] = { 0, 1 };
55 test_range<int, random_access_iterator_wrapper> r(a);
56 static_assert(same_as<decltype(std::ranges::begin(r)), decltype(r.begin())>);
57 VERIFY( std::ranges::begin(r) == r.begin() );
59 test_range<int, input_iterator_wrapper> i(a);
60 static_assert(same_as<decltype(std::ranges::begin(i)), decltype(i.begin())>);
61 VERIFY( std::ranges::begin(i) == i.begin() );
63 test_range<int, output_iterator_wrapper> o(a);
64 static_assert(same_as<decltype(std::ranges::begin(o)), decltype(o.begin())>);
65 *std::ranges::begin(o) = 99;
66 VERIFY( a[0] == 99 );
69 struct R
71 int a[4] = { 0, 1, 2, 3 };
73 friend int* begin(R& r) { return r.a + 0; }
74 friend int* begin(R&& r) { return r.a + 1; }
75 friend const int* begin(const R& r) noexcept { return r.a + 2; }
76 friend const int* begin(const R&& r) noexcept { return r.a + 3; }
79 void
80 test03()
82 R r;
83 const R& c = r;
85 static_assert(same_as<decltype(std::ranges::begin(r)), decltype(begin(r))>);
86 static_assert(!noexcept(std::ranges::begin(r)));
87 VERIFY( std::ranges::begin(r) == begin(r) );
89 static_assert(same_as<decltype(std::ranges::begin(std::move(r))),
90 decltype(begin(std::move(r)))>);
91 static_assert(!noexcept(std::ranges::begin(std::move(r))));
92 VERIFY( std::ranges::begin(std::move(r)) == begin(std::move(r)) );
95 static_assert(same_as<decltype(std::ranges::begin(c)), decltype(begin(c))>);
96 static_assert(noexcept(std::ranges::begin(c)));
97 VERIFY( std::ranges::begin(c) == begin(c) );
99 static_assert(same_as<decltype(std::ranges::begin(std::move(c))),
100 decltype(begin(std::move(c)))>);
101 static_assert(noexcept(std::ranges::begin(std::move(c))));
102 VERIFY( std::ranges::begin(std::move(c)) == begin(std::move(c)) );
105 struct RR
107 short s = 0;
108 long l = 0;
109 int a[4] = { 0, 1, 2, 3 };
111 short* begin() noexcept { return &s; }
112 const long* begin() const { return &l; }
114 friend int* begin(RR& r) { return r.a + 0; }
115 friend int* begin(RR&& r) { return r.a + 1; }
116 friend const int* begin(const RR& r) { return r.a + 2; }
117 friend const int* begin(const RR&& r) noexcept { return r.a + 3; }
120 void
121 test04()
123 RR r;
124 const RR& c = r;
125 VERIFY( std::ranges::begin(r) == &r.s );
126 static_assert(noexcept(std::ranges::begin(r)));
128 VERIFY( std::ranges::begin(std::move(r)) == r.a + 1 );
129 static_assert(!noexcept(std::ranges::begin(std::move(r))));
131 VERIFY( std::ranges::begin(c) == &r.l );
132 static_assert(!noexcept(std::ranges::begin(c)));
134 VERIFY( std::ranges::begin(std::move(c)) == r.a + 3 );
135 static_assert(noexcept(std::ranges::begin(std::move(c))));
139 main()
141 test01();
142 test02();
143 test03();
144 test04();