]>
Commit | Line | Data |
---|---|---|
02d92e3b | 1 | // 1999-06-29 bkoz |
b2dad0e3 | 2 | |
a5544970 | 3 | // Copyright (C) 1999-2019 Free Software Foundation, Inc. |
b2dad0e3 BK |
4 | // |
5 | // This file is part of the GNU ISO C++ Library. This library is free | |
6 | // software; you can redistribute it and/or modify it under the | |
7 | // terms of the GNU General Public License as published by the | |
748086b7 | 8 | // Free Software Foundation; either version 3, or (at your option) |
b2dad0e3 BK |
9 | // any later version. |
10 | ||
11 | // This library is distributed in the hope that it will be useful, | |
12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | // GNU General Public License for more details. | |
15 | ||
16 | // You should have received a copy of the GNU General Public License along | |
748086b7 JJ |
17 | // with this library; see the file COPYING3. If not see |
18 | // <http://www.gnu.org/licenses/>. | |
b2dad0e3 BK |
19 | |
20 | // 23.2.4.1 vector constructors, copy, and assignment | |
21 | ||
22 | #include <vector> | |
072a15d9 | 23 | #include <string> |
162c7cd9 | 24 | #include <testsuite_allocator.h> |
fe413112 | 25 | #include <testsuite_hooks.h> |
b2dad0e3 | 26 | |
aecf642c | 27 | using __gnu_test::copy_tracker; |
9f9900db BK |
28 | using __gnu_test::tracker_allocator_counter; |
29 | using __gnu_test::tracker_allocator; | |
aecf642c BK |
30 | using __gnu_test::copy_constructor; |
31 | using __gnu_test::assignment_operator; | |
162c7cd9 SW |
32 | |
33 | // @fn test_default_ctor_exception_gurantee This test verifies that if | |
34 | // one of the vector's contained objects throws an exception from its | |
35 | // constructor while the vector is being constructed and filled with | |
36 | // default values, all memory is returned to the allocator whence it | |
37 | // came. | |
38 | void | |
39 | test_default_ctor_exception_gurantee() | |
40 | { | |
41 | // setup | |
8d59b230 | 42 | typedef copy_tracker T; |
9f9900db | 43 | typedef std::vector<T, tracker_allocator<T> > X; |
162c7cd9 | 44 | |
8d59b230 BK |
45 | copy_tracker::reset(); |
46 | copy_constructor::throw_on(3); | |
9f9900db | 47 | tracker_allocator_counter::reset(); |
162c7cd9 SW |
48 | |
49 | // run test | |
50 | try | |
51 | { | |
7165791e FD |
52 | T ref; |
53 | X a(7, ref); | |
11f10e6b | 54 | VERIFY(false); |
162c7cd9 SW |
55 | } |
56 | catch (...) | |
57 | { | |
58 | } | |
59 | ||
60 | // assert postconditions | |
9f9900db | 61 | VERIFY( tracker_allocator_counter::get_allocation_count() == tracker_allocator_counter::get_deallocation_count() ); |
162c7cd9 SW |
62 | |
63 | // teardown | |
64 | } | |
65 | ||
66 | // @fn test_copy_ctor_exception_gurantee This test verifies that if | |
67 | // one of the vector's contained objects throws an exception from its | |
68 | // constructor while the vector is being copy constructed, all memory | |
69 | // is returned to the allocator whence it came. | |
70 | void | |
71 | test_copy_ctor_exception_gurantee() | |
72 | { | |
73 | // setup | |
8d59b230 | 74 | typedef copy_tracker T; |
9f9900db | 75 | typedef std::vector<T, tracker_allocator<T> > X; |
162c7cd9 | 76 | |
9f9900db | 77 | tracker_allocator_counter::reset(); |
162c7cd9 SW |
78 | { |
79 | X a(7); | |
8d59b230 BK |
80 | copy_tracker::reset(); |
81 | copy_constructor::throw_on(3); | |
162c7cd9 SW |
82 | |
83 | // run test | |
84 | try | |
85 | { | |
86 | X u(a); | |
11f10e6b | 87 | VERIFY(false); |
162c7cd9 SW |
88 | } |
89 | catch (...) | |
90 | { | |
91 | } | |
92 | } | |
93 | ||
94 | // assert postconditions | |
9f9900db | 95 | VERIFY(tracker_allocator_counter::get_allocation_count() == tracker_allocator_counter::get_deallocation_count()); |
162c7cd9 SW |
96 | |
97 | // teardown | |
8d59b230 | 98 | copy_tracker::reset(); |
9f9900db | 99 | tracker_allocator_counter::reset(); |
162c7cd9 SW |
100 | } |
101 | ||
102 | // operator=() | |
103 | // | |
104 | // case 1: lhs.size() > rhs.size() | |
105 | // case 2: lhs.size() < rhs.size() < lhs.capacity() | |
106 | // case 3: lhs.capacity() < rhs.size() | |
107 | // | |
108 | void | |
109 | test_assignment_operator_1() | |
110 | { | |
111 | // setup | |
8d59b230 | 112 | typedef copy_tracker T; |
9f9900db | 113 | typedef std::vector<T, tracker_allocator<T> > X; |
162c7cd9 SW |
114 | |
115 | X r(9); | |
116 | X a(r.size() - 2); | |
8d59b230 | 117 | copy_tracker::reset(); |
9f9900db | 118 | tracker_allocator_counter::reset(); |
162c7cd9 SW |
119 | |
120 | // preconditions | |
121 | VERIFY(r.size() > a.size()); | |
122 | ||
123 | // run test | |
124 | r = a; | |
125 | ||
126 | // assert postconditions | |
127 | VERIFY(r == a); | |
9f9900db | 128 | VERIFY(tracker_allocator_counter::get_allocation_count() == 0); |
162c7cd9 SW |
129 | |
130 | // teardown | |
8d59b230 | 131 | copy_tracker::reset(); |
9f9900db | 132 | tracker_allocator_counter::reset(); |
162c7cd9 SW |
133 | } |
134 | ||
135 | void | |
136 | test_assignment_operator_2() | |
137 | { | |
138 | // setup | |
8d59b230 | 139 | typedef copy_tracker T; |
9f9900db | 140 | typedef std::vector<T, tracker_allocator<T> > X; |
162c7cd9 SW |
141 | |
142 | X r(1); | |
143 | r.reserve(17); | |
144 | X a(r.size() + 7); | |
8d59b230 | 145 | copy_tracker::reset(); |
9f9900db | 146 | tracker_allocator_counter::reset(); |
162c7cd9 SW |
147 | |
148 | // preconditions | |
149 | VERIFY(r.size() < a.size()); | |
150 | VERIFY(a.size() < r.capacity()); | |
151 | ||
152 | // run test | |
153 | r = a; | |
154 | ||
155 | // assert postconditions | |
156 | VERIFY(r == a); | |
9f9900db | 157 | VERIFY(tracker_allocator_counter::get_allocation_count() == 0); |
162c7cd9 SW |
158 | |
159 | // teardown | |
8d59b230 | 160 | copy_tracker::reset(); |
9f9900db | 161 | tracker_allocator_counter::reset(); |
162c7cd9 SW |
162 | } |
163 | ||
164 | void | |
165 | test_assignment_operator_3() | |
166 | { | |
167 | // setup | |
8d59b230 | 168 | typedef copy_tracker T; |
9f9900db | 169 | typedef std::vector<T, tracker_allocator<T> > X; |
162c7cd9 | 170 | |
9f9900db | 171 | tracker_allocator_counter::reset(); |
162c7cd9 SW |
172 | { |
173 | X r(1); | |
174 | X a(r.capacity() + 7); | |
8d59b230 | 175 | copy_tracker::reset(); |
162c7cd9 SW |
176 | |
177 | // preconditions | |
178 | VERIFY(r.capacity() < a.size()); | |
179 | ||
180 | // run test | |
181 | r = a; | |
182 | ||
183 | // assert postconditions | |
184 | VERIFY(r == a); | |
185 | } | |
9f9900db | 186 | VERIFY(tracker_allocator_counter::get_allocation_count() == tracker_allocator_counter::get_deallocation_count()); |
162c7cd9 SW |
187 | |
188 | // teardown | |
8d59b230 | 189 | copy_tracker::reset(); |
9f9900db | 190 | tracker_allocator_counter::reset(); |
162c7cd9 SW |
191 | } |
192 | ||
193 | void | |
194 | test_assignment_operator_3_exception_guarantee() | |
195 | { | |
196 | // setup | |
8d59b230 | 197 | typedef copy_tracker T; |
9f9900db | 198 | typedef std::vector<T, tracker_allocator<T> > X; |
162c7cd9 | 199 | |
9f9900db | 200 | tracker_allocator_counter::reset(); |
162c7cd9 SW |
201 | { |
202 | X r(1); | |
203 | X a(r.capacity() + 7); | |
8d59b230 BK |
204 | copy_tracker::reset(); |
205 | copy_constructor::throw_on(3); | |
162c7cd9 SW |
206 | |
207 | // preconditions | |
208 | VERIFY(r.capacity() < a.size()); | |
209 | ||
210 | // run test | |
211 | try | |
212 | { | |
213 | r = a; | |
11f10e6b | 214 | VERIFY(false); |
162c7cd9 SW |
215 | } |
216 | catch (...) | |
217 | { | |
218 | } | |
219 | } | |
220 | ||
221 | // assert postconditions | |
9f9900db | 222 | VERIFY(tracker_allocator_counter::get_allocation_count() == tracker_allocator_counter::get_deallocation_count()); |
162c7cd9 SW |
223 | |
224 | // teardown | |
8d59b230 | 225 | copy_tracker::reset(); |
9f9900db | 226 | tracker_allocator_counter::reset(); |
162c7cd9 SW |
227 | } |
228 | ||
229 | // fill assign() | |
230 | // | |
231 | // case 1: [23.2.4.1 (3)] n <= size() | |
232 | // case 2: [23.2.4.1 (3)] size() < n <= capacity() | |
233 | // case 3: [23.2.4.1 (3)] n > capacity() | |
234 | // case 4: [23.2.4.1 (3)] n > capacity(), exception guarantees | |
235 | // case 5: [23.1.1 (9)] fill assign disguised as a range assign | |
236 | // | |
237 | void | |
238 | test_fill_assign_1() | |
239 | { | |
240 | // setup | |
8d59b230 | 241 | typedef copy_tracker T; |
9f9900db | 242 | typedef std::vector<T, tracker_allocator<T> > X; |
162c7cd9 SW |
243 | |
244 | X a(7); | |
245 | X::size_type old_size = a.size(); | |
246 | X::size_type new_size = old_size - 2; | |
247 | const T t; | |
248 | ||
8d59b230 | 249 | copy_tracker::reset(); |
9f9900db | 250 | tracker_allocator_counter::reset(); |
162c7cd9 SW |
251 | |
252 | // run test | |
253 | a.assign(new_size, t); | |
254 | ||
255 | // assert postconditions | |
256 | VERIFY(a.size() == new_size); | |
9f9900db | 257 | VERIFY(tracker_allocator_counter::get_allocation_count() == 0); |
162c7cd9 SW |
258 | |
259 | // teardown | |
8d59b230 | 260 | copy_tracker::reset(); |
9f9900db | 261 | tracker_allocator_counter::reset(); |
162c7cd9 SW |
262 | } |
263 | ||
264 | void | |
265 | test_fill_assign_2() | |
266 | { | |
267 | // setup | |
8d59b230 | 268 | typedef copy_tracker T; |
9f9900db | 269 | typedef std::vector<T, tracker_allocator<T> > X; |
162c7cd9 SW |
270 | |
271 | X a(7); | |
272 | a.reserve(11); | |
273 | X::size_type old_size = a.size(); | |
274 | X::size_type old_capacity = a.capacity(); | |
275 | X::size_type new_size = old_size + 2; | |
276 | const T t; | |
277 | ||
8d59b230 | 278 | copy_tracker::reset(); |
9f9900db | 279 | tracker_allocator_counter::reset(); |
162c7cd9 SW |
280 | |
281 | // assert preconditions | |
282 | VERIFY(old_size < new_size); | |
283 | VERIFY(new_size <= old_capacity); | |
284 | ||
285 | // run test | |
286 | a.assign(new_size, t); | |
287 | ||
288 | // assert postconditions | |
289 | VERIFY(a.size() == new_size); | |
9f9900db | 290 | VERIFY(tracker_allocator_counter::get_allocation_count() == 0); |
162c7cd9 SW |
291 | |
292 | // teardown | |
8d59b230 | 293 | copy_tracker::reset(); |
9f9900db | 294 | tracker_allocator_counter::reset(); |
162c7cd9 SW |
295 | } |
296 | ||
297 | void | |
298 | test_fill_assign_3() | |
299 | { | |
300 | // setup | |
8d59b230 | 301 | typedef copy_tracker T; |
9f9900db | 302 | typedef std::vector<T, tracker_allocator<T> > X; |
162c7cd9 | 303 | |
9f9900db | 304 | tracker_allocator_counter::reset(); |
162c7cd9 SW |
305 | { |
306 | X a(7); | |
162c7cd9 SW |
307 | X::size_type old_capacity = a.capacity(); |
308 | X::size_type new_size = old_capacity + 4; | |
309 | const T t; | |
310 | ||
8d59b230 | 311 | copy_tracker::reset(); |
162c7cd9 SW |
312 | |
313 | // assert preconditions | |
314 | VERIFY(new_size > old_capacity); | |
315 | ||
316 | // run test | |
317 | a.assign(new_size, t); | |
318 | ||
319 | // assert postconditions | |
320 | VERIFY(a.size() == new_size); | |
321 | } | |
322 | ||
9f9900db BK |
323 | VERIFY(tracker_allocator_counter::get_allocation_count() > 0); |
324 | VERIFY(tracker_allocator_counter::get_allocation_count() == tracker_allocator_counter::get_deallocation_count()); | |
162c7cd9 SW |
325 | |
326 | // teardown | |
8d59b230 | 327 | copy_tracker::reset(); |
9f9900db | 328 | tracker_allocator_counter::reset(); |
162c7cd9 SW |
329 | } |
330 | ||
331 | void | |
332 | test_fill_assign_3_exception_guarantee() | |
333 | { | |
334 | // setup | |
8d59b230 | 335 | typedef copy_tracker T; |
9f9900db | 336 | typedef std::vector<T, tracker_allocator<T> > X; |
162c7cd9 | 337 | |
9f9900db | 338 | tracker_allocator_counter::reset(); |
162c7cd9 SW |
339 | { |
340 | X a(7); | |
341 | X::size_type old_size = a.size(); | |
342 | X::size_type old_capacity = a.capacity(); | |
343 | X::size_type new_size = old_capacity + 4; | |
344 | const T t; | |
345 | ||
8d59b230 BK |
346 | copy_tracker::reset(); |
347 | copy_constructor::throw_on(3); | |
162c7cd9 SW |
348 | |
349 | // assert preconditions | |
350 | VERIFY(new_size > old_capacity); | |
351 | ||
352 | // run test | |
353 | try | |
354 | { | |
355 | a.assign(new_size, t); | |
11f10e6b | 356 | VERIFY(false); |
162c7cd9 SW |
357 | } |
358 | catch (...) | |
359 | { | |
360 | } | |
361 | ||
362 | // assert postconditions | |
363 | VERIFY(a.size() == old_size); | |
364 | VERIFY(a.capacity() == old_capacity); | |
365 | } | |
366 | ||
9f9900db BK |
367 | VERIFY(tracker_allocator_counter::get_allocation_count() > 0); |
368 | VERIFY(tracker_allocator_counter::get_allocation_count() == tracker_allocator_counter::get_deallocation_count()); | |
162c7cd9 SW |
369 | |
370 | // teardown | |
8d59b230 | 371 | copy_tracker::reset(); |
9f9900db | 372 | tracker_allocator_counter::reset(); |
162c7cd9 SW |
373 | } |
374 | ||
375 | void | |
376 | test_fill_assign_4() | |
377 | { | |
378 | // setup | |
8d59b230 | 379 | typedef copy_tracker T; |
9f9900db | 380 | typedef std::vector<T, tracker_allocator<T> > X; |
162c7cd9 SW |
381 | |
382 | X a(7); | |
383 | X::size_type old_size = a.size(); | |
384 | X::size_type new_size = old_size - 2; | |
385 | X::size_type new_value = 117; | |
386 | ||
8d59b230 | 387 | copy_tracker::reset(); |
9f9900db | 388 | tracker_allocator_counter::reset(); |
162c7cd9 SW |
389 | |
390 | // run test | |
391 | a.assign(new_size, new_value); | |
392 | ||
393 | // assert postconditions | |
394 | VERIFY(a.size() == new_size); | |
9f9900db | 395 | VERIFY(tracker_allocator_counter::get_allocation_count() == 0); |
162c7cd9 SW |
396 | |
397 | // teardown | |
8d59b230 | 398 | copy_tracker::reset(); |
9f9900db | 399 | tracker_allocator_counter::reset(); |
162c7cd9 SW |
400 | } |
401 | ||
402 | // range assign() | |
403 | // | |
404 | // case 1: [23.2.4.1 (2)] input iterator | |
405 | // case 2: [23.2.4.1 (2)] forward iterator, distance(first, last) <= size() | |
406 | // case 3: [23.2.4.1 (2)] | |
407 | // forward iterator, size() < distance(first, last) <= capacity() | |
408 | // case 4: [23.2.4.1 (2)] forward iterator, distance(first, last) > capacity() | |
409 | // case 5: [23.2.4.1 (2)] | |
410 | // forward iterator, distance(first, last) > capacity(), | |
411 | // exception guarantees | |
412 | void | |
413 | test_range_assign_1() | |
414 | { | |
415 | // @TODO | |
416 | } | |
417 | ||
418 | void | |
419 | test_range_assign_2() | |
420 | { | |
421 | // setup | |
8d59b230 | 422 | typedef copy_tracker T; |
9f9900db | 423 | typedef std::vector<T, tracker_allocator<T> > X; |
162c7cd9 SW |
424 | |
425 | X a(7); | |
426 | X b(3); | |
162c7cd9 | 427 | |
8d59b230 | 428 | copy_tracker::reset(); |
9f9900db | 429 | tracker_allocator_counter::reset(); |
162c7cd9 SW |
430 | |
431 | // assert preconditions | |
432 | VERIFY(b.size() < a.capacity()); | |
433 | ||
434 | // run test | |
435 | a.assign(b.begin(), b.end()); | |
436 | ||
437 | // assert postconditions | |
438 | VERIFY(a.size() == b.size()); | |
439 | VERIFY(a == b); | |
9f9900db | 440 | VERIFY(tracker_allocator_counter::get_allocation_count() == 0); |
162c7cd9 SW |
441 | |
442 | // teardown | |
8d59b230 | 443 | copy_tracker::reset(); |
9f9900db | 444 | tracker_allocator_counter::reset(); |
162c7cd9 SW |
445 | } |
446 | ||
447 | void | |
448 | test_range_assign_3() | |
449 | { | |
450 | // setup | |
8d59b230 | 451 | typedef copy_tracker T; |
9f9900db | 452 | typedef std::vector<T, tracker_allocator<T> > X; |
162c7cd9 SW |
453 | |
454 | X a(7); | |
455 | a.reserve(a.size() + 7); | |
456 | X b(a.size() + 3); | |
162c7cd9 | 457 | |
8d59b230 | 458 | copy_tracker::reset(); |
9f9900db | 459 | tracker_allocator_counter::reset(); |
162c7cd9 SW |
460 | |
461 | // assert preconditions | |
462 | VERIFY(a.size() < b.size()); | |
463 | VERIFY(b.size() < a.capacity()); | |
464 | ||
465 | // run test | |
466 | a.assign(b.begin(), b.end()); | |
467 | ||
468 | // assert postconditions | |
469 | VERIFY(a.size() == b.size()); | |
470 | VERIFY(a == b); | |
9f9900db | 471 | VERIFY(tracker_allocator_counter::get_allocation_count() == 0); |
162c7cd9 SW |
472 | |
473 | // teardown | |
8d59b230 | 474 | copy_tracker::reset(); |
9f9900db | 475 | tracker_allocator_counter::reset(); |
162c7cd9 SW |
476 | } |
477 | ||
478 | void | |
479 | test_range_assign_4() | |
480 | { | |
481 | // setup | |
8d59b230 | 482 | typedef copy_tracker T; |
9f9900db | 483 | typedef std::vector<T, tracker_allocator<T> > X; |
162c7cd9 | 484 | |
9f9900db | 485 | tracker_allocator_counter::reset(); |
162c7cd9 SW |
486 | { |
487 | X a(7); | |
488 | X b(a.capacity() + 7); | |
162c7cd9 | 489 | |
8d59b230 | 490 | copy_tracker::reset(); |
162c7cd9 SW |
491 | |
492 | // assert preconditions | |
493 | VERIFY(b.size() > a.capacity()); | |
494 | ||
495 | // run test | |
496 | a.assign(b.begin(), b.end()); | |
497 | ||
498 | // assert postconditions | |
499 | VERIFY(a.size() == b.size()); | |
500 | VERIFY(a == b); | |
501 | } | |
9f9900db BK |
502 | VERIFY(tracker_allocator_counter::get_allocation_count() > 0); |
503 | VERIFY(tracker_allocator_counter::get_allocation_count() == tracker_allocator_counter::get_deallocation_count()); | |
162c7cd9 SW |
504 | |
505 | // teardown | |
8d59b230 | 506 | copy_tracker::reset(); |
9f9900db | 507 | tracker_allocator_counter::reset(); |
162c7cd9 SW |
508 | } |
509 | ||
510 | void | |
511 | test_range_assign_4_exception_guarantee() | |
512 | { | |
513 | // setup | |
8d59b230 | 514 | typedef copy_tracker T; |
9f9900db | 515 | typedef std::vector<T, tracker_allocator<T> > X; |
162c7cd9 | 516 | |
9f9900db | 517 | tracker_allocator_counter::reset(); |
162c7cd9 SW |
518 | { |
519 | X a(7); | |
520 | X b(a.capacity() + 7); | |
162c7cd9 | 521 | |
8d59b230 BK |
522 | copy_tracker::reset(); |
523 | copy_constructor::throw_on(3); | |
162c7cd9 SW |
524 | |
525 | // assert preconditions | |
526 | VERIFY(b.size() > a.capacity()); | |
527 | ||
528 | // run test | |
529 | try | |
530 | { | |
531 | a.assign(b.begin(), b.end()); | |
11f10e6b | 532 | VERIFY(false); |
162c7cd9 SW |
533 | } |
534 | catch (...) | |
535 | { | |
536 | } | |
537 | } | |
538 | ||
539 | // assert postconditions | |
9f9900db BK |
540 | VERIFY(tracker_allocator_counter::get_allocation_count() > 0); |
541 | VERIFY(tracker_allocator_counter::get_allocation_count() == tracker_allocator_counter::get_deallocation_count()); | |
162c7cd9 SW |
542 | |
543 | // teardown | |
8d59b230 | 544 | copy_tracker::reset(); |
9f9900db | 545 | tracker_allocator_counter::reset(); |
162c7cd9 SW |
546 | } |
547 | ||
548 | ||
b2dad0e3 BK |
549 | int main() |
550 | { | |
162c7cd9 SW |
551 | test_default_ctor_exception_gurantee(); |
552 | test_copy_ctor_exception_gurantee(); | |
553 | test_assignment_operator_1(); | |
554 | test_assignment_operator_2(); | |
555 | test_assignment_operator_3(); | |
556 | test_assignment_operator_3_exception_guarantee(); | |
557 | test_fill_assign_1(); | |
558 | test_fill_assign_2(); | |
559 | test_fill_assign_3(); | |
560 | test_fill_assign_3_exception_guarantee(); | |
561 | test_fill_assign_4(); | |
562 | test_range_assign_1(); | |
563 | test_range_assign_2(); | |
564 | test_range_assign_3(); | |
565 | test_range_assign_4(); | |
566 | test_range_assign_4_exception_guarantee(); | |
02d92e3b | 567 | |
b2dad0e3 BK |
568 | return 0; |
569 | } |