]> git.ipfire.org Git - thirdparty/gcc.git/blame - libstdc++-v3/testsuite/util/testsuite_containers.h
Update copyright years.
[thirdparty/gcc.git] / libstdc++-v3 / testsuite / util / testsuite_containers.h
CommitLineData
43308b7e 1// -*- C++ -*-
2
fbd26352 3// Copyright (C) 2009-2019 Free Software Foundation, Inc.
43308b7e 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 terms
7// of the GNU General Public License as published by the Free Software
8// Foundation; either version 3, or (at your option) any later
9// version.
10
11// This library is distributed in the hope that it will be useful, but
12// WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14// 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#ifndef _GLIBCXX_TESTSUITE_CONTAINERS_H
21#define _GLIBCXX_TESTSUITE_CONTAINERS_H
22
319d9891 23#include <bits/boost_concept_check.h>
43308b7e 24#include <cassert>
25#include <testsuite_container_traits.h>
9fe2a042 26#include <utility> // for rel_ops.
43308b7e 27
28// Container requirement testing.
29namespace __gnu_test
30{
31 // Compile-time typedef testing.
32 template<typename _Tp, bool _Bt = traits<_Tp>::is_container::value>
33 struct basic_types
34 {
35 // Base container requirements (table 80)
36 typedef _Tp test_type;
37 typedef typename test_type::value_type value_type;
d0b5b304 38 typedef typename test_type::pointer pointer;
39 typedef typename test_type::const_pointer const_pointer;
43308b7e 40 typedef typename test_type::reference reference;
41 typedef typename test_type::const_reference const_reference;
42 typedef typename test_type::iterator iterator;
43 typedef typename test_type::const_iterator const_iterator;
44 typedef typename test_type::size_type size_type;
45 typedef typename test_type::difference_type difference_type;
46 };
47
48 // Conditional typedef testing, positive.
49 template<typename _Tp, bool _Bt = traits<_Tp>::is_reversible::value>
50 struct reversible_types
51 {
52 // Reversible container requirements (table 81)
53 typedef _Tp test_type;
54 typedef typename test_type::reverse_iterator reverse_iterator;
55 typedef typename test_type::const_reverse_iterator const_reverse_iterator;
56 };
57
58 template<typename _Tp, bool _Bt = traits<_Tp>::is_allocator_aware::value>
59 struct allocator_aware_types
60 {
4f4a327e 61 // _Alloc-aware requirements (table 82)
43308b7e 62 typedef _Tp test_type;
63 typedef typename test_type::allocator_type allocator_type;
64 };
65
43308b7e 66 template<typename _Tp, bool _Bt = traits<_Tp>::is_associative::value>
67 struct associative_types
68 {
69 // Associative container requirements (table 85)
70 typedef _Tp test_type;
71 typedef typename test_type::key_type key_type;
72 typedef typename test_type::key_compare key_compare;
73 typedef typename test_type::value_compare value_compare;
74 };
75
76 template<typename _Tp, bool = traits<_Tp>::is_unordered::value>
77 struct unordered_types
78 {
79 // Unordered associative container requirements (table 87)
80 typedef _Tp test_type;
81 typedef typename test_type::key_type key_type;
82 typedef typename test_type::hasher hasher;
83 typedef typename test_type::key_equal key_equal;
84 typedef typename test_type::local_iterator local_iterator;
85 typedef typename test_type::const_local_iterator const_local_iterator;
86 };
87
88 template<typename _Tp, bool _Bt = traits<_Tp>::is_mapped::value>
89 struct mapped_types
90 {
91 typedef _Tp test_type;
92 typedef typename test_type::mapped_type mapped_type;
93 };
94
95 template<typename _Tp, bool = traits<_Tp>::is_adaptor::value>
96 struct adaptor_types
97 {
98 // Container adaptor requirements.
99 typedef _Tp test_type;
100 typedef typename test_type::value_type value_type;
101 typedef typename test_type::reference reference;
102 typedef typename test_type::const_reference const_reference;
103 typedef typename test_type::size_type size_type;
104 typedef typename test_type::container_type container_type;
105 };
106
107 // Conditional typedef testing, negative.
108 template<typename _Tp>
109 struct basic_types<_Tp, false> { };
110
111 template<typename _Tp>
d0b5b304 112 struct adaptor_types<_Tp, false> { };
43308b7e 113
114 template<typename _Tp>
d0b5b304 115 struct reversible_types<_Tp, false> { };
43308b7e 116
117 template<typename _Tp>
d0b5b304 118 struct allocator_aware_types<_Tp, false> { };
43308b7e 119
120 template<typename _Tp>
121 struct associative_types<_Tp, false> { };
122
123 template<typename _Tp>
124 struct unordered_types<_Tp, false> { };
125
126 template<typename _Tp>
127 struct mapped_types<_Tp, false> { };
128
43308b7e 129 // Primary template.
130 template<typename _Tp>
131 struct types
132 : basic_types<_Tp>, adaptor_types<_Tp>, reversible_types<_Tp>,
d0b5b304 133 allocator_aware_types<_Tp>, associative_types<_Tp>,
134 unordered_types<_Tp>, mapped_types<_Tp>
43308b7e 135 { };
136
137
138 // Run-time test for constant_iterator requirements.
139 template<typename _Tp, bool = traits<_Tp>::is_allocator_aware::value>
140 struct populate
141 {
142 populate(_Tp& container)
143 {
cfcd3170 144 // Avoid uninitialized warnings, requires DefaultContructible.
145 typedef typename _Tp::value_type value_type;
146 container.insert(container.begin(), value_type());
147 container.insert(container.begin(), value_type());
43308b7e 148 }
149 };
150
151 template<typename _Tp>
152 struct populate<_Tp, false>
153 {
154 populate(_Tp& container) { }
155 };
156
157 template<typename _Tp, bool = traits<_Tp>::is_reversible::value>
158 struct reverse_members
159 {
160 reverse_members(_Tp& container)
161 {
162 assert( container.crbegin() == container.rbegin() );
163 assert( container.crend() == container.rend() );
164 assert( container.crbegin() != container.crend() );
165 }
166 };
167
168 template<typename _Tp>
169 struct reverse_members<_Tp, false>
170 {
171 reverse_members(_Tp& container) { }
172 };
173
9fe2a042 174 template<typename _Iterator,
175 bool _Mutable,
176 typename = typename std::iterator_traits<_Iterator>::iterator_category>
177 struct iterator_concept_checks;
178
f505dfb9 179#if __cplusplus >= 201103L
43308b7e 180 // DR 691.
9fe2a042 181 template<typename _Tp>
43308b7e 182 struct forward_members_unordered
183 {
f505dfb9 184 forward_members_unordered(const typename _Tp::value_type& v)
43308b7e 185 {
9fe2a042 186 // Make sure that even if rel_ops is injected there is no ambiguity
187 // when comparing iterators.
188 using namespace std::rel_ops;
189
43308b7e 190 typedef _Tp test_type;
191 test_type container;
192 container.insert(v);
9fe2a042 193
194 iterator_concept_checks<typename _Tp::local_iterator, false> cc;
195 iterator_concept_checks<typename _Tp::const_local_iterator,
196 false> ccc;
197
43308b7e 198 assert( container.cbegin(0) == container.begin(0) );
199 assert( container.cend(0) == container.end(0) );
f505dfb9 200 const auto bn = container.bucket(1);
201 auto clit = container.cbegin(bn);
202 assert( clit != container.cend(bn) );
203 assert( clit != container.end(bn) );
204 assert( clit++ == container.cbegin(bn) );
205 assert( clit == container.end(bn) );
206
207 clit = container.cbegin(bn);
208 assert( ++clit == container.cend(bn) );
209
9fe2a042 210 assert( container.begin(bn) != container.cend(bn) );
43308b7e 211 }
212 };
f505dfb9 213#endif
43308b7e 214
319d9891 215 template<typename _Iterator>
216 struct iterator_concept_checks<_Iterator, false,
217 std::forward_iterator_tag>
218 {
219 iterator_concept_checks()
220 {
221 using namespace __gnu_cxx;
222 __function_requires<_ForwardIteratorConcept<_Iterator>>();
223 }
224 };
225
226 template<typename _Iterator>
227 struct iterator_concept_checks<_Iterator, true,
228 std::forward_iterator_tag>
229 {
230 iterator_concept_checks()
231 {
232 using namespace __gnu_cxx;
233 __function_requires<_Mutable_ForwardIteratorConcept<_Iterator>>();
234 }
235 };
236
237 template<typename _Iterator>
238 struct iterator_concept_checks<_Iterator, false,
239 std::bidirectional_iterator_tag>
240 {
241 iterator_concept_checks()
242 {
243 using namespace __gnu_cxx;
244 __function_requires<_BidirectionalIteratorConcept<_Iterator>>();
245 }
246 };
247
248 template<typename _Iterator>
249 struct iterator_concept_checks<_Iterator, true,
250 std::bidirectional_iterator_tag>
251 {
252 iterator_concept_checks()
253 {
254 using namespace __gnu_cxx;
255 __function_requires<_Mutable_BidirectionalIteratorConcept<_Iterator>>();
256 }
257 };
258
259 template<typename _Iterator>
260 struct iterator_concept_checks<_Iterator, false,
261 std::random_access_iterator_tag>
262 {
263 iterator_concept_checks()
264 {
265 using namespace __gnu_cxx;
266 __function_requires<_RandomAccessIteratorConcept<_Iterator>>();
267 }
268 };
269
270 template<typename _Iterator>
271 struct iterator_concept_checks<_Iterator, true,
272 std::random_access_iterator_tag>
273 {
274 iterator_concept_checks()
275 {
276 using namespace __gnu_cxx;
277 __function_requires<_Mutable_RandomAccessIteratorConcept<_Iterator>>();
278 }
279 };
280
9fe2a042 281 template<typename _Tp>
282 struct forward_members
283 {
284 forward_members(_Tp& container)
285 {
286 // Make sure that even if rel_ops is injected there is no ambiguity
287 // when comparing iterators.
288 using namespace std::rel_ops;
289
290 typedef traits<_Tp> traits_type;
291 iterator_concept_checks<typename _Tp::iterator,
292 !(traits_type::is_associative::value
293 || traits_type::is_unordered::value)> cc;
294 iterator_concept_checks<typename _Tp::const_iterator, false> ccc;
295
296 assert( container.cbegin() == container.begin() );
297 assert( container.end() == container.cend() );
298 assert( container.cbegin() != container.cend() );
299 assert( container.cbegin() != container.end() );
300 assert( container.begin() != container.cend() );
301 }
302 };
303
304 template<typename _Tp,
305 typename
306 = typename std::iterator_traits<typename _Tp::iterator>::iterator_category>
307 struct category_members : forward_members<_Tp>
308 {
309 category_members(_Tp& container)
310 : forward_members<_Tp>(container)
311 { };
312 };
313
314 template<typename _Tp>
315 struct category_members<_Tp, std::random_access_iterator_tag>
316 : forward_members<_Tp>
317 {
318 category_members(_Tp& container)
319 : forward_members<_Tp>(container)
320 {
321 // Make sure that even if rel_ops is injected there is no ambiguity
322 // when comparing iterators.
323 using namespace std::rel_ops;
324
325 assert( !(container.begin() < container.begin()) );
326 assert( !(container.cbegin() < container.cbegin()) );
327 assert( !(container.cbegin() < container.begin()) );
328 assert( !(container.begin() < container.cbegin()) );
329 assert( container.begin() <= container.begin() );
330 assert( container.cbegin() <= container.cbegin() );
331 assert( container.cbegin() <= container.begin() );
332 assert( container.begin() <= container.cbegin() );
333
334 assert( !(container.begin() > container.begin()) );
335 assert( !(container.cbegin() > container.cbegin()) );
336 assert( !(container.cbegin() > container.begin()) );
337 assert( !(container.begin() > container.cbegin()) );
338 assert( container.begin() >= container.begin() );
339 assert( container.cbegin() >= container.cbegin() );
340 assert( container.cbegin() >= container.begin() );
341 assert( container.begin() >= container.cbegin() );
342
343 assert( container.begin() - container.begin() == 0 );
344 assert( container.cbegin() - container.cbegin() == 0 );
345 assert( container.cbegin() - container.begin() == 0 );
346 assert( container.begin() - container.cbegin() == 0 );
347
348 assert( container.begin() + 0 == container.begin() );
349 assert( container.cbegin() + 0 == container.cbegin() );
350 assert( 0 + container.begin() == container.begin() );
351 assert( 0 + container.cbegin() == container.cbegin() );
352 assert( container.begin() - 0 == container.begin() );
353 assert( container.cbegin() - 0 == container.cbegin() );
354 }
355 };
356
43308b7e 357 template<typename _Tp>
358 struct citerator
359 {
360 typedef _Tp test_type;
361 typedef traits<test_type> traits_type;
362 typedef typename test_type::value_type value_type;
363
364 static test_type _S_container;
365
366 // Unconditional.
9fe2a042 367 struct members : category_members<_Tp>
43308b7e 368 {
9fe2a042 369 members() : category_members<_Tp>(_S_container)
370 { }
43308b7e 371 };
372
373 // Run test.
374 citerator()
375 {
376 populate<test_type> p(_S_container);
9fe2a042 377 members m1;
43308b7e 378 reverse_members<test_type> m2(_S_container);
379 }
380 };
381
382 template<typename _Tp>
383 _Tp citerator<_Tp>::_S_container;
384
8544d95d 385 // DR 130 vs. C++98 vs. C++11.
386 // Defined in testsuite_shared.cc.
33b7ef52 387 void
8544d95d 388 erase_external(std::set<int>& s);
389
33b7ef52 390 void
8544d95d 391 erase_external(std::multiset<int>& s);
392
33b7ef52 393 void
8544d95d 394 erase_external(std::map<int, int>& s);
395
33b7ef52 396 void
8544d95d 397 erase_external(std::multimap<int, int>& s);
398
33b7ef52 399 void
8544d95d 400 erase_external_iterators(std::set<int>& s);
401
33b7ef52 402 void
8544d95d 403 erase_external_iterators(std::multiset<int>& s);
404
33b7ef52 405 void
8544d95d 406 erase_external_iterators(std::map<int, int>& s);
407
33b7ef52 408 void
8544d95d 409 erase_external_iterators(std::multimap<int, int>& s);
410
411// NB: "must be compiled with C++11"
412#if __cplusplus >= 201103L
413template<typename _Tp>
33b7ef52 414 void
8544d95d 415 linkage_check_cxx98_cxx11_erase(_Tp& container)
416 {
7b96e840 417 // Crashing when external reference and internal reference symbols are
8544d95d 418 // equivalently mangled but have different size return types in C++98
419 // and C++11 signatures.
420 erase_external(container); // C++98
421 container.erase(container.begin()); // C++11
422 }
423
424template<typename _Tp>
33b7ef52 425 void
8544d95d 426 linkage_check_cxx98_cxx11_erase_iterators(_Tp& container)
427 {
7b96e840 428 // Crashing when external reference and internal reference symbols are
8544d95d 429 // equivalently mangled but have different size return types in C++98
430 // and C++11 signatures.
431 erase_external_iterators(container);// C++98
432
433 auto iter = container.begin();
434 container.erase(iter, ++iter); // C++11
435 }
436#endif
43308b7e 437
438} // namespace __gnu_test
439
440#endif