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