1 // 1999-06-29 bkoz
2
3 // Copyright (C) 1999-2001, 2002, 2003 Free Software Foundation, Inc.
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
8 // Free Software Foundation; either version 2, or (at your option)
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
17 // with this library; see the file COPYING. If not, write to the Free
18 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
19 // USA.
20
21 // 23.2.4.1 vector constructors, copy, and assignment
22
23 #include <vector>
24 #include <string>
25 #include <testsuite_allocator.h>
26 #include <testsuite_hooks.h>
27
28 using __gnu_cxx_test::copy_tracker;
29 using __gnu_cxx_test::allocation_tracker;
30 using __gnu_cxx_test::tracker_alloc;
31 using __gnu_cxx_test::copy_constructor;
32 using __gnu_cxx_test::assignment_operator;
33
34 template<typename T>
35 struct A { };
36
37 struct B { };
38
test01()39 void test01()
40 {
41 // 1
42 bool test = true;
43 std::vector< A<B> > vec01;
44 std::vector< A<B> > vec02(5);
45 typedef std::vector< A<B> >::size_type size_type;
46
47 vec01 = vec02;
48
49 #ifdef DEBUG_ASSERT
50 assert(test);
51 #endif
52 }
53
54 // 2
55 template class std::vector<double>;
56 template class std::vector< A<B> >;
57
58
59 // libstdc++/102
test02()60 void test02()
61 {
62 std::vector<int> v1;
63 std::vector<int> v2 (v1);
64 }
65
66 // test range constructors and range-fill constructor
67 void
test03()68 test03()
69 {
70 bool test = true;
71 const int A[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17};
72 const int B[] = {7, 7, 7, 7, 7};
73 const int N = sizeof(A) / sizeof(int);
74 const int M = sizeof(B) / sizeof(int);
75
76 std::vector<int> v3(A, A + N);
77 VERIFY(std::equal(v3.begin(), v3.end(), A));
78
79 std::vector<int> v4(v3.begin(), v3.end());
80 VERIFY(std::equal(v4.begin(), v4.end(), A));
81
82 std::vector<int> v5(M, 7);
83 VERIFY(std::equal(v5.begin(), v5.end(), B));
84 VERIFY(std::equal(B, B + M, v5.begin()));
85
86 #ifdef DEBUG_ASSERT
87 assert(test);
88 #endif
89 }
90
91 // libstdc++/6513
test04()92 void test04()
93 {
94 bool test = true;
95 const char* c_strings[5] = { "1", "2", "3", "4", "5" };
96 std::vector<std::string> strings(c_strings, c_strings + 5);
97
98 #ifdef DEBUG_ASSERT
99 assert(test);
100 #endif
101 }
102
103
104 // @fn test_default_ctor_exception_gurantee This test verifies that if
105 // one of the vector's contained objects throws an exception from its
106 // constructor while the vector is being constructed and filled with
107 // default values, all memory is returned to the allocator whence it
108 // came.
109 void
test_default_ctor_exception_gurantee()110 test_default_ctor_exception_gurantee()
111 {
112 // setup
113 bool test = true;
114 typedef copy_tracker T;
115 typedef std::vector<T, tracker_alloc<T> > X;
116
117 copy_tracker::reset();
118 copy_constructor::throw_on(3);
119 allocation_tracker::resetCounts();
120
121 // run test
122 try
123 {
124 X a(7);
125 VERIFY(("no exception thrown", false));
126 }
127 catch (...)
128 {
129 }
130
131 // assert postconditions
132 VERIFY(("memory leak detected:",
133 allocation_tracker::allocationTotal() == allocation_tracker::deallocationTotal()));
134
135 // teardown
136 }
137
138 // @fn test_copy_ctor_exception_gurantee This test verifies that if
139 // one of the vector's contained objects throws an exception from its
140 // constructor while the vector is being copy constructed, all memory
141 // is returned to the allocator whence it came.
142 void
test_copy_ctor_exception_gurantee()143 test_copy_ctor_exception_gurantee()
144 {
145 // setup
146 bool test = true;
147 typedef copy_tracker T;
148 typedef std::vector<T, tracker_alloc<T> > X;
149
150 allocation_tracker::resetCounts();
151 {
152 X a(7);
153 copy_tracker::reset();
154 copy_constructor::throw_on(3);
155
156 // run test
157 try
158 {
159 X u(a);
160 VERIFY(("no exception thrown", false));
161 }
162 catch (...)
163 {
164 }
165 }
166
167 // assert postconditions
168 VERIFY(allocation_tracker::allocationTotal() == allocation_tracker::deallocationTotal());
169
170 // teardown
171 copy_tracker::reset();
172 allocation_tracker::resetCounts();
173 }
174
175 // operator=()
176 //
177 // case 1: lhs.size() > rhs.size()
178 // case 2: lhs.size() < rhs.size() < lhs.capacity()
179 // case 3: lhs.capacity() < rhs.size()
180 //
181 void
test_assignment_operator_1()182 test_assignment_operator_1()
183 {
184 // setup
185 bool test = true;
186 typedef copy_tracker T;
187 typedef std::vector<T, tracker_alloc<T> > X;
188
189 X r(9);
190 X a(r.size() - 2);
191 copy_tracker::reset();
192 allocation_tracker::resetCounts();
193
194 // preconditions
195 VERIFY(r.size() > a.size());
196
197 // run test
198 r = a;
199
200 // assert postconditions
201 VERIFY(r == a);
202 VERIFY(allocation_tracker::allocationTotal() == 0);
203
204 // teardown
205 copy_tracker::reset();
206 allocation_tracker::resetCounts();
207 }
208
209 void
test_assignment_operator_2()210 test_assignment_operator_2()
211 {
212 // setup
213 bool test = true;
214 typedef copy_tracker T;
215 typedef std::vector<T, tracker_alloc<T> > X;
216
217 X r(1);
218 r.reserve(17);
219 X a(r.size() + 7);
220 copy_tracker::reset();
221 allocation_tracker::resetCounts();
222
223 // preconditions
224 VERIFY(r.size() < a.size());
225 VERIFY(a.size() < r.capacity());
226
227 // run test
228 r = a;
229
230 // assert postconditions
231 VERIFY(r == a);
232 VERIFY(allocation_tracker::allocationTotal() == 0);
233
234 // teardown
235 copy_tracker::reset();
236 allocation_tracker::resetCounts();
237 }
238
239 void
test_assignment_operator_3()240 test_assignment_operator_3()
241 {
242 // setup
243 bool test = true;
244 typedef copy_tracker T;
245 typedef std::vector<T, tracker_alloc<T> > X;
246
247 allocation_tracker::resetCounts();
248 {
249 X r(1);
250 X a(r.capacity() + 7);
251 copy_tracker::reset();
252
253 // preconditions
254 VERIFY(r.capacity() < a.size());
255
256 // run test
257 r = a;
258
259 // assert postconditions
260 VERIFY(r == a);
261 }
262 VERIFY(allocation_tracker::allocationTotal() == allocation_tracker::deallocationTotal());
263
264 // teardown
265 copy_tracker::reset();
266 allocation_tracker::resetCounts();
267 }
268
269 void
test_assignment_operator_3_exception_guarantee()270 test_assignment_operator_3_exception_guarantee()
271 {
272 // setup
273 bool test = true;
274 typedef copy_tracker T;
275 typedef std::vector<T, tracker_alloc<T> > X;
276
277 allocation_tracker::resetCounts();
278 {
279 X r(1);
280 X a(r.capacity() + 7);
281 copy_tracker::reset();
282 copy_constructor::throw_on(3);
283
284 // preconditions
285 VERIFY(r.capacity() < a.size());
286
287 // run test
288 try
289 {
290 r = a;
291 VERIFY(("no exception thrown", false));
292 }
293 catch (...)
294 {
295 }
296 }
297
298 // assert postconditions
299 VERIFY(allocation_tracker::allocationTotal() == allocation_tracker::deallocationTotal());
300
301 // teardown
302 copy_tracker::reset();
303 allocation_tracker::resetCounts();
304 }
305
306 // fill assign()
307 //
308 // case 1: [23.2.4.1 (3)] n <= size()
309 // case 2: [23.2.4.1 (3)] size() < n <= capacity()
310 // case 3: [23.2.4.1 (3)] n > capacity()
311 // case 4: [23.2.4.1 (3)] n > capacity(), exception guarantees
312 // case 5: [23.1.1 (9)] fill assign disguised as a range assign
313 //
314 void
test_fill_assign_1()315 test_fill_assign_1()
316 {
317 // setup
318 bool test = true;
319 typedef copy_tracker T;
320 typedef std::vector<T, tracker_alloc<T> > X;
321
322 X a(7);
323 X::size_type old_size = a.size();
324 X::size_type new_size = old_size - 2;
325 const T t;
326
327 copy_tracker::reset();
328 allocation_tracker::resetCounts();
329
330 // run test
331 a.assign(new_size, t);
332
333 // assert postconditions
334 VERIFY(a.size() == new_size);
335 VERIFY(allocation_tracker::allocationTotal() == 0);
336
337 // teardown
338 copy_tracker::reset();
339 allocation_tracker::resetCounts();
340 }
341
342 void
test_fill_assign_2()343 test_fill_assign_2()
344 {
345 // setup
346 bool test = true;
347 typedef copy_tracker T;
348 typedef std::vector<T, tracker_alloc<T> > X;
349
350 X a(7);
351 a.reserve(11);
352 X::size_type old_size = a.size();
353 X::size_type old_capacity = a.capacity();
354 X::size_type new_size = old_size + 2;
355 const T t;
356
357 copy_tracker::reset();
358 allocation_tracker::resetCounts();
359
360 // assert preconditions
361 VERIFY(old_size < new_size);
362 VERIFY(new_size <= old_capacity);
363
364 // run test
365 a.assign(new_size, t);
366
367 // assert postconditions
368 VERIFY(a.size() == new_size);
369 VERIFY(allocation_tracker::allocationTotal() == 0);
370
371 // teardown
372 copy_tracker::reset();
373 allocation_tracker::resetCounts();
374 }
375
376 void
test_fill_assign_3()377 test_fill_assign_3()
378 {
379 // setup
380 bool test = true;
381 typedef copy_tracker T;
382 typedef std::vector<T, tracker_alloc<T> > X;
383
384 allocation_tracker::resetCounts();
385 {
386 X a(7);
387 X::size_type old_size = a.size();
388 X::size_type old_capacity = a.capacity();
389 X::size_type new_size = old_capacity + 4;
390 const T t;
391
392 copy_tracker::reset();
393
394 // assert preconditions
395 VERIFY(new_size > old_capacity);
396
397 // run test
398 a.assign(new_size, t);
399
400 // assert postconditions
401 VERIFY(a.size() == new_size);
402 }
403
404 VERIFY(allocation_tracker::allocationTotal() > 0);
405 VERIFY(allocation_tracker::allocationTotal() == allocation_tracker::deallocationTotal());
406
407 // teardown
408 copy_tracker::reset();
409 allocation_tracker::resetCounts();
410 }
411
412 void
test_fill_assign_3_exception_guarantee()413 test_fill_assign_3_exception_guarantee()
414 {
415 // setup
416 bool test = true;
417 typedef copy_tracker T;
418 typedef std::vector<T, tracker_alloc<T> > X;
419
420 allocation_tracker::resetCounts();
421 {
422 X a(7);
423 X::size_type old_size = a.size();
424 X::size_type old_capacity = a.capacity();
425 X::size_type new_size = old_capacity + 4;
426 const T t;
427
428 copy_tracker::reset();
429 copy_constructor::throw_on(3);
430
431 // assert preconditions
432 VERIFY(new_size > old_capacity);
433
434 // run test
435 try
436 {
437 a.assign(new_size, t);
438 VERIFY(("no exception thrown", false));
439 }
440 catch (...)
441 {
442 }
443
444 // assert postconditions
445 VERIFY(a.size() == old_size);
446 VERIFY(a.capacity() == old_capacity);
447 }
448
449 VERIFY(allocation_tracker::allocationTotal() > 0);
450 VERIFY(allocation_tracker::allocationTotal() == allocation_tracker::deallocationTotal());
451
452 // teardown
453 copy_tracker::reset();
454 allocation_tracker::resetCounts();
455 }
456
457 void
test_fill_assign_4()458 test_fill_assign_4()
459 {
460 // setup
461 bool test = true;
462 typedef copy_tracker T;
463 typedef std::vector<T, tracker_alloc<T> > X;
464
465 X a(7);
466 X::size_type old_size = a.size();
467 X::size_type new_size = old_size - 2;
468 X::size_type new_value = 117;
469
470 copy_tracker::reset();
471 allocation_tracker::resetCounts();
472
473 // run test
474 a.assign(new_size, new_value);
475
476 // assert postconditions
477 VERIFY(a.size() == new_size);
478 VERIFY(allocation_tracker::allocationTotal() == 0);
479
480 // teardown
481 copy_tracker::reset();
482 allocation_tracker::resetCounts();
483 }
484
485 // range assign()
486 //
487 // case 1: [23.2.4.1 (2)] input iterator
488 // case 2: [23.2.4.1 (2)] forward iterator, distance(first, last) <= size()
489 // case 3: [23.2.4.1 (2)]
490 // forward iterator, size() < distance(first, last) <= capacity()
491 // case 4: [23.2.4.1 (2)] forward iterator, distance(first, last) > capacity()
492 // case 5: [23.2.4.1 (2)]
493 // forward iterator, distance(first, last) > capacity(),
494 // exception guarantees
495 void
test_range_assign_1()496 test_range_assign_1()
497 {
498 // @TODO
499 }
500
501 void
test_range_assign_2()502 test_range_assign_2()
503 {
504 // setup
505 bool test = true;
506 typedef copy_tracker T;
507 typedef std::vector<T, tracker_alloc<T> > X;
508
509 X a(7);
510 X b(3);
511 X::size_type old_size = a.size();
512
513 copy_tracker::reset();
514 allocation_tracker::resetCounts();
515
516 // assert preconditions
517 VERIFY(b.size() < a.capacity());
518
519 // run test
520 a.assign(b.begin(), b.end());
521
522 // assert postconditions
523 VERIFY(a.size() == b.size());
524 VERIFY(a == b);
525 VERIFY(allocation_tracker::allocationTotal() == 0);
526
527 // teardown
528 copy_tracker::reset();
529 allocation_tracker::resetCounts();
530 }
531
532 void
test_range_assign_3()533 test_range_assign_3()
534 {
535 // setup
536 bool test = true;
537 typedef copy_tracker T;
538 typedef std::vector<T, tracker_alloc<T> > X;
539
540 X a(7);
541 a.reserve(a.size() + 7);
542 X b(a.size() + 3);
543 X::size_type old_size = a.size();
544
545 copy_tracker::reset();
546 allocation_tracker::resetCounts();
547
548 // assert preconditions
549 VERIFY(a.size() < b.size());
550 VERIFY(b.size() < a.capacity());
551
552 // run test
553 a.assign(b.begin(), b.end());
554
555 // assert postconditions
556 VERIFY(a.size() == b.size());
557 VERIFY(a == b);
558 VERIFY(allocation_tracker::allocationTotal() == 0);
559
560 // teardown
561 copy_tracker::reset();
562 allocation_tracker::resetCounts();
563 }
564
565 void
test_range_assign_4()566 test_range_assign_4()
567 {
568 // setup
569 bool test = true;
570 typedef copy_tracker T;
571 typedef std::vector<T, tracker_alloc<T> > X;
572
573 allocation_tracker::resetCounts();
574 {
575 X a(7);
576 X b(a.capacity() + 7);
577 X::size_type old_size = a.size();
578
579 copy_tracker::reset();
580
581 // assert preconditions
582 VERIFY(b.size() > a.capacity());
583
584 // run test
585 a.assign(b.begin(), b.end());
586
587 // assert postconditions
588 VERIFY(a.size() == b.size());
589 VERIFY(a == b);
590 }
591 VERIFY(allocation_tracker::allocationTotal() > 0);
592 VERIFY(allocation_tracker::allocationTotal() == allocation_tracker::deallocationTotal());
593
594 // teardown
595 copy_tracker::reset();
596 allocation_tracker::resetCounts();
597 }
598
599 void
test_range_assign_4_exception_guarantee()600 test_range_assign_4_exception_guarantee()
601 {
602 // setup
603 bool test = true;
604 typedef copy_tracker T;
605 typedef std::vector<T, tracker_alloc<T> > X;
606
607 allocation_tracker::resetCounts();
608 {
609 X a(7);
610 X b(a.capacity() + 7);
611 X::size_type old_size = a.size();
612
613 copy_tracker::reset();
614 copy_constructor::throw_on(3);
615
616 // assert preconditions
617 VERIFY(b.size() > a.capacity());
618
619 // run test
620 try
621 {
622 a.assign(b.begin(), b.end());
623 VERIFY(("no exception thrown", false));
624 }
625 catch (...)
626 {
627 }
628 }
629
630 // assert postconditions
631 VERIFY(allocation_tracker::allocationTotal() > 0);
632 VERIFY(allocation_tracker::allocationTotal() == allocation_tracker::deallocationTotal());
633
634 // teardown
635 copy_tracker::reset();
636 allocation_tracker::resetCounts();
637 }
638
639
main()640 int main()
641 {
642 test01();
643 test02();
644 test03();
645 test04();
646 test_default_ctor_exception_gurantee();
647 test_copy_ctor_exception_gurantee();
648 test_assignment_operator_1();
649 test_assignment_operator_2();
650 test_assignment_operator_3();
651 test_assignment_operator_3_exception_guarantee();
652 test_fill_assign_1();
653 test_fill_assign_2();
654 test_fill_assign_3();
655 test_fill_assign_3_exception_guarantee();
656 test_fill_assign_4();
657 test_range_assign_1();
658 test_range_assign_2();
659 test_range_assign_3();
660 test_range_assign_4();
661 test_range_assign_4_exception_guarantee();
662
663 return 0;
664 }
665