]> git.ipfire.org Git - thirdparty/gcc.git/blob - libstdc++-v3/testsuite/20_util/specialized_algorithms/memory_management_tools/1.cc
Update copyright years.
[thirdparty/gcc.git] / libstdc++-v3 / testsuite / 20_util / specialized_algorithms / memory_management_tools / 1.cc
1 // Copyright (C) 2016-2020 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++17" }
19
20 #include <memory>
21 #include <testsuite_hooks.h>
22 #include <testsuite_iterators.h>
23 #include <string>
24 #include <vector>
25 #include <sstream>
26
27 int del_count = 0;
28 int ctor_count = 0;
29 int throw_after = 0;
30
31 struct DelCount
32 {
33 ~DelCount() { ++del_count; }
34 };
35
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
59 template<typename T>
60 using FwdIteratorRange
61 = __gnu_test::test_container<T, __gnu_test::forward_iterator_wrapper>;
62
63 void test01()
64 {
65 char test_data[] = "123456";
66 FwdIteratorRange<char> r(test_data);
67 std::uninitialized_default_construct(std::begin(r), std::end(r));
68 VERIFY(std::string(test_data) == "123456");
69 }
70
71 void test02()
72 {
73 char test_data[] = "123456";
74 FwdIteratorRange<char> r(test_data);
75 std::uninitialized_value_construct(std::begin(r), std::end(r));
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";
82 FwdIteratorRange<char> r(test_data);
83 auto end = std::uninitialized_default_construct_n(std::begin(r), 6);
84 VERIFY(std::string(test_data) == "123456");
85 VERIFY( end == std::next(r.begin(), 6) );
86 }
87
88 void test04()
89 {
90 char test_data[] = "123456";
91 FwdIteratorRange<char> r(test_data);
92 auto end = std::uninitialized_value_construct_n(std::begin(r), 5);
93 VERIFY(std::string(test_data, 6) == std::string("\0\0\0\0\0" "6", 6));
94 VERIFY( end == std::next(r.begin(), 5) );
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;
124 auto end = std::destroy_n(x, 10);
125 VERIFY(del_count == 10);
126 VERIFY( end == x + 10 );
127 del_count = 0;
128 free(x);
129 }
130
131 struct MoveOnly
132 {
133 MoveOnly() : val(-1) { }
134 MoveOnly(MoveOnly&& m) : val(m.val) { m.val = -1; }
135 int val;
136 };
137
138 void test08()
139 {
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) );
151 free(target);
152 }
153
154 void test09()
155 {
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) );
168 free(target);
169 }
170
171 void test10()
172 {
173 char* x = (char*)malloc(sizeof(char)*10);
174 for (int i = 0; i < 10; ++i) new (x+i) char;
175 FwdIteratorRange<char> r(x, x+10);
176 std::destroy(r.begin(), r.end());
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;
184 FwdIteratorRange<char> r(x, x+10);
185 auto end = std::destroy_n(r.begin(), 10);
186 VERIFY( end == std::next(r.begin(), 10) );
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 }
201 free(target);
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 }
220 free(target);
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 }
239 free(target);
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 }
258 free(target);
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 }
279 free(target);
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 }
299 free(target);
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";
321 auto end = std::uninitialized_move_n(std::begin(test_source),
322 6,
323 test_target);
324 VERIFY(std::string(test_target) == "123456");
325 VERIFY( end.first == test_source + 6 );
326 VERIFY( end.second == test_target + 6 );
327 }
328
329 int main()
330 {
331 test01();
332 test02();
333 test03();
334 test04();
335 test05();
336 test06();
337 test07();
338 test08();
339 test09();
340 test10();
341 test11();
342 test12();
343 test13();
344 test14();
345 test15();
346 test16();
347 test17();
348 test18();
349 test19();
350 }