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