]>
Commit | Line | Data |
---|---|---|
bb2ae697 PE |
1 | // 2001-12-27 pme |
2 | // | |
8d59b230 | 3 | // Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. |
bb2ae697 PE |
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.1.1 deque constructors, copy, and assignment | |
22 | ||
23 | #include <deque> | |
162c7cd9 SW |
24 | #include <iterator> |
25 | #include <sstream> | |
26 | #include <testsuite_allocator.h> | |
bb2ae697 PE |
27 | #include <testsuite_hooks.h> |
28 | ||
aecf642c BK |
29 | using __gnu_test::copy_tracker; |
30 | using __gnu_test::allocation_tracker; | |
31 | using __gnu_test::tracker_alloc; | |
32 | using __gnu_test::copy_constructor; | |
33 | using __gnu_test::assignment_operator; | |
34 | using __gnu_test::counter; | |
35 | using __gnu_test::destructor; | |
8d59b230 BK |
36 | |
37 | typedef std::deque<counter> gdeque; | |
bb2ae697 | 38 | |
11f10e6b | 39 | bool test __attribute__((unused)) = true; |
bb2ae697 | 40 | |
162c7cd9 SW |
41 | // 23.2.1 required types |
42 | // | |
43 | // A missing required type will cause a compile failure. | |
44 | // | |
45 | void | |
46 | requiredTypesCheck() | |
47 | { | |
48 | typedef int T; | |
49 | typedef std::deque<T> X; | |
50 | ||
51 | typedef X::reference reference; | |
52 | typedef X::const_reference const_reference; | |
53 | typedef X::iterator iterator; | |
54 | typedef X::const_iterator const_iterator; | |
55 | typedef X::size_type size_type; | |
56 | typedef X::difference_type difference_type; | |
57 | typedef X::value_type value_type; | |
58 | typedef X::allocator_type allocator_type; | |
59 | typedef X::pointer pointer; | |
60 | typedef X::const_pointer const_pointer; | |
61 | typedef X::reverse_iterator reverse_iterator; | |
62 | typedef X::const_reverse_iterator const_reverse_iterator; | |
63 | } | |
64 | ||
65 | ||
66 | // @fn defaultConstructorCheck | |
67 | // Explicitly checks the default deque constructor and destructor for both | |
68 | // trivial and non-trivial types. In addition, the size() and empty() | |
69 | // member functions are explicitly checked here since it should be their | |
70 | // first use. Checking those functions means checking the begin() and | |
71 | // end() and their const brethren functions as well. | |
72 | // | |
73 | // @verbatim | |
74 | // 23.2.1.1 default ctor/dtor | |
75 | // effects: | |
76 | // 23.2.1.1 constructs an empty deque using the specified allocator | |
77 | // postconditions: | |
78 | // 23.1 table 65 u.size() == 0 | |
79 | // throws: | |
80 | // complexity: | |
81 | // 23.1 table 65 constant | |
82 | // | |
83 | // 23.2.1.2 bool empty() const | |
84 | // semantics: | |
85 | // 23.1 table 65 a.size() == 0 | |
86 | // 23.1 (7) a.begin() == a.end() | |
87 | // throws: | |
88 | // complexity: | |
89 | // 23.1 table 65 constant | |
90 | // | |
91 | // 23.2.1.2 size_type size() const | |
92 | // semantics: | |
93 | // 23.1 table 65 a.end() - a.begin() | |
94 | // throws: | |
95 | // complexity: | |
96 | // 23.1 table 65(A) should be constant | |
97 | // | |
98 | // 23.2.1 iterator begin() | |
99 | // const_iterator begin() const | |
100 | // iterator end() | |
101 | // const_iterator end() const | |
102 | // throws: | |
103 | // 23.1 (10) pt. 4 does not throw | |
104 | // complexity: | |
105 | // 23.1 table 65 constant | |
106 | // @endverbatim | |
107 | void | |
108 | defaultConstructorCheckPOD() | |
109 | { | |
110 | // setup | |
111 | typedef int T; | |
112 | typedef std::deque<T> X; | |
113 | ||
114 | // run test | |
115 | X u; | |
116 | ||
117 | // assert postconditions | |
118 | VERIFY(u.empty()); | |
119 | VERIFY(0 == u.size()); | |
120 | VERIFY(u.begin() == u.end()); | |
121 | VERIFY(0 == std::distance(u.begin(), u.end())); | |
122 | ||
123 | // teardown | |
124 | } | |
125 | ||
126 | ||
127 | void | |
128 | defaultConstructorCheck() | |
129 | { | |
130 | // setup | |
8d59b230 | 131 | typedef copy_tracker T; |
162c7cd9 SW |
132 | typedef std::deque<T> X; |
133 | ||
8d59b230 | 134 | copy_tracker::reset(); |
162c7cd9 SW |
135 | |
136 | // run test | |
137 | const X u; | |
138 | ||
139 | // assert postconditions | |
140 | VERIFY(u.empty()); | |
141 | VERIFY(0 == u.size()); | |
142 | VERIFY(u.begin() == u.end()); | |
143 | VERIFY(0 == std::distance(u.begin(), u.end())); | |
144 | ||
145 | // teardown | |
146 | } | |
147 | ||
148 | ||
149 | // @fn copyConstructorCheck() | |
150 | // Explicitly checks the deque copy constructor. Continues verificaton of | |
151 | // ancillary member functions documented under defaultConstructorCheck(). | |
152 | // | |
153 | // This check also tests the push_back() member function. | |
154 | // | |
155 | // @verbatim | |
156 | // 23.2.1 copy constructor | |
157 | // effects: | |
158 | // postconditions: | |
159 | // 22.1.1 table 65 a == X(a) | |
160 | // u == a | |
161 | // throws: | |
162 | // complexity: | |
163 | // 22.1.1 table 65 linear | |
164 | // @endverbatim | |
165 | void | |
166 | copyConstructorCheck() | |
167 | { | |
168 | // setup | |
8d59b230 | 169 | typedef copy_tracker T; |
162c7cd9 SW |
170 | typedef std::deque<T> X; |
171 | ||
11f10e6b | 172 | const std::size_t copyBaseSize = 17; // arbitrary |
162c7cd9 SW |
173 | |
174 | X a; | |
11f10e6b | 175 | for (std::size_t i = 0; i < copyBaseSize; ++i) |
162c7cd9 | 176 | a.push_back(i); |
8d59b230 | 177 | copy_tracker::reset(); |
162c7cd9 SW |
178 | |
179 | // assert preconditions | |
180 | VERIFY(!a.empty()); | |
181 | VERIFY(copyBaseSize == a.size()); | |
182 | VERIFY(a.begin() != a.end()); | |
11f10e6b | 183 | VERIFY( copyBaseSize == static_cast<std::size_t>(std::distance(a.begin(), a.end())) ); |
162c7cd9 SW |
184 | |
185 | // run test | |
186 | X u = a; | |
187 | ||
188 | // assert postconditions | |
189 | VERIFY(u == a); | |
8d59b230 | 190 | VERIFY(copyBaseSize == copy_constructor::count()); |
162c7cd9 SW |
191 | |
192 | // teardown | |
193 | } | |
194 | ||
195 | ||
196 | // @fn fillConstructorCheck() | |
197 | // This test explicitly verifies the basic fill constructor. Like the default | |
198 | // constructor, later tests depend on the fill constructor working correctly. | |
199 | // That means this explicit test should preceed the later tests so the error | |
200 | // message given on assertion failure can be more helpful n tracking the | |
201 | // problem. | |
202 | // | |
203 | // 23.2.1.1 fill constructor | |
204 | // complexity: | |
205 | // 23.2.1.1 linear in N | |
206 | void | |
207 | fillConstructorCheck() | |
208 | { | |
209 | // setup | |
8d59b230 | 210 | typedef copy_tracker T; |
162c7cd9 SW |
211 | typedef std::deque<T> X; |
212 | ||
213 | const X::size_type n(23); | |
214 | const X::value_type t(111); | |
215 | ||
8d59b230 | 216 | copy_tracker::reset(); |
162c7cd9 SW |
217 | |
218 | // run test | |
219 | X a(n, t); | |
220 | ||
221 | // assert postconditions | |
222 | VERIFY(n == a.size()); | |
8d59b230 | 223 | VERIFY(n == copy_constructor::count()); |
162c7cd9 SW |
224 | |
225 | // teardown | |
226 | } | |
227 | ||
228 | ||
229 | // @fn fillConstructorCheck2() | |
230 | // Explicit check for fill constructors masqueraded as range constructors as | |
231 | // elucidated in clause 23.1.1 paragraph 9 of the standard. | |
232 | // | |
233 | // 23.1.1 (9) fill constructor looking like a range constructor | |
234 | void | |
235 | fillConstructorCheck2() | |
236 | { | |
8d59b230 | 237 | typedef copy_tracker T; |
162c7cd9 SW |
238 | typedef std::deque<T> X; |
239 | ||
11f10e6b BK |
240 | const std::size_t f = 23; |
241 | const std::size_t l = 111; | |
162c7cd9 | 242 | |
8d59b230 | 243 | copy_tracker::reset(); |
162c7cd9 SW |
244 | |
245 | X a(f, l); | |
246 | ||
247 | VERIFY(f == a.size()); | |
8d59b230 | 248 | VERIFY(f == copy_constructor::count()); |
162c7cd9 SW |
249 | } |
250 | ||
251 | ||
252 | // @fn rangeConstructorCheckForwardIterator() | |
253 | // This test copies from one deque to another to force the copy | |
254 | // constructor for T to be used because the compiler will kindly | |
255 | // elide copies if the default constructor can be used with | |
256 | // type conversions. Trust me. | |
257 | // | |
258 | // 23.2.1.1 range constructor, forward iterators | |
259 | void | |
260 | rangeConstructorCheckForwardIterator() | |
261 | { | |
262 | // setup | |
8d59b230 | 263 | typedef copy_tracker T; |
162c7cd9 SW |
264 | typedef std::deque<T> X; |
265 | ||
266 | const X::size_type n(726); | |
267 | const X::value_type t(307); | |
268 | X source(n, t); | |
269 | X::iterator i = source.begin(); | |
270 | X::iterator j = source.end(); | |
271 | X::size_type rangeSize = std::distance(i, j); | |
272 | ||
8d59b230 | 273 | copy_tracker::reset(); |
162c7cd9 SW |
274 | |
275 | // test | |
276 | X a(i, j); | |
277 | ||
278 | // assert postconditions | |
279 | VERIFY(rangeSize == a.size()); | |
8d59b230 | 280 | VERIFY(copy_constructor::count() <= rangeSize); |
162c7cd9 SW |
281 | } |
282 | ||
283 | ||
284 | // @fn rangeConstructorCheckInputIterator() | |
285 | // An explicit check for range construction on an input iterator | |
286 | // range, which the standard expounds upon as having a different | |
287 | // complexity than forward iterators. | |
288 | // | |
289 | // 23.2.1.1 range constructor, input iterators | |
290 | void | |
291 | rangeConstructorCheckInputIterator() | |
292 | { | |
8d59b230 | 293 | typedef copy_tracker T; |
162c7cd9 SW |
294 | typedef std::deque<T> X; |
295 | ||
296 | std::istringstream ibuf("1234567890123456789"); | |
297 | const X::size_type rangeSize = ibuf.str().size(); | |
298 | std::istream_iterator<char> i(ibuf); | |
299 | std::istream_iterator<char> j; | |
300 | ||
8d59b230 | 301 | copy_tracker::reset(); |
162c7cd9 SW |
302 | |
303 | X a(i, j); | |
304 | ||
305 | VERIFY(rangeSize == a.size()); | |
8d59b230 | 306 | VERIFY(copy_constructor::count() <= (2 * rangeSize)); |
162c7cd9 SW |
307 | } |
308 | ||
309 | ||
310 | // 23.2.1 copy assignment | |
311 | void | |
312 | copyAssignmentCheck() | |
313 | { | |
8d59b230 | 314 | typedef copy_tracker T; |
162c7cd9 SW |
315 | typedef std::deque<T> X; |
316 | ||
317 | const X::size_type n(18); | |
318 | const X::value_type t(1023); | |
319 | X a(n, t); | |
320 | X r; | |
321 | ||
8d59b230 | 322 | copy_tracker::reset(); |
162c7cd9 SW |
323 | |
324 | r = a; | |
325 | ||
326 | VERIFY(r == a); | |
8d59b230 | 327 | VERIFY(n == copy_constructor::count()); |
162c7cd9 SW |
328 | } |
329 | ||
330 | ||
331 | // 23.2.1.1 fill assignment | |
332 | // | |
333 | // The complexity check must check dtors+copyAssign and | |
334 | // copyCtor+copyAssign because that's the way the SGI implementation | |
335 | // works. Dunno if it's true standard compliant (which specifies fill | |
336 | // assignment in terms of erase and insert only), but it should work | |
337 | // as (most) users expect and is more efficient. | |
338 | void | |
339 | fillAssignmentCheck() | |
340 | { | |
8d59b230 | 341 | typedef copy_tracker T; |
162c7cd9 SW |
342 | typedef std::deque<T> X; |
343 | ||
344 | const X::size_type starting_size(10); | |
345 | const X::value_type starting_value(66); | |
346 | const X::size_type n(23); | |
347 | const X::value_type t(111); | |
348 | ||
349 | X a(starting_size, starting_value); | |
8d59b230 | 350 | copy_tracker::reset(); |
162c7cd9 SW |
351 | |
352 | // preconditions | |
353 | VERIFY(starting_size == a.size()); | |
354 | ||
355 | // test | |
356 | a.assign(n, t); | |
357 | ||
358 | // postconditions | |
359 | VERIFY(n == a.size()); | |
8d59b230 BK |
360 | VERIFY(n == (copy_constructor::count() + assignment_operator::count())); |
361 | VERIFY(starting_size == (destructor::count() + assignment_operator::count())); | |
162c7cd9 SW |
362 | } |
363 | ||
364 | ||
365 | // @verbatim | |
366 | // 23.2.1 range assignment | |
367 | // 23.2.1.1 deque constructors, copy, and assignment | |
368 | // effects: | |
369 | // Constructs a deque equal to the range [first, last), using the | |
370 | // specified allocator. | |
371 | // | |
372 | // template<typename InputIterator> | |
373 | // assign(InputIterator first, InputIterator last); | |
374 | // | |
375 | // is equivalent to | |
376 | // | |
377 | // erase(begin(), end()); | |
378 | // insert(begin(), first, last); | |
379 | // | |
380 | // postconditions: | |
381 | // throws: | |
382 | // complexity: | |
383 | // forward iterators: N calls to the copy constructor, 0 reallocations | |
384 | // input iterators: 2N calls to the copy constructor, log(N) reallocations | |
385 | // @endverbatim | |
386 | void | |
387 | rangeAssignmentCheck() | |
388 | { | |
8d59b230 | 389 | typedef copy_tracker T; |
162c7cd9 SW |
390 | typedef std::deque<T> X; |
391 | ||
392 | const X::size_type source_size(726); | |
393 | const X::value_type source_value(307); | |
394 | const X::size_type starting_size(10); | |
395 | const X::value_type starting_value(66); | |
396 | ||
397 | X source(source_size, source_value); | |
398 | X::iterator i = source.begin(); | |
399 | X::iterator j = source.end(); | |
400 | X::size_type rangeSize = std::distance(i, j); | |
401 | ||
402 | X a(starting_size, starting_value); | |
403 | VERIFY(starting_size == a.size()); | |
404 | ||
8d59b230 | 405 | copy_tracker::reset(); |
162c7cd9 SW |
406 | |
407 | a.assign(i, j); | |
408 | ||
409 | VERIFY(source == a); | |
8d59b230 BK |
410 | VERIFY(rangeSize == (copy_constructor::count() + assignment_operator::count())); |
411 | VERIFY(starting_size == (destructor::count() + assignment_operator::count())); | |
162c7cd9 SW |
412 | } |
413 | ||
414 | ||
415 | // 23.1 (10) range assignment | |
416 | // 23.2.1.3 with exception | |
417 | void | |
418 | rangeAssignmentCheckWithException() | |
419 | { | |
420 | // setup | |
8d59b230 | 421 | typedef copy_tracker T; |
162c7cd9 SW |
422 | typedef std::deque<T> X; |
423 | ||
424 | // test | |
425 | // What does "no effects" mean? | |
426 | } | |
427 | ||
428 | ||
429 | // 23.1.1 (9) fill assignment looking like a range assignment | |
430 | void | |
431 | fillAssignmentCheck2() | |
432 | { | |
433 | // setup | |
8d59b230 | 434 | typedef copy_tracker T; |
162c7cd9 SW |
435 | typedef std::deque<T> X; |
436 | ||
437 | // test | |
438 | // What does "no effects" mean? | |
439 | } | |
440 | ||
441 | // Verify that the default deque constructor offers the basic exception | |
442 | // guarantee. | |
443 | void | |
444 | test_default_ctor_exception_safety() | |
445 | { | |
446 | // setup | |
8d59b230 BK |
447 | typedef copy_tracker T; |
448 | typedef std::deque<T, tracker_alloc<T> > X; | |
162c7cd9 SW |
449 | |
450 | T::reset(); | |
8d59b230 BK |
451 | copy_constructor::throw_on(3); |
452 | allocation_tracker::resetCounts(); | |
162c7cd9 SW |
453 | |
454 | // test | |
455 | try | |
456 | { | |
457 | X a(7); | |
11f10e6b | 458 | VERIFY( false ); |
162c7cd9 SW |
459 | } |
460 | catch (...) | |
461 | { | |
462 | } | |
463 | ||
464 | // assert postconditions | |
8d59b230 | 465 | VERIFY(allocation_tracker::allocationTotal() == allocation_tracker::deallocationTotal()); |
162c7cd9 SW |
466 | |
467 | // teardown | |
468 | } | |
469 | ||
470 | // Verify that the copy constructor offers the basic exception guarantee. | |
471 | void | |
472 | test_copy_ctor_exception_safety() | |
473 | { | |
474 | // setup | |
8d59b230 BK |
475 | typedef copy_tracker T; |
476 | typedef std::deque<T, tracker_alloc<T> > X; | |
162c7cd9 | 477 | |
8d59b230 | 478 | allocation_tracker::resetCounts(); |
162c7cd9 SW |
479 | { |
480 | X a(7); | |
481 | T::reset(); | |
8d59b230 | 482 | copy_constructor::throw_on(3); |
162c7cd9 SW |
483 | |
484 | ||
485 | // test | |
486 | try | |
487 | { | |
488 | X u(a); | |
11f10e6b | 489 | VERIFY(false); |
162c7cd9 SW |
490 | } |
491 | catch (...) | |
492 | { | |
493 | } | |
494 | } | |
495 | ||
496 | // assert postconditions | |
8d59b230 | 497 | VERIFY(allocation_tracker::allocationTotal() == allocation_tracker::deallocationTotal()); |
162c7cd9 SW |
498 | |
499 | // teardown | |
500 | } | |
501 | ||
502 | ||
bb2ae697 PE |
503 | int main() |
504 | { | |
162c7cd9 SW |
505 | // basic functionality and standard conformance checks |
506 | requiredTypesCheck(); | |
507 | defaultConstructorCheckPOD(); | |
508 | defaultConstructorCheck(); | |
509 | test_default_ctor_exception_safety(); | |
510 | copyConstructorCheck(); | |
511 | test_copy_ctor_exception_safety(); | |
512 | fillConstructorCheck(); | |
513 | fillConstructorCheck2(); | |
514 | rangeConstructorCheckInputIterator(); | |
515 | rangeConstructorCheckForwardIterator(); | |
516 | copyAssignmentCheck(); | |
517 | fillAssignmentCheck(); | |
518 | fillAssignmentCheck2(); | |
519 | rangeAssignmentCheck(); | |
520 | rangeAssignmentCheckWithException(); | |
17472bb6 | 521 | return 0; |
bb2ae697 | 522 | } |