1// Copyright (C) 2010-2015 Free Software Foundation, Inc.
2//
3// This file is part of the GNU ISO C++ Library.  This library is free
4// software; you can redistribute it and/or modify it under the
5// terms of the GNU General Public License as published by the
6// Free Software Foundation; either version 3, or (at your option)
7// any later version.
8//
9// This library is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License along
15// with this library; see the file COPYING3.  If not see
16// <http://www.gnu.org/licenses/>.
17//
18
19#include <vector>
20#include <deque>
21#include <list>
22#ifndef _GLIBCXX_DEBUG
23#  include <debug/vector>
24#  include <debug/deque>
25#  include <debug/list>
26#endif
27#include <testsuite_hooks.h>
28
29namespace __gnu_test
30{
31  template<typename _Tp>
32    struct CopyableValueType
33    {
34      typedef _Tp value_type;
35    };
36
37  template<typename _Tp1, typename _Tp2>
38    struct CopyableValueType<std::pair<const _Tp1, _Tp2> >
39    {
40      typedef std::pair<_Tp1, _Tp2> value_type;
41    };
42
43  template<typename _Tp>
44    struct generate_unique
45    {
46      typedef _Tp value_type;
47
48      value_type build()
49      {
50	static value_type _S_;
51	++_S_;
52	return _S_;
53      }
54    };
55
56  template<typename _Tp1, typename _Tp2>
57    struct generate_unique<std::pair<_Tp1, _Tp2> >
58    {
59      typedef _Tp1 first_type;
60      typedef _Tp2 second_type;
61      typedef std::pair<_Tp1, _Tp2> pair_type;
62
63      pair_type build()
64      {
65	static first_type _S_1;
66	static second_type _S_2;
67	++_S_1;
68	++_S_2;
69	return pair_type(_S_1, _S_2);
70      }
71    };
72
73  // Check that invalid range of pointers is detected
74  template<typename _Tp>
75    void
76    check_assign1()
77    {
78      bool test __attribute__((unused)) = true;
79
80      typedef _Tp cont_type;
81      typedef typename cont_type::value_type cont_val_type;
82      typedef typename CopyableValueType<cont_val_type>::value_type val_type;
83      typedef std::vector<val_type> vector_type;
84
85      generate_unique<val_type> gu;
86
87      vector_type v;
88      for (int i = 0; i != 5; ++i)
89        v.push_back(gu.build());
90      VERIFY(v.size() == 5);
91
92      const val_type* first = &v.front() + 1;
93      const val_type* last = first + 2;
94
95      cont_type c1;
96      c1.assign(first, last);
97      VERIFY(c1.size() == 2);
98
99      cont_type c2;
100      c2.assign(last, first); // Expected failure
101    }
102
103  // Check that invalid range of debug random iterators is detected
104  template<typename _Tp>
105    void
106    check_assign2()
107    {
108      bool test __attribute__((unused)) = true;
109
110      typedef _Tp cont_type;
111      typedef typename cont_type::value_type cont_val_type;
112      typedef typename CopyableValueType<cont_val_type>::value_type val_type;
113      typedef std::vector<val_type> vector_type;
114
115      generate_unique<val_type> gu;
116
117      vector_type v;
118      for (int i = 0; i != 5; ++i)
119        v.push_back(gu.build());
120      VERIFY(v.size() == 5);
121
122      typename vector_type::iterator first = v.begin() + 1;
123      typename vector_type::iterator last = first + 2;
124      cont_type c1;
125      c1.assign(first, last);
126      VERIFY(c1.size() == 2);
127
128      cont_type c2;
129      c2.assign(last, first); // Expected failure
130    }
131
132  // Check that invalid range of debug not random iterators is detected
133  template<typename _Tp>
134    void
135    check_assign3()
136    {
137      bool test __attribute__((unused)) = true;
138
139      typedef _Tp cont_type;
140      typedef typename cont_type::value_type cont_val_type;
141      typedef typename CopyableValueType<cont_val_type>::value_type val_type;
142      typedef std::list<val_type> list_type;
143
144      generate_unique<val_type> gu;
145
146      list_type l;
147      for (int i = 0; i != 5; ++i)
148        l.push_back(gu.build());
149      VERIFY(l.size() == 5);
150
151      typename list_type::iterator first = l.begin(); ++first;
152      typename list_type::iterator last = first; ++last; ++last;
153      cont_type c1;
154      c1.assign(first, last);
155      VERIFY(c1.size() == 2);
156
157      cont_type c2;
158      c2.assign(last, first); // Expected failure
159    }
160
161  // Check that invalid range of pointers is detected
162  template<typename _Tp>
163    void
164    check_construct1()
165    {
166      bool test __attribute__((unused)) = true;
167
168      typedef _Tp cont_type;
169      typedef typename cont_type::value_type cont_val_type;
170      typedef typename CopyableValueType<cont_val_type>::value_type val_type;
171      typedef std::vector<val_type> vector_type;
172
173      generate_unique<val_type> gu;
174
175      vector_type v;
176      for (int i = 0; i != 5; ++i)
177        v.push_back(gu.build());
178      VERIFY(v.size() == 5);
179
180      val_type *first = &v.front() + 1;
181      val_type *last = first + 2;
182
183      cont_type c(last, first); // Expected failure
184    }
185
186  // Check that invalid range of debug random iterators is detected
187  template<typename _Tp>
188    void
189    check_construct2()
190    {
191      bool test __attribute__((unused)) = true;
192
193      typedef _Tp cont_type;
194      typedef typename cont_type::value_type cont_val_type;
195      typedef typename CopyableValueType<cont_val_type>::value_type val_type;
196      typedef std::vector<val_type> vector_type;
197
198      generate_unique<val_type> gu;
199
200      vector_type v;
201      for (int i = 0; i != 5; ++i)
202        v.push_back(gu.build());
203      VERIFY(v.size() == 5);
204
205      typename vector_type::iterator first = v.begin() + 1;
206      typename vector_type::iterator last = first + 2;
207
208      cont_type c(last, first); // Expected failure
209    }
210
211  // Check that invalid range of debug not random iterators is detected
212  template<typename _Tp>
213    void
214    check_construct3()
215    {
216      bool test __attribute__((unused)) = true;
217
218      typedef _Tp cont_type;
219      typedef typename cont_type::value_type cont_val_type;
220      typedef typename CopyableValueType<cont_val_type>::value_type val_type;
221      typedef std::list<val_type> list_type;
222
223      generate_unique<val_type> gu;
224
225      list_type l;
226      for (int i = 0; i != 5; ++i)
227        l.push_back(gu.build());
228      VERIFY(l.size() == 5);
229
230      typename list_type::iterator first = l.begin(); ++first;
231      typename list_type::iterator last = first; ++last; ++last;
232
233      cont_type c(last, first); // Expected failure
234    }
235
236  template <typename _Cont>
237    struct InsertRangeHelper
238    {
239      template <typename _It>
240        static void
241        Insert(_Cont& cont, _It first, _It last)
242	{ cont.insert(first, last); }
243    };
244
245  template <typename _Cont>
246    struct InsertRangeHelperAux
247    {
248      template <typename _It>
249        static void
250        Insert(_Cont& cont, _It first, _It last)
251	{ cont.insert(cont.begin(), first, last); }
252    };
253
254  template <typename _Tp1, typename _Tp2>
255    struct InsertRangeHelper<std::vector<_Tp1, _Tp2> >
256    : InsertRangeHelperAux<std::vector<_Tp1, _Tp2> >
257    { };
258
259  template <typename _Tp1, typename _Tp2>
260    struct InsertRangeHelper<std::deque<_Tp1, _Tp2> >
261    : InsertRangeHelperAux<std::deque<_Tp1, _Tp2> >
262    { };
263
264  template <typename _Tp1, typename _Tp2>
265    struct InsertRangeHelper<std::list<_Tp1, _Tp2> >
266    : InsertRangeHelperAux<std::list<_Tp1, _Tp2> >
267    { };
268
269#ifndef _GLIBCXX_DEBUG
270  template <typename _Tp1, typename _Tp2>
271    struct InsertRangeHelper<__gnu_debug::vector<_Tp1, _Tp2> >
272    : InsertRangeHelperAux<__gnu_debug::vector<_Tp1, _Tp2> >
273    { };
274
275  template <typename _Tp1, typename _Tp2>
276    struct InsertRangeHelper<__gnu_debug::deque<_Tp1, _Tp2> >
277    : InsertRangeHelperAux<__gnu_debug::deque<_Tp1, _Tp2> >
278    { };
279
280  template <typename _Tp1, typename _Tp2>
281    struct InsertRangeHelper<__gnu_debug::list<_Tp1, _Tp2> >
282    : InsertRangeHelperAux<__gnu_debug::list<_Tp1, _Tp2> >
283    { };
284#endif
285
286  template<typename _Tp>
287    void
288    check_insert1()
289    {
290      bool test __attribute__((unused)) = true;
291
292      typedef _Tp cont_type;
293      typedef typename cont_type::value_type cont_val_type;
294      typedef typename CopyableValueType<cont_val_type>::value_type val_type;
295      typedef std::vector<val_type> vector_type;
296
297      generate_unique<val_type> gu;
298
299      vector_type v;
300      for (int i = 0; i != 5; ++i)
301        v.push_back(gu.build());
302      VERIFY(v.size() == 5);
303
304      const val_type* first = &v.front() + 1;
305      const val_type* last = first + 2;
306
307      cont_type c1;
308      InsertRangeHelper<cont_type>::Insert(c1, first, last);
309      VERIFY(c1.size() == 2);
310
311      cont_type c2;
312      InsertRangeHelper<cont_type>::Insert(c2, last, first); // Expected failure
313    }
314
315  template<typename _Tp>
316    void
317    check_insert2()
318    {
319      bool test __attribute__((unused)) = true;
320
321      typedef _Tp cont_type;
322      typedef typename cont_type::value_type cont_val_type;
323      typedef typename CopyableValueType<cont_val_type>::value_type val_type;
324      typedef std::vector<val_type> vector_type;
325
326      generate_unique<val_type> gu;
327
328      vector_type v;
329      for (int i = 0; i != 5; ++i)
330        v.push_back(gu.build());
331      VERIFY(v.size() == 5);
332
333      typename vector_type::iterator first = v.begin() + 1;
334      typename vector_type::iterator last = first + 2;
335
336      cont_type c1;
337      InsertRangeHelper<cont_type>::Insert(c1, first, last);
338      VERIFY(c1.size() == 2);
339
340      cont_type c2;
341      InsertRangeHelper<cont_type>::Insert(c2, last, first); // Expected failure
342    }
343
344  template<typename _Tp>
345    void
346    check_insert3()
347    {
348      bool test __attribute__((unused)) = true;
349
350      typedef _Tp cont_type;
351      typedef typename cont_type::value_type cont_val_type;
352      typedef typename CopyableValueType<cont_val_type>::value_type val_type;
353      typedef std::list<val_type> list_type;
354
355      generate_unique<val_type> gu;
356
357      list_type l;
358      for (int i = 0; i != 5; ++i)
359        l.push_back(gu.build());
360      VERIFY(l.size() == 5);
361
362      typename list_type::iterator first = l.begin(); ++first;
363      typename list_type::iterator last = first; ++last; ++last;
364
365      cont_type c1;
366      InsertRangeHelper<cont_type>::Insert(c1, first, last);
367      VERIFY(c1.size() == 2);
368
369      cont_type c2;
370      InsertRangeHelper<cont_type>::Insert(c2, last, first); // Expected failure
371    }
372
373  template<typename _Tp>
374    void
375    check_insert4()
376    {
377      bool test __attribute__((unused)) = true;
378
379      typedef _Tp cont_type;
380      typedef typename cont_type::value_type cont_val_type;
381      typedef typename CopyableValueType<cont_val_type>::value_type val_type;
382      typedef std::list<val_type> list_type;
383
384      generate_unique<val_type> gu;
385
386      list_type l;
387      for (int i = 0; i != 5; ++i)
388        l.push_back(gu.build());
389      VERIFY(l.size() == 5);
390
391      typename list_type::iterator first = l.begin(); ++first;
392      typename list_type::iterator last = first; ++last; ++last;
393
394      cont_type c1;
395      InsertRangeHelper<cont_type>::Insert(c1, l.begin(), l.end());
396      VERIFY(c1.size() == 5);
397
398      c1.insert(c1.begin(), c1.begin(), c1.end()); // Expected failure.
399    }
400
401  template<typename _Tp>
402    void use_invalid_iterator()
403    {
404      bool test __attribute__((unused)) = true;
405
406      typedef _Tp cont_type;
407      typedef typename cont_type::value_type cont_val_type;
408      typedef typename CopyableValueType<cont_val_type>::value_type val_type;
409      generate_unique<val_type> gu;
410
411      cont_type c;
412      for (size_t i = 0; i != 5; ++i)
413	c.insert(gu.build());
414
415      typename cont_type::iterator it = c.begin();
416      cont_val_type val = *it;
417      c.clear();
418      VERIFY( *it == val );
419    }
420}
421
422