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