3 // Copyright (C) 1999-2025 Free Software Foundation, Inc.
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
8 // Free Software Foundation; either version 3, or (at your option)
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.
16 // You should have received a copy of the GNU General Public License along
17 // with this library; see the file COPYING3. If not see
18 // <http://www.gnu.org/licenses/>.
20 // 23.2.4.1 vector constructors, copy, and assignment
24 #include <testsuite_allocator.h>
25 #include <testsuite_hooks.h>
27 using __gnu_test::copy_tracker
;
28 using __gnu_test::tracker_allocator_counter
;
29 using __gnu_test::tracker_allocator
;
30 using __gnu_test::copy_constructor
;
31 using __gnu_test::assignment_operator
;
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
39 test_default_ctor_exception_gurantee()
42 typedef copy_tracker T
;
43 typedef std::vector
<T
, tracker_allocator
<T
> > X
;
45 copy_tracker::reset();
46 copy_constructor::throw_on(3);
47 tracker_allocator_counter::reset();
60 // assert postconditions
61 VERIFY( tracker_allocator_counter::get_allocation_count() == tracker_allocator_counter::get_deallocation_count() );
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.
71 test_copy_ctor_exception_gurantee()
74 typedef copy_tracker T
;
75 typedef std::vector
<T
, tracker_allocator
<T
> > X
;
77 tracker_allocator_counter::reset();
80 copy_tracker::reset();
81 copy_constructor::throw_on(3);
94 // assert postconditions
95 VERIFY(tracker_allocator_counter::get_allocation_count() == tracker_allocator_counter::get_deallocation_count());
98 copy_tracker::reset();
99 tracker_allocator_counter::reset();
104 // case 1: lhs.size() > rhs.size()
105 // case 2: lhs.size() < rhs.size() < lhs.capacity()
106 // case 3: lhs.capacity() < rhs.size()
109 test_assignment_operator_1()
112 typedef copy_tracker T
;
113 typedef std::vector
<T
, tracker_allocator
<T
> > X
;
117 copy_tracker::reset();
118 tracker_allocator_counter::reset();
121 VERIFY(r
.size() > a
.size());
126 // assert postconditions
128 VERIFY(tracker_allocator_counter::get_allocation_count() == 0);
131 copy_tracker::reset();
132 tracker_allocator_counter::reset();
136 test_assignment_operator_2()
139 typedef copy_tracker T
;
140 typedef std::vector
<T
, tracker_allocator
<T
> > X
;
145 copy_tracker::reset();
146 tracker_allocator_counter::reset();
149 VERIFY(r
.size() < a
.size());
150 VERIFY(a
.size() < r
.capacity());
155 // assert postconditions
157 VERIFY(tracker_allocator_counter::get_allocation_count() == 0);
160 copy_tracker::reset();
161 tracker_allocator_counter::reset();
165 test_assignment_operator_3()
168 typedef copy_tracker T
;
169 typedef std::vector
<T
, tracker_allocator
<T
> > X
;
171 tracker_allocator_counter::reset();
174 X
a(r
.capacity() + 7);
175 copy_tracker::reset();
178 VERIFY(r
.capacity() < a
.size());
183 // assert postconditions
186 VERIFY(tracker_allocator_counter::get_allocation_count() == tracker_allocator_counter::get_deallocation_count());
189 copy_tracker::reset();
190 tracker_allocator_counter::reset();
194 test_assignment_operator_3_exception_guarantee()
197 typedef copy_tracker T
;
198 typedef std::vector
<T
, tracker_allocator
<T
> > X
;
200 tracker_allocator_counter::reset();
203 X
a(r
.capacity() + 7);
204 copy_tracker::reset();
205 copy_constructor::throw_on(3);
208 VERIFY(r
.capacity() < a
.size());
221 // assert postconditions
222 VERIFY(tracker_allocator_counter::get_allocation_count() == tracker_allocator_counter::get_deallocation_count());
225 copy_tracker::reset();
226 tracker_allocator_counter::reset();
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
241 typedef copy_tracker T
;
242 typedef std::vector
<T
, tracker_allocator
<T
> > X
;
245 X::size_type old_size
= a
.size();
246 X::size_type new_size
= old_size
- 2;
249 copy_tracker::reset();
250 tracker_allocator_counter::reset();
253 a
.assign(new_size
, t
);
255 // assert postconditions
256 VERIFY(a
.size() == new_size
);
257 VERIFY(tracker_allocator_counter::get_allocation_count() == 0);
260 copy_tracker::reset();
261 tracker_allocator_counter::reset();
268 typedef copy_tracker T
;
269 typedef std::vector
<T
, tracker_allocator
<T
> > X
;
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;
278 copy_tracker::reset();
279 tracker_allocator_counter::reset();
281 // assert preconditions
282 VERIFY(old_size
< new_size
);
283 VERIFY(new_size
<= old_capacity
);
286 a
.assign(new_size
, t
);
288 // assert postconditions
289 VERIFY(a
.size() == new_size
);
290 VERIFY(tracker_allocator_counter::get_allocation_count() == 0);
293 copy_tracker::reset();
294 tracker_allocator_counter::reset();
301 typedef copy_tracker T
;
302 typedef std::vector
<T
, tracker_allocator
<T
> > X
;
304 tracker_allocator_counter::reset();
307 X::size_type old_capacity
= a
.capacity();
308 X::size_type new_size
= old_capacity
+ 4;
311 copy_tracker::reset();
313 // assert preconditions
314 VERIFY(new_size
> old_capacity
);
317 a
.assign(new_size
, t
);
319 // assert postconditions
320 VERIFY(a
.size() == new_size
);
323 VERIFY(tracker_allocator_counter::get_allocation_count() > 0);
324 VERIFY(tracker_allocator_counter::get_allocation_count() == tracker_allocator_counter::get_deallocation_count());
327 copy_tracker::reset();
328 tracker_allocator_counter::reset();
332 test_fill_assign_3_exception_guarantee()
335 typedef copy_tracker T
;
336 typedef std::vector
<T
, tracker_allocator
<T
> > X
;
338 tracker_allocator_counter::reset();
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;
346 copy_tracker::reset();
347 copy_constructor::throw_on(3);
349 // assert preconditions
350 VERIFY(new_size
> old_capacity
);
355 a
.assign(new_size
, t
);
362 // assert postconditions
363 VERIFY(a
.size() == old_size
);
364 VERIFY(a
.capacity() == old_capacity
);
367 VERIFY(tracker_allocator_counter::get_allocation_count() > 0);
368 VERIFY(tracker_allocator_counter::get_allocation_count() == tracker_allocator_counter::get_deallocation_count());
371 copy_tracker::reset();
372 tracker_allocator_counter::reset();
379 typedef copy_tracker T
;
380 typedef std::vector
<T
, tracker_allocator
<T
> > X
;
383 X::size_type old_size
= a
.size();
384 X::size_type new_size
= old_size
- 2;
385 X::size_type new_value
= 117;
387 copy_tracker::reset();
388 tracker_allocator_counter::reset();
391 a
.assign(new_size
, new_value
);
393 // assert postconditions
394 VERIFY(a
.size() == new_size
);
395 VERIFY(tracker_allocator_counter::get_allocation_count() == 0);
398 copy_tracker::reset();
399 tracker_allocator_counter::reset();
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
413 test_range_assign_1()
419 test_range_assign_2()
422 typedef copy_tracker T
;
423 typedef std::vector
<T
, tracker_allocator
<T
> > X
;
428 copy_tracker::reset();
429 tracker_allocator_counter::reset();
431 // assert preconditions
432 VERIFY(b
.size() < a
.capacity());
435 a
.assign(b
.begin(), b
.end());
437 // assert postconditions
438 VERIFY(a
.size() == b
.size());
440 VERIFY(tracker_allocator_counter::get_allocation_count() == 0);
443 copy_tracker::reset();
444 tracker_allocator_counter::reset();
448 test_range_assign_3()
451 typedef copy_tracker T
;
452 typedef std::vector
<T
, tracker_allocator
<T
> > X
;
455 a
.reserve(a
.size() + 7);
458 copy_tracker::reset();
459 tracker_allocator_counter::reset();
461 // assert preconditions
462 VERIFY(a
.size() < b
.size());
463 VERIFY(b
.size() < a
.capacity());
466 a
.assign(b
.begin(), b
.end());
468 // assert postconditions
469 VERIFY(a
.size() == b
.size());
471 VERIFY(tracker_allocator_counter::get_allocation_count() == 0);
474 copy_tracker::reset();
475 tracker_allocator_counter::reset();
479 test_range_assign_4()
482 typedef copy_tracker T
;
483 typedef std::vector
<T
, tracker_allocator
<T
> > X
;
485 tracker_allocator_counter::reset();
488 X
b(a
.capacity() + 7);
490 copy_tracker::reset();
492 // assert preconditions
493 VERIFY(b
.size() > a
.capacity());
496 a
.assign(b
.begin(), b
.end());
498 // assert postconditions
499 VERIFY(a
.size() == b
.size());
502 VERIFY(tracker_allocator_counter::get_allocation_count() > 0);
503 VERIFY(tracker_allocator_counter::get_allocation_count() == tracker_allocator_counter::get_deallocation_count());
506 copy_tracker::reset();
507 tracker_allocator_counter::reset();
511 test_range_assign_4_exception_guarantee()
514 typedef copy_tracker T
;
515 typedef std::vector
<T
, tracker_allocator
<T
> > X
;
517 tracker_allocator_counter::reset();
520 X
b(a
.capacity() + 7);
522 copy_tracker::reset();
523 copy_constructor::throw_on(3);
525 // assert preconditions
526 VERIFY(b
.size() > a
.capacity());
531 a
.assign(b
.begin(), b
.end());
539 // assert postconditions
540 VERIFY(tracker_allocator_counter::get_allocation_count() > 0);
541 VERIFY(tracker_allocator_counter::get_allocation_count() == tracker_allocator_counter::get_deallocation_count());
544 copy_tracker::reset();
545 tracker_allocator_counter::reset();
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();