3 // Copyright (C) 2009-2022 Free Software Foundation, Inc.
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
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.
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/>.
20 #ifndef _GLIBCXX_TESTSUITE_CONTAINERS_H
21 #define _GLIBCXX_TESTSUITE_CONTAINERS_H
23 #include <bits/boost_concept_check.h>
25 #include <testsuite_container_traits.h>
26 #include <utility> // for rel_ops.
28 // Container requirement testing.
31 // Compile-time typedef testing.
32 template<typename _Tp
, bool _Bt
= traits
<_Tp
>::is_container::value
>
35 // Base container requirements (table 80)
36 typedef _Tp test_type
;
37 typedef typename
test_type::value_type value_type
;
38 typedef typename
test_type::pointer pointer
;
39 typedef typename
test_type::const_pointer const_pointer
;
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
;
48 // Conditional typedef testing, positive.
49 template<typename _Tp
, bool _Bt
= traits
<_Tp
>::is_reversible::value
>
50 struct reversible_types
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
;
58 template<typename _Tp
, bool _Bt
= traits
<_Tp
>::is_allocator_aware::value
>
59 struct allocator_aware_types
61 // _Alloc-aware requirements (table 82)
62 typedef _Tp test_type
;
63 typedef typename
test_type::allocator_type allocator_type
;
66 template<typename _Tp
, bool _Bt
= traits
<_Tp
>::is_associative::value
>
67 struct associative_types
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
;
76 template<typename _Tp
, bool = traits
<_Tp
>::is_unordered::value
>
77 struct unordered_types
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
;
88 template<typename _Tp
, bool _Bt
= traits
<_Tp
>::is_mapped::value
>
91 typedef _Tp test_type
;
92 typedef typename
test_type::mapped_type mapped_type
;
95 template<typename _Tp
, bool = traits
<_Tp
>::is_adaptor::value
>
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
;
107 // Conditional typedef testing, negative.
108 template<typename _Tp
>
109 struct basic_types
<_Tp
, false> { };
111 template<typename _Tp
>
112 struct adaptor_types
<_Tp
, false> { };
114 template<typename _Tp
>
115 struct reversible_types
<_Tp
, false> { };
117 template<typename _Tp
>
118 struct allocator_aware_types
<_Tp
, false> { };
120 template<typename _Tp
>
121 struct associative_types
<_Tp
, false> { };
123 template<typename _Tp
>
124 struct unordered_types
<_Tp
, false> { };
126 template<typename _Tp
>
127 struct mapped_types
<_Tp
, false> { };
130 template<typename _Tp
>
132 : basic_types
<_Tp
>, adaptor_types
<_Tp
>, reversible_types
<_Tp
>,
133 allocator_aware_types
<_Tp
>, associative_types
<_Tp
>,
134 unordered_types
<_Tp
>, mapped_types
<_Tp
>
138 // Run-time test for constant_iterator requirements.
139 template<typename _Tp
, bool = traits
<_Tp
>::is_allocator_aware::value
>
142 populate(_Tp
& container
)
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());
151 template<typename _Tp
>
152 struct populate
<_Tp
, false>
154 populate(_Tp
& container
) { }
157 template<typename _Tp
, bool = traits
<_Tp
>::is_reversible::value
>
158 struct reverse_members
160 reverse_members(_Tp
& container
)
162 assert( container
.crbegin() == container
.rbegin() );
163 assert( container
.crend() == container
.rend() );
164 assert( container
.crbegin() != container
.crend() );
168 template<typename _Tp
>
169 struct reverse_members
<_Tp
, false>
171 reverse_members(_Tp
&) { }
174 template<typename _Iterator
,
176 typename
= typename
std::iterator_traits
<_Iterator
>::iterator_category
>
177 struct iterator_concept_checks
;
179 #if __cplusplus >= 201103L
181 template<typename _Tp
>
182 struct forward_members_unordered
184 forward_members_unordered(const typename
_Tp::value_type
& v
)
186 // Make sure that even if rel_ops is injected there is no ambiguity
187 // when comparing iterators.
188 using namespace std::rel_ops
;
190 typedef _Tp test_type
;
194 iterator_concept_checks
<typename
_Tp::local_iterator
, false> cc
;
195 iterator_concept_checks
<typename
_Tp::const_local_iterator
,
198 assert( container
.cbegin(0) == container
.begin(0) );
199 assert( container
.cend(0) == container
.end(0) );
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
) );
207 clit
= container
.cbegin(bn
);
208 assert( ++clit
== container
.cend(bn
) );
210 assert( container
.begin(bn
) != container
.cend(bn
) );
215 template<typename _Iterator
>
216 struct iterator_concept_checks
<_Iterator
, false,
217 std::forward_iterator_tag
>
219 iterator_concept_checks()
221 using namespace __gnu_cxx
;
222 __function_requires
<_ForwardIteratorConcept
<_Iterator
>>();
226 template<typename _Iterator
>
227 struct iterator_concept_checks
<_Iterator
, true,
228 std::forward_iterator_tag
>
230 iterator_concept_checks()
232 using namespace __gnu_cxx
;
233 __function_requires
<_Mutable_ForwardIteratorConcept
<_Iterator
>>();
237 template<typename _Iterator
>
238 struct iterator_concept_checks
<_Iterator
, false,
239 std::bidirectional_iterator_tag
>
241 iterator_concept_checks()
243 using namespace __gnu_cxx
;
244 __function_requires
<_BidirectionalIteratorConcept
<_Iterator
>>();
248 template<typename _Iterator
>
249 struct iterator_concept_checks
<_Iterator
, true,
250 std::bidirectional_iterator_tag
>
252 iterator_concept_checks()
254 using namespace __gnu_cxx
;
255 __function_requires
<_Mutable_BidirectionalIteratorConcept
<_Iterator
>>();
259 template<typename _Iterator
>
260 struct iterator_concept_checks
<_Iterator
, false,
261 std::random_access_iterator_tag
>
263 iterator_concept_checks()
265 using namespace __gnu_cxx
;
266 __function_requires
<_RandomAccessIteratorConcept
<_Iterator
>>();
270 template<typename _Iterator
>
271 struct iterator_concept_checks
<_Iterator
, true,
272 std::random_access_iterator_tag
>
274 iterator_concept_checks()
276 using namespace __gnu_cxx
;
277 __function_requires
<_Mutable_RandomAccessIteratorConcept
<_Iterator
>>();
281 template<typename _Tp
>
282 struct forward_members
284 forward_members(_Tp
& container
)
286 // Make sure that even if rel_ops is injected there is no ambiguity
287 // when comparing iterators.
288 using namespace std::rel_ops
;
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
;
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() );
304 template<typename _Tp
,
306 = typename
std::iterator_traits
<typename
_Tp::iterator
>::iterator_category
>
307 struct category_members
: forward_members
<_Tp
>
309 category_members(_Tp
& container
)
310 : forward_members
<_Tp
>(container
)
314 template<typename _Tp
>
315 struct category_members
<_Tp
, std::random_access_iterator_tag
>
316 : forward_members
<_Tp
>
318 category_members(_Tp
& container
)
319 : forward_members
<_Tp
>(container
)
321 // Make sure that even if rel_ops is injected there is no ambiguity
322 // when comparing iterators.
323 using namespace std::rel_ops
;
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() );
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() );
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 );
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() );
357 template<typename _Tp
>
360 typedef _Tp test_type
;
361 typedef traits
<test_type
> traits_type
;
362 typedef typename
test_type::value_type value_type
;
364 static test_type _S_container
;
367 struct members
: category_members
<_Tp
>
369 members() : category_members
<_Tp
>(_S_container
)
376 populate
<test_type
> p(_S_container
);
378 reverse_members
<test_type
> m2(_S_container
);
382 template<typename _Tp
>
383 _Tp citerator
<_Tp
>::_S_container
;
385 // DR 130 vs. C++98 vs. C++11.
386 // Defined in testsuite_shared.cc.
388 erase_external(std::set
<int>& s
);
391 erase_external(std::multiset
<int>& s
);
394 erase_external(std::map
<int, int>& s
);
397 erase_external(std::multimap
<int, int>& s
);
400 erase_external_iterators(std::set
<int>& s
);
403 erase_external_iterators(std::multiset
<int>& s
);
406 erase_external_iterators(std::map
<int, int>& s
);
409 erase_external_iterators(std::multimap
<int, int>& s
);
411 #if __cplusplus < 201103L
412 # error "must be compiled with C++11 (or later)"
414 template<typename _Tp
>
416 linkage_check_cxx98_cxx11_erase(_Tp
& container
)
418 // Crashing when external reference and internal reference symbols are
419 // equivalently mangled but have different size return types in C++98
420 // and C++11 signatures.
421 erase_external(container
); // C++98
422 container
.erase(container
.begin()); // C++11
425 template<typename _Tp
>
427 linkage_check_cxx98_cxx11_erase_iterators(_Tp
& container
)
429 // Crashing when external reference and internal reference symbols are
430 // equivalently mangled but have different size return types in C++98
431 // and C++11 signatures.
432 erase_external_iterators(container
);// C++98
434 auto iter
= container
.begin();
435 container
.erase(iter
, ++iter
); // C++11
439 } // namespace __gnu_test