diff options
Diffstat (limited to 'libstdc++-v3')
65 files changed, 2753 insertions, 453 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 7c20083923a..2077dc14ec7 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,154 @@ +2009-12-18 Jimmy Guo <jguo@yahoo-inc.com> + + PR libstdc++/40088 + * src/locale_init.cc (locale::locale()): Optimize the common case + where _S_global still points to _S_classic. + +2009-12-17 Dave Korn <dave.korn.cygwin@gmail.com> + + PR target/42377 + * config/abi/pre/gnu.ver: Adjust mangled function signatures to permit + LLP64 sizetypes throughout. + +2009-12-17 Paolo Carlini <paolo.carlini@oracle.com> + + PR libstdc++/42198 + * src/thread.cc (thread::_M_start_thread): Throw system_error + immediately if the thread system is inactive. + +2009-12-16 Benjamin Kosnik <bkoz@redhat.com> + + PR libstdc++/21772 part 2 + * doc/xml/manual/test.xml: Add documentation about testing details. + * testsuite/util/exception/safety.h: New. Functor objects for + testing C++0x container classes. + * testsuite/util/testsuite_container_traits.h: Add traits. + + * testsuite/23_containers/list/requirements/exception/ + basic.cc: New. + generation_prohibited.cc: New. + propagation_consistent.cc: New. + +2009-12-15 Benjamin Kosnik <bkoz@redhat.com> + + PR libstdc++/21772 part 1 + * include/ext/throw_allocator.h: Rework. + (__gnu_cxx::throw_allocator): To... + (__gnu_cxx::throw_allocator_limit): ...this. + (__gnu_cxx::throw_allocator_random): ...and this. + (throw_value_base, throw_value_limit, throw_value_random): Add. + (condition_base, random_condition, limit_condition): Add. + (forced_exception_error): To... + (forced_error): ...this. + * testsuite/ext/throw_value: New. + * testsuite/ext/throw_value/cons.cc: New. + * testsuite/ext/throw_allocator/deallocate_global.cc: Adjust for + throw_allocator, forced_exception_error changes. + * testsuite/ext/throw_allocator/check_delete.cc: Same. + * testsuite/ext/throw_allocator/check_allocate_max_size.cc: Same. + * testsuite/ext/throw_allocator/check_deallocate_null.cc: Same. + * testsuite/ext/throw_allocator/explicit_instantiation.cc: Same. + * testsuite/ext/throw_allocator/check_new.cc: Same. + * testsuite/ext/throw_allocator/variadic_construct.cc: Same. + * testsuite/ext/throw_allocator/deallocate_local.cc: Same. + * testsuite/23_containers/list/modifiers/insert/25288.cc: Same. + * testsuite/23_containers/list/modifiers/insert/25288.h: Same. + * testsuite/util/regression/common_type.hpp: Same. + * testsuite/util/regression/rand/priority_queue/ + container_rand_regression_test.tcc: Same. + * testsuite/util/regression/rand/assoc/ + container_rand_regression_test.h: Same. + * testsuite/util/regression/rand/assoc/ + container_rand_regression_test.tcc: Same. + * testsuite/util/regression/basic_type.hpp: Same. + + * testsuite/ext/forced_exception_error/cons_virtual_derivation.cc: To... + * testsuite/ext/forced_error/cons_virtual_derivation.cc: ...this, same. + +2009-12-15 Paolo Carlini <paolo.carlini@oracle.com> + + PR libstdc++/42381 + * include/bits/stl_deque.h (_GLIBCXX_DEQUE_BUF_SIZE): Add. + (__deque_buf_size(size_t)): Use it. + * testsuite/23_containers/deque/requirements/dr438/ + assign_neg.cc: Adjust dg-error line numbers. + * testsuite/23_containers/deque/requirements/dr438/ + insert_neg.cc: Likewise. + * testsuite/23_containers/deque/requirements/dr438/ + constructor_1_neg.cc: Likewise. + * testsuite/23_containers/deque/requirements/dr438/ + constructor_2_neg.cc: Likewise. + +2009-12-15 Jonathan Wakely <jwakely.gcc@gmail.com> + + * include/std/future (unique_future::get, promise::set_value): Remove + workaround for c++/34022. + (packaged_task::get_future, packaged_task::operator()): Use + __throw_bad_function_call. + * testsuite/30_threads/packaged_task/cons/assign_neg.cc: Adjust. + * testsuite/30_threads/packaged_task/cons/copy_neg.cc: Likewise. + * testsuite/30_threads/promise/cons/assign_neg.cc: Likewise. + * testsuite/30_threads/promise/cons/copy_neg.cc: Likewise. + * testsuite/30_threads/shared_future/cons/assign_neg.cc: Likewise. + * testsuite/30_threads/unique_future/cons/assign_neg.cc: Likewise. + * testsuite/30_threads/unique_future/cons/copy_neg.cc: Likewise. + +2009-12-15 Jonathan Wakely <jwakely.gcc@gmail.com> + + * include/std/functional (function::function): Move construct target. + (function::operator=): Use perfect forwarding for argument. + (function::operator()): Use new __throw_bad_function_call. + * include/bits/functexcept.h (__throw_bad_function_call): Declare. + * src/functexcept.cc (__throw_bad_function_call): Define. + * config/abi/pre/gnu.ver: Add new symbol. + * testsuite/20_util/function/cons/move_target.cc: New. + * testsuite/20_util/function/assign/move_target.cc: New. + +2009-12-15 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/42379 + * testsuite/23_containers/set/operators/1_neg.cc: Fix dg-error strings. + * testsuite/23_containers/map/operators/1_neg.cc: Likewise. + +2009-12-14 Paolo Carlini <paolo.carlini@oracle.com> + + PR libstdc++/25304, DR 865 [Ready] + * include/bits/stl_algobase.h (fill_n): Add comment about DR 865. + * include/bits/stl_algo.h (generate_n): Likewise. + * include/bits/algorithmfwd.h: Remove obsolete comment. + * doc/xml/manual/intro.xml: Add an entry for DR 865. + +2009-12-14 Ralf Wildenhues <Ralf.Wildenhues@gmx.de> + + * configure.ac: Remove code to un-precious-ize CC, CXX, + CXXFLAGS, CFLAGS, LDFLAGS. + * configure: Regenerate. + +2009-12-14 Paolo Carlini <paolo.carlini@oracle.com> + + * testsuite/23_containers/queue/requirements/ + explicit_instantiation/1_c++0x.cc: New. + * testsuite/23_containers/priority_queue/requirements/ + explicit_instantiation/1_c++0x.cc: Likewise. + * testsuite/23_containers/multimap/requirements/ + explicit_instantiation/1_c++0x.cc: Likewise. + * testsuite/23_containers/bitset/requirements/ + explicit_instantiation/1_c++0x.cc: Likewise. + * testsuite/23_containers/set/requirements/ + explicit_instantiation/1_c++0x.cc: Likewise. + * testsuite/23_containers/vector/requirements/ + explicit_instantiation/1_c++0x.cc: Likewise. + * testsuite/23_containers/deque/requirements/ + explicit_instantiation/1_c++0x.cc: Likewise. + * testsuite/23_containers/stack/requirements/ + explicit_instantiation/1_c++0x.cc: Likewise. + * testsuite/23_containers/multiset/requirements/ + explicit_instantiation/1_c++0x.cc: Likewise. + * testsuite/23_containers/list/requirements/ + explicit_instantiation/1_c++0x.cc: Likewise. + * testsuite/23_containers/map/requirements/ + explicit_instantiation/1_c++0x.cc: Likewise. + 2009-12-14 Paolo Carlini <paolo.carlini@oracle.com> * include/bits/stl_list.h (splice(iterator, list&), splice(iterator, @@ -81,7 +232,7 @@ 2009-12-10 Paolo Carlini <paolo.carlini@oracle.com> Revert: - 2009-12-03 Paolo Carlini <paolo.carlini@oracle.com> + 2009-12-03 Paolo Carlini <paolo.carlini@oracle.com> PR libstdc++/42261 * include/bits/basic_string.h (_S_construct_aux(_Integer, _Integer, @@ -211,21 +362,21 @@ 2009-11-30 Jonathan Wakely <jwakely.gcc@gmail.com> - * include/tr1_impl/functional (function): Add rvalue support and - tweak doxygen markup. - * testsuite/20_util/function/assign/move.cc: New. - * testsuite/20_util/function/cons/move.cc: New. - * testsuite/20_util/function/invoke/move_only.cc: New. - * testsuite/20_util/function/cmp/cmp_neg.cc: New. - * testsuite/20_util/function/1.cc: Copy from testsuite/tr1/. - * testsuite/20_util/function/2.cc: Likewise. - * testsuite/20_util/function/3.cc: Likewise. - * testsuite/20_util/function/4.cc: Likewise. - * testsuite/20_util/function/5.cc: Likewise. - * testsuite/20_util/function/6.cc: Likewise. - * testsuite/20_util/function/7.cc: Likewise. - * testsuite/20_util/function/8.cc: Likewise. - * testsuite/20_util/function/9.cc: Likewise. + * include/tr1_impl/functional (function): Add rvalue support and + tweak doxygen markup. + * testsuite/20_util/function/assign/move.cc: New. + * testsuite/20_util/function/cons/move.cc: New. + * testsuite/20_util/function/invoke/move_only.cc: New. + * testsuite/20_util/function/cmp/cmp_neg.cc: New. + * testsuite/20_util/function/1.cc: Copy from testsuite/tr1/. + * testsuite/20_util/function/2.cc: Likewise. + * testsuite/20_util/function/3.cc: Likewise. + * testsuite/20_util/function/4.cc: Likewise. + * testsuite/20_util/function/5.cc: Likewise. + * testsuite/20_util/function/6.cc: Likewise. + * testsuite/20_util/function/7.cc: Likewise. + * testsuite/20_util/function/8.cc: Likewise. + * testsuite/20_util/function/9.cc: Likewise. 2009-11-29 Jonathan Wakely <jwakely.gcc@gmail.com> @@ -290,10 +441,10 @@ 2009-11-19 Johannes Singler <singler@kit.edu> - * include/parallel/partition.h (__parallel_partition): Correctly - initialize chunk size. - (__parallel_nth_element): Respect nth_element_minimal_n. Use - sequential nth_element as base case, instead of sequential sort. + * include/parallel/partition.h (__parallel_partition): Correctly + initialize chunk size. + (__parallel_nth_element): Respect nth_element_minimal_n. Use + sequential nth_element as base case, instead of sequential sort. 2009-11-17 Benjamin Kosnik <bkoz@redhat.com> @@ -764,26 +915,26 @@ 009-10-20 Paolo Carlini <paolo.carlini@oracle.com> - PR libstdc++/41773 - Revert: - 2009-10-20 Paolo Carlini <paolo.carlini@oracle.com> - - * include/bits/basic_string.h (_S_construct(const _CharT*, size_type, - const _Alloc&)): New, declare. - (_S_construct(_CharT*, _CharT*, const _Alloc&), - _S_construct(const _CharT*, const _CharT*, const _Alloc&), - _S_construct(iterator, iterator, const _Alloc&), - _S_construct(const_iterator, const_iterator, const _Alloc&)): New, - forward to the latter. - * include/bits/basic_string.tcc (_S_construct(const _CharT*, - size_type, const _Alloc&)): Define. - (basic_string(const basic_string&, size_type, size_type), - basic_string(const basic_string&, size_type, size_type, - const _Alloc&), basic_string(const _CharT*, size_type, - const _Alloc&), basic_string(const _CharT*, const _Alloc&), - basic_string(initializer_list<>, const _Alloc&)): Call the latter. - * config/abi/pre/gnu.ver: Remove recently added exports. - * src/string-inst.cc: Remove instantiations. + PR libstdc++/41773 + Revert: + 2009-10-20 Paolo Carlini <paolo.carlini@oracle.com> + + * include/bits/basic_string.h (_S_construct(const _CharT*, size_type, + const _Alloc&)): New, declare. + (_S_construct(_CharT*, _CharT*, const _Alloc&), + _S_construct(const _CharT*, const _CharT*, const _Alloc&), + _S_construct(iterator, iterator, const _Alloc&), + _S_construct(const_iterator, const_iterator, const _Alloc&)): New, + forward to the latter. + * include/bits/basic_string.tcc (_S_construct(const _CharT*, + size_type, const _Alloc&)): Define. + (basic_string(const basic_string&, size_type, size_type), + basic_string(const basic_string&, size_type, size_type, + const _Alloc&), basic_string(const _CharT*, size_type, + const _Alloc&), basic_string(const _CharT*, const _Alloc&), + basic_string(initializer_list<>, const _Alloc&)): Call the latter. + * config/abi/pre/gnu.ver: Remove recently added exports. + * src/string-inst.cc: Remove instantiations. 2009-10-20 Paolo Carlini <paolo.carlini@oracle.com> diff --git a/libstdc++-v3/config/abi/pre/gnu.ver b/libstdc++-v3/config/abi/pre/gnu.ver index 4ed1cfeb2cd..cbd0596fa9b 100644 --- a/libstdc++-v3/config/abi/pre/gnu.ver +++ b/libstdc++-v3/config/abi/pre/gnu.ver @@ -175,23 +175,28 @@ GLIBCXX_3.4 { # __gnu_debug::_Error_formatter* }; - # Names not in an 'extern' block are mangled names. + # Names not in an 'extern' block are mangled names. Character classes + # are used in many of the regex patterns to compensate for minor differences + # among the standard integer types and sizes on different platforms and + # under different modes of 64-bit architecture (ILP64, LLP64, etc.) # std::string - _ZNSsC[12][EI][PRjmvN]*; + # 'y' here and below represents 'unsigned long long' + # where it is used for size_type on LLP64 platforms. + _ZNSsC[12][EI][PRjmvyN]*; _ZNSsD*; _ZNSs[0-58-9][a-z]*; -# _ZNSs[67][a-z]*E[PRcjmv]*; - _ZNSs6appendE[PRcjmv]*; - _ZNSs6assignE[PRcjmv]*; - _ZNSs6insertE[PRcjmv]*; - _ZNSs6insertEN9__gnu_cxx17__normal_iteratorIPcSsEE[PRcjmv]*; - _ZNSs[67][j-z]*E[PRcjmv]*; - _ZNSs7[a-z]*EES2_[NPRjm]*; +# _ZNSs[67][a-z]*E[PRcjmvy]*; + _ZNSs6appendE[PRcjmvy]*; + _ZNSs6assignE[PRcjmvy]*; + _ZNSs6insertE[PRcjmvy]*; + _ZNSs6insertEN9__gnu_cxx17__normal_iteratorIPcSsEE[PRcjmvy]*; + _ZNSs[67][j-z]*E[PRcjmvy]*; + _ZNSs7[a-z]*EES2_[NPRjmy]*; _ZNSs7[a-z]*EES2_S[12]*; _ZNSs12_Alloc_hiderC*; _ZNSs12_M_leak_hardEv; - _ZNSs12_S_constructE[jm]cRKSaIcE; + _ZNSs12_S_constructE[jmy]cRKSaIcE; _ZNSs12_S_empty_repEv; _ZNSs13_S_copy_chars*; _ZNSs[0-9][0-9]_M_replace*; @@ -204,10 +209,10 @@ GLIBCXX_3.4 { _ZNSs4_Rep15_M_set_sharableEv; _ZNSs4_Rep7_M_grab*; _ZNSs4_Rep8_M_clone*; - _ZNSs4_Rep9_S_createE[jm][jm]*; + _ZNSs4_Rep9_S_createE[jmy][jmy]*; _ZNSs7_M_dataEPc; _ZNSs7_M_leakEv; - _ZNSs9_M_mutateE[jm][jm][jm]; + _ZNSs9_M_mutateE[jmy][jmy][jmy]; _ZNSs4_Rep20_S_empty_rep_storageE; _ZNSs4_Rep11_S_max_sizeE; _ZNSs4_Rep11_S_terminalE; @@ -230,23 +235,23 @@ GLIBCXX_3.4 { _ZNKSs7compare*; _ZNKSs5c_strEv; _ZNKSs8capacityEv; - _ZNKSs4copyEPc[jm][jm]; + _ZNKSs4copyEPc[jmy][jmy]; # std::wstring - _ZNSbIwSt11char_traitsIwESaIwEEC[12][EI][PRjmvN]*; + _ZNSbIwSt11char_traitsIwESaIwEEC[12][EI][PRjmvyN]*; _ZNSbIwSt11char_traitsIwESaIwEED*; _ZNSbIwSt11char_traitsIwESaIwEE[0-58-9][a-z]*; -# _ZNSbIwSt11char_traitsIwESaIwEE[67][a-b]*E[PRwjmv]*; - _ZNSbIwSt11char_traitsIwESaIwEE6appendE[PRwjmv]*; - _ZNSbIwSt11char_traitsIwESaIwEE6assignE[PRwjmv]*; - _ZNSbIwSt11char_traitsIwESaIwEE6insertE[PRwjmv]*; - _ZNSbIwSt11char_traitsIwESaIwEE6insertEN9__gnu_cxx17__normal_iteratorIPwS2_EE[PRwjmv]*; - _ZNSbIwSt11char_traitsIwESaIwEE[67][j-z]*E[PRwjmv]*; - _ZNSbIwSt11char_traitsIwESaIwEE7[a-z]*EES6_[NPRjm]*; +# _ZNSbIwSt11char_traitsIwESaIwEE[67][a-b]*E[PRwjmvy]*; + _ZNSbIwSt11char_traitsIwESaIwEE6appendE[PRwjmvy]*; + _ZNSbIwSt11char_traitsIwESaIwEE6assignE[PRwjmvy]*; + _ZNSbIwSt11char_traitsIwESaIwEE6insertE[PRwjmvy]*; + _ZNSbIwSt11char_traitsIwESaIwEE6insertEN9__gnu_cxx17__normal_iteratorIPwS2_EE[PRwjmvy]*; + _ZNSbIwSt11char_traitsIwESaIwEE[67][j-z]*E[PRwjmvy]*; + _ZNSbIwSt11char_traitsIwESaIwEE7[a-z]*EES6_[NPRjmy]*; _ZNSbIwSt11char_traitsIwESaIwEE7[a-z]*EES6_S[56]*; _ZNSbIwSt11char_traitsIwESaIwEE12_Alloc_hiderC*; _ZNSbIwSt11char_traitsIwESaIwEE12_M_leak_hardEv; - _ZNSbIwSt11char_traitsIwESaIwEE12_S_constructE[jm]wRKS1_; + _ZNSbIwSt11char_traitsIwESaIwEE12_S_constructE[jmy]wRKS1_; _ZNSbIwSt11char_traitsIwESaIwEE12_S_empty_repEv; _ZNSbIwSt11char_traitsIwESaIwEE13_S_copy_chars*; _ZNSbIwSt11char_traitsIwESaIwEE[0-9][0-9]_M_replace*; @@ -259,10 +264,10 @@ GLIBCXX_3.4 { _ZNSbIwSt11char_traitsIwESaIwEE4_Rep15_M_set_sharableEv; _ZNSbIwSt11char_traitsIwESaIwEE4_Rep7_M_grab*; _ZNSbIwSt11char_traitsIwESaIwEE4_Rep8_M_clone*; - _ZNSbIwSt11char_traitsIwESaIwEE4_Rep9_S_createE[jm][jm]*; + _ZNSbIwSt11char_traitsIwESaIwEE4_Rep9_S_createE[jmy][jmy]*; _ZNSbIwSt11char_traitsIwESaIwEE7_M_dataEPw; _ZNSbIwSt11char_traitsIwESaIwEE7_M_leakEv; - _ZNSbIwSt11char_traitsIwESaIwEE9_M_mutateE[jm][jm][jm]; + _ZNSbIwSt11char_traitsIwESaIwEE9_M_mutateE[jmy][jmy][jmy]; _ZNSbIwSt11char_traitsIwESaIwEE4_Rep20_S_empty_rep_storageE; _ZNSbIwSt11char_traitsIwESaIwEE4_Rep11_S_max_sizeE; _ZNSbIwSt11char_traitsIwESaIwEE4_Rep11_S_terminalE; @@ -285,7 +290,7 @@ GLIBCXX_3.4 { _ZNKSbIwSt11char_traitsIwESaIwEE7compare*; _ZNKSbIwSt11char_traitsIwESaIwEE5c_strEv; _ZNKSbIwSt11char_traitsIwESaIwEE8capacityEv; - _ZNKSbIwSt11char_traitsIwESaIwEE4copyEPw[jm][jm]; + _ZNKSbIwSt11char_traitsIwESaIwEE4copyEPw[jmy][jmy]; # std::basic_streambuf _ZNSt15basic_streambufI[cw]St11char_traitsI[cw]EE[CD]*; @@ -354,7 +359,9 @@ GLIBCXX_3.4 { _ZNKSi[0-9][a-z]*; _ZNSi[0-9][a-h]*; _ZNSi[0-9][j-z]*; - _ZNSi6ignoreE[il][il]; + # 'x' here and below matches 'long long' where it + # is used for signed sizetypes on LLP64 platforms. + _ZNSi6ignoreE[ilx][ilx]; _ZNSirsE*[^g]; # std::basic_istream<wchar_t> @@ -363,7 +370,7 @@ GLIBCXX_3.4 { _ZNKSt13basic_istreamIwSt11char_traitsIwEE[0-9][a-z]*; _ZNSt13basic_istreamIwSt11char_traitsIwEE[0-9][a-h]*; _ZNSt13basic_istreamIwSt11char_traitsIwEE[0-9][j-z]*; - _ZNSt13basic_istreamIwSt11char_traitsIwEE6ignoreE[il][ijlm]; + _ZNSt13basic_istreamIwSt11char_traitsIwEE6ignoreE[ilx][ijlmx]; _ZNSt13basic_istreamIwSt11char_traitsIwEErsE*[^g]; # std::istream operators and extractors @@ -380,7 +387,7 @@ GLIBCXX_3.4 { _ZNSoC*; _ZNSoD*; _ZNKSo6sentrycvbEv; - _ZNSo8_M_writeEPKc[il]; + _ZNSo8_M_writeEPKc[ilx]; _ZNSo[0-9][a-z]*; _ZNSolsE*[^g]; @@ -394,7 +401,7 @@ GLIBCXX_3.4 { _ZNSt13basic_ostreamIwSt11char_traitsIwEE5tellpEv; _ZNSt13basic_ostreamIwSt11char_traitsIwEE5writeEPKw*; _ZNSt13basic_ostreamIwSt11char_traitsIwEE6sentry*; - _ZNSt13basic_ostreamIwSt11char_traitsIwEE8_M_writeEPKw[il]; + _ZNSt13basic_ostreamIwSt11char_traitsIwEE8_M_writeEPKw[ilx]; _ZNSt13basic_ostreamIwSt11char_traitsIwEElsE*[^g]; # std::ostream operators and inserters @@ -533,9 +540,9 @@ GLIBCXX_3.4 { _ZSt24__throw_invalid_argumentPKc; # operator new(size_t) - _Znw[jm]; + _Znw[jmy]; # operator new(size_t, std::nothrow_t const&) - _Znw[jm]RKSt9nothrow_t; + _Znw[jmy]RKSt9nothrow_t; # operator delete(void*) _ZdlPv; @@ -543,9 +550,9 @@ GLIBCXX_3.4 { _ZdlPvRKSt9nothrow_t; # operator new[](size_t) - _Zna[jm]; + _Zna[jmy]; # operator new[](size_t, std::nothrow_t const&) - _Zna[jm]RKSt9nothrow_t; + _Zna[jmy]RKSt9nothrow_t; # operator delete[](void*) _ZdaPv; @@ -700,26 +707,26 @@ GLIBCXX_3.4 { # GLIBCXX_ABI compatibility only. # std::string _ZNKSs11_M_disjunctEPKc; - _ZNKSs15_M_check_lengthE[jm][jm]PKc; + _ZNKSs15_M_check_lengthE[jmy][jmy]PKc; _ZNSs4_Rep26_M_set_length_and_sharableE*; - _ZNSs7_M_copyEPcPKc[jm]; - _ZNSs7_M_moveEPcPKc[jm]; - _ZNSs9_M_assignEPc[jm]c; + _ZNSs7_M_copyEPcPKc[jmy]; + _ZNSs7_M_moveEPcPKc[jmy]; + _ZNSs9_M_assignEPc[jmy]c; # std::wstring _ZNKSbIwSt11char_traitsIwESaIwEE11_M_disjunctEPKw; - _ZNKSbIwSt11char_traitsIwESaIwEE15_M_check_lengthE[jm][jm]PKc; + _ZNKSbIwSt11char_traitsIwESaIwEE15_M_check_lengthE[jmy][jmy]PKc; _ZNSbIwSt11char_traitsIwESaIwEE4_Rep26_M_set_length_and_sharableE*; - _ZNSbIwSt11char_traitsIwESaIwEE7_M_copyEPwPKw[jm]; - _ZNSbIwSt11char_traitsIwESaIwEE7_M_moveEPwPKw[jm]; - _ZNSbIwSt11char_traitsIwESaIwEE9_M_assignEPw[jm]w; + _ZNSbIwSt11char_traitsIwESaIwEE7_M_copyEPwPKw[jmy]; + _ZNSbIwSt11char_traitsIwESaIwEE7_M_moveEPwPKw[jmy]; + _ZNSbIwSt11char_traitsIwESaIwEE9_M_assignEPw[jmy]w; _ZNKSt13basic_fstreamI[cw]St11char_traitsI[cw]EE7is_openEv; _ZNKSt14basic_ifstreamI[cw]St11char_traitsI[cw]EE7is_openEv; _ZNKSt14basic_ofstreamI[cw]St11char_traitsI[cw]EE7is_openEv; - _ZNSi6ignoreE[ilv]; - _ZNSt13basic_istreamIwSt11char_traitsIwEE6ignoreE[ilv]; + _ZNSi6ignoreE[ilvx]; + _ZNSt13basic_istreamIwSt11char_traitsIwEE6ignoreE[ilvx]; _ZNSt11char_traitsI[cw]E2eqERK[cw]S2_; @@ -747,8 +754,8 @@ GLIBCXX_3.4.2 { _ZN9__gnu_cxx18stdio_sync_filebufI[cw]St11char_traitsI[cw]EE4fileEv; - _ZN9__gnu_cxx17__pool_alloc_base9_M_refillE[jm]; - _ZN9__gnu_cxx17__pool_alloc_base16_M_get_free_listE[jm]; + _ZN9__gnu_cxx17__pool_alloc_base9_M_refillE[jmy]; + _ZN9__gnu_cxx17__pool_alloc_base16_M_get_free_listE[jmy]; _ZN9__gnu_cxx17__pool_alloc_base12_M_get_mutexEv; } GLIBCXX_3.4.1; @@ -783,8 +790,8 @@ GLIBCXX_3.4.4 { _ZN9__gnu_cxx6__poolILb1EE13_M_initializeEPFvPvE; _ZN9__gnu_cxx6__poolILb1EE21_M_destroy_thread_keyEPv; _ZN9__gnu_cxx6__poolILb1EE16_M_get_thread_idEv; - _ZN9__gnu_cxx6__poolILb[01]EE16_M_reserve_blockE[jm][jm]; - _ZN9__gnu_cxx6__poolILb[01]EE16_M_reclaim_blockEPc[jm]; + _ZN9__gnu_cxx6__poolILb[01]EE16_M_reserve_blockE[jmy][jmy]; + _ZN9__gnu_cxx6__poolILb[01]EE16_M_reclaim_blockEPc[jmy]; _ZN9__gnu_cxx6__poolILb[01]EE10_M_destroyEv; _ZN9__gnu_cxx9free_list6_M_getE*; @@ -796,26 +803,26 @@ GLIBCXX_3.4.5 { # std::string _ZNKSs11_M_disjunctEPKc; - _ZNKSs15_M_check_lengthE[jm][jm]PKc; + _ZNKSs15_M_check_lengthE[jmy][jmy]PKc; _ZNSs4_Rep26_M_set_length_and_sharableE*; - _ZNSs7_M_copyEPcPKc[jm]; - _ZNSs7_M_moveEPcPKc[jm]; - _ZNSs9_M_assignEPc[jm]c; + _ZNSs7_M_copyEPcPKc[jmy]; + _ZNSs7_M_moveEPcPKc[jmy]; + _ZNSs9_M_assignEPc[jmy]c; # std::wstring _ZNKSbIwSt11char_traitsIwESaIwEE11_M_disjunctEPKw; - _ZNKSbIwSt11char_traitsIwESaIwEE15_M_check_lengthE[jm][jm]PKc; + _ZNKSbIwSt11char_traitsIwESaIwEE15_M_check_lengthE[jmy][jmy]PKc; _ZNSbIwSt11char_traitsIwESaIwEE4_Rep26_M_set_length_and_sharableE*; - _ZNSbIwSt11char_traitsIwESaIwEE7_M_copyEPwPKw[jm]; - _ZNSbIwSt11char_traitsIwESaIwEE7_M_moveEPwPKw[jm]; - _ZNSbIwSt11char_traitsIwESaIwEE9_M_assignEPw[jm]w; + _ZNSbIwSt11char_traitsIwESaIwEE7_M_copyEPwPKw[jmy]; + _ZNSbIwSt11char_traitsIwESaIwEE7_M_moveEPwPKw[jmy]; + _ZNSbIwSt11char_traitsIwESaIwEE9_M_assignEPw[jmy]w; _ZNKSt13basic_fstreamI[cw]St11char_traitsI[cw]EE7is_openEv; _ZNKSt14basic_ifstreamI[cw]St11char_traitsI[cw]EE7is_openEv; _ZNKSt14basic_ofstreamI[cw]St11char_traitsI[cw]EE7is_openEv; - _ZNSi6ignoreE[ilv]; - _ZNSt13basic_istreamIwSt11char_traitsIwEE6ignoreE[ilv]; + _ZNSi6ignoreE[ilvx]; + _ZNSt13basic_istreamIwSt11char_traitsIwEE6ignoreE[ilvx]; _ZNSt11char_traitsI[cw]E2eqERK[cw]S2_; @@ -825,7 +832,7 @@ GLIBCXX_3.4.5 { GLIBCXX_3.4.6 { - _ZSt17__copy_streambufsI[cw]St11char_traitsI[cw]EEiPSt15basic_streambuf*; + _ZSt17__copy_streambufsI[cw]St11char_traitsI[cw]EE[ix]PSt15basic_streambuf*; _ZNSt8ios_base17_M_call_callbacksENS_5eventE; _ZNSt8ios_base20_M_dispose_callbacksEv; _ZNSt6locale5facet13_S_get_c_nameEv; @@ -840,7 +847,7 @@ GLIBCXX_3.4.6 { GLIBCXX_3.4.7 { - _ZNSt6locale5_Impl16_M_install_cacheEPKNS_5facetE[jm]; + _ZNSt6locale5_Impl16_M_install_cacheEPKNS_5facetE[jmy]; } GLIBCXX_3.4.6; @@ -863,7 +870,7 @@ GLIBCXX_3.4.9 { _ZNSi10_M_extractI[^g]*; _ZNSt13basic_istreamIwSt11char_traitsIwEE10_M_extractI[^g]*; - _ZSt21__copy_streambufs_eofI[cw]St11char_traitsI[cw]EE[il]PSt15basic_streambuf*; + _ZSt21__copy_streambufs_eofI[cw]St11char_traitsI[cw]EE[ilx]PSt15basic_streambuf*; _ZSt16__ostream_insert*; @@ -1068,6 +1075,8 @@ GLIBCXX_3.4.14 { _ZNSs18_S_construct_aux_2*; _ZNSbIwSt11char_traitsIwESaIwEE18_S_construct_aux_2*; + _ZSt25__throw_bad_function_callv; + } GLIBCXX_3.4.13; # Symbols in the support library (libsupc++) have their own tag. diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure index 894ab7bbe7a..6bd3c2273e5 100755 --- a/libstdc++-v3/configure +++ b/libstdc++-v3/configure @@ -843,8 +843,15 @@ enable_version_specific_runtime_libs ac_precious_vars='build_alias host_alias target_alias -CPP +CC +CFLAGS +LDFLAGS +LIBS CPPFLAGS +CXX +CXXFLAGS +CCC +CPP CXXCPP' @@ -3485,26 +3492,9 @@ am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -' -# We're almost certainly being configured before anything else which uses -# C++, so all of our AC_PROG_* discoveries will be cached. It's vital that -# we not cache the value of CXX that we "discover" here, because it's set -# to something unique for us and libjava. Other target libraries need to -# find CXX for themselves. We yank the rug out from under the normal AC_* -# process by sneakily renaming the cache variable. This also lets us debug -# the value of "our" CXX in postmortems. -# -# We must also force CXX to /not/ be a precious variable, otherwise the -# wrong (non-multilib-adjusted) value will be used in multilibs. This -# little trick also affects CPPFLAGS, CXXFLAGS, and LDFLAGS. And as a side -# effect, CXXFLAGS is no longer automagically subst'd, so we have to do -# that ourselves. Un-preciousing AC_PROG_CC also affects CC and CFLAGS. -# # -fno-builtin must be present here so that a non-conflicting form of # std::exit can be guessed by AC_PROG_CXX, and used in later tests. - - - save_CXXFLAGS="$CXXFLAGS" CXXFLAGS="$CXXFLAGS -fno-builtin" ac_ext=c @@ -4317,11 +4307,11 @@ if test -z "$CXX"; then set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${glibcxx_cv_prog_CXX+set}" = set; then : +if test "${ac_cv_prog_CXX+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$CXX"; then - glibcxx_cv_prog_CXX="$CXX" # Let the user override the test. + ac_cv_prog_CXX="$CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH @@ -4330,7 +4320,7 @@ do test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - glibcxx_cv_prog_CXX="$ac_tool_prefix$ac_prog" + ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi @@ -4340,7 +4330,7 @@ IFS=$as_save_IFS fi fi -CXX=$glibcxx_cv_prog_CXX +CXX=$ac_cv_prog_CXX if test -n "$CXX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 $as_echo "$CXX" >&6; } @@ -4560,9 +4550,6 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu CXXFLAGS="$save_CXXFLAGS" - - - # Runs configure.host, and assorted other critical bits. Sets # up critical shell variables. @@ -11454,7 +11441,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11457 "configure" +#line 11444 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -11560,7 +11547,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11563 "configure" +#line 11550 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -14897,7 +14884,7 @@ fi # # Fake what AC_TRY_COMPILE does. XXX Look at redoing this new-style. cat > conftest.$ac_ext << EOF -#line 14900 "configure" +#line 14887 "configure" struct S { ~S(); }; void bar(); void foo() @@ -15265,7 +15252,7 @@ $as_echo "$glibcxx_cv_atomic_long_long" >&6; } # Fake what AC_TRY_COMPILE does. cat > conftest.$ac_ext << EOF -#line 15268 "configure" +#line 15255 "configure" int main() { typedef bool atomic_type; @@ -15302,7 +15289,7 @@ $as_echo "$glibcxx_cv_atomic_bool" >&6; } rm -f conftest* cat > conftest.$ac_ext << EOF -#line 15305 "configure" +#line 15292 "configure" int main() { typedef short atomic_type; @@ -15339,7 +15326,7 @@ $as_echo "$glibcxx_cv_atomic_short" >&6; } rm -f conftest* cat > conftest.$ac_ext << EOF -#line 15342 "configure" +#line 15329 "configure" int main() { // NB: _Atomic_word not necessarily int. @@ -15377,7 +15364,7 @@ $as_echo "$glibcxx_cv_atomic_int" >&6; } rm -f conftest* cat > conftest.$ac_ext << EOF -#line 15380 "configure" +#line 15367 "configure" int main() { typedef long long atomic_type; @@ -15453,7 +15440,7 @@ $as_echo "$as_me: WARNING: Performance of certain classes will degrade as a resu # unnecessary for this test. cat > conftest.$ac_ext << EOF -#line 15456 "configure" +#line 15443 "configure" int main() { _Decimal32 d1; diff --git a/libstdc++-v3/configure.ac b/libstdc++-v3/configure.ac index 1fd8119b51d..2ee2bdbce28 100644 --- a/libstdc++-v3/configure.ac +++ b/libstdc++-v3/configure.ac @@ -78,34 +78,14 @@ AM_INIT_AUTOMAKE([1.9.3 no-define foreign no-dependencies -Wall -Wno-portability AH_TEMPLATE(PACKAGE, [Name of package]) AH_TEMPLATE(VERSION, [Version number of package]) -# We're almost certainly being configured before anything else which uses -# C++, so all of our AC_PROG_* discoveries will be cached. It's vital that -# we not cache the value of CXX that we "discover" here, because it's set -# to something unique for us and libjava. Other target libraries need to -# find CXX for themselves. We yank the rug out from under the normal AC_* -# process by sneakily renaming the cache variable. This also lets us debug -# the value of "our" CXX in postmortems. -# -# We must also force CXX to /not/ be a precious variable, otherwise the -# wrong (non-multilib-adjusted) value will be used in multilibs. This -# little trick also affects CPPFLAGS, CXXFLAGS, and LDFLAGS. And as a side -# effect, CXXFLAGS is no longer automagically subst'd, so we have to do -# that ourselves. Un-preciousing AC_PROG_CC also affects CC and CFLAGS. -# # -fno-builtin must be present here so that a non-conflicting form of # std::exit can be guessed by AC_PROG_CXX, and used in later tests. -m4_define([ac_cv_prog_CXX],[glibcxx_cv_prog_CXX]) -m4_rename([_AC_ARG_VAR_PRECIOUS],[glibcxx_PRECIOUS]) -m4_define([_AC_ARG_VAR_PRECIOUS],[]) save_CXXFLAGS="$CXXFLAGS" CXXFLAGS="$CXXFLAGS -fno-builtin" AC_PROG_CC AC_PROG_CXX CXXFLAGS="$save_CXXFLAGS" -m4_rename_force([glibcxx_PRECIOUS],[_AC_ARG_VAR_PRECIOUS]) -AC_SUBST(CFLAGS) -AC_SUBST(CXXFLAGS) # Runs configure.host, and assorted other critical bits. Sets # up critical shell variables. diff --git a/libstdc++-v3/doc/xml/manual/intro.xml b/libstdc++-v3/doc/xml/manual/intro.xml index 1c5e7f64e55..a3cdbdf1c46 100644 --- a/libstdc++-v3/doc/xml/manual/intro.xml +++ b/libstdc++-v3/doc/xml/manual/intro.xml @@ -815,6 +815,13 @@ requirements of the license of GCC. </term> <listitem><para>Update / add the signatures. </para></listitem></varlistentry> + + <varlistentry><term><ulink url="../ext/lwg-active.html#865">865</ulink>: + <emphasis>More algorithms that throw away information</emphasis> + </term> + <listitem><para>The traditional HP / SGI return type and value is blessed + by the resolution of the DR. + </para></listitem></varlistentry> </variablelist> </sect2> diff --git a/libstdc++-v3/doc/xml/manual/test.xml b/libstdc++-v3/doc/xml/manual/test.xml index 887f4035686..3da168ec45b 100644 --- a/libstdc++-v3/doc/xml/manual/test.xml +++ b/libstdc++-v3/doc/xml/manual/test.xml @@ -1,6 +1,6 @@ <sect1 id="manual.intro.setup.test" xreflabel="Testing"> <?dbhtml filename="test.html"?> - + <sect1info> <keywordset> <keyword> @@ -48,7 +48,7 @@ regressions, ABI, and performance. that are packaged in a separate testing library. </para> -<para> +<para> All test cases for functionality required by the runtime components of the C++ standard (ISO 14882) are files within the following directories. @@ -65,6 +65,9 @@ regressions, ABI, and performance. 25_algorithms 26_numerics 27_io +28_regex +29_atomics +30_threads </programlisting> <para> @@ -77,9 +80,8 @@ backward Tests for backwards compatibility and deprecated features. demangle Tests for __cxa_demangle, the IA 64 C++ ABI demangler ext Tests for extensions. performance Tests for performance analysis, and performance regressions. -thread Tests for threads. </programlisting> - + <para> Some directories don't have test files, but instead contain auxiliary information: @@ -104,7 +106,7 @@ util Files for libtestc++, utilities and testing routines. </para> <programlisting> 21_strings/find.cc - </programlisting> + </programlisting> <para> However, that practice soon became a liability as the test cases became huge and unwieldy, and testing new or extended @@ -123,11 +125,11 @@ util Files for libtestc++, utilities and testing routines. 21_strings/basic_string/find/wchar_t/1.cc 21_strings/basic_string/find/wchar_t/2.cc 21_strings/basic_string/find/wchar_t/3.cc - </programlisting> + </programlisting> <para> All new tests should be written with the policy of one test - case, one file in mind. + case, one file in mind. </para> </sect3> @@ -140,7 +142,7 @@ util Files for libtestc++, utilities and testing routines. used within the testsuite to designate particular kinds of tests. </para> - + <itemizedlist> <listitem> <para> @@ -151,10 +153,10 @@ util Files for libtestc++, utilities and testing routines. to finish or pass. At the moment, the interactive tests are not run by default. Instead, they are run by hand, like: </para> - <programlisting> + <programlisting> g++ 27_io/objects/char/3_xin.cc cat 27_io/objects/char/3_xin.in | a.out - </programlisting> + </programlisting> </listitem> <listitem> <para> @@ -232,7 +234,7 @@ cat 27_io/objects/char/3_xin.in | a.out <sect3 id="test.run.basic"> <title>Basic</title> - + <para> You can check the status of the build without installing it using the dejagnu harness, much like the rest of the gcc @@ -254,7 +256,7 @@ cat 27_io/objects/char/3_xin.in | a.out the exact command line passed to the compiler, the compiler output, and the executable output (if any). </para> - + <para> Archives of test results for various versions and platforms are available on the GCC website in the <ulink @@ -266,7 +268,7 @@ cat 27_io/objects/char/3_xin.in | a.out combination of source version, operating system, and host CPU. </para> </sect3> - + <sect3 id="test.run.variations"> <title>Variations</title> <para> @@ -322,7 +324,7 @@ make check-target-libstdc++-v3 RUNTESTFLAGS="--target_board=calmrisc32-sid" make check-target-libstdc++-v3 RUNTESTFLAGS="--target_board=arm-sim" </programlisting> - <para> + <para> Also, here is an example of how to run the libstdc++ testsuite for a multilibed build directory with different ABI settings: </para> @@ -330,7 +332,7 @@ make check-target-libstdc++-v3 RUNTESTFLAGS="--target_board=arm-sim" <programlisting> make check-target-libstdc++-v3 RUNTESTFLAGS='--target_board \"unix{-mabi=32,,-mabi=64}\"' </programlisting> - + <para> You can run the tests with a compiler and library that have already been installed. Make sure that the compiler (e.g., @@ -354,7 +356,7 @@ runtest --tool libstdc++ --srcdir=/path/to/gcc/libstdc++-v3/testsuite testsuites in parallel from the same directory. </para> - <para> + <para> In addition, there are some testing options that are mostly of interest to library maintainers and system integrators. As such, these tests may not work on all cpu and host combinations, and @@ -378,7 +380,7 @@ runtest --tool libstdc++ --srcdir=/path/to/gcc/libstdc++-v3/testsuite <para> <emphasis>testsuite_files</emphasis> </para> - <para> + <para> This is a list of all the test cases that will be run. Each test case is on a separate line, given with an absolute path from the <emphasis>libsrcdir/testsuite</emphasis> directory. @@ -389,7 +391,7 @@ runtest --tool libstdc++ --srcdir=/path/to/gcc/libstdc++-v3/testsuite <para> <emphasis>testsuite_files_interactive</emphasis> </para> - <para> + <para> This is a list of all the interactive test cases, using the same format as the file list above. These tests are not run by default. @@ -400,7 +402,7 @@ runtest --tool libstdc++ --srcdir=/path/to/gcc/libstdc++-v3/testsuite <para> <emphasis>testsuite_files_performance</emphasis> </para> - <para> + <para> This is a list of all the performance test cases, using the same format as the file list above. These tests are not run by default. @@ -411,7 +413,7 @@ runtest --tool libstdc++ --srcdir=/path/to/gcc/libstdc++-v3/testsuite <para> <emphasis>testsuite_thread</emphasis> </para> - <para> + <para> This file indicates that the host system can run tests which involved multiple threads. </para> @@ -421,7 +423,7 @@ runtest --tool libstdc++ --srcdir=/path/to/gcc/libstdc++-v3/testsuite <para> <emphasis>testsuite_wchar_t</emphasis> </para> - <para> + <para> This file indicates that the host system can run the wchar_t tests, and corresponds to the macro definition <code> _GLIBCXX_USE_WCHAR_T</code> in the file c++config.h. @@ -432,11 +434,11 @@ runtest --tool libstdc++ --srcdir=/path/to/gcc/libstdc++-v3/testsuite <programlisting> make check-abi </programlisting> - + <para> The library ABI can be tested. This involves testing the shared library against an ABI-defining previous version of symbol - exports. + exports. </para> <programlisting> @@ -507,7 +509,7 @@ runtest --tool libstdc++ --srcdir=/path/to/gcc/libstdc++-v3/testsuite <para> The first step in making a new test case is to choose the correct directory and file name, given the organization as previously - described. + described. </para> <para> @@ -638,7 +640,7 @@ up in the normal.exp file. <sect3 id="test.harness.dejagnu"> <title>Dejagnu Harness Details</title> - <para> + <para> Underlying details of testing for conformance and regressions are abstracted via the GNU Dejagnu package. This is similar to the rest of GCC. @@ -684,7 +686,7 @@ only default variables. <sect3 id="test.harness.utils"> <title>Utilities</title> - <para> + <para> </para> <para> The testsuite directory also contains some files that implement @@ -709,11 +711,11 @@ only default variables. <emphasis>testsuite_abi_check.cc</emphasis> </para> <para> - Creates the executable <emphasis>abi_check</emphasis>. - Used to check correctness of symbol versioning, visibility of - exported symbols, and compatibility on symbols in the shared - library, for hosts that support this feature. More information - can be found in the ABI documentation <link linkend="appendix.porting.abi">here</link> + Creates the executable <emphasis>abi_check</emphasis>. + Used to check correctness of symbol versioning, visibility of + exported symbols, and compatibility on symbols in the shared + library, for hosts that support this feature. More information + can be found in the ABI documentation <link linkend="appendix.porting.abi">here</link> </para> </listitem> <listitem> @@ -722,11 +724,11 @@ only default variables. <emphasis>testsuite_allocator.cc</emphasis> </para> <para> - Contains specialized allocators that keep track of construction - and destruction. Also, support for overriding global new and - delete operators, including verification that new and delete - are called during execution, and that allocation over max_size - fails. + Contains specialized allocators that keep track of construction + and destruction. Also, support for overriding global new and + delete operators, including verification that new and delete + are called during execution, and that allocation over max_size + fails. </para> </listitem> <listitem> @@ -734,9 +736,9 @@ only default variables. <emphasis>testsuite_character.h</emphasis> </para> <para> - Contains <code>std::char_traits</code> and - <code>std::codecvt</code> specializations for a user-defined - POD. + Contains <code>std::char_traits</code> and + <code>std::codecvt</code> specializations for a user-defined + POD. </para> </listitem> <listitem> @@ -748,20 +750,20 @@ only default variables. A large number of utilities, including: </para> <itemizedlist> - <listitem><para>VERIFY</para></listitem> - <listitem><para>set_memory_limits</para></listitem> - <listitem><para>verify_demangle</para></listitem> - <listitem><para>run_tests_wrapped_locale</para></listitem> - <listitem><para>run_tests_wrapped_env</para></listitem> - <listitem><para>try_named_locale</para></listitem> - <listitem><para>try_mkfifo</para></listitem> - <listitem><para>func_callback</para></listitem> - <listitem><para>counter</para></listitem> - <listitem><para>copy_tracker</para></listitem> - <listitem><para>copy_constructor</para></listitem> - <listitem><para>assignment_operator</para></listitem> - <listitem><para>destructor</para></listitem> - <listitem> + <listitem><para>VERIFY</para></listitem> + <listitem><para>set_memory_limits</para></listitem> + <listitem><para>verify_demangle</para></listitem> + <listitem><para>run_tests_wrapped_locale</para></listitem> + <listitem><para>run_tests_wrapped_env</para></listitem> + <listitem><para>try_named_locale</para></listitem> + <listitem><para>try_mkfifo</para></listitem> + <listitem><para>func_callback</para></listitem> + <listitem><para>counter</para></listitem> + <listitem><para>copy_tracker</para></listitem> + <listitem><para>copy_constructor</para></listitem> + <listitem><para>assignment_operator</para></listitem> + <listitem><para>destructor</para></listitem> + <listitem> <para>pod_char, pod_int and associated char_traits specializations</para> </listitem> </itemizedlist> @@ -792,13 +794,239 @@ only default variables. reporting functions including: </para> <itemizedlist> - <listitem><para>time_counter</para></listitem> - <listitem><para>resource_counter</para></listitem> - <listitem><para>report_performance</para></listitem> + <listitem><para>time_counter</para></listitem> + <listitem><para>resource_counter</para></listitem> + <listitem><para>report_performance</para></listitem> </itemizedlist> </listitem> </itemizedlist> </sect3> </sect2> + +<sect2 id="test.special"> +<title>Special Topics</title> + +<sect3 id="test.exception.safety"> +<title> + Qualifying Exception Safety Guarantees + <indexterm> + <primary>Test</primary> + <secondary>Exception Safety</secondary> + </indexterm> +</title> + +<sect4 id="test.exception.safety.overview"> +<title>Overview</title> + + <para> + Testing is composed of running a particular test sequence, + and looking at what happens to the surrounding code when + exceptions are thrown. Each test is composed of measuring + initial state, executing a particular sequence of code under + some instrumented conditions, measuring a final state, and + then examining the differences between the two states. + </para> + + <para> + Test sequences are composed of constructed code sequences + that exercise a particular function or member function, and + either confirm no exceptions were generated, or confirm the + consistency/coherency of the test subject in the event of a + thrown exception. + </para> + + <para> + Random code paths can be constructed using the the basic test + sequences and instrumentation as above, only combined in a + random or pseudo-random way. + </para> + + <para> To compute the code paths that throw, test instruments + are used that throw on allocation events + (<classname>__gnu_cxx::throw_allocator_random</classname> + and <classname>__gnu_cxx::throw_allocator_limit</classname>) + and copy, assignment, comparison, increment, swap, and + various operators + (<classname>__gnu_cxx::throw_type_random</classname> + and <classname>__gnu_cxx::throw_type_limit</classname>). Looping + through a given test sequence and conditionally throwing in + all instrumented places. Then, when the test sequence + completes without an exception being thrown, assume all + potential error paths have been exercised in a sequential + manner. + </para> +</sect4> + + +<sect4 id="test.exception.safety.status"> +<title> + Existing tests +</title> + + <itemizedlist> + <listitem> + <para> + Ad Hoc + </para> + <para> + For example, + <filename>testsuite/23_containers/list/modifiers/3.cc</filename>. + </para> + </listitem> + + <listitem> + <para> + Policy Based Data Structures + </para> + <para> + For example, take the test + functor <classname>rand_reg_test</classname> in + in <filename>testsuite/ext/pb_ds/regression/tree_no_data_map_rand.cc</filename>. This uses <classname>container_rand_regression_test</classname> in +<filename>testsuite/util/regression/rand/assoc/container_rand_regression_test.h</filename>. + + </para> + + <para> + Which has several tests for container member functions, +Includes control and test container objects. Configuration includes +random seed, iterations, number of distinct values, and the +probability that and exception will be thrown. Assumes instantiating +container uses an extension +allocator, <classname>__gnu_cxx::throw_allocator_random</classname>, +as the allocator type. + </para> + </listitem> + + <listitem> + <para> + C++0x Container Requirements. + </para> + + <para> + Coverage is currently limited to testing container + requirements for exception safety, + although <classname>__gnu_cxx::throw_type</classname> meets + the additional type requirements for testing numeric data + structures and instantiating algorithms. + </para> + + <para> + Of particular interest is extending testing to algorithms and + then to parallel algorithms. Also io, and locales. + </para> + </listitem> + </itemizedlist> +</sect4> + + +<sect4 id="test.exception.safety.containers"> +<title> +C++0x Requirements Test Sequence Descriptions +</title> + + <itemizedlist> + <listitem> + <para> + Basic + </para> + + <para> + Basic consistency on exception propagation tests. For + each container, an object of that container is constructed, + a specific member function is exercised in + a <literal>try</literal> block, and then any thrown + exceptions lead to error checking in the appropriate + <literal>catch</literal> block. The container's use of + resources is compared to the container's use prior to the + test block. Resource monitoring is limited to allocations + made through the container's <type>allocator_type</type>, + which should be sufficient for container data + structures. Included in these tests are member functions + are <type>iterator</type> and <type>const_iterator</type> + operations, <function>pop_front</function>, <function>pop_back</function>, <function>push_front</function>, <function>push_back</function>, <function>insert</function>, <function>erase</function>, <function>swap</function>, <function>clear</function>, + and <function>rehash</function>. The container in question is + instantiated with two instrumented template arguments, + with <classname>__gnu_cxx::throw_allocator_limit</classname> + as the allocator type, and + with <classname>__gnu_cxx::throw_type_limit</classname> as + the value type. This allows the test to loop through + conditional throw points. + </para> + + <para> + The general form is demonstrated in + <filename>testsuite/23_containers/list/requirements/exception/basic.cc + </filename>. The instantiating test object is <classname>__gnu_test::basic_safety</classname> and is detailed in <filename>testsuite/util/exception/safety.h</filename>. + </para> + </listitem> + + + <listitem> + <para> + Generation Prohibited + </para> + + <para> + Exception generation tests. For each container, an object of + that container is constructed and all member functions + required to not throw exceptions are exercised. Included in + these tests are member functions + are <type>iterator</type> and <type>const_iterator</type> operations, <function>erase</function>, <function>pop_front</function>, <function>pop_back</function>, <function>swap</function>, + and <function>clear</function>. The container in question is + instantiated with two instrumented template arguments, + with <classname>__gnu_cxx::throw_allocator_random</classname> + as the allocator type, and + with <classname>__gnu_cxx::throw_type_random</classname> as + the value type. This test does not loop, an instead is sudden + death: first error fails. + </para> + <para> + The general form is demonstrated in + <filename>testsuite/23_containers/list/requirements/exception/generation_prohibited.cc + </filename>. The instantiating test object is <classname>__gnu_test::generation_prohibited</classname> and is detailed in <filename>testsuite/util/exception/safety.h</filename>. + </para> + </listitem> + + + <listitem> + <para> + Propagation Consistent + </para> + + <para> + Container rollback on exception propagation tests. For + each container, an object of that container is constructed, + a specific member function that requires rollback to a previous + known good state is exercised in + a <literal>try</literal> block, and then any thrown + exceptions lead to error checking in the appropriate + <literal>catch</literal> block. The container is compared to + the container's last known good state using such parameters + as size, contents, and iterator references. Included in these + tests are member functions + are <function>push_front</function>, <function>push_back</function>, <function>insert</function>, + and <function>rehash</function>. The container in question is + instantiated with two instrumented template arguments, + with <classname>__gnu_cxx::throw_allocator_limit</classname> + as the allocator type, and + with <classname>__gnu_cxx::throw_type_limit</classname> as + the value type. This allows the test to loop through + conditional throw points. + </para> + + <para> + The general form demonstrated in + <filename>testsuite/23_containers/list/requirements/exception/propagation_coherent.cc + </filename>. The instantiating test object is <classname>__gnu_test::propagation_coherent</classname> and is detailed in <filename>testsuite/util/exception/safety.h</filename>. + </para> + </listitem> + </itemizedlist> + +</sect4> + +</sect3> + +</sect2> + </sect1> diff --git a/libstdc++-v3/include/bits/algorithmfwd.h b/libstdc++-v3/include/bits/algorithmfwd.h index e33a14c3bdc..7625ee4af51 100644 --- a/libstdc++-v3/include/bits/algorithmfwd.h +++ b/libstdc++-v3/include/bits/algorithmfwd.h @@ -236,13 +236,6 @@ _GLIBCXX_BEGIN_NAMESPACE(std) void fill(_FIter, _FIter, const _Tp&); -/* - XXX NB: return type different from ISO C++. - template<typename _OIter, typename _Size, typename _Tp> - void - fill_n(_OIter, _Size, const _Tp&); -*/ - template<typename _OIter, typename _Size, typename _Tp> _OIter fill_n(_OIter, _Size, const _Tp&); @@ -620,13 +613,6 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_P) void generate(_FIter, _FIter, _Generator); -/* - XXX NB: return type different from ISO C++. - template<typename _OIter, typename _Size, typename _Tp> - void - generate_n(_OIter, _Size, _Generator); -*/ - template<typename _OIter, typename _Size, typename _Generator> _OIter generate_n(_OIter, _Size, _Generator); diff --git a/libstdc++-v3/include/bits/functexcept.h b/libstdc++-v3/include/bits/functexcept.h index 62174819118..5b2e9fc0455 100644 --- a/libstdc++-v3/include/bits/functexcept.h +++ b/libstdc++-v3/include/bits/functexcept.h @@ -91,6 +91,10 @@ _GLIBCXX_BEGIN_NAMESPACE(std) void __throw_future_error(int) __attribute__((__noreturn__)); + // Helpers for exception objects in <functional> + void + __throw_bad_function_call() __attribute__((__noreturn__)); + _GLIBCXX_END_NAMESPACE #endif diff --git a/libstdc++-v3/include/bits/stl_algo.h b/libstdc++-v3/include/bits/stl_algo.h index 088414d097f..f6c98f8f59c 100644 --- a/libstdc++-v3/include/bits/stl_algo.h +++ b/libstdc++-v3/include/bits/stl_algo.h @@ -4921,6 +4921,9 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_P) * * Performs the assignment @c *i = @p gen() for each @c i in the range * @p [first,first+n). + * + * _GLIBCXX_RESOLVE_LIB_DEFECTS + * DR 865. More algorithms that throw away information */ template<typename _OutputIterator, typename _Size, typename _Generator> _OutputIterator diff --git a/libstdc++-v3/include/bits/stl_algobase.h b/libstdc++-v3/include/bits/stl_algobase.h index f9c3ab2b428..bc04723439e 100644 --- a/libstdc++-v3/include/bits/stl_algobase.h +++ b/libstdc++-v3/include/bits/stl_algobase.h @@ -781,6 +781,9 @@ _GLIBCXX_BEGIN_NAMESPACE(std) * This function fills a range with copies of the same value. For char * types filling contiguous areas of memory, this becomes an inline call * to @c memset or @ wmemset. + * + * _GLIBCXX_RESOLVE_LIB_DEFECTS + * DR 865. More algorithms that throw away information */ template<typename _OI, typename _Size, typename _Tp> inline _OI diff --git a/libstdc++-v3/include/bits/stl_deque.h b/libstdc++-v3/include/bits/stl_deque.h index 7f601cbf0fb..d7589f71d7a 100644 --- a/libstdc++-v3/include/bits/stl_deque.h +++ b/libstdc++-v3/include/bits/stl_deque.h @@ -72,11 +72,19 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D) * This function started off as a compiler kludge from SGI, but seems to * be a useful wrapper around a repeated constant expression. The '512' is * tunable (and no other code needs to change), but no investigation has - * been done since inheriting the SGI code. + * been done since inheriting the SGI code. Touch _GLIBCXX_DEQUE_BUF_SIZE + * only if you know what you are doing, however: changing it breaks the + * binary compatibility!! */ + +#ifndef _GLIBCXX_DEQUE_BUF_SIZE +#define _GLIBCXX_DEQUE_BUF_SIZE 512 +#endif + inline size_t __deque_buf_size(size_t __size) - { return __size < 512 ? size_t(512 / __size) : size_t(1); } + { return (__size < _GLIBCXX_DEQUE_BUF_SIZE + ? size_t(_GLIBCXX_DEQUE_BUF_SIZE / __size) : size_t(1)); } /** @@ -1798,6 +1806,8 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D) swap(deque<_Tp,_Alloc>& __x, deque<_Tp,_Alloc>& __y) { __x.swap(__y); } +#undef _GLIBCXX_DEQUE_BUF_SIZE + _GLIBCXX_END_NESTED_NAMESPACE #endif /* _STL_DEQUE_H */ diff --git a/libstdc++-v3/include/ext/throw_allocator.h b/libstdc++-v3/include/ext/throw_allocator.h index 69daa15f5db..fd939b2e168 100644 --- a/libstdc++-v3/include/ext/throw_allocator.h +++ b/libstdc++-v3/include/ext/throw_allocator.h @@ -36,9 +36,11 @@ /** @file ext/throw_allocator.h * This file is a GNU extension to the Standard C++ Library. * - * Contains an exception-throwing allocator, useful for testing - * exception safety. In addition, allocation addresses are stored and - * sanity checked. + * Contains two exception-generating types (throw_value, throw_allocator) + * intended to be used as value and allocator types while testing + * exception safety in templatized containers and algorithms. The + * allocator has additional log and debug features. The exception + * generated is of type forced_exception_error. */ #ifndef _THROW_ALLOCATOR_H @@ -64,27 +66,30 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) /** - * @brief Thown by throw_allocator. + * @brief Thown by exception safety machinery. * @ingroup exceptions */ - struct forced_exception_error : public std::exception + struct forced_error : public std::exception { }; - // Substitute for concurrence_error object in the case of -fno-exceptions. + // Substitute for forced_error object when -fno-exceptions. inline void - __throw_forced_exception_error() + __throw_forced_error() { #if __EXCEPTIONS - throw forced_exception_error(); + throw forced_error(); #else __builtin_abort(); #endif } - // Base class for checking address and label information about - // allocations. Create a std::map between the allocated address - // (void*) and a datum for annotations, which are a pair of numbers - // corresponding to label and allocated size. + + /** + * @brief Base class for checking address and label information + * about allocations. Create a std::map between the allocated + * address (void*) and a datum for annotations, which are a pair of + * numbers corresponding to label and allocated size. + */ struct annotate_base { annotate_base() @@ -92,7 +97,7 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) label(); map(); } - + static void set_label(size_t l) { label() = l; } @@ -106,7 +111,7 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) { if (p == NULL) { - std::string error("throw_allocator_base::insert null insert!\n"); + std::string error("annotate_base::insert null insert!\n"); log_to_string(error, make_entry(p, size)); std::__throw_logic_error(error.c_str()); } @@ -114,7 +119,7 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) const_iterator found = map().find(p); if (found != map().end()) { - std::string error("throw_allocator_base::insert double insert!\n"); + std::string error("annotate_base::insert double insert!\n"); log_to_string(error, make_entry(p, size)); log_to_string(error, *found); std::__throw_logic_error(error.c_str()); @@ -130,7 +135,7 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) map().erase(p); } - // See if a particular address and size has been allocated. + // See if a particular address and allocation size has been saved. inline void check_allocated(void* p, size_t size) { @@ -142,7 +147,7 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) log_to_string(error, make_entry(p, size)); std::__throw_logic_error(error.c_str()); } - + if (found->second.second != size) { std::string error("annotate_base::check_allocated by value " @@ -166,7 +171,7 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) log_to_string(found, *beg); ++beg; } - + if (!found.empty()) { std::string error("annotate_base::check_allocated by label\n"); @@ -213,15 +218,15 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) static size_t& label() { - static size_t ll; - return ll; + static size_t _S_label(std::numeric_limits<size_t>::max()); + return _S_label; } static map_type& map() { - static map_type mp; - return mp; + static map_type _S_map; + return _S_map; } }; @@ -237,47 +242,133 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) return os << error; } - /// Base class for probability control and throw. - struct probability_base + + /** + * @brief Base struct for condition policy. + * + * Requires a public member function with the signature + * void throw_conditionally() + */ + struct condition_base + { + virtual ~condition_base() { }; + }; + + + /** + * @brief Base class for incremental control and throw. + */ + struct limit_condition : public condition_base { - // Scope-level probability adjustor objects: set probability for - // throw at the beginning of a scope block, and restores to - // previous probability when object is destroyed on exiting the - // block. + // Scope-level adjustor objects: set limit for throw at the + // beginning of a scope block, and restores to previous limit when + // object is destroyed on exiting the block. struct adjustor_base { private: - const double _M_prob; + const size_t _M_orig; public: - adjustor_base() : _M_prob(get_probability()) { } + adjustor_base() : _M_orig(limit()) { } + + virtual + ~adjustor_base() { set_limit(_M_orig); } + }; + + /// Never enter the condition. + struct never_adjustor : public adjustor_base + { + never_adjustor() { set_limit(std::numeric_limits<size_t>::max()); } + }; + + /// Always enter the condition. + struct always_adjustor : public adjustor_base + { + always_adjustor() { set_limit(count()); } + }; + + /// Enter the nth condition. + struct limit_adjustor : public adjustor_base + { + limit_adjustor(const size_t __l) { set_limit(__l); } + }; + + // Increment _S_count every time called. + // If _S_count matches the limit count, throw. + static void + throw_conditionally() + { + if (count() == limit()) + __throw_forced_error(); + ++count(); + } + + static size_t& + count() + { + static size_t _S_count(0); + return _S_count; + } + + static size_t& + limit() + { + static size_t _S_limit(std::numeric_limits<size_t>::max()); + return _S_limit; + } + + // Zero the throw counter, set limit to argument. + static void + set_limit(const size_t __l) + { + limit() = __l; + count() = 0; + } + }; + + + /** + * @brief Base class for random probability control and throw. + */ + struct random_condition : public condition_base + { + // Scope-level adjustor objects: set probability for throw at the + // beginning of a scope block, and restores to previous + // probability when object is destroyed on exiting the block. + struct adjustor_base + { + private: + const double _M_orig; + + public: + adjustor_base() : _M_orig(probability()) { } virtual ~adjustor_base() - { set_probability(_M_prob); } + { set_probability(_M_orig); } }; - // Group condition. + /// Group condition. struct group_adjustor : public adjustor_base { group_adjustor(size_t size) - { set_probability(1 - std::pow(double(1 - get_probability()), + { set_probability(1 - std::pow(double(1 - probability()), double(0.5 / (size + 1)))); } }; - // Never enter the condition. + /// Never enter the condition. struct never_adjustor : public adjustor_base { never_adjustor() { set_probability(0); } }; - // Always enter the condition. + /// Always enter the condition. struct always_adjustor : public adjustor_base { always_adjustor() { set_probability(1); } }; - probability_base() + random_condition() { probability(); engine(); @@ -287,15 +378,11 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) set_probability(double __p) { probability() = __p; } - static double& - get_probability() - { return probability(); } - - void + static void throw_conditionally() { - if (generate() < get_probability()) - __throw_forced_exception_error(); + if (generate() < probability()) + __throw_forced_error(); } void @@ -311,7 +398,7 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) typedef std::tr1::mt19937 engine_type; #endif - double + static double generate() { #ifdef __GXX_EXPERIMENTAL_CXX0X__ @@ -327,7 +414,7 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) double random = generator(); if (random < distribution.min() || random > distribution.max()) { - std::string __s("throw_allocator::throw_conditionally"); + std::string __s("random_condition::generate"); __s += "\n"; __s += "random number generated is: "; char buf[40]; @@ -342,54 +429,186 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) static double& probability() { - static double __p; - return __p; + static double _S_p; + return _S_p; } static engine_type& engine() { - static engine_type __e; - return __e; + static engine_type _S_e; + return _S_e; } }; + /** - * @brief Allocator class with logging and exception control. + * @brief Class with exception generation control. Intended to be + * used as a value_type in templatized code. + * + * Note: Destructor not allowed to throw. + */ + template<typename _Cond> + struct throw_value_base : public _Cond + { + typedef _Cond condition_type; + + using condition_type::throw_conditionally; + + std::size_t _M_i; + + throw_value_base() : _M_i(0) + { throw_conditionally(); } + + throw_value_base(const throw_value_base& __v) + : _M_i(__v._M_i) + { throw_conditionally(); } + + explicit throw_value_base(const std::size_t __i) + : _M_i(__i) + { throw_conditionally(); } + + throw_value_base& + operator=(const throw_value_base& __v) + { + throw_conditionally(); + _M_i = __v._M_i; + return *this; + } + + throw_value_base& + operator++() + { + throw_conditionally(); + ++_M_i; + return *this; + } + }; + + template<typename _Cond> + inline void + swap(throw_value_base<_Cond>& __a, throw_value_base<_Cond>& __b) + { + typedef throw_value_base<_Cond> throw_value; + throw_value::throw_conditionally(); + throw_value orig(__a); + __a = __b; + __b = orig; + } + + // General instantiable types requirements. + template<typename _Cond> + inline bool + operator==(const throw_value_base<_Cond>& __a, + const throw_value_base<_Cond>& __b) + { + typedef throw_value_base<_Cond> throw_value; + throw_value::throw_conditionally(); + bool __ret = __a._M_i == __b._M_i; + return __ret; + } + + template<typename _Cond> + inline bool + operator<(const throw_value_base<_Cond>& __a, + const throw_value_base<_Cond>& __b) + { + typedef throw_value_base<_Cond> throw_value; + throw_value::throw_conditionally(); + bool __ret = __a._M_i < __b._M_i; + return __ret; + } + + // Numeric algorithms instantiable types requirements. + template<typename _Cond> + inline throw_value_base<_Cond> + operator+(const throw_value_base<_Cond>& __a, + const throw_value_base<_Cond>& __b) + { + typedef throw_value_base<_Cond> throw_value; + throw_value::throw_conditionally(); + throw_value __ret(__a._M_i + __b._M_i); + return __ret; + } + + template<typename _Cond> + inline throw_value_base<_Cond> + operator-(const throw_value_base<_Cond>& __a, + const throw_value_base<_Cond>& __b) + { + typedef throw_value_base<_Cond> throw_value; + throw_value::throw_conditionally(); + throw_value __ret(__a._M_i - __b._M_i); + return __ret; + } + + template<typename _Cond> + inline throw_value_base<_Cond> + operator*(const throw_value_base<_Cond>& __a, + const throw_value_base<_Cond>& __b) + { + typedef throw_value_base<_Cond> throw_value; + throw_value::throw_conditionally(); + throw_value __ret(__a._M_i * __b._M_i); + return __ret; + } + + /// Type throwing via limit condition. + struct throw_value_limit : public throw_value_base<limit_condition> + { + typedef throw_value_base<limit_condition> base_type; + + throw_value_limit() { } + + throw_value_limit(const throw_value_limit& __other) + : base_type(__other._M_i) { } + + explicit throw_value_limit(const std::size_t __i) : base_type(__i) { } + }; + + /// Type throwing via random condition. + struct throw_value_random : public throw_value_base<random_condition> + { + typedef throw_value_base<random_condition> base_type; + + throw_value_random() { } + + throw_value_random(const throw_value_random& __other) + : base_type(__other._M_i) { } + + + explicit throw_value_random(const std::size_t __i) : base_type(__i) { } + }; + + + /** + * @brief Allocator class with logging and exception generation control. + * Intended to be used as an allocator_type in templatized code. * @ingroup allocators + * + * Note: Deallocate not allowed to throw. */ - template<typename T> - class throw_allocator - : public probability_base, public annotate_base + template<typename _Tp, typename _Cond> + class throw_allocator_base + : public annotate_base, public _Cond { public: typedef size_t size_type; typedef ptrdiff_t difference_type; - typedef T value_type; + typedef _Tp value_type; typedef value_type* pointer; typedef const value_type* const_pointer; typedef value_type& reference; typedef const value_type& const_reference; private: - std::allocator<value_type> _M_allocator; + typedef _Cond condition_type; - public: - template<typename U> - struct rebind - { - typedef throw_allocator<U> other; - }; - - throw_allocator() throw() { } - - throw_allocator(const throw_allocator&) throw() { } - - template<typename U> - throw_allocator(const throw_allocator<U>&) throw() { } + std::allocator<value_type> _M_allocator; - ~throw_allocator() throw() { } + using condition_type::throw_conditionally; + public: size_type max_size() const throw() { return _M_allocator.max_size(); } @@ -407,7 +626,7 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) } void - construct(pointer __p, const T& val) + construct(pointer __p, const value_type& val) { return _M_allocator.construct(__p, val); } #ifdef __GXX_EXPERIMENTAL_CXX0X__ @@ -435,19 +654,97 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) annotate_base::check_allocated(__p, __t); } - using annotate_base::check_allocated; - }; + void + check_allocated(size_type __n) + { annotate_base::check_allocated(__n); } + }; - template<typename T> + template<typename _Tp, typename _Cond> inline bool - operator==(const throw_allocator<T>&, const throw_allocator<T>&) + operator==(const throw_allocator_base<_Tp, _Cond>&, + const throw_allocator_base<_Tp, _Cond>&) { return true; } - template<typename T> + template<typename _Tp, typename _Cond> inline bool - operator!=(const throw_allocator<T>&, const throw_allocator<T>&) + operator!=(const throw_allocator_base<_Tp, _Cond>&, + const throw_allocator_base<_Tp, _Cond>&) { return false; } + /// Allocator throwing via limit condition. + template<typename _Tp> + struct throw_allocator_limit + : public throw_allocator_base<_Tp, limit_condition> + { + template<typename _Tp1> + struct rebind + { typedef throw_allocator_limit<_Tp1> other; }; + + throw_allocator_limit() throw() { } + + throw_allocator_limit(const throw_allocator_limit&) throw() { } + + template<typename _Tp1> + throw_allocator_limit(const throw_allocator_limit<_Tp1>&) throw() { } + + ~throw_allocator_limit() throw() { } + }; + + /// Allocator throwing via random condition. + template<typename _Tp> + struct throw_allocator_random + : public throw_allocator_base<_Tp, random_condition> + { + template<typename _Tp1> + struct rebind + { typedef throw_allocator_random<_Tp1> other; }; + + throw_allocator_random() throw() { } + + throw_allocator_random(const throw_allocator_random&) throw() { } + + template<typename _Tp1> + throw_allocator_random(const throw_allocator_random<_Tp1>&) throw() { } + + ~throw_allocator_random() throw() { } + }; + _GLIBCXX_END_NAMESPACE +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + +# include <bits/functional_hash.h> + +namespace std +{ + /// Explicit specialization of std::hash for __gnu_cxx::throw_value_limit. + template<> + struct hash<__gnu_cxx::throw_value_limit> + : public std::unary_function<__gnu_cxx::throw_value_limit, size_t> + { + size_t + operator()(__gnu_cxx::throw_value_limit __val) const + { + std::hash<std::size_t> h; + size_t __result = h(__val._M_i); + return __result; + } + }; + + /// Explicit specialization of std::hash for __gnu_cxx::throw_value_limit. + template<> + struct hash<__gnu_cxx::throw_value_random> + : public std::unary_function<__gnu_cxx::throw_value_random, size_t> + { + size_t + operator()(__gnu_cxx::throw_value_random __val) const + { + std::hash<std::size_t> h; + size_t __result = h(__val._M_i); + return __result; + } + }; +} // end namespace std +#endif + #endif diff --git a/libstdc++-v3/include/std/functional b/libstdc++-v3/include/std/functional index eb10b348ad1..19503bdf05e 100644 --- a/libstdc++-v3/include/std/functional +++ b/libstdc++-v3/include/std/functional @@ -1571,8 +1571,8 @@ namespace std } static void - _M_init_functor(_Any_data& __functor, const _Functor& __f) - { _M_init_functor(__functor, __f, _Local_storage()); } + _M_init_functor(_Any_data& __functor, _Functor&& __f) + { _M_init_functor(__functor, std::move(__f), _Local_storage()); } template<typename _Signature> static bool @@ -1595,13 +1595,13 @@ namespace std { return true; } private: - static void - _M_init_functor(_Any_data& __functor, const _Functor& __f, true_type) - { new (__functor._M_access()) _Functor(__f); } + static void + _M_init_functor(_Any_data& __functor, _Functor&& __f, true_type) + { new (__functor._M_access()) _Functor(std::move(__f)); } static void - _M_init_functor(_Any_data& __functor, const _Functor& __f, false_type) - { __functor._M_access<_Functor*>() = new _Functor(__f); } + _M_init_functor(_Any_data& __functor, _Functor&& __f, false_type) + { __functor._M_access<_Functor*>() = new _Functor(std::move(__f)); } }; template<typename _Functor> @@ -1927,9 +1927,9 @@ namespace std template<typename _Functor> typename __gnu_cxx::__enable_if<!is_integral<_Functor>::value, function&>::__type - operator=(_Functor __f) + operator=(_Functor&& __f) { - function(__f).swap(*this); + function(std::forward<_Functor>(__f)).swap(*this); return *this; } @@ -1969,9 +1969,10 @@ namespace std /* template<typename _Functor, typename _Alloc> void - assign(_Functor __f, const _Alloc& __a) + assign(_Functor&& __f, const _Alloc& __a) { - function(__f, __a).swap(*this); + function(allocator_arg, __a, + std::forward<_Functor>(__f)).swap(*this); } */ @@ -2066,7 +2067,7 @@ namespace std { _M_invoker = &_My_handler::_M_invoke; _M_manager = &_My_handler::_M_manager; - _My_handler::_M_init_functor(_M_functor, __f); + _My_handler::_M_init_functor(_M_functor, std::move(__f)); } } @@ -2076,13 +2077,7 @@ namespace std operator()(_ArgTypes... __args) const { if (_M_empty()) - { -#if __EXCEPTIONS - throw bad_function_call(); -#else - __builtin_abort(); -#endif - } + __throw_bad_function_call(); return _M_invoker(_M_functor, std::forward<_ArgTypes>(__args)...); } diff --git a/libstdc++-v3/include/std/future b/libstdc++-v3/include/std/future index b8c54b6075f..8f9975dea1a 100644 --- a/libstdc++-v3/include/std/future +++ b/libstdc++-v3/include/std/future @@ -42,6 +42,7 @@ #include <system_error> #include <exception> #include <cstdatomic> +#include <bits/functexcept.h> namespace std { @@ -172,7 +173,7 @@ namespace std void _M_set(_Res&& __res) { - ::new (_M_addr()) _Res(_Move_result<_Res>::_S_move(__res)); + ::new (_M_addr()) _Res(std::move(__res)); _M_initialized = true; } @@ -183,27 +184,6 @@ namespace std }; - /// Workaround for CWG issue 664 and c++/34022 - template<typename _Res, bool = is_scalar<_Res>::value> - struct _Move_result; - - /// Specialization for scalar types returns rvalue not rvalue-reference. - template<typename _Res> - struct _Move_result<_Res, true> - { - typedef _Res __rval_type; - static _Res _S_move(_Res __res) { return __res; } - }; - - /// Specialization for non-scalar types returns rvalue-reference. - template<typename _Res> - struct _Move_result<_Res, false> - { - typedef _Res&& __rval_type; - static _Res&& _S_move(_Res& __res) { return std::move(__res); } - }; - - // TODO: use template alias when available /* template<typename _Res> @@ -426,7 +406,6 @@ namespace std typedef __basic_future<_Res> _Base_type; typedef typename _Base_type::__state_type __state_type; - typedef __future_base::_Move_result<_Res> _Mover; explicit unique_future(const __state_type& __state) : _Base_type(__state) { } @@ -440,9 +419,9 @@ namespace std unique_future& operator=(const unique_future&) = delete; /// Retrieving the value - typename _Mover::__rval_type + _Res&& get() - { return _Mover::_S_move(this->_M_get_result()._M_value()); } + { return std::move(this->_M_get_result()._M_value()); } }; /// Partial specialization for unique_future<R&> @@ -586,7 +565,6 @@ namespace std template<typename> friend class packaged_task; typedef __future_base::_State _State; - typedef __future_base::_Move_result<_Res> _Mover; typedef __future_base::_Result<_Res> result_type; shared_ptr<_State> _M_future; @@ -654,7 +632,7 @@ namespace std set_value(_Res&& __r) { if (!_M_satisfied()) - _M_storage->_M_set(_Mover::_S_move(__r)); + _M_storage->_M_set(std::move(__r)); _M_future->_M_set_result(std::move(_M_storage)); } @@ -940,11 +918,9 @@ namespace std } __catch (const future_error& __e) { -#ifdef __EXCEPTIONS if (__e.code() == future_errc::future_already_retrieved) - throw std::bad_function_call(); - throw; -#endif + __throw_bad_function_call(); + __throw_exception_again; } } @@ -953,13 +929,7 @@ namespace std operator()(_ArgTypes... __args) { if (!static_cast<bool>(_M_task) || _M_promise._M_satisfied()) - { -#ifdef __EXCEPTIONS - throw std::bad_function_call(); -#else - __builtin_abort(); -#endif - } + __throw_bad_function_call(); __try { diff --git a/libstdc++-v3/src/functexcept.cc b/libstdc++-v3/src/functexcept.cc index 352a6b70aef..d47eccbe11c 100644 --- a/libstdc++-v3/src/functexcept.cc +++ b/libstdc++-v3/src/functexcept.cc @@ -29,6 +29,7 @@ #include <ios> #include <system_error> #include <future> +#include <functional> #ifdef _GLIBCXX_USE_NLS # include <libintl.h> @@ -104,6 +105,9 @@ _GLIBCXX_BEGIN_NAMESPACE(std) __throw_future_error(int __i) { throw future_error(future_errc(__i)); } + void + __throw_bad_function_call() + { throw bad_function_call(); } #else void __throw_bad_exception(void) @@ -169,6 +173,10 @@ _GLIBCXX_BEGIN_NAMESPACE(std) __throw_future_error(int) { std::abort(); } + void + __throw_bad_function_call() + { std::abort(); } + #endif //__EXCEPTIONS _GLIBCXX_END_NAMESPACE diff --git a/libstdc++-v3/src/locale_init.cc b/libstdc++-v3/src/locale_init.cc index 1a479742517..893b6063d5c 100644 --- a/libstdc++-v3/src/locale_init.cc +++ b/libstdc++-v3/src/locale_init.cc @@ -208,9 +208,25 @@ _GLIBCXX_BEGIN_NAMESPACE(std) locale::locale() throw() : _M_impl(0) { _S_initialize(); - __gnu_cxx::__scoped_lock sentry(get_locale_mutex()); - _S_global->_M_add_reference(); + + // Checked locking to optimize the common case where _S_global + // still points to _S_classic (locale::_S_initialize_once()): + // - If they are the same, just increment the reference count and + // we are done. This effectively constructs a C locale object + // identical to the static c_locale. + // - Otherwise, _S_global can and may be destroyed due to + // locale::global() call on another thread, in which case we + // fall back to lock protected access to both _S_global and + // its reference count. _M_impl = _S_global; + if (_M_impl == _S_classic) + _M_impl->_M_add_reference(); + else + { + __gnu_cxx::__scoped_lock sentry(get_locale_mutex()); + _S_global->_M_add_reference(); + _M_impl = _S_global; + } } locale diff --git a/libstdc++-v3/src/thread.cc b/libstdc++-v3/src/thread.cc index 334e5cb8f1f..879e864edd4 100644 --- a/libstdc++-v3/src/thread.cc +++ b/libstdc++-v3/src/thread.cc @@ -83,6 +83,9 @@ namespace std void thread::_M_start_thread(__shared_base_type __b) { + if (!__gthread_active_p()) + __throw_system_error(int(errc::operation_not_permitted)); + __b->_M_this_ptr = __b; int __e = __gthread_create(&_M_id._M_thread, &execute_native_thread_routine, __b.get()); diff --git a/libstdc++-v3/testsuite/20_util/function/assign/move_target.cc b/libstdc++-v3/testsuite/20_util/function/assign/move_target.cc new file mode 100644 index 00000000000..0a1c189e504 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/function/assign/move_target.cc @@ -0,0 +1,47 @@ +// { dg-options "-std=gnu++0x" } + +// Copyright (C) 2009 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/>. + +#include <functional> + +struct moveable +{ + moveable() = default; + ~moveable() = default; + // target object must be CopyConstructible, + // but should not be copied during this test + moveable(const moveable& c) { throw "copied"; } + moveable& operator=(const moveable&) = delete; + moveable(moveable&&) { } + + void operator()() const { } +}; + +void test01() +{ + std::function<void ()> f; + f = moveable(); + f(); +} + +int main() +{ + test01(); + + return 0; +} diff --git a/libstdc++-v3/testsuite/20_util/function/cons/move_target.cc b/libstdc++-v3/testsuite/20_util/function/cons/move_target.cc new file mode 100644 index 00000000000..2396ca10171 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/function/cons/move_target.cc @@ -0,0 +1,46 @@ +// { dg-options "-std=gnu++0x" } + +// Copyright (C) 2009 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/>. + +#include <functional> + +struct moveable +{ + moveable() = default; + ~moveable() = default; + // target object must be CopyConstructible, + // but should not be copied during this test + moveable(const moveable& c) { throw "copied"; } + moveable& operator=(const moveable&) = delete; + moveable(moveable&&) { } + + void operator()() const { } +}; + +void test01() +{ + std::function<void ()> f = moveable(); + f(); +} + +int main() +{ + test01(); + + return 0; +} diff --git a/libstdc++-v3/testsuite/23_containers/bitset/requirements/explicit_instantiation/1_c++0x.cc b/libstdc++-v3/testsuite/23_containers/bitset/requirements/explicit_instantiation/1_c++0x.cc new file mode 100644 index 00000000000..0393ac71d16 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/bitset/requirements/explicit_instantiation/1_c++0x.cc @@ -0,0 +1,25 @@ +// { dg-options "-std=gnu++0x" } +// { dg-do compile } + +// Copyright (C) 2009 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/>. + +// This file tests explicit instantiation of library containers. + +#include <bitset> + +template class std::bitset<10>; diff --git a/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/assign_neg.cc b/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/assign_neg.cc index f7439944837..314a13f64e7 100644 --- a/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/assign_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/assign_neg.cc @@ -18,7 +18,7 @@ // <http://www.gnu.org/licenses/>. // { dg-do compile } -// { dg-error "no matching" "" { target *-*-* } 1494 } +// { dg-error "no matching" "" { target *-*-* } 1502 } // { dg-excess-errors "" } #include <deque> diff --git a/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_1_neg.cc b/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_1_neg.cc index b1136f59cf7..2ae51b836d8 100644 --- a/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_1_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_1_neg.cc @@ -18,7 +18,7 @@ // <http://www.gnu.org/licenses/>. // { dg-do compile } -// { dg-error "no matching" "" { target *-*-* } 1433 } +// { dg-error "no matching" "" { target *-*-* } 1441 } // { dg-excess-errors "" } #include <deque> diff --git a/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_2_neg.cc b/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_2_neg.cc index 8752a7e7b10..22bb275068b 100644 --- a/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_2_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_2_neg.cc @@ -18,7 +18,7 @@ // <http://www.gnu.org/licenses/>. // { dg-do compile } -// { dg-error "no matching" "" { target *-*-* } 1433 } +// { dg-error "no matching" "" { target *-*-* } 1441 } // { dg-excess-errors "" } #include <deque> diff --git a/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/insert_neg.cc b/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/insert_neg.cc index 8cf322e8219..cdacae483f9 100644 --- a/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/insert_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/insert_neg.cc @@ -18,7 +18,7 @@ // <http://www.gnu.org/licenses/>. // { dg-do compile } -// { dg-error "no matching" "" { target *-*-* } 1578 } +// { dg-error "no matching" "" { target *-*-* } 1586 } // { dg-excess-errors "" } #include <deque> diff --git a/libstdc++-v3/testsuite/23_containers/deque/requirements/explicit_instantiation/1_c++0x.cc b/libstdc++-v3/testsuite/23_containers/deque/requirements/explicit_instantiation/1_c++0x.cc new file mode 100644 index 00000000000..21997008251 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/deque/requirements/explicit_instantiation/1_c++0x.cc @@ -0,0 +1,25 @@ +// { dg-options "-std=gnu++0x" } +// { dg-do compile } + +// Copyright (C) 2009 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/>. + +// This file tests explicit instantiation of library containers + +#include <deque> + +template class std::deque<int>; diff --git a/libstdc++-v3/testsuite/23_containers/list/modifiers/insert/25288.cc b/libstdc++-v3/testsuite/23_containers/list/modifiers/insert/25288.cc index e9195ddbc64..eb286e0f54d 100644 --- a/libstdc++-v3/testsuite/23_containers/list/modifiers/insert/25288.cc +++ b/libstdc++-v3/testsuite/23_containers/list/modifiers/insert/25288.cc @@ -23,7 +23,7 @@ int main() { typedef int value_type; - typedef __gnu_cxx::throw_allocator<value_type> allocator_type; + typedef __gnu_cxx::throw_allocator_random<value_type> allocator_type; typedef std::list<value_type, allocator_type> list_type; insert1<list_type>(); diff --git a/libstdc++-v3/testsuite/23_containers/list/modifiers/insert/25288.h b/libstdc++-v3/testsuite/23_containers/list/modifiers/insert/25288.h index c3ec6628f3d..aebbe0ba537 100644 --- a/libstdc++-v3/testsuite/23_containers/list/modifiers/insert/25288.h +++ b/libstdc++-v3/testsuite/23_containers/list/modifiers/insert/25288.h @@ -47,7 +47,7 @@ void insert1() list1.insert(list1.begin(), 10, 99); VERIFY( false ); } - catch (__gnu_cxx::forced_exception_error&) + catch (__gnu_cxx::forced_error&) { VERIFY( true ); } @@ -74,7 +74,7 @@ void insert1() list2.insert(list2.begin(), data, data + 10); VERIFY( false ); } - catch (__gnu_cxx::forced_exception_error&) + catch (__gnu_cxx::forced_error&) { VERIFY( true ); } diff --git a/libstdc++-v3/testsuite/23_containers/list/requirements/exception/basic.cc b/libstdc++-v3/testsuite/23_containers/list/requirements/exception/basic.cc new file mode 100644 index 00000000000..33232f965f6 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/list/requirements/exception/basic.cc @@ -0,0 +1,40 @@ +// { dg-options "-std=gnu++0x" } +// { dg-require-cstdint "" } + +// 2009-11-30 Benjamin Kosnik <benjamin@redhat.com> + +// Copyright (C) 2009 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/>. + +#include <list> +#include <exception/safety.h> + +void +value() +{ + typedef __gnu_cxx::throw_value_limit value_type; + typedef __gnu_cxx::throw_allocator_limit<value_type> allocator_type; + typedef std::list<value_type, allocator_type> test_type; + __gnu_test::basic_safety<test_type> test; +} + +// Container requirement testing, exceptional behavior +int main() +{ + value(); + return 0; +} diff --git a/libstdc++-v3/testsuite/23_containers/list/requirements/exception/generation_prohibited.cc b/libstdc++-v3/testsuite/23_containers/list/requirements/exception/generation_prohibited.cc new file mode 100644 index 00000000000..f3d16028e2a --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/list/requirements/exception/generation_prohibited.cc @@ -0,0 +1,34 @@ +// { dg-options "-std=gnu++0x" } +// { dg-require-cstdint "" } + +// 2009-09-09 Benjamin Kosnik <benjamin@redhat.com> + +// Copyright (C) 2009 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/>. + +#include <list> +#include <exception/safety.h> + +// Container requirement testing, exceptional behavior +int main() +{ + typedef __gnu_cxx::throw_value_random value_type; + typedef __gnu_cxx::throw_allocator_random<value_type> allocator_type; + typedef std::list<value_type, allocator_type> test_type; + __gnu_test::generation_prohibited<test_type> test; + return 0; +} diff --git a/libstdc++-v3/testsuite/23_containers/list/requirements/exception/propagation_consistent.cc b/libstdc++-v3/testsuite/23_containers/list/requirements/exception/propagation_consistent.cc new file mode 100644 index 00000000000..02d8d0b254f --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/list/requirements/exception/propagation_consistent.cc @@ -0,0 +1,34 @@ +// { dg-options "-std=gnu++0x" } +// { dg-require-cstdint "" } + +// 2009-09-09 Benjamin Kosnik <benjamin@redhat.com> + +// Copyright (C) 2009 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/>. + +#include <list> +#include <exception/safety.h> + +// Container requirement testing, exceptional behavior +int main() +{ + typedef __gnu_cxx::throw_value_limit value_type; + typedef __gnu_cxx::throw_allocator_limit<value_type> allocator_type; + typedef std::list<value_type, allocator_type> test_type; + __gnu_test::propagation_consistent<test_type> test; + return 0; +} diff --git a/libstdc++-v3/testsuite/23_containers/list/requirements/explicit_instantiation/1_c++0x.cc b/libstdc++-v3/testsuite/23_containers/list/requirements/explicit_instantiation/1_c++0x.cc new file mode 100644 index 00000000000..78e026a7fd0 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/list/requirements/explicit_instantiation/1_c++0x.cc @@ -0,0 +1,25 @@ +// { dg-options "-std=gnu++0x" } +// { dg-do compile } + +// Copyright (C) 2009 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/>. + +// This file tests explicit instantiation of library containers + +#include <list> + +template class std::list<int>; diff --git a/libstdc++-v3/testsuite/23_containers/map/operators/1_neg.cc b/libstdc++-v3/testsuite/23_containers/map/operators/1_neg.cc index 031e4a749c3..647fef7f808 100644 --- a/libstdc++-v3/testsuite/23_containers/map/operators/1_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/map/operators/1_neg.cc @@ -41,5 +41,5 @@ void test01() test &= itr == mapByName.end(); // { dg-error "no" } } -// { dg-error "candidates are" "" { target *-*-* } 212 } -// { dg-error "candidates are" "" { target *-*-* } 216 } +// { dg-error "candidate is" "" { target *-*-* } 212 } +// { dg-error "candidate is" "" { target *-*-* } 216 } diff --git a/libstdc++-v3/testsuite/23_containers/map/requirements/explicit_instantiation/1_c++0x.cc b/libstdc++-v3/testsuite/23_containers/map/requirements/explicit_instantiation/1_c++0x.cc new file mode 100644 index 00000000000..3b35d54b0b1 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/map/requirements/explicit_instantiation/1_c++0x.cc @@ -0,0 +1,25 @@ +// { dg-options "-std=gnu++0x" } +// { dg-do compile } + +// Copyright (C) 2009 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/>. + +// This file tests explicit instantiation of library containers + +#include <map> + +template class std::map<int, double>; diff --git a/libstdc++-v3/testsuite/23_containers/multimap/requirements/explicit_instantiation/1_c++0x.cc b/libstdc++-v3/testsuite/23_containers/multimap/requirements/explicit_instantiation/1_c++0x.cc new file mode 100644 index 00000000000..be8fcb04917 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/multimap/requirements/explicit_instantiation/1_c++0x.cc @@ -0,0 +1,25 @@ +// { dg-options "-std=gnu++0x" } +// { dg-do compile } + +// Copyright (C) 2009 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/>. + +// This file tests explicit instantiation of library containers + +#include <map> + +template class std::multimap<int, double>; diff --git a/libstdc++-v3/testsuite/23_containers/multiset/requirements/explicit_instantiation/1_c++0x.cc b/libstdc++-v3/testsuite/23_containers/multiset/requirements/explicit_instantiation/1_c++0x.cc new file mode 100644 index 00000000000..cb522b2e5c8 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/multiset/requirements/explicit_instantiation/1_c++0x.cc @@ -0,0 +1,25 @@ +// { dg-options "-std=gnu++0x" } +// { dg-do compile } + +// Copyright (C) 2009 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/>. + +// This file tests explicit instantiation of library containers + +#include <set> + +template class std::multiset<int>; diff --git a/libstdc++-v3/testsuite/23_containers/priority_queue/requirements/explicit_instantiation/1_c++0x.cc b/libstdc++-v3/testsuite/23_containers/priority_queue/requirements/explicit_instantiation/1_c++0x.cc new file mode 100644 index 00000000000..54a25271f1d --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/priority_queue/requirements/explicit_instantiation/1_c++0x.cc @@ -0,0 +1,25 @@ +// { dg-options "-std=gnu++0x" } +// { dg-do compile } + +// Copyright (C) 2009 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/>. + +// This file tests explicit instantiation of library containers. + +#include <queue> + +template class std::priority_queue<int>; diff --git a/libstdc++-v3/testsuite/23_containers/queue/requirements/explicit_instantiation/1_c++0x.cc b/libstdc++-v3/testsuite/23_containers/queue/requirements/explicit_instantiation/1_c++0x.cc new file mode 100644 index 00000000000..7daf02999ee --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/queue/requirements/explicit_instantiation/1_c++0x.cc @@ -0,0 +1,25 @@ +// { dg-options "-std=gnu++0x" } +// { dg-do compile } + +// Copyright (C) 2009 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/>. + +// This file tests explicit instantiation of library containers. + +#include <queue> + +template class std::queue<int>; diff --git a/libstdc++-v3/testsuite/23_containers/set/operators/1_neg.cc b/libstdc++-v3/testsuite/23_containers/set/operators/1_neg.cc index 9f12a6bcfcf..6765fc1d1da 100644 --- a/libstdc++-v3/testsuite/23_containers/set/operators/1_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/set/operators/1_neg.cc @@ -39,5 +39,5 @@ void test01() test &= itr == setByName.end(); // { dg-error "no" } } -// { dg-error "candidates are" "" { target *-*-* } 287 } -// { dg-error "candidates are" "" { target *-*-* } 291 } +// { dg-error "candidate is" "" { target *-*-* } 287 } +// { dg-error "candidate is" "" { target *-*-* } 291 } diff --git a/libstdc++-v3/testsuite/23_containers/set/requirements/explicit_instantiation/1_c++0x.cc b/libstdc++-v3/testsuite/23_containers/set/requirements/explicit_instantiation/1_c++0x.cc new file mode 100644 index 00000000000..e957decf042 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/set/requirements/explicit_instantiation/1_c++0x.cc @@ -0,0 +1,25 @@ +// { dg-options "-std=gnu++0x" } +// { dg-do compile } + +// Copyright (C) 2009 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/>. + +// This file tests explicit instantiation of library containers + +#include <set> + +template class std::set<int>; diff --git a/libstdc++-v3/testsuite/23_containers/stack/requirements/explicit_instantiation/1_c++0x.cc b/libstdc++-v3/testsuite/23_containers/stack/requirements/explicit_instantiation/1_c++0x.cc new file mode 100644 index 00000000000..93307bcf43d --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/stack/requirements/explicit_instantiation/1_c++0x.cc @@ -0,0 +1,25 @@ +// { dg-options "-std=gnu++0x" } +// { dg-do compile } + +// Copyright (C) 2009 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/>. + +// This file tests explicit instantiation of library containers. + +#include <stack> + +template class std::stack<int>; diff --git a/libstdc++-v3/testsuite/23_containers/vector/requirements/explicit_instantiation/1_c++0x.cc b/libstdc++-v3/testsuite/23_containers/vector/requirements/explicit_instantiation/1_c++0x.cc new file mode 100644 index 00000000000..2e5787702a0 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/vector/requirements/explicit_instantiation/1_c++0x.cc @@ -0,0 +1,25 @@ +// { dg-options "-std=gnu++0x" } +// { dg-do compile } + +// Copyright (C) 2009 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/>. + +// This file tests explicit instantiation of library containers + +#include <vector> + +template class std::vector<int>; diff --git a/libstdc++-v3/testsuite/30_threads/packaged_task/cons/assign_neg.cc b/libstdc++-v3/testsuite/30_threads/packaged_task/cons/assign_neg.cc index db3baf35772..031ce0ba38e 100644 --- a/libstdc++-v3/testsuite/30_threads/packaged_task/cons/assign_neg.cc +++ b/libstdc++-v3/testsuite/30_threads/packaged_task/cons/assign_neg.cc @@ -33,4 +33,4 @@ void test01() } // { dg-error "used here" "" { target *-*-* } 32 } -// { dg-error "deleted function" "" { target *-*-* } 912 } +// { dg-error "deleted function" "" { target *-*-* } 890 } diff --git a/libstdc++-v3/testsuite/30_threads/packaged_task/cons/copy_neg.cc b/libstdc++-v3/testsuite/30_threads/packaged_task/cons/copy_neg.cc index 8e57d3198f4..65cf9fdbf9c 100644 --- a/libstdc++-v3/testsuite/30_threads/packaged_task/cons/copy_neg.cc +++ b/libstdc++-v3/testsuite/30_threads/packaged_task/cons/copy_neg.cc @@ -32,4 +32,4 @@ void test01() } // { dg-error "used here" "" { target *-*-* } 31 } -// { dg-error "deleted function" "" { target *-*-* } 911 } +// { dg-error "deleted function" "" { target *-*-* } 889 } diff --git a/libstdc++-v3/testsuite/30_threads/promise/cons/assign_neg.cc b/libstdc++-v3/testsuite/30_threads/promise/cons/assign_neg.cc index 5e16d145ccc..54347408c53 100644 --- a/libstdc++-v3/testsuite/30_threads/promise/cons/assign_neg.cc +++ b/libstdc++-v3/testsuite/30_threads/promise/cons/assign_neg.cc @@ -33,4 +33,4 @@ void test01() } // { dg-error "used here" "" { target *-*-* } 32 } -// { dg-error "deleted function" "" { target *-*-* } 630 } +// { dg-error "deleted function" "" { target *-*-* } 608 } diff --git a/libstdc++-v3/testsuite/30_threads/promise/cons/copy_neg.cc b/libstdc++-v3/testsuite/30_threads/promise/cons/copy_neg.cc index 1e857977927..79d2e16639f 100644 --- a/libstdc++-v3/testsuite/30_threads/promise/cons/copy_neg.cc +++ b/libstdc++-v3/testsuite/30_threads/promise/cons/copy_neg.cc @@ -32,4 +32,4 @@ void test01() } // { dg-error "used here" "" { target *-*-* } 31 } -// { dg-error "deleted function" "" { target *-*-* } 614 } +// { dg-error "deleted function" "" { target *-*-* } 592 } diff --git a/libstdc++-v3/testsuite/30_threads/shared_future/cons/assign_neg.cc b/libstdc++-v3/testsuite/30_threads/shared_future/cons/assign_neg.cc index 26211fe1c76..0f284cd0a26 100644 --- a/libstdc++-v3/testsuite/30_threads/shared_future/cons/assign_neg.cc +++ b/libstdc++-v3/testsuite/30_threads/shared_future/cons/assign_neg.cc @@ -35,4 +35,4 @@ void test01() } // { dg-error "used here" "" { target *-*-* } 34 } -// { dg-error "deleted function" "" { target *-*-* } 514 } +// { dg-error "deleted function" "" { target *-*-* } 493 } diff --git a/libstdc++-v3/testsuite/30_threads/unique_future/cons/assign_neg.cc b/libstdc++-v3/testsuite/30_threads/unique_future/cons/assign_neg.cc index e29148ee785..69caf12edb4 100644 --- a/libstdc++-v3/testsuite/30_threads/unique_future/cons/assign_neg.cc +++ b/libstdc++-v3/testsuite/30_threads/unique_future/cons/assign_neg.cc @@ -35,4 +35,4 @@ void test01() } // { dg-error "used here" "" { target *-*-* } 34 } -// { dg-error "deleted function" "" { target *-*-* } 440 } +// { dg-error "deleted function" "" { target *-*-* } 419 } diff --git a/libstdc++-v3/testsuite/30_threads/unique_future/cons/copy_neg.cc b/libstdc++-v3/testsuite/30_threads/unique_future/cons/copy_neg.cc index 8134c7d9219..43e940cfa76 100644 --- a/libstdc++-v3/testsuite/30_threads/unique_future/cons/copy_neg.cc +++ b/libstdc++-v3/testsuite/30_threads/unique_future/cons/copy_neg.cc @@ -34,4 +34,4 @@ void test01() } // { dg-error "used here" "" { target *-*-* } 33 } -// { dg-error "deleted function" "" { target *-*-* } 439 } +// { dg-error "deleted function" "" { target *-*-* } 418 } diff --git a/libstdc++-v3/testsuite/ext/forced_exception_error/cons_virtual_derivation.cc b/libstdc++-v3/testsuite/ext/forced_error/cons_virtual_derivation.cc index ba6b1f49013..f505a796ed0 100644 --- a/libstdc++-v3/testsuite/ext/forced_exception_error/cons_virtual_derivation.cc +++ b/libstdc++-v3/testsuite/ext/forced_error/cons_virtual_derivation.cc @@ -24,7 +24,7 @@ int main() { - typedef __gnu_cxx::forced_exception_error test_type; + typedef __gnu_cxx::forced_error test_type; __gnu_test::diamond_derivation<test_type, true>::test(); return 0; } diff --git a/libstdc++-v3/testsuite/ext/throw_allocator/check_allocate_max_size.cc b/libstdc++-v3/testsuite/ext/throw_allocator/check_allocate_max_size.cc index 1c7a6278bce..b4d099671e2 100644 --- a/libstdc++-v3/testsuite/ext/throw_allocator/check_allocate_max_size.cc +++ b/libstdc++-v3/testsuite/ext/throw_allocator/check_allocate_max_size.cc @@ -24,7 +24,7 @@ int main() { typedef int value_type; - typedef __gnu_cxx::throw_allocator<value_type> allocator_type; + typedef __gnu_cxx::throw_allocator_random<value_type> allocator_type; __gnu_test::check_allocate_max_size<allocator_type>(); return 0; } diff --git a/libstdc++-v3/testsuite/ext/throw_allocator/check_deallocate_null.cc b/libstdc++-v3/testsuite/ext/throw_allocator/check_deallocate_null.cc index 1a98078c825..3f9d37ab12d 100644 --- a/libstdc++-v3/testsuite/ext/throw_allocator/check_deallocate_null.cc +++ b/libstdc++-v3/testsuite/ext/throw_allocator/check_deallocate_null.cc @@ -24,7 +24,7 @@ int main() { typedef int value_type; - typedef __gnu_cxx::throw_allocator<value_type> allocator_type; + typedef __gnu_cxx::throw_allocator_random<value_type> allocator_type; try { __gnu_test::check_deallocate_null<allocator_type>(); } catch (std::logic_error&) diff --git a/libstdc++-v3/testsuite/ext/throw_allocator/check_delete.cc b/libstdc++-v3/testsuite/ext/throw_allocator/check_delete.cc index cfc38ee02f6..181a1ebc78e 100644 --- a/libstdc++-v3/testsuite/ext/throw_allocator/check_delete.cc +++ b/libstdc++-v3/testsuite/ext/throw_allocator/check_delete.cc @@ -24,7 +24,7 @@ int main() { - typedef __gnu_cxx::throw_allocator<unsigned int> allocator_type; + typedef __gnu_cxx::throw_allocator_random<unsigned int> allocator_type; __gnu_test::check_delete<allocator_type, true>(); return 0; } diff --git a/libstdc++-v3/testsuite/ext/throw_allocator/check_new.cc b/libstdc++-v3/testsuite/ext/throw_allocator/check_new.cc index 2d42891766b..4338471a02a 100644 --- a/libstdc++-v3/testsuite/ext/throw_allocator/check_new.cc +++ b/libstdc++-v3/testsuite/ext/throw_allocator/check_new.cc @@ -24,7 +24,7 @@ int main() { - typedef __gnu_cxx::throw_allocator<unsigned int> allocator_type; + typedef __gnu_cxx::throw_allocator_random<unsigned int> allocator_type; __gnu_test::check_new<allocator_type, true>(); return 0; } diff --git a/libstdc++-v3/testsuite/ext/throw_allocator/deallocate_global.cc b/libstdc++-v3/testsuite/ext/throw_allocator/deallocate_global.cc index c53517ebc13..65ef6dbb661 100644 --- a/libstdc++-v3/testsuite/ext/throw_allocator/deallocate_global.cc +++ b/libstdc++-v3/testsuite/ext/throw_allocator/deallocate_global.cc @@ -25,7 +25,7 @@ typedef char char_t; typedef std::char_traits<char_t> traits_t; -typedef __gnu_cxx::throw_allocator<char_t> allocator_t; +typedef __gnu_cxx::throw_allocator_random<char_t> allocator_t; typedef std::basic_string<char_t, traits_t, allocator_t> string_t; string_t s("bayou bend"); diff --git a/libstdc++-v3/testsuite/ext/throw_allocator/deallocate_local.cc b/libstdc++-v3/testsuite/ext/throw_allocator/deallocate_local.cc index c2e918ccc25..4f00928c69b 100644 --- a/libstdc++-v3/testsuite/ext/throw_allocator/deallocate_local.cc +++ b/libstdc++-v3/testsuite/ext/throw_allocator/deallocate_local.cc @@ -24,7 +24,7 @@ typedef char char_t; typedef std::char_traits<char_t> traits_t; -typedef __gnu_cxx::throw_allocator<char_t> allocator_t; +typedef __gnu_cxx::throw_allocator_random<char_t> allocator_t; typedef std::basic_string<char_t, traits_t, allocator_t> string_t; int main() diff --git a/libstdc++-v3/testsuite/ext/throw_allocator/explicit_instantiation.cc b/libstdc++-v3/testsuite/ext/throw_allocator/explicit_instantiation.cc index 659807d0be6..c2600446ff2 100644 --- a/libstdc++-v3/testsuite/ext/throw_allocator/explicit_instantiation.cc +++ b/libstdc++-v3/testsuite/ext/throw_allocator/explicit_instantiation.cc @@ -21,4 +21,5 @@ #include <cstdlib> #include <ext/throw_allocator.h> -template class __gnu_cxx::throw_allocator<int>; +template class __gnu_cxx::throw_allocator_random<int>; +template class __gnu_cxx::throw_allocator_limit<int>; diff --git a/libstdc++-v3/testsuite/ext/throw_allocator/variadic_construct.cc b/libstdc++-v3/testsuite/ext/throw_allocator/variadic_construct.cc index 395cacc0348..fd1ee8df499 100644 --- a/libstdc++-v3/testsuite/ext/throw_allocator/variadic_construct.cc +++ b/libstdc++-v3/testsuite/ext/throw_allocator/variadic_construct.cc @@ -29,7 +29,7 @@ void test01() { bool test __attribute__((unused)) = true; typedef std::pair<int, char> pair_type; - __gnu_cxx::throw_allocator<pair_type> alloc1; + __gnu_cxx::throw_allocator_random<pair_type> alloc1; pair_type* ptp1 = alloc1.allocate(1); alloc1.construct(ptp1, 3, 'a'); diff --git a/libstdc++-v3/testsuite/ext/throw_value/cons.cc b/libstdc++-v3/testsuite/ext/throw_value/cons.cc new file mode 100644 index 00000000000..fa3f3f71ca0 --- /dev/null +++ b/libstdc++-v3/testsuite/ext/throw_value/cons.cc @@ -0,0 +1,43 @@ +// { dg-options "-std=gnu++0x" } + +// Copyright (C) 2009 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/>. + +#include <type_traits> +#include <ext/throw_allocator.h> + +void foo1() +{ + typedef __gnu_cxx::throw_value_limit value_type; + value_type v1; + value_type v2(v2); + value_type v3(value_type()); +} + +bool foo2() +{ + typedef __gnu_cxx::throw_value_limit value_type; + bool b = std::is_convertible<value_type, value_type>::value; + return b; +} + +int main() +{ + foo1(); + foo2(); + return 0; +} diff --git a/libstdc++-v3/testsuite/util/exception/safety.h b/libstdc++-v3/testsuite/util/exception/safety.h new file mode 100644 index 00000000000..ce9dad4f7ba --- /dev/null +++ b/libstdc++-v3/testsuite/util/exception/safety.h @@ -0,0 +1,1066 @@ +// -*- C++ -*- + +// Copyright (C) 2009 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_EXCEPTION_SAFETY_H +#define _GLIBCXX_EXCEPTION_SAFETY_H + +#include <testsuite_container_traits.h> +#include <ext/throw_allocator.h> + +// Container requirement testing. +namespace __gnu_test +{ + // Base class for exception testing, contains utilities. + struct setup_base + { + typedef std::size_t size_type; + typedef std::uniform_int_distribution<size_type> distribution_type; + typedef std::mt19937 engine_type; + + // Return randomly generated integer on range [0, __max_size]. + static size_type + generate(size_type __max_size) + { + // Make the generator static... + const engine_type engine; + const distribution_type distribution; + static auto generator = std::bind(distribution, engine, + std::placeholders::_1); + + // ... but set the range for this particular invocation here. + const typename distribution_type::param_type p(0, __max_size); + size_type random = generator(p); + if (random < distribution.min() || random > distribution.max()) + { + std::string __s("setup_base::generate"); + __s += "\n"; + __s += "random number generated is: "; + char buf[40]; + __builtin_sprintf(buf, "%lu", random); + __s += buf; + __s += " on range ["; + __builtin_sprintf(buf, "%lu", distribution.min()); + __s += buf; + __s += ", "; + __builtin_sprintf(buf, "%lu", distribution.max()); + __s += buf; + __s += "]\n"; + std::__throw_out_of_range(__s.c_str()); + } + return random; + } + + // Given an instantiating type, return a unique value. + template<typename _Tp> + struct generate_unique + { + typedef _Tp value_type; + + operator value_type() + { + static value_type __ret; + ++__ret; + return __ret; + } + }; + + // Partial specialization for pair. + template<typename _Tp1, typename _Tp2> + struct generate_unique<std::pair<const _Tp1, _Tp2>> + { + typedef _Tp1 first_type; + typedef _Tp2 second_type; + typedef std::pair<const _Tp1, _Tp2> pair_type; + + operator pair_type() + { + static first_type _S_1; + static second_type _S_2; + ++_S_1; + ++_S_2; + return pair_type(_S_1, _S_2); + } + }; + + // Partial specialization for throw_value + template<typename _Cond> + struct generate_unique<__gnu_cxx::throw_value_base<_Cond>> + { + typedef __gnu_cxx::throw_value_base<_Cond> value_type; + + operator value_type() + { + static size_t _S_i(0); + return value_type(_S_i++); + } + }; + + + // Construct container of size n directly. _Tp == container type. + template<typename _Tp> + struct make_container_base + { + _Tp _M_container; + + make_container_base() = default; + make_container_base(const size_type n): _M_container(n) { } + + operator _Tp&() { return _M_container; } + }; + + // Construct container of size n, via multiple insertions. For + // associated and unordered types, unique value_type elements are + // necessary. + template<typename _Tp, bool = traits<_Tp>::is_mapped::value> + struct make_insert_container_base + : public make_container_base<_Tp> + { + using make_container_base<_Tp>::_M_container; + typedef typename _Tp::value_type value_type; + + make_insert_container_base(const size_type n) + { + for (size_type i = 0; i < n; ++i) + { + value_type v = generate_unique<value_type>(); + _M_container.insert(v); + } + assert(_M_container.size() == n); + } + }; + + template<typename _Tp> + struct make_insert_container_base<_Tp, false> + : public make_container_base<_Tp> + { + using make_container_base<_Tp>::_M_container; + typedef typename _Tp::value_type value_type; + + make_insert_container_base(const size_type n) + { + for (size_type i = 0; i < n; ++i) + { + value_type v = generate_unique<value_type>(); + _M_container.insert(_M_container.end(), v); + } + assert(_M_container.size() == n); + } + }; + + template<typename _Tp, bool = traits<_Tp>::has_size_type_constructor::value> + struct make_container_n; + + // Specialization for non-associative types that have a constructor with + // a size argument. + template<typename _Tp> + struct make_container_n<_Tp, true> + : public make_container_base<_Tp> + { + make_container_n(const size_type n) : make_container_base<_Tp>(n) { } + }; + + template<typename _Tp> + struct make_container_n<_Tp, false> + : public make_insert_container_base<_Tp> + { + make_container_n(const size_type n) + : make_insert_container_base<_Tp>(n) { } + }; + + + // Randomly size and populate a given container reference. + // NB: Responsibility for turning off exceptions lies with caller. + template<typename _Tp, bool = traits<_Tp>::is_allocator_aware::value> + struct populate + { + typedef _Tp container_type; + typedef typename container_type::allocator_type allocator_type; + typedef typename container_type::value_type value_type; + + populate(_Tp& __container) + { + const allocator_type a = __container.get_allocator(); + + // Size test container. + const size_type max_elements = 100; + size_type n = generate(max_elements); + + // Construct new container. + make_container_n<container_type> made(n); + container_type& tmp = made; + std::swap(tmp, __container); + } + }; + + // Partial specialization, empty. + template<typename _Tp> + struct populate<_Tp, false> + { + populate(_Tp&) { } + }; + + // Compare two containers for equivalence. + // Right now, that means size. + // Returns true if equal, throws if not. + template<typename _Tp> + static bool + compare(const _Tp& __control, const _Tp& __test) + { + // Make sure test container is in a consistent state, as + // compared to the control container. + // NB: Should be equivalent to __test != __control, but + // computed without equivalence operators + const size_type szt = std::distance(__test.begin(), __test.end()); + const size_type szc = std::distance(__control.begin(), + __control.end()); + bool __equal_size = szt == szc; + + // Should test iterator validity before and after exception. + bool __equal_it = std::equal(__test.begin(), __test.end(), + __control.begin()); + + if (!__equal_size || !__equal_it) + throw std::logic_error("setup_base::compare containers not equal"); + + return true; + } + }; + + + // Containing structure holding functors. + struct functor_base : public setup_base + { + // Abstract the erase function. + template<typename _Tp> + struct erase_base + { + typedef typename _Tp::iterator iterator; + + iterator (_Tp::* _F_erase_point)(iterator); + iterator (_Tp::* _F_erase_range)(iterator, iterator); + + erase_base() + : _F_erase_point(&_Tp::erase), _F_erase_range(&_Tp::erase) { } + }; + + // Specialization, as forward_list has erase_after. + template<typename _Tp1, typename _Tp2> + struct erase_base<std::forward_list<_Tp1, _Tp2>> + { + typedef std::forward_list<_Tp1, _Tp2> container_type; + typedef typename container_type::iterator iterator; + typedef typename container_type::const_iterator const_iterator; + + void (container_type::* _F_erase_point)(const_iterator); + void (container_type::* _F_erase_range)(const_iterator, const_iterator); + + erase_base() + : _F_erase_point(&container_type::erase_after), + _F_erase_range(&container_type::erase_after) { } + }; + + template<typename _Tp, bool = traits<_Tp>::has_erase::value> + struct erase_point : public erase_base<_Tp> + { + using erase_base<_Tp>::_F_erase_point; + + void + operator()(_Tp& __container) + { + try + { + // NB: Should be equivalent to size() member function, but + // computed with begin() and end(). + const size_type sz = std::distance(__container.begin(), + __container.end()); + + // NB: Lowest common denominator: use forward iterator operations. + auto i = __container.begin(); + std::advance(i, generate(sz)); + + // Makes it easier to think of this as __container.erase(i) + (__container.*_F_erase_point)(i); + } + catch(const __gnu_cxx::forced_error&) + { throw; } + } + }; + + // Specialization, empty. + template<typename _Tp> + struct erase_point<_Tp, false> + { + void + operator()(_Tp&) { } + }; + + + template<typename _Tp, bool = traits<_Tp>::has_erase::value> + struct erase_range : public erase_base<_Tp> + { + using erase_base<_Tp>::_F_erase_range; + + void + operator()(_Tp& __container) + { + try + { + const size_type sz = std::distance(__container.begin(), + __container.end()); + size_type s1 = generate(sz); + size_type s2 = generate(sz); + auto i1 = __container.begin(); + auto i2 = __container.begin(); + std::advance(i1, std::min(s1, s2)); + std::advance(i2, std::max(s1, s2)); + + // Makes it easier to think of this as __container.erase(i1, i2). + (__container.*_F_erase_range)(i1, i2); + } + catch(const __gnu_cxx::forced_error&) + { throw; } + } + }; + + // Specialization, empty. + template<typename _Tp> + struct erase_range<_Tp, false> + { + void + operator()(_Tp&) { } + }; + + + template<typename _Tp, bool = traits<_Tp>::has_push_pop::value> + struct pop_front + { + void + operator()(_Tp& __container) + { + try + { + __container.pop_front(); + } + catch(const __gnu_cxx::forced_error&) + { throw; } + } + }; + + // Specialization, empty. + template<typename _Tp> + struct pop_front<_Tp, false> + { + void + operator()(_Tp&) { } + }; + + + template<typename _Tp, bool = traits<_Tp>::has_push_pop::value + && traits<_Tp>::is_reversible::value> + struct pop_back + { + void + operator()(_Tp& __container) + { + try + { + __container.pop_back(); + } + catch(const __gnu_cxx::forced_error&) + { throw; } + } + }; + + // Specialization, empty. + template<typename _Tp> + struct pop_back<_Tp, false> + { + void + operator()(_Tp&) { } + }; + + + template<typename _Tp, bool = traits<_Tp>::has_push_pop::value> + struct push_front + { + typedef _Tp container_type; + typedef typename container_type::value_type value_type; + + void + operator()(_Tp& __test) + { + try + { + const value_type cv = generate_unique<value_type>(); + __test.push_front(cv); + } + catch(const __gnu_cxx::forced_error&) + { throw; } + } + + // Assumes containers start out equivalent. + void + operator()(_Tp& __control, _Tp& __test) + { + try + { + const value_type cv = generate_unique<value_type>(); + __test.push_front(cv); + } + catch(const __gnu_cxx::forced_error&) + { throw; } + } + }; + + // Specialization, empty. + template<typename _Tp> + struct push_front<_Tp, false> + { + void + operator()(_Tp&) { } + + void + operator()(_Tp&, _Tp&) { } + }; + + + template<typename _Tp, bool = traits<_Tp>::has_push_pop::value + && traits<_Tp>::is_reversible::value> + struct push_back + { + typedef _Tp container_type; + typedef typename container_type::value_type value_type; + + void + operator()(_Tp& __test) + { + try + { + const value_type cv = generate_unique<value_type>(); + __test.push_back(cv); + } + catch(const __gnu_cxx::forced_error&) + { throw; } + } + + // Assumes containers start out equivalent. + void + operator()(_Tp& __control, _Tp& __test) + { + try + { + const value_type cv = generate_unique<value_type>(); + __test.push_back(cv); + } + catch(const __gnu_cxx::forced_error&) + { throw; } + } + }; + + // Specialization, empty. + template<typename _Tp> + struct push_back<_Tp, false> + { + void + operator()(_Tp&) { } + + void + operator()(_Tp&, _Tp&) { } + }; + + + // Abstract the insert function into two parts: + // 1, insert_base_functions == holds function pointer + // 2, insert_base == links function pointer to class insert method + template<typename _Tp> + struct insert_base + { + typedef typename _Tp::iterator iterator; + typedef typename _Tp::value_type value_type; + + iterator (_Tp::* _F_insert_point)(iterator, const value_type&); + + insert_base() : _F_insert_point(&_Tp::insert) { } + }; + + // Specialization, as string insertion has a different signature. + template<typename _Tp1, typename _Tp2, typename _Tp3> + struct insert_base<std::basic_string<_Tp1, _Tp2, _Tp3>> + { + typedef std::basic_string<_Tp1, _Tp2, _Tp3> container_type; + typedef typename container_type::iterator iterator; + typedef typename container_type::value_type value_type; + + iterator (container_type::* _F_insert_point)(iterator, value_type); + + insert_base() : _F_insert_point(&container_type::insert) { } + }; + + template<typename _Tp1, typename _Tp2, typename _Tp3> + struct insert_base<__gnu_cxx::__versa_string<_Tp1, _Tp2, _Tp3>> + { + typedef __gnu_cxx::__versa_string<_Tp1, _Tp2, _Tp3> container_type; + typedef typename container_type::iterator iterator; + typedef typename container_type::value_type value_type; + + iterator (container_type::* _F_insert_point)(iterator, value_type); + + insert_base() : _F_insert_point(&container_type::insert) { } + }; + + // Specialization, as forward_list insertion has a different signature. + template<typename _Tp1, typename _Tp2> + struct insert_base<std::forward_list<_Tp1, _Tp2>> + { + typedef std::forward_list<_Tp1, _Tp2> container_type; + typedef typename container_type::iterator iterator; + typedef typename container_type::const_iterator const_iterator; + typedef typename container_type::value_type value_type; + + iterator (container_type::* _F_insert_point)(const_iterator, + const value_type&); + + insert_base() : _F_insert_point(&container_type::insert_after) { } + }; + + template<typename _Tp, bool = traits<_Tp>::has_insert::value> + struct insert_point : public insert_base<_Tp> + { + typedef _Tp container_type; + typedef typename container_type::value_type value_type; + using insert_base<_Tp>::_F_insert_point; + + void + operator()(_Tp& __test) + { + try + { + const value_type cv = generate_unique<value_type>(); + const size_type sz = std::distance(__test.begin(), __test.end()); + size_type s = generate(sz); + auto i = __test.begin(); + std::advance(i, s); + (__test.*_F_insert_point)(i, cv); + } + catch(const __gnu_cxx::forced_error&) + { throw; } + } + + // Assumes containers start out equivalent. + void + operator()(_Tp& __control, _Tp& __test) + { + try + { + const value_type cv = generate_unique<value_type>(); + const size_type sz = std::distance(__test.begin(), __test.end()); + size_type s = generate(sz); + auto i = __test.begin(); + std::advance(i, s); + (__test.*_F_insert_point)(i, cv); + } + catch(const __gnu_cxx::forced_error&) + { throw; } + } + }; + + // Specialization, empty. + template<typename _Tp> + struct insert_point<_Tp, false> + { + void + operator()(_Tp&) { } + + void + operator()(_Tp&, _Tp&) { } + }; + + + template<typename _Tp, bool = traits<_Tp>::is_associative::value + || traits<_Tp>::is_unordered::value> + struct clear + { + void + operator()(_Tp& __container) + { + try + { + __container.clear(); + } + catch(const __gnu_cxx::forced_error&) + { throw; } + } + }; + + // Specialization, empty. + template<typename _Tp> + struct clear<_Tp, false> + { + void + operator()(_Tp&) { } + }; + + + template<typename _Tp, bool = traits<_Tp>::is_unordered::value> + struct rehash + { + void + operator()(_Tp& __test) + { + try + { + size_type s = generate(__test.bucket_count()); + __test.rehash(s); + } + catch(const __gnu_cxx::forced_error&) + { throw; } + } + + void + operator()(_Tp& __control, _Tp& __test) + { + try + { + size_type s = generate(__test.bucket_count()); + __test.rehash(s); + } + catch(const __gnu_cxx::forced_error&) + { + // Also check hash status. + bool fail(false); + if (__control.load_factor() != __test.load_factor()) + fail = true; + if (__control.max_load_factor() != __test.max_load_factor()) + fail = true; + if (__control.bucket_count() != __test.bucket_count()) + fail = true; + if (__control.max_bucket_count() != __test.max_bucket_count()) + fail = true; + + if (fail) + { + char buf[40]; + std::string __s("setup_base::rehash " + "containers not equal"); + __s += "\n"; + __s += "\n"; + __s += "\t\t\tcontrol : test"; + __s += "\n"; + __s += "load_factor\t\t"; + __builtin_sprintf(buf, "%lu", __control.load_factor()); + __s += buf; + __s += " : "; + __builtin_sprintf(buf, "%lu", __test.load_factor()); + __s += buf; + __s += "\n"; + + __s += "max_load_factor\t\t"; + __builtin_sprintf(buf, "%lu", __control.max_load_factor()); + __s += buf; + __s += " : "; + __builtin_sprintf(buf, "%lu", __test.max_load_factor()); + __s += buf; + __s += "\n"; + + __s += "bucket_count\t\t"; + __builtin_sprintf(buf, "%lu", __control.bucket_count()); + __s += buf; + __s += " : "; + __builtin_sprintf(buf, "%lu", __test.bucket_count()); + __s += buf; + __s += "\n"; + + __s += "max_bucket_count\t"; + __builtin_sprintf(buf, "%lu", __control.max_bucket_count()); + __s += buf; + __s += " : "; + __builtin_sprintf(buf, "%lu", __test.max_bucket_count()); + __s += buf; + __s += "\n"; + + std::__throw_logic_error(__s.c_str()); + } + } + } + }; + + // Specialization, empty. + template<typename _Tp> + struct rehash<_Tp, false> + { + void + operator()(_Tp&) { } + + void + operator()(_Tp&, _Tp&) { } + }; + + + template<typename _Tp> + struct swap + { + _Tp _M_other; + + void + operator()(_Tp& __container) + { + try + { + __container.swap(_M_other); + } + catch(const __gnu_cxx::forced_error&) + { throw; } + } + }; + + + template<typename _Tp> + struct iterator_operations + { + typedef _Tp container_type; + typedef typename container_type::iterator iterator; + + void + operator()(_Tp& __container) + { + try + { + // Any will do. + iterator i = __container.begin(); + iterator __attribute__((unused)) icopy(i); + iterator __attribute__((unused)) iassign = i; + } + catch(const __gnu_cxx::forced_error&) + { throw; } + } + }; + + + template<typename _Tp> + struct const_iterator_operations + { + typedef _Tp container_type; + typedef typename container_type::const_iterator const_iterator; + + void + operator()(_Tp& __container) + { + try + { + // Any will do. + const_iterator i = __container.begin(); + const_iterator __attribute__((unused)) icopy(i); + const_iterator __attribute__((unused)) iassign = i; + } + catch(const __gnu_cxx::forced_error&) + { throw; } + } + }; + }; + + // Base class for exception tests. + template<typename _Tp> + struct test_base: public functor_base + { + typedef _Tp container_type; + + typedef functor_base base_type; + typedef populate<container_type> populate; + typedef make_container_n<container_type> make_container_n; + + typedef clear<container_type> clear; + typedef erase_point<container_type> erase_point; + typedef erase_range<container_type> erase_range; + typedef insert_point<container_type> insert_point; + typedef pop_front<container_type> pop_front; + typedef pop_back<container_type> pop_back; + typedef push_front<container_type> push_front; + typedef push_back<container_type> push_back; + typedef rehash<container_type> rehash; + typedef swap<container_type> swap; + typedef iterator_operations<container_type> iterator_ops; + typedef const_iterator_operations<container_type> const_iterator_ops; + + using base_type::compare; + + // Functor objects. + clear _M_clear; + erase_point _M_erasep; + erase_range _M_eraser; + insert_point _M_insertp; + pop_front _M_popf; + pop_back _M_popb; + push_front _M_pushf; + push_back _M_pushb; + rehash _M_rehash; + swap _M_swap; + + iterator_ops _M_iops; + const_iterator_ops _M_ciops; + }; + + + // Run through all member functions for basic exception safety + // guarantee: no resource leaks when exceptions are thrown. + // + // Types of resources checked: memory. + // + // For each member function, use throw_value and throw_allocator as + // value_type and allocator_type to force potential exception safety + // errors. + // + // NB: Assumes + // _Tp::value_type is __gnu_cxx::throw_value_* + // _Tp::allocator_type is __gnu_cxx::throw_allocator_* + // And that the _Cond template parameter for them both is + // __gnu_cxx::limit_condition. + template<typename _Tp> + struct basic_safety : public test_base<_Tp> + { + typedef _Tp container_type; + typedef test_base<container_type> base_type; + typedef typename base_type::populate populate; + typedef std::function<void(container_type&)> function_type; + typedef __gnu_cxx::limit_condition condition_type; + + using base_type::generate; + + container_type _M_container; + std::vector<function_type> _M_functions; + + basic_safety() { run(); } + + void + run() + { + // Setup. + condition_type::never_adjustor off; + + // Construct containers. + populate p1(_M_container); + populate p2(base_type::_M_swap._M_other); + + // Construct list of member functions to exercise. + _M_functions.push_back(function_type(base_type::_M_iops)); + _M_functions.push_back(function_type(base_type::_M_ciops)); + + _M_functions.push_back(function_type(base_type::_M_erasep)); + _M_functions.push_back(function_type(base_type::_M_eraser)); + _M_functions.push_back(function_type(base_type::_M_insertp)); + _M_functions.push_back(function_type(base_type::_M_popf)); + _M_functions.push_back(function_type(base_type::_M_popb)); + _M_functions.push_back(function_type(base_type::_M_pushf)); + _M_functions.push_back(function_type(base_type::_M_pushb)); + _M_functions.push_back(function_type(base_type::_M_rehash)); + _M_functions.push_back(function_type(base_type::_M_swap)); + + // Last. + _M_functions.push_back(function_type(base_type::_M_clear)); + + // Run tests. + auto i = _M_functions.begin(); + for (auto i = _M_functions.begin(); i != _M_functions.end(); ++i) + { + function_type& f = *i; + run_steps_to_limit(f); + } + } + + template<typename _Funct> + void + run_steps_to_limit(const _Funct& __f) + { + size_t i(1); + bool exit(false); + auto a = _M_container.get_allocator(); + + do + { + // Use the current step as an allocator label. + a.set_label(i); + + try + { + condition_type::limit_adjustor limit(i); + __f(_M_container); + + // If we get here, done. + exit = true; + } + catch(const __gnu_cxx::forced_error&) + { + // Check this step for allocations. + // NB: Will throw std::logic_error if allocations. + a.check_allocated(i); + + // Check memory allocated with operator new. + + ++i; + } + } + while (!exit); + + // Log count info. + std::cout << __f.target_type().name() << std::endl; + std::cout << "end count " << i << std::endl; + } + }; + + + // Run through all member functions with a no throw requirement, sudden death. + // all: member functions erase, pop_back, pop_front, swap + // iterator copy ctor, assignment operator + // unordered and associative: clear + // NB: Assumes _Tp::allocator_type is __gnu_cxx::throw_allocator_random. + template<typename _Tp> + struct generation_prohibited : public test_base<_Tp> + { + typedef _Tp container_type; + typedef test_base<container_type> base_type; + typedef typename base_type::populate populate; + typedef __gnu_cxx::random_condition condition_type; + + container_type _M_container; + + generation_prohibited() { run(); } + + void + run() + { + // Furthermore, assumes that the test functor will throw + // forced_exception via throw_allocator, that all errors are + // propagated and in error. Sudden death! + + // Setup. + { + condition_type::never_adjustor off; + populate p1(_M_container); + populate p2(base_type::_M_swap._M_other); + } + + // Run tests. + { + condition_type::always_adjustor on; + + _M_erasep(_M_container); + _M_eraser(_M_container); + + _M_popf(_M_container); + _M_popb(_M_container); + + _M_iops(_M_container); + _M_ciops(_M_container); + + _M_swap(_M_container); + + // Last. + _M_clear(_M_container); + } + } + }; + + + // Test strong exception guarantee. + // Run through all member functions with a roll-back, consistent + // coherent requirement. + // all: member functions insert of a single element, push_back, push_front + // unordered: rehash + template<typename _Tp> + struct propagation_consistent : public test_base<_Tp> + { + typedef _Tp container_type; + typedef test_base<container_type> base_type; + typedef typename base_type::populate populate; + typedef std::function<void(container_type&)> function_type; + typedef __gnu_cxx::limit_condition condition_type; + + using base_type::compare; + + container_type _M_container_test; + container_type _M_container_control; + std::vector<function_type> _M_functions; + + propagation_consistent() { run(); } + + void + sync() + { _M_container_test = _M_container_control; } + + // Run test. + void + run() + { + // Setup. + condition_type::never_adjustor off; + + // Construct containers. + populate p(_M_container_control); + sync(); + + // Construct list of member functions to exercise. + _M_functions.push_back(function_type(base_type::_M_pushf)); + _M_functions.push_back(function_type(base_type::_M_pushb)); + _M_functions.push_back(function_type(base_type::_M_insertp)); + _M_functions.push_back(function_type(base_type::_M_rehash)); + + // Run tests. + auto i = _M_functions.begin(); + for (auto i = _M_functions.begin(); i != _M_functions.end(); ++i) + { + function_type& f = *i; + run_steps_to_limit(f); + } + } + + template<typename _Funct> + void + run_steps_to_limit(const _Funct& __f) + { + size_t i(1); + bool exit(false); + + do + { + sync(); + + try + { + condition_type::limit_adjustor limit(i); + __f(_M_container_test); + + // If we get here, done. + exit = true; + } + catch(const __gnu_cxx::forced_error&) + { + compare(_M_container_control, _M_container_test); + ++i; + } + } + while (!exit); + + // Log count info. + std::cout << __f.target_type().name() << std::endl; + std::cout << "end count " << i << std::endl; + } + }; + +} // namespace __gnu_test + +#endif diff --git a/libstdc++-v3/testsuite/util/regression/basic_type.hpp b/libstdc++-v3/testsuite/util/regression/basic_type.hpp index 6d12bd68f77..9fe6ef24d41 100644 --- a/libstdc++-v3/testsuite/util/regression/basic_type.hpp +++ b/libstdc++-v3/testsuite/util/regression/basic_type.hpp @@ -46,7 +46,7 @@ namespace test { #define PB_DS_BASE_C_DEC \ std::basic_string<char, std::char_traits<char>, \ - __gnu_cxx::throw_allocator<char> > + __gnu_cxx::throw_allocator_random<char> > struct basic_type : public PB_DS_BASE_C_DEC { diff --git a/libstdc++-v3/testsuite/util/regression/common_type.hpp b/libstdc++-v3/testsuite/util/regression/common_type.hpp index 9e6a80d68fc..37705bc2d7d 100644 --- a/libstdc++-v3/testsuite/util/regression/common_type.hpp +++ b/libstdc++-v3/testsuite/util/regression/common_type.hpp @@ -46,7 +46,7 @@ namespace __gnu_pbds { namespace test { - typedef __gnu_cxx::throw_allocator<basic_type> alloc_type; + typedef __gnu_cxx::throw_allocator_random<basic_type> alloc_type; struct hash { diff --git a/libstdc++-v3/testsuite/util/regression/rand/assoc/container_rand_regression_test.h b/libstdc++-v3/testsuite/util/regression/rand/assoc/container_rand_regression_test.h index 393463a4dc0..ca443321216 100644 --- a/libstdc++-v3/testsuite/util/regression/rand/assoc/container_rand_regression_test.h +++ b/libstdc++-v3/testsuite/util/regression/rand/assoc/container_rand_regression_test.h @@ -80,7 +80,7 @@ namespace detail typedef typename test_traits::native_type native_type; typedef twister_rand_gen gen; typedef __gnu_pbds::container_traits<Cntnr> container_traits; - typedef __gnu_cxx::throw_allocator<char> alloc_t; + typedef __gnu_cxx::throw_allocator_random<char> alloc_t; enum op { diff --git a/libstdc++-v3/testsuite/util/regression/rand/assoc/container_rand_regression_test.tcc b/libstdc++-v3/testsuite/util/regression/rand/assoc/container_rand_regression_test.tcc index d995a049ed6..43cdb9f2b62 100644 --- a/libstdc++-v3/testsuite/util/regression/rand/assoc/container_rand_regression_test.tcc +++ b/libstdc++-v3/testsuite/util/regression/rand/assoc/container_rand_regression_test.tcc @@ -66,7 +66,7 @@ default_constructor() { m_p_c = new Cntnr; } - catch(__gnu_cxx::forced_exception_error&) + catch(__gnu_cxx::forced_error&) { done = false; } @@ -107,7 +107,7 @@ copy_constructor() p_c = new Cntnr(*m_p_c); std::swap(p_c, m_p_c); } - catch(__gnu_cxx::forced_exception_error& ) + catch(__gnu_cxx::forced_error&) { done = false; } @@ -134,7 +134,7 @@ assignment_operator() * p_c =* m_p_c; std::swap(p_c, m_p_c); } - catch(__gnu_cxx::forced_exception_error& ) + catch(__gnu_cxx::forced_error&) { done = false; } @@ -210,7 +210,7 @@ it_constructor_imp(__gnu_pbds::cc_hash_tag) }; std::swap(p_c, m_p_c); } - catch (__gnu_cxx::forced_exception_error&) + catch (__gnu_cxx::forced_error&) { done = false; } @@ -293,7 +293,7 @@ it_constructor_imp(__gnu_pbds::gp_hash_tag) }; std::swap(p_c, m_p_c); } - catch (__gnu_cxx::forced_exception_error&) + catch (__gnu_cxx::forced_error&) { done = false; } @@ -329,7 +329,7 @@ it_constructor_imp(__gnu_pbds::tree_tag) }; std::swap(p_c, m_p_c); } - catch (__gnu_cxx::forced_exception_error&) + catch (__gnu_cxx::forced_error&) { done = false; } @@ -354,7 +354,7 @@ it_constructor_imp(__gnu_pbds::list_update_tag) p_c = new Cntnr(m_p_c->begin(), m_p_c->end()); std::swap(p_c, m_p_c); } - catch (__gnu_cxx::forced_exception_error&) + catch (__gnu_cxx::forced_error&) { done = false; } @@ -392,7 +392,7 @@ it_constructor_imp(__gnu_pbds::pat_trie_tag) std::swap(p_c, m_p_c); } - catch (__gnu_cxx::forced_exception_error&) + catch (__gnu_cxx::forced_error&) { done = false; } @@ -1088,7 +1088,7 @@ insert() } m_native_c.insert(test_traits::native_value(v)); } - catch(__gnu_cxx::forced_exception_error&) + catch(__gnu_cxx::forced_error&) { done = false; } @@ -1139,7 +1139,7 @@ subscript_imp(__gnu_pbds::detail::false_type) m_native_c[test_traits::native_value(v).first] = test_traits::native_value(v).second; } - catch(__gnu_cxx::forced_exception_error& ) + catch(__gnu_cxx::forced_error&) { done = false; } @@ -1164,7 +1164,7 @@ subscript_imp(__gnu_pbds::detail::true_type) (*m_p_c)[v] = __gnu_pbds::null_mapped_type(); m_native_c.insert(test_traits::native_value(v)); } - catch(__gnu_cxx::forced_exception_error& ) + catch(__gnu_cxx::forced_error&) { done = false; } @@ -1213,7 +1213,7 @@ erase() PB_DS_THROW_IF_FAILED(m_p_c->find(k) == m_p_c->end(), "", m_p_c, &m_native_c); } - catch(__gnu_cxx::forced_exception_error& ) + catch(__gnu_cxx::forced_error&) { done = false; @@ -1251,7 +1251,7 @@ erase_if() PB_DS_THROW_IF_FAILED(ersd == native_ersd, ersd << " " << native_ersd, m_p_c, &m_native_c); } - catch(__gnu_cxx::forced_exception_error&) + catch(__gnu_cxx::forced_error&) { done = false; PB_DS_THROW_IF_FAILED(container_traits::erase_can_throw, @@ -1329,7 +1329,7 @@ erase_it_imp(__gnu_pbds::detail::true_type) if (range_guarantee) PB_DS_THROW_IF_FAILED(next_ers_it == next_it, "", m_p_c, &m_native_c); } - catch(__gnu_cxx::forced_exception_error& ) + catch(__gnu_cxx::forced_error&) { done = false; PB_DS_THROW_IF_FAILED(container_traits::erase_can_throw, container_traits::erase_can_throw, m_p_c, &m_native_c); @@ -1392,7 +1392,7 @@ erase_rev_it_imp(__gnu_pbds::detail::true_type) if (native_it != m_native_c.end()) m_native_c.erase(native_it); } - catch(__gnu_cxx::forced_exception_error& ) + catch(__gnu_cxx::forced_error&) { done = false; PB_DS_THROW_IF_FAILED(container_traits::erase_can_throw, @@ -1763,7 +1763,7 @@ split_join_imp(__gnu_pbds::detail::true_type) PB_DS_THROW_IF_FAILED(rhs.empty(), rhs.size(), m_p_c, &m_native_c); m_p_c->swap(lhs); } - catch(__gnu_cxx::forced_exception_error& ) + catch(__gnu_cxx::forced_error&) { done = false; PB_DS_THROW_IF_FAILED(container_traits::split_join_can_throw, diff --git a/libstdc++-v3/testsuite/util/regression/rand/priority_queue/container_rand_regression_test.tcc b/libstdc++-v3/testsuite/util/regression/rand/priority_queue/container_rand_regression_test.tcc index fe8ae6ba7ed..f964911facb 100644 --- a/libstdc++-v3/testsuite/util/regression/rand/priority_queue/container_rand_regression_test.tcc +++ b/libstdc++-v3/testsuite/util/regression/rand/priority_queue/container_rand_regression_test.tcc @@ -66,7 +66,7 @@ default_constructor() { m_p_c = new Cntnr; } - catch(__gnu_cxx::forced_exception_error& ) + catch(__gnu_cxx::forced_error&) { done = false; } @@ -110,7 +110,7 @@ copy_constructor() p_c = new Cntnr(*m_p_c); std::swap(p_c, m_p_c); } - catch(__gnu_cxx::forced_exception_error& ) + catch(__gnu_cxx::forced_error&) { done = false; } @@ -139,7 +139,7 @@ assignment_operator() *p_c = *m_p_c; std::swap(p_c, m_p_c); } - catch(__gnu_cxx::forced_exception_error& ) + catch(__gnu_cxx::forced_error&) { done = false; } @@ -180,7 +180,7 @@ it_constructor() std::swap(p_c, m_p_c); } - catch(__gnu_cxx::forced_exception_error& ) + catch(__gnu_cxx::forced_error&) { done = false; } @@ -433,7 +433,7 @@ push() _GLIBCXX_THROW_IF(sz != m_p_c->size() - 1, sz, m_p_c, &m_native_c); m_native_c.push(test_traits::native_value(v)); } - catch(__gnu_cxx::forced_exception_error& ) + catch(__gnu_cxx::forced_error&) { done = false; } @@ -475,7 +475,7 @@ modify() m_native_c.modify(native_v, new_native_v); } } - catch(__gnu_cxx::forced_exception_error&) + catch(__gnu_cxx::forced_error&) { done = false; _GLIBCXX_THROW_IF(true, "", m_p_c, &m_native_c); @@ -517,7 +517,7 @@ pop() m_native_c.pop(); } } - catch(__gnu_cxx::forced_exception_error&) + catch(__gnu_cxx::forced_error&) { done = false; _GLIBCXX_THROW_IF(true, "", m_p_c, &m_native_c); @@ -560,7 +560,7 @@ erase_if() _GLIBCXX_THROW_IF(ersd != native_ersd, ersd << " " << native_ersd, m_p_c, &m_native_c); } - catch(__gnu_cxx::forced_exception_error&) + catch(__gnu_cxx::forced_error&) { done = false; _GLIBCXX_THROW_IF(true, "", m_p_c, &m_native_c); @@ -592,7 +592,7 @@ erase_it() m_p_c->erase(it); } } - catch(__gnu_cxx::forced_exception_error&) + catch(__gnu_cxx::forced_error&) { done = false; _GLIBCXX_THROW_IF(true, "", m_p_c, &m_native_c); @@ -715,7 +715,7 @@ split_join() _GLIBCXX_THROW_IF(rhs.size() != 0, rhs.size(), m_p_c, &m_native_c); _GLIBCXX_THROW_IF(!rhs.empty(), rhs.size(), m_p_c, &m_native_c); } - catch(__gnu_cxx::forced_exception_error&) + catch(__gnu_cxx::forced_error&) { done = false; const bool b = __gnu_pbds::container_traits<cntnr>::split_join_can_throw; diff --git a/libstdc++-v3/testsuite/util/testsuite_container_traits.h b/libstdc++-v3/testsuite/util/testsuite_container_traits.h index 7c4b1a27097..85d04c5728c 100644 --- a/libstdc++-v3/testsuite/util/testsuite_container_traits.h +++ b/libstdc++-v3/testsuite/util/testsuite_container_traits.h @@ -24,8 +24,9 @@ #include <ext/vstring.h> namespace __gnu_test -{ +{ // Container traits. + // Base class with default false values for all traits. struct traits_base { // Type, nested type, and typedef related traits. @@ -37,6 +38,11 @@ namespace __gnu_test typedef std::false_type is_associative; typedef std::false_type is_unordered; typedef std::false_type is_mapped; + + typedef std::false_type has_erase; + typedef std::false_type has_insert; + typedef std::false_type has_push_pop; + typedef std::false_type has_size_type_constructor; }; // Primary template does nothing. Specialize on each type under @@ -46,40 +52,55 @@ namespace __gnu_test // Specialize for each container. template<typename _Tp, size_t _Np> - struct traits<std::array<_Tp, _Np> > : public traits_base + struct traits<std::array<_Tp, _Np>> : public traits_base { typedef std::true_type is_container; typedef std::true_type is_reversible; }; - template<typename _Tp> - struct traits<std::deque<_Tp> > : public traits_base + template<typename _Tp1, typename _Tp2> + struct traits<std::deque<_Tp1, _Tp2>> : public traits_base { typedef std::true_type is_container; typedef std::true_type is_reversible; typedef std::true_type is_allocator_aware; typedef std::true_type is_pointer_aware; + + typedef std::true_type has_erase; + typedef std::true_type has_insert; + typedef std::true_type has_push_pop; + typedef std::true_type has_size_type_constructor; }; - template<typename _Tp> - struct traits<std::forward_list<_Tp> > : public traits_base + template<typename _Tp1, typename _Tp2> + struct traits<std::forward_list<_Tp1, _Tp2>> : public traits_base { typedef std::true_type is_container; typedef std::true_type is_allocator_aware; typedef std::true_type is_pointer_aware; + + typedef std::true_type has_erase; + typedef std::true_type has_insert; + typedef std::true_type has_push_pop; + typedef std::true_type has_size_type_constructor; }; - template<typename _Tp> - struct traits<std::list<_Tp> > : public traits_base + template<typename _Tp1, typename _Tp2> + struct traits<std::list<_Tp1, _Tp2>> : public traits_base { typedef std::true_type is_container; typedef std::true_type is_reversible; typedef std::true_type is_allocator_aware; typedef std::true_type is_pointer_aware; + + typedef std::true_type has_erase; + typedef std::true_type has_insert; + typedef std::true_type has_push_pop; + typedef std::true_type has_size_type_constructor; }; - template<typename _Kp, typename _Tp> - struct traits<std::map<_Kp, _Tp> > : public traits_base + template<typename _Tp1, typename _Tp2, typename _Tp3, typename _Tp4> + struct traits<std::map<_Tp1, _Tp2, _Tp3, _Tp4>> : public traits_base { typedef std::true_type is_container; typedef std::true_type is_reversible; @@ -87,10 +108,12 @@ namespace __gnu_test typedef std::true_type is_pointer_aware; typedef std::true_type is_associative; typedef std::true_type is_mapped; + + typedef std::true_type has_insert; }; - template<typename _Kp, typename _Tp> - struct traits<std::multimap<_Kp, _Tp> > : public traits_base + template<typename _Tp1, typename _Tp2, typename _Tp3, typename _Tp4> + struct traits<std::multimap<_Tp1, _Tp2, _Tp3, _Tp4>> : public traits_base { typedef std::true_type is_container; typedef std::true_type is_reversible; @@ -100,108 +123,142 @@ namespace __gnu_test typedef std::true_type is_mapped; }; - template<typename _Tp> - struct traits<std::multiset<_Tp> > : public traits_base + template<typename _Tp1, typename _Tp2, typename _Tp3> + struct traits<std::multiset<_Tp1, _Tp2, _Tp3>> : public traits_base { typedef std::true_type is_container; typedef std::true_type is_reversible; typedef std::true_type is_allocator_aware; typedef std::true_type is_pointer_aware; typedef std::true_type is_associative; + + typedef std::true_type has_insert; }; - template<typename _Tp> - struct traits<std::priority_queue<_Tp> > : public traits_base + template<typename _Tp1, typename _Tp2> + struct traits<std::priority_queue<_Tp1, _Tp2>> : public traits_base { typedef std::true_type is_adaptor; }; - template<typename _Tp> - struct traits<std::queue<_Tp> > : public traits_base + template<typename _Tp1, typename _Tp2> + struct traits<std::queue<_Tp1, _Tp2>> : public traits_base { typedef std::true_type is_adaptor; }; - template<typename _Tp> - struct traits<std::set<_Tp> > : public traits_base + template<typename _Tp1, typename _Tp2, typename _Tp3> + struct traits<std::set<_Tp1, _Tp2, _Tp3>> : public traits_base { typedef std::true_type is_container; typedef std::true_type is_reversible; typedef std::true_type is_allocator_aware; typedef std::true_type is_pointer_aware; typedef std::true_type is_associative; + + typedef std::true_type has_insert; }; - template<typename _Tp> - struct traits<std::stack<_Tp> > : public traits_base + template<typename _Tp1, typename _Tp2> + struct traits<std::stack<_Tp1, _Tp2> > : public traits_base { typedef std::true_type is_adaptor; }; - template<typename _Kp, typename _Tp> - struct traits<std::unordered_map<_Kp, _Tp> > : public traits_base + template<typename _Tp1, typename _Tp2, typename _Tp3, + typename _Tp4, typename _Tp5> + struct traits<std::unordered_map<_Tp1, _Tp2, _Tp3, _Tp4, _Tp5>> + : public traits_base { typedef std::true_type is_container; typedef std::true_type is_allocator_aware; typedef std::true_type is_pointer_aware; typedef std::true_type is_unordered; typedef std::true_type is_mapped; + + typedef std::true_type has_size_type_constructor; + typedef std::true_type has_insert; }; - template<typename _Kp, typename _Tp> - struct traits<std::unordered_multimap<_Kp, _Tp> > : public traits_base + template<typename _Tp1, typename _Tp2, typename _Tp3, + typename _Tp4, typename _Tp5> + struct traits<std::unordered_multimap<_Tp1, _Tp2, _Tp3, _Tp4, _Tp5>> + : public traits_base { typedef std::true_type is_container; typedef std::true_type is_allocator_aware; typedef std::true_type is_pointer_aware; typedef std::true_type is_unordered; typedef std::true_type is_mapped; + + typedef std::true_type has_size_type_constructor; }; - template<typename _Tp> - struct traits<std::unordered_multiset<_Tp> > : public traits_base + template<typename _Tp1, typename _Tp2, typename _Tp3, typename _Tp4> + struct traits<std::unordered_multiset<_Tp1, _Tp2, _Tp3, _Tp4>> + : public traits_base { typedef std::true_type is_container; typedef std::true_type is_allocator_aware; typedef std::true_type is_pointer_aware; typedef std::true_type is_unordered; + + typedef std::true_type has_insert; }; - template<typename _Tp> - struct traits<std::unordered_set<_Tp> > : public traits_base + template<typename _Tp1, typename _Tp2, typename _Tp3, typename _Tp4> + struct traits<std::unordered_set<_Tp1, _Tp2, _Tp3, _Tp4>> + : public traits_base { typedef std::true_type is_container; typedef std::true_type is_allocator_aware; typedef std::true_type is_pointer_aware; typedef std::true_type is_unordered; + + typedef std::true_type has_size_type_constructor; + typedef std::true_type has_insert; }; - template<typename _Tp> - struct traits<std::vector<_Tp> > : public traits_base + template<typename _Tp1, typename _Tp2> + struct traits<std::vector<_Tp1, _Tp2>> : public traits_base { typedef std::true_type is_container; typedef std::true_type is_reversible; typedef std::true_type is_allocator_aware; typedef std::true_type is_pointer_aware; + + typedef std::true_type has_erase; + typedef std::true_type has_insert; + typedef std::true_type has_size_type_constructor; }; - template<typename _Tp> - struct traits<std::basic_string<_Tp> > : public traits_base + template<typename _Tp1, typename _Tp2, typename _Tp3> + struct traits<std::basic_string<_Tp1, _Tp2, _Tp3>> : public traits_base { typedef std::true_type is_container; typedef std::true_type is_reversible; typedef std::true_type is_allocator_aware; typedef std::true_type is_pointer_aware; + + typedef std::true_type has_erase; + typedef std::true_type has_insert; }; - template<typename _Tp> - struct traits<__gnu_cxx::__versa_string<_Tp> > : public traits_base + template<typename _Tp1, typename _Tp2, typename _Tp3, + template <typename, typename, typename> class _Tp4> + struct traits<__gnu_cxx::__versa_string<_Tp1, _Tp2, _Tp3, _Tp4>> + : public traits_base { typedef std::true_type is_container; typedef std::true_type is_reversible; typedef std::true_type is_allocator_aware; typedef std::true_type is_pointer_aware; + + typedef std::true_type has_erase; + + // XXX no vstring<rc>::insert + // typedef std::true_type has_insert; }; } // namespace __gnu_test -#endif +#endif |