123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441 |
- // -*- C++ -*-
- // Copyright (C) 2009-2022 Free Software Foundation, Inc.
- //
- // This file is part of the GNU ISO C++ Library. This library is free
- // software; you can redistribute it and/or modify it under the terms
- // of the GNU General Public License as published by the Free Software
- // Foundation; either version 3, or (at your option) any later
- // version.
- // This library is distributed in the hope that it will be useful, but
- // WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- // General Public License for more details.
- // You should have received a copy of the GNU General Public License along
- // with this library; see the file COPYING3. If not see
- // <http://www.gnu.org/licenses/>.
- #ifndef _GLIBCXX_TESTSUITE_CONTAINERS_H
- #define _GLIBCXX_TESTSUITE_CONTAINERS_H
- #include <bits/boost_concept_check.h>
- #include <cassert>
- #include <testsuite_container_traits.h>
- #include <utility> // for rel_ops.
- // Container requirement testing.
- namespace __gnu_test
- {
- // Compile-time typedef testing.
- template<typename _Tp, bool _Bt = traits<_Tp>::is_container::value>
- struct basic_types
- {
- // Base container requirements (table 80)
- typedef _Tp test_type;
- typedef typename test_type::value_type value_type;
- typedef typename test_type::pointer pointer;
- typedef typename test_type::const_pointer const_pointer;
- typedef typename test_type::reference reference;
- typedef typename test_type::const_reference const_reference;
- typedef typename test_type::iterator iterator;
- typedef typename test_type::const_iterator const_iterator;
- typedef typename test_type::size_type size_type;
- typedef typename test_type::difference_type difference_type;
- };
- // Conditional typedef testing, positive.
- template<typename _Tp, bool _Bt = traits<_Tp>::is_reversible::value>
- struct reversible_types
- {
- // Reversible container requirements (table 81)
- typedef _Tp test_type;
- typedef typename test_type::reverse_iterator reverse_iterator;
- typedef typename test_type::const_reverse_iterator const_reverse_iterator;
- };
- template<typename _Tp, bool _Bt = traits<_Tp>::is_allocator_aware::value>
- struct allocator_aware_types
- {
- // _Alloc-aware requirements (table 82)
- typedef _Tp test_type;
- typedef typename test_type::allocator_type allocator_type;
- };
- template<typename _Tp, bool _Bt = traits<_Tp>::is_associative::value>
- struct associative_types
- {
- // Associative container requirements (table 85)
- typedef _Tp test_type;
- typedef typename test_type::key_type key_type;
- typedef typename test_type::key_compare key_compare;
- typedef typename test_type::value_compare value_compare;
- };
- template<typename _Tp, bool = traits<_Tp>::is_unordered::value>
- struct unordered_types
- {
- // Unordered associative container requirements (table 87)
- typedef _Tp test_type;
- typedef typename test_type::key_type key_type;
- typedef typename test_type::hasher hasher;
- typedef typename test_type::key_equal key_equal;
- typedef typename test_type::local_iterator local_iterator;
- typedef typename test_type::const_local_iterator const_local_iterator;
- };
- template<typename _Tp, bool _Bt = traits<_Tp>::is_mapped::value>
- struct mapped_types
- {
- typedef _Tp test_type;
- typedef typename test_type::mapped_type mapped_type;
- };
- template<typename _Tp, bool = traits<_Tp>::is_adaptor::value>
- struct adaptor_types
- {
- // Container adaptor requirements.
- typedef _Tp test_type;
- typedef typename test_type::value_type value_type;
- typedef typename test_type::reference reference;
- typedef typename test_type::const_reference const_reference;
- typedef typename test_type::size_type size_type;
- typedef typename test_type::container_type container_type;
- };
- // Conditional typedef testing, negative.
- template<typename _Tp>
- struct basic_types<_Tp, false> { };
- template<typename _Tp>
- struct adaptor_types<_Tp, false> { };
- template<typename _Tp>
- struct reversible_types<_Tp, false> { };
- template<typename _Tp>
- struct allocator_aware_types<_Tp, false> { };
- template<typename _Tp>
- struct associative_types<_Tp, false> { };
- template<typename _Tp>
- struct unordered_types<_Tp, false> { };
- template<typename _Tp>
- struct mapped_types<_Tp, false> { };
- // Primary template.
- template<typename _Tp>
- struct types
- : basic_types<_Tp>, adaptor_types<_Tp>, reversible_types<_Tp>,
- allocator_aware_types<_Tp>, associative_types<_Tp>,
- unordered_types<_Tp>, mapped_types<_Tp>
- { };
- // Run-time test for constant_iterator requirements.
- template<typename _Tp, bool = traits<_Tp>::is_allocator_aware::value>
- struct populate
- {
- populate(_Tp& container)
- {
- // Avoid uninitialized warnings, requires DefaultContructible.
- typedef typename _Tp::value_type value_type;
- container.insert(container.begin(), value_type());
- container.insert(container.begin(), value_type());
- }
- };
- template<typename _Tp>
- struct populate<_Tp, false>
- {
- populate(_Tp& container) { }
- };
- template<typename _Tp, bool = traits<_Tp>::is_reversible::value>
- struct reverse_members
- {
- reverse_members(_Tp& container)
- {
- assert( container.crbegin() == container.rbegin() );
- assert( container.crend() == container.rend() );
- assert( container.crbegin() != container.crend() );
- }
- };
- template<typename _Tp>
- struct reverse_members<_Tp, false>
- {
- reverse_members(_Tp&) { }
- };
- template<typename _Iterator,
- bool _Mutable,
- typename = typename std::iterator_traits<_Iterator>::iterator_category>
- struct iterator_concept_checks;
- #if __cplusplus >= 201103L
- // DR 691.
- template<typename _Tp>
- struct forward_members_unordered
- {
- forward_members_unordered(const typename _Tp::value_type& v)
- {
- // Make sure that even if rel_ops is injected there is no ambiguity
- // when comparing iterators.
- using namespace std::rel_ops;
- typedef _Tp test_type;
- test_type container;
- container.insert(v);
- iterator_concept_checks<typename _Tp::local_iterator, false> cc;
- iterator_concept_checks<typename _Tp::const_local_iterator,
- false> ccc;
- assert( container.cbegin(0) == container.begin(0) );
- assert( container.cend(0) == container.end(0) );
- const auto bn = container.bucket(1);
- auto clit = container.cbegin(bn);
- assert( clit != container.cend(bn) );
- assert( clit != container.end(bn) );
- assert( clit++ == container.cbegin(bn) );
- assert( clit == container.end(bn) );
- clit = container.cbegin(bn);
- assert( ++clit == container.cend(bn) );
- assert( container.begin(bn) != container.cend(bn) );
- }
- };
- #endif
- template<typename _Iterator>
- struct iterator_concept_checks<_Iterator, false,
- std::forward_iterator_tag>
- {
- iterator_concept_checks()
- {
- using namespace __gnu_cxx;
- __function_requires<_ForwardIteratorConcept<_Iterator>>();
- }
- };
- template<typename _Iterator>
- struct iterator_concept_checks<_Iterator, true,
- std::forward_iterator_tag>
- {
- iterator_concept_checks()
- {
- using namespace __gnu_cxx;
- __function_requires<_Mutable_ForwardIteratorConcept<_Iterator>>();
- }
- };
- template<typename _Iterator>
- struct iterator_concept_checks<_Iterator, false,
- std::bidirectional_iterator_tag>
- {
- iterator_concept_checks()
- {
- using namespace __gnu_cxx;
- __function_requires<_BidirectionalIteratorConcept<_Iterator>>();
- }
- };
- template<typename _Iterator>
- struct iterator_concept_checks<_Iterator, true,
- std::bidirectional_iterator_tag>
- {
- iterator_concept_checks()
- {
- using namespace __gnu_cxx;
- __function_requires<_Mutable_BidirectionalIteratorConcept<_Iterator>>();
- }
- };
- template<typename _Iterator>
- struct iterator_concept_checks<_Iterator, false,
- std::random_access_iterator_tag>
- {
- iterator_concept_checks()
- {
- using namespace __gnu_cxx;
- __function_requires<_RandomAccessIteratorConcept<_Iterator>>();
- }
- };
- template<typename _Iterator>
- struct iterator_concept_checks<_Iterator, true,
- std::random_access_iterator_tag>
- {
- iterator_concept_checks()
- {
- using namespace __gnu_cxx;
- __function_requires<_Mutable_RandomAccessIteratorConcept<_Iterator>>();
- }
- };
- template<typename _Tp>
- struct forward_members
- {
- forward_members(_Tp& container)
- {
- // Make sure that even if rel_ops is injected there is no ambiguity
- // when comparing iterators.
- using namespace std::rel_ops;
- typedef traits<_Tp> traits_type;
- iterator_concept_checks<typename _Tp::iterator,
- !(traits_type::is_associative::value
- || traits_type::is_unordered::value)> cc;
- iterator_concept_checks<typename _Tp::const_iterator, false> ccc;
- assert( container.cbegin() == container.begin() );
- assert( container.end() == container.cend() );
- assert( container.cbegin() != container.cend() );
- assert( container.cbegin() != container.end() );
- assert( container.begin() != container.cend() );
- }
- };
- template<typename _Tp,
- typename
- = typename std::iterator_traits<typename _Tp::iterator>::iterator_category>
- struct category_members : forward_members<_Tp>
- {
- category_members(_Tp& container)
- : forward_members<_Tp>(container)
- { };
- };
- template<typename _Tp>
- struct category_members<_Tp, std::random_access_iterator_tag>
- : forward_members<_Tp>
- {
- category_members(_Tp& container)
- : forward_members<_Tp>(container)
- {
- // Make sure that even if rel_ops is injected there is no ambiguity
- // when comparing iterators.
- using namespace std::rel_ops;
- assert( !(container.begin() < container.begin()) );
- assert( !(container.cbegin() < container.cbegin()) );
- assert( !(container.cbegin() < container.begin()) );
- assert( !(container.begin() < container.cbegin()) );
- assert( container.begin() <= container.begin() );
- assert( container.cbegin() <= container.cbegin() );
- assert( container.cbegin() <= container.begin() );
- assert( container.begin() <= container.cbegin() );
- assert( !(container.begin() > container.begin()) );
- assert( !(container.cbegin() > container.cbegin()) );
- assert( !(container.cbegin() > container.begin()) );
- assert( !(container.begin() > container.cbegin()) );
- assert( container.begin() >= container.begin() );
- assert( container.cbegin() >= container.cbegin() );
- assert( container.cbegin() >= container.begin() );
- assert( container.begin() >= container.cbegin() );
- assert( container.begin() - container.begin() == 0 );
- assert( container.cbegin() - container.cbegin() == 0 );
- assert( container.cbegin() - container.begin() == 0 );
- assert( container.begin() - container.cbegin() == 0 );
- assert( container.begin() + 0 == container.begin() );
- assert( container.cbegin() + 0 == container.cbegin() );
- assert( 0 + container.begin() == container.begin() );
- assert( 0 + container.cbegin() == container.cbegin() );
- assert( container.begin() - 0 == container.begin() );
- assert( container.cbegin() - 0 == container.cbegin() );
- }
- };
- template<typename _Tp>
- struct citerator
- {
- typedef _Tp test_type;
- typedef traits<test_type> traits_type;
- typedef typename test_type::value_type value_type;
- static test_type _S_container;
- // Unconditional.
- struct members : category_members<_Tp>
- {
- members() : category_members<_Tp>(_S_container)
- { }
- };
- // Run test.
- citerator()
- {
- populate<test_type> p(_S_container);
- members m1;
- reverse_members<test_type> m2(_S_container);
- }
- };
- template<typename _Tp>
- _Tp citerator<_Tp>::_S_container;
- // DR 130 vs. C++98 vs. C++11.
- // Defined in testsuite_shared.cc.
- void
- erase_external(std::set<int>& s);
- void
- erase_external(std::multiset<int>& s);
- void
- erase_external(std::map<int, int>& s);
- void
- erase_external(std::multimap<int, int>& s);
- void
- erase_external_iterators(std::set<int>& s);
- void
- erase_external_iterators(std::multiset<int>& s);
- void
- erase_external_iterators(std::map<int, int>& s);
- void
- erase_external_iterators(std::multimap<int, int>& s);
- #if __cplusplus < 201103L
- # error "must be compiled with C++11 (or later)"
- #else
- template<typename _Tp>
- void
- linkage_check_cxx98_cxx11_erase(_Tp& container)
- {
- // Crashing when external reference and internal reference symbols are
- // equivalently mangled but have different size return types in C++98
- // and C++11 signatures.
- erase_external(container); // C++98
- container.erase(container.begin()); // C++11
- }
- template<typename _Tp>
- void
- linkage_check_cxx98_cxx11_erase_iterators(_Tp& container)
- {
- // Crashing when external reference and internal reference symbols are
- // equivalently mangled but have different size return types in C++98
- // and C++11 signatures.
- erase_external_iterators(container);// C++98
- auto iter = container.begin();
- container.erase(iter, ++iter); // C++11
- }
- #endif
- } // namespace __gnu_test
- #endif
|