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