xref: /openbsd-src/gnu/lib/libstdc++/libstdc++/testsuite/23_containers/vector_ctor.cc (revision 03a78d155d6fff5698289342b62759a75b20d130)
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