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