]> git.ipfire.org Git - thirdparty/gcc.git/blob - libstdc++-v3/testsuite/24_iterators/common_iterator/1.cc
Update copyright years.
[thirdparty/gcc.git] / libstdc++-v3 / testsuite / 24_iterators / common_iterator / 1.cc
1 // Copyright (C) 2019-2023 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 <iterator>
22 #include <testsuite_hooks.h>
23
24 void
25 test01()
26 {
27 using I = std::common_iterator<int*, const int*>;
28 static_assert( std::is_default_constructible_v<I> );
29 static_assert( std::is_copy_constructible_v<I> );
30 static_assert( std::is_move_constructible_v<I> );
31 static_assert( std::is_copy_assignable_v<I> );
32 static_assert( std::is_move_assignable_v<I> );
33 static_assert( std::is_constructible_v<I, int*> );
34 static_assert( std::is_constructible_v<I, const int*> );
35
36 static_assert( std::is_nothrow_copy_constructible_v<I> ); // GCC extension
37 static_assert( std::is_nothrow_move_constructible_v<I> ); // GCC extension
38 static_assert( std::is_nothrow_copy_assignable_v<I> ); // GCC extension
39 static_assert( std::is_nothrow_move_assignable_v<I> ); // GCC extension
40
41 struct sentinel { operator int*() const noexcept { return nullptr; } };
42 using K = std::common_iterator<int*, sentinel>;
43 static_assert( std::is_constructible_v<I, const K&> );
44 static_assert( std::is_assignable_v<I, const K&> );
45
46 static_assert( std::is_nothrow_assignable_v<I&, const K&> ); // GCC extension
47
48 struct sentinel_throwing { operator int*() const { return nullptr; } };
49 using K_throwing = std::common_iterator<int*, sentinel_throwing>;
50 // Conversion is noexcept(false)
51 static_assert( ! std::is_nothrow_assignable_v<I&, const K_throwing&> );
52
53
54 struct sentinel2
55 {
56 const int* p;
57 sentinel2(const int* p = 0) : p(p) { }
58 bool operator==(const int* p) const { return p == this->p; }
59 };
60
61 using J = std::common_iterator<const int*, sentinel2>;
62 static_assert( std::is_constructible_v<J, const I&> );
63 static_assert( std::is_convertible_v<const I&, J> );
64
65 static_assert( std::is_constructible_v<J, I> );
66 static_assert( std::is_convertible_v<I, J> );
67
68 // Constructor is noexcept(false)
69 static_assert( ! std::is_nothrow_constructible_v<J, I> );
70 }
71
72 void
73 test02()
74 {
75 struct sentinel { int limit; };
76
77 struct iterator
78 {
79 using iterator_category = std::input_iterator_tag;
80 using value_type = int;
81 using difference_type = std::ptrdiff_t;
82 using reference = const int&;
83
84 const int& operator*() const { return counter; }
85
86 iterator& operator++() { ++counter; return *this; }
87
88 iterator operator++(int) { auto i = *this; ++counter; return i; }
89
90 bool operator==(sentinel s) const { return counter == s.limit; }
91
92 int counter = 0;
93 };
94
95 static_assert( std::sentinel_for<sentinel, iterator> );
96
97 int out[5] = { };
98 std::common_iterator<int*, const int*> obegin = std::begin(out);
99 std::common_iterator<int*, const int*> oend = std::cend(out);
100
101 iterator i;
102 sentinel s{5};
103 std::common_iterator<iterator, sentinel> begin = i, end = s;
104 while (begin != end)
105 *obegin++ = *begin++;
106
107 VERIFY(obegin == oend);
108 for (int& i : out)
109 VERIFY( i == (&i - out) );
110 }
111
112 constexpr bool
113 test03()
114 {
115 int arr[2] = { 1, 2 };
116 std::common_iterator<int*, const int*> i = std::ranges::begin(arr);
117 std::common_iterator<int*, const int*> end = std::ranges::cend(arr);
118 VERIFY( i != end );
119 VERIFY( (end - i) == 2 );
120 VERIFY( (i - end) == -2 );
121 auto j = i;
122 VERIFY( j == i );
123 VERIFY( (j - i) == 0 );
124 j = end;
125 VERIFY( j != i );
126 VERIFY( j == end );
127 j = std::ranges::next(i);
128 VERIFY( j != i );
129 VERIFY( j != end );
130 VERIFY( (end - j) == 1 );
131 VERIFY( (j - i) == 1 );
132 VERIFY( (i - j) == -1 );
133 ++j;
134 VERIFY( j == end );
135 VERIFY( (end - j) == 0 );
136 j = i;
137 VERIFY( j == i );
138 VERIFY( (j - end) == -2 );
139 VERIFY( (j - i) == 0 );
140
141 if (std::is_constant_evaluated())
142 return true;
143
144 try
145 {
146 struct S { operator const int*() const { throw 1; } };
147 i = std::common_iterator<int*, S>(S{});
148 VERIFY( false );
149 }
150 catch (int)
151 {
152 }
153
154 return true;
155 }
156
157 static_assert( test03() );
158
159 void
160 test04()
161 {
162 struct X
163 {
164 X(int i) : i(i) { }
165 X(X&& x) : i(x.i) { x.i = -1; }
166 X& operator=(X&& x) { i = x.i; x.i = 0; return *this; }
167 int i;
168 };
169
170 X arr[] = { 1, 2 };
171 std::common_iterator<X*, const X*> i(arr), j(arr+1);
172 std::ranges::iter_swap(i, j);
173 VERIFY( arr[0].i == 2 );
174 VERIFY( arr[1].i == 1 );
175
176 X x = std::ranges::iter_move(i);
177 VERIFY( arr[0].i == -1 );
178 VERIFY( x.i == 2 );
179 }
180
181 constexpr bool
182 test_pr103992()
183 {
184 using C1 = std::common_iterator<std::reverse_iterator<int*>,
185 std::unreachable_sentinel_t>;
186 using C2 = std::common_iterator<std::reverse_iterator<const int*>,
187 std::unreachable_sentinel_t>;
188 C1 c1;
189 C2 c2 = c1;
190 C1 c3 = c1;
191
192 return true;
193 }
194
195 static_assert( test_pr103992() );
196
197 int
198 main()
199 {
200 test01();
201 test02();
202 test03();
203 test04();
204 }