// -*- C++ -*- // Copyright (C) 2009-2018 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 // . #ifndef _GLIBCXX_TESTSUITE_CONTAINERS_H #define _GLIBCXX_TESTSUITE_CONTAINERS_H #include #include // Container requirement testing. namespace __gnu_test { // Compile-time typedef testing. template::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::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::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::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::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::is_mapped::value> struct mapped_types { typedef _Tp test_type; typedef typename test_type::mapped_type mapped_type; }; template::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 struct basic_types<_Tp, false> { }; template struct adaptor_types<_Tp, false> { }; template struct reversible_types<_Tp, false> { }; template struct allocator_aware_types<_Tp, false> { }; template struct associative_types<_Tp, false> { }; template struct unordered_types<_Tp, false> { }; template struct mapped_types<_Tp, false> { }; // Primary template. template 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::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 struct populate<_Tp, false> { populate(_Tp& container) { } }; template::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 struct reverse_members<_Tp, false> { reverse_members(_Tp& container) { } }; // DR 691. template::is_unordered::value> struct forward_members_unordered { forward_members_unordered(typename _Tp::value_type& v) { typedef _Tp test_type; test_type container; container.insert(v); assert( container.cbegin(0) == container.begin(0) ); assert( container.cend(0) == container.end(0) ); const typename test_type::size_type bn = container.bucket(1); assert( container.cbegin(bn) != container.cend(bn) ); } }; template struct forward_members_unordered<_Tp, false> { forward_members_unordered(_Tp& container) { } }; template struct citerator { typedef _Tp test_type; typedef traits traits_type; typedef typename test_type::value_type value_type; static test_type _S_container; // Unconditional. struct forward_members { forward_members() { assert( _S_container.cbegin() == _S_container.begin() ); assert( _S_container.cend() == _S_container.end() ); assert( _S_container.cbegin() != _S_container.cend() ); } }; // Run test. citerator() { populate p(_S_container); forward_members m1; reverse_members m2(_S_container); } }; template _Tp citerator<_Tp>::_S_container; // DR 130 vs. C++98 vs. C++11. // Defined in testsuite_shared.cc. void erase_external(std::set& s); void erase_external(std::multiset& s); void erase_external(std::map& s); void erase_external(std::multimap& s); void erase_external_iterators(std::set& s); void erase_external_iterators(std::multiset& s); void erase_external_iterators(std::map& s); void erase_external_iterators(std::multimap& s); // NB: "must be compiled with C++11" #if __cplusplus >= 201103L template 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 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