]>
Commit | Line | Data |
---|---|---|
a945c346 | 1 | // Copyright (C) 2016-2024 Free Software Foundation, Inc. |
8e14a10c VV |
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 | ||
6458742a | 18 | // { dg-do run { target c++17 } } |
8e14a10c VV |
19 | |
20 | #include <memory> | |
21 | #include <testsuite_hooks.h> | |
d67be443 | 22 | #include <testsuite_iterators.h> |
8e14a10c | 23 | #include <string> |
d67dd0be | 24 | #include <vector> |
377f30c0 | 25 | #include <sstream> |
8e14a10c VV |
26 | |
27 | int del_count = 0; | |
377f30c0 VV |
28 | int ctor_count = 0; |
29 | int throw_after = 0; | |
8e14a10c VV |
30 | |
31 | struct DelCount | |
32 | { | |
33 | ~DelCount() { ++del_count; } | |
34 | }; | |
35 | ||
377f30c0 VV |
36 | struct ThrowAfterN |
37 | { | |
38 | ThrowAfterN() | |
39 | { | |
40 | if (++ctor_count == throw_after) { | |
41 | std::ostringstream os; | |
42 | os << "ThrowAfterN(), ctor_count: " << ctor_count | |
43 | << " throw_after: " << throw_after << std::endl; | |
44 | throw std::runtime_error(os.str()); | |
45 | } | |
46 | } | |
47 | ThrowAfterN(ThrowAfterN&&) | |
48 | { | |
49 | if (++ctor_count == throw_after) { | |
50 | std::ostringstream os; | |
51 | os << "ThrowAfterN(), ctor_count: " << ctor_count | |
52 | << " throw_after: " << throw_after << std::endl; | |
53 | throw std::runtime_error(os.str()); | |
54 | } | |
55 | } | |
56 | DelCount dc; | |
57 | }; | |
58 | ||
d67be443 JW |
59 | template<typename T> |
60 | using FwdIteratorRange | |
61 | = __gnu_test::test_container<T, __gnu_test::forward_iterator_wrapper>; | |
62 | ||
8e14a10c VV |
63 | void test01() |
64 | { | |
65 | char test_data[] = "123456"; | |
d67be443 JW |
66 | FwdIteratorRange<char> r(test_data); |
67 | std::uninitialized_default_construct(std::begin(r), std::end(r)); | |
8e14a10c VV |
68 | VERIFY(std::string(test_data) == "123456"); |
69 | } | |
70 | ||
71 | void test02() | |
72 | { | |
73 | char test_data[] = "123456"; | |
d67be443 JW |
74 | FwdIteratorRange<char> r(test_data); |
75 | std::uninitialized_value_construct(std::begin(r), std::end(r)); | |
8e14a10c VV |
76 | VERIFY(std::string(test_data, 6) == std::string("\0\0\0\0\0\0", 6)); |
77 | } | |
78 | ||
79 | void test03() | |
80 | { | |
81 | char test_data[] = "123456"; | |
d67be443 JW |
82 | FwdIteratorRange<char> r(test_data); |
83 | auto end = std::uninitialized_default_construct_n(std::begin(r), 6); | |
8e14a10c | 84 | VERIFY(std::string(test_data) == "123456"); |
d67be443 | 85 | VERIFY( end == std::next(r.begin(), 6) ); |
8e14a10c VV |
86 | } |
87 | ||
88 | void test04() | |
89 | { | |
90 | char test_data[] = "123456"; | |
d67be443 JW |
91 | FwdIteratorRange<char> r(test_data); |
92 | auto end = std::uninitialized_value_construct_n(std::begin(r), 5); | |
08a53a2e | 93 | VERIFY(std::string(test_data, 6) == std::string("\0\0\0\0\0" "6", 6)); |
d67be443 | 94 | VERIFY( end == std::next(r.begin(), 5) ); |
8e14a10c VV |
95 | } |
96 | ||
97 | void test05() | |
98 | { | |
99 | del_count = 0; | |
100 | DelCount* x = (DelCount*)malloc(sizeof(DelCount)); | |
101 | new (x) DelCount; | |
102 | std::destroy_at(&x[0]); | |
103 | VERIFY(del_count == 1); | |
104 | del_count = 0; | |
105 | free(x); | |
106 | } | |
107 | ||
108 | void test06() | |
109 | { | |
110 | del_count = 0; | |
111 | DelCount* x = (DelCount*)malloc(sizeof(DelCount)*10); | |
112 | for (int i = 0; i < 10; ++i) new (x+i) DelCount; | |
113 | std::destroy(x, x+10); | |
114 | VERIFY(del_count == 10); | |
115 | del_count = 0; | |
116 | free(x); | |
117 | } | |
118 | ||
119 | void test07() | |
120 | { | |
121 | del_count = 0; | |
122 | DelCount* x = (DelCount*)malloc(sizeof(DelCount)*10); | |
123 | for (int i = 0; i < 10; ++i) new (x+i) DelCount; | |
08a53a2e | 124 | auto end = std::destroy_n(x, 10); |
8e14a10c | 125 | VERIFY(del_count == 10); |
08a53a2e | 126 | VERIFY( end == x + 10 ); |
8e14a10c VV |
127 | del_count = 0; |
128 | free(x); | |
129 | } | |
130 | ||
d67be443 JW |
131 | struct MoveOnly |
132 | { | |
133 | MoveOnly() : val(-1) { } | |
134 | MoveOnly(MoveOnly&& m) : val(m.val) { m.val = -1; } | |
135 | int val; | |
136 | }; | |
137 | ||
8e14a10c VV |
138 | void test08() |
139 | { | |
d67be443 JW |
140 | MoveOnly source[10]; |
141 | for (int i = 0; i < 10; ++i) source[i].val = i; | |
142 | FwdIteratorRange<MoveOnly> src(source); | |
143 | MoveOnly* target = (MoveOnly*)malloc(sizeof(MoveOnly)*10); | |
144 | FwdIteratorRange<MoveOnly> tgt(target, target+10); | |
145 | auto end = std::uninitialized_move(src.begin(), src.end(), tgt.begin()); | |
146 | VERIFY( end == std::next(tgt.begin(), 10) ); | |
147 | for (const auto& x : source) VERIFY( x.val == -1 ); | |
148 | for (int i = 0; i < 10; ++i) VERIFY( target[i].val == i ); | |
149 | auto end2 = std::destroy_n(tgt.begin(), 10); | |
150 | VERIFY( end2 == std::next(tgt.begin(), 10) ); | |
8e14a10c VV |
151 | free(target); |
152 | } | |
153 | ||
154 | void test09() | |
155 | { | |
d67be443 JW |
156 | MoveOnly source[10]; |
157 | for (int i = 0; i < 10; ++i) source[i].val = i; | |
158 | FwdIteratorRange<MoveOnly> src(source); | |
159 | MoveOnly* target = (MoveOnly*)malloc(sizeof(MoveOnly)*10); | |
160 | FwdIteratorRange<MoveOnly> tgt(target, target+10); | |
161 | auto end = std::uninitialized_move_n(src.begin(), 10, tgt.begin()); | |
162 | VERIFY( end.first == std::next(src.begin(), 10) ); | |
163 | VERIFY( end.second == std::next(tgt.begin(), 10) ); | |
164 | for (const auto& x : source) VERIFY( x.val == -1 ); | |
165 | for (int i = 0; i < 10; ++i) VERIFY( target[i].val == i ); | |
166 | auto end2 = std::destroy_n(tgt.begin(), 10); | |
167 | VERIFY( end2 == std::next(tgt.begin(), 10) ); | |
8e14a10c VV |
168 | free(target); |
169 | } | |
170 | ||
377f30c0 VV |
171 | void test10() |
172 | { | |
173 | char* x = (char*)malloc(sizeof(char)*10); | |
174 | for (int i = 0; i < 10; ++i) new (x+i) char; | |
d67be443 JW |
175 | FwdIteratorRange<char> r(x, x+10); |
176 | std::destroy(r.begin(), r.end()); | |
377f30c0 VV |
177 | free(x); |
178 | } | |
179 | ||
180 | void test11() | |
181 | { | |
182 | char* x = (char*)malloc(sizeof(char)*10); | |
183 | for (int i = 0; i < 10; ++i) new (x+i) char; | |
d67be443 JW |
184 | FwdIteratorRange<char> r(x, x+10); |
185 | auto end = std::destroy_n(r.begin(), 10); | |
186 | VERIFY( end == std::next(r.begin(), 10) ); | |
377f30c0 VV |
187 | free(x); |
188 | } | |
189 | ||
190 | void test12() | |
191 | { | |
192 | throw_after = 5; | |
193 | del_count = 0; | |
194 | ctor_count = 0; | |
195 | ThrowAfterN* target = | |
196 | (ThrowAfterN*)malloc(sizeof(ThrowAfterN)*10); | |
197 | try { | |
198 | std::uninitialized_default_construct(target, target+10); | |
199 | } catch (...) { | |
200 | } | |
32aaf6ef | 201 | free(target); |
377f30c0 VV |
202 | VERIFY(ctor_count == 5); |
203 | VERIFY(del_count == 5); | |
204 | throw_after = 0; | |
205 | del_count = 0; | |
206 | ctor_count = 0; | |
207 | } | |
208 | ||
209 | void test13() | |
210 | { | |
211 | throw_after = 5; | |
212 | del_count = 0; | |
213 | ctor_count = 0; | |
214 | ThrowAfterN* target = | |
215 | (ThrowAfterN*)malloc(sizeof(ThrowAfterN)*10); | |
216 | try { | |
217 | std::uninitialized_value_construct(target, target+10); | |
218 | } catch (...) { | |
219 | } | |
32aaf6ef | 220 | free(target); |
377f30c0 VV |
221 | VERIFY(ctor_count == 5); |
222 | VERIFY(del_count == 5); | |
223 | throw_after = 0; | |
224 | del_count = 0; | |
225 | ctor_count = 0; | |
226 | } | |
227 | ||
228 | void test14() | |
229 | { | |
230 | throw_after = 5; | |
231 | del_count = 0; | |
232 | ctor_count = 0; | |
233 | ThrowAfterN* target = | |
234 | (ThrowAfterN*)malloc(sizeof(ThrowAfterN)*10); | |
235 | try { | |
236 | std::uninitialized_default_construct_n(target, 10); | |
237 | } catch (...) { | |
238 | } | |
32aaf6ef | 239 | free(target); |
377f30c0 VV |
240 | VERIFY(ctor_count == 5); |
241 | VERIFY(del_count == 5); | |
242 | throw_after = 0; | |
243 | del_count = 0; | |
244 | ctor_count = 0; | |
245 | } | |
246 | ||
247 | void test15() | |
248 | { | |
249 | throw_after = 5; | |
250 | del_count = 0; | |
251 | ctor_count = 0; | |
252 | ThrowAfterN* target = | |
253 | (ThrowAfterN*)malloc(sizeof(ThrowAfterN)*10); | |
254 | try { | |
255 | std::uninitialized_value_construct_n(target, 10); | |
256 | } catch (...) { | |
257 | } | |
32aaf6ef | 258 | free(target); |
377f30c0 VV |
259 | VERIFY(ctor_count == 5); |
260 | VERIFY(del_count == 5); | |
261 | throw_after = 0; | |
262 | del_count = 0; | |
263 | ctor_count = 0; | |
264 | } | |
265 | ||
266 | void test16() | |
267 | { | |
268 | std::vector<ThrowAfterN> source(10); | |
269 | del_count = 0; | |
270 | ctor_count = 0; | |
271 | throw_after = 5; | |
272 | throw_after = 5; | |
273 | ThrowAfterN* target = | |
274 | (ThrowAfterN*)malloc(sizeof(ThrowAfterN)*10); | |
275 | try { | |
276 | std::uninitialized_move(source.begin(), source.end(), target); | |
277 | } catch (...) { | |
278 | } | |
32aaf6ef | 279 | free(target); |
377f30c0 VV |
280 | VERIFY(ctor_count == 5); |
281 | VERIFY(del_count == 5); | |
282 | throw_after = 0; | |
283 | del_count = 0; | |
284 | ctor_count = 0; | |
285 | } | |
286 | ||
287 | void test17() | |
288 | { | |
289 | std::vector<ThrowAfterN> source(10); | |
290 | del_count = 0; | |
291 | ctor_count = 0; | |
292 | throw_after = 5; | |
293 | ThrowAfterN* target = | |
294 | (ThrowAfterN*)malloc(sizeof(ThrowAfterN)*10); | |
295 | try { | |
296 | std::uninitialized_move_n(source.begin(), 10, target); | |
297 | } catch (...) { | |
298 | } | |
32aaf6ef | 299 | free(target); |
377f30c0 VV |
300 | VERIFY(ctor_count == 5); |
301 | VERIFY(del_count == 5); | |
302 | throw_after = 0; | |
303 | del_count = 0; | |
304 | ctor_count = 0; | |
305 | } | |
306 | ||
307 | void test18() | |
308 | { | |
309 | char test_source[] = "123456"; | |
310 | char test_target[] = "000000"; | |
311 | std::uninitialized_move(std::begin(test_source), | |
312 | std::end(test_source), | |
313 | test_target); | |
314 | VERIFY(std::string(test_target) == "123456"); | |
315 | } | |
316 | ||
317 | void test19() | |
318 | { | |
319 | char test_source[] = "123456"; | |
320 | char test_target[] = "000000"; | |
08a53a2e JW |
321 | auto end = std::uninitialized_move_n(std::begin(test_source), |
322 | 6, | |
323 | test_target); | |
377f30c0 | 324 | VERIFY(std::string(test_target) == "123456"); |
08a53a2e JW |
325 | VERIFY( end.first == test_source + 6 ); |
326 | VERIFY( end.second == test_target + 6 ); | |
377f30c0 VV |
327 | } |
328 | ||
8e14a10c VV |
329 | int main() |
330 | { | |
331 | test01(); | |
332 | test02(); | |
333 | test03(); | |
334 | test04(); | |
335 | test05(); | |
336 | test06(); | |
337 | test07(); | |
338 | test08(); | |
339 | test09(); | |
377f30c0 VV |
340 | test10(); |
341 | test11(); | |
342 | test12(); | |
343 | test13(); | |
344 | test14(); | |
345 | test15(); | |
346 | test16(); | |
347 | test17(); | |
348 | test18(); | |
349 | test19(); | |
8e14a10c | 350 | } |