diff options
Diffstat (limited to 'libstdc++-v3')
194 files changed, 6279 insertions, 3907 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 7f8cae5fb99..0957953de2f 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,584 @@ +2013-10-20 Tim Shen <timshen91@gmail.com> + + * include/bits/regex.h: Remove virtual class _Automaton. + * include/bits/regex_automaton.h: Likewise. + * include/bits/regex.tcc: Adjust comment for policy changing. + * include/bits/regex_executor.h: Update comments of complexity. + * include/bits/regex_executor.tcc: Adjust executor choosing + policy. Now DFS executor is the default one. + * testsuite/util/testsuite_regex.h (regex_match_debug, + regex_search_debug): Adjust for policy changing. + +2013-10-20 Chris Jefferson <chris@bubblescope.net> + Paolo Carlini <paolo.carlini@oracle.com> + + PR libstdc++/58800 + * include/bits/stl_algo.h (__unguarded_partition_pivot): Change + __last - 2 to __last - 1. + * testsuite/25_algorithms/nth_element/58800.cc: New + +2013-10-18 Edward Smith-Rowland <3dw4rd@verizon.net> + + PR libstdc++/58729 + * include/tr2/dynamic_bitset (_M_resize, resize): Use input value + to set bits; (_M_do_left_shift, _M_do_right_shift, _M_do_to_ulong, + _M_do_to_ullong, _M_do_find_first, _M_do_find_next, _M_copy_from_ptr, + operator>>): Move long methods outline to... + * include/tr2/dynamic_bitset.tcc: New. + * include/Makefile.am: Add dynamic_bitset.tcc. + * include/Makefile.in: Add dynamic_bitset.tcc. + * testsuite/tr2/dynamic_bitset/pr58729.cc: New. + +2013-10-18 Tim Shen <timshen91@gmail.com> + + * include/bits/regex_scanner.tcc: (_Scanner<>::_M_scan_normal, + _Scanner<>::_M_eat_escape_ecma, _Scanner<>::_M_eat_escape_posix, + _Scanner<>::_M_eat_escape_awk): Narrow character before finding in maps. + * testsuite/28_regex/algorithms/regex_match/ecma/wchar_t/cjk_match.cc: + New. + +2013-10-17 Tim Shen <timshen91@gmail.com> + + * include/bits/regex.h (regex_token_iterator<>::regex_token_iterator): + Fix initialization orders in initialization list and add explicit braces + for potentially ambiguous(actually not) `else` branch to eliminate + warnings. + * include/bits/regex_automaton.h (_NFA<>::_NFA): Likewise. + * include/bits/regex_compiler.h (_CharMatcher<>::_CharMatcher, + _BracketMatcher<>::_BracketMatcher): Likewise. + * include/bits/regex_compiler.tcc (_Compiler<>::_Compiler, + _Compiler<>::_M_atom): Likewise. + * include/bits/regex_executor.h (_Executor<>::_Executor): Likewise. + * include/bits/regex_executor.tcc (_DFSExecutor<>::_M_dfs, + _Executor<>::_M_word_boundry): Likewise. + * include/bits/regex_scanner.tcc (_Scanner<>::_Scanner, + _Scanner<>::_M_eat_class): Likewise. + * include/bits/regex.tcc (__regex_algo_impl<>, + regex_iterator<>::operator++): Likewise, and remove unused typedef. + +2013-10-16 Tim Shen <timshen91@gmail.com> + + * include/bits/regex.h (regex_token_iterator<>::regex_token_iterator): + Add initialization for _M_has_m1. + * include/bits/regex.tcc (regex_token_iterator<>::operator=): Add return + statment. + +2013-10-15 Diego Novillo <dnovillo@google.com> + + * testsuite/20_util/exchange/1.cc: Add missing function + bodies. + +2013-10-15 Tim Shen <timshen91@gmail.com> + + PR libstdc++/58737 + * include/bits/regex_automaton.h (_Automaton<>::~_Automaton): Fix memory + leak by adding it. + * include/bits/regex_executor.h (_Executor<>::~_Executor): Likewise. + +2013-10-11 H.J. Lu <hongjiu.lu@intel.com> + + * config/abi/post/x86_64-linux-gnu/x32/baseline_symbols.txt: Update. + +2013-10-10 Marcus Shawcroft <marcus.shawcroft@arm.com> + + * testsuite/29_atomics/atomic/cons/49445.cc + (dg-require-atomic-builtins): Add. + +2013-10-09 Jonathan Wakely <jwakely.gcc@gmail.com> + + * testsuite/20_util/shared_ptr/cons/58659.cc: Use VERIFY instead of + aborting. + +2013-10-09 Marcus Shawcroft <marcus.shawcroft@arm.com> + + * testsuite/20_util/shared_ptr/cons/58659.cc: Use __builtin_abort(). + +2013-10-08 Jonathan Wakely <jwakely.gcc@gmail.com> + + * testsuite/*: Remove stray semi-colons after function definitions. + +2013-10-08 Jonathan Wakely <jwakely.gcc@gmail.com> + + PR libstdc++/58659 + * include/bits/shared_ptr_base.h (__shared_count::__shared_count(P,D)): + Delegate to constructor taking allocator. + (__shared_count::_S_create_from_up): Inline into ... + (__shared_count::__shared_count(unique_ptr<Y,D>&&): Here. Use + std::conditional instead of constrained overloads. Allocate memory + using the allocator type that will be used for deallocation. + * testsuite/20_util/shared_ptr/cons/58659.cc: New. + * testsuite/20_util/shared_ptr/cons/43820_neg.cc: Adjust. + +2013-10-08 Tim Shen <timshen91@gmail.com> + + * include/bits/regex_executor.h: Add _TodoList class. + * include/bits/regex_executor.tcc (_BFSExecutor<>::_M_main): Add + _M_match_stack and _M_stack to make everything faster. Break if + _M_stack is empty, to reduce unnecessary idling. + * testsuite/performance/28_regex/split.cc: New. + +2013-10-06 Tim Shen <timshen91@gmail.com> + + * include/bits/regex.h: (regex_token_iterator<>::regex_token_iterator): + Fix compile error. + * include/bits/regex.tcc: (regex_replace<>): Remove default parameter. + +2013-10-06 Tim Shen <timshen91@gmail.com> + + * include/bits/regex.h (__regex_algo_impl<>, regex_match<>, + regex_search<>): New abstract function for regex_match and regex_search. + * include/bits/regex.tcc (__regex_algo_impl<>): Implement. + * include/bits/regex_executor.h + (_Executor<>::_M_lookahead, + _DFSExecutor<>::_M_clone, + _BFSExecutor<>::_M_clone): Let _M_clone to choose which executor to + use. + * include/bits/regex_executor.tcc (__get_executor<>): Update the + definition to support __policy. + * testsuite/28_regex/algorithms/regex_match/awk/cstring_01.cc: Use + *_debug. + * testsuite/28_regex/algorithms/regex_match/basic/empty_range.cc: Same. + * testsuite/28_regex/algorithms/regex_match/basic/string_01.cc: Same. + * testsuite/28_regex/algorithms/regex_match/basic/string_range_00_03.cc: + Same. + * testsuite/28_regex/algorithms/regex_match/basic/string_range_01_03.cc: + Same. + * testsuite/28_regex/algorithms/regex_match/basic/string_range_02_03.cc: + Same. + * testsuite/28_regex/algorithms/regex_match/ecma/char/53622.cc: Same. + * testsuite/28_regex/algorithms/regex_match/ecma/char/57173.cc: Same. + * testsuite/28_regex/algorithms/regex_match/ecma/char/58576.cc: Same. + * testsuite/28_regex/algorithms/regex_match/ecma/char/anymatcher.cc: + Same. + * testsuite/28_regex/algorithms/regex_match/ecma/char/backref.cc: Same. + * testsuite/28_regex/algorithms/regex_match/ecma/char/empty_range.cc: + Same. + * testsuite/28_regex/algorithms/regex_match/ecma/char/emptygroup.cc: + Same. + * testsuite/28_regex/algorithms/regex_match/ecma/char/hex.cc: Same. + * testsuite/28_regex/algorithms/regex_match/ecma/char/quoted_char.cc: + Same. + * testsuite/28_regex/algorithms/regex_match/ecma/wchar_t/anymatcher.cc: + Same. + * testsuite/28_regex/algorithms/regex_match/ecma/wchar_t/hex.cc: Same. + * testsuite/28_regex/algorithms/regex_match/extended/ + string_bracket_01.cc: Same. + * testsuite/28_regex/algorithms/regex_match/extended/cstring_plus.cc: + Same. + * testsuite/28_regex/algorithms/regex_match/extended/ + string_questionmark.cc: Same. + * testsuite/28_regex/algorithms/regex_match/extended/cstring_range.cc: + Same. + * testsuite/28_regex/algorithms/regex_match/extended/string_any.cc: + Same. + * testsuite/28_regex/algorithms/regex_match/extended/ + string_dispatch_01.cc: Same. + * testsuite/28_regex/algorithms/regex_match/extended/ + string_range_00_03.cc: Same. + * testsuite/28_regex/algorithms/regex_match/extended/ + string_range_01_03.cc: Same. + * testsuite/28_regex/algorithms/regex_match/extended/ + string_range_02_03.cc: Same. + * testsuite/28_regex/algorithms/regex_match/extended/wstring_locale.cc: + Same. + * testsuite/28_regex/algorithms/regex_search/basic/string_01.cc: Same. + * testsuite/28_regex/algorithms/regex_search/ecma/assertion.cc: Same. + * testsuite/28_regex/algorithms/regex_search/ecma/flags.cc: Same. + * testsuite/28_regex/algorithms/regex_search/ecma/greedy.cc: Same. + * testsuite/28_regex/algorithms/regex_search/ecma/string_01.cc: Same. + * testsuite/28_regex/match_results/format.cc: Same. + * testsuite/util/testsuite_regex.h + (regex_match_debug<>, regex_search_debug<>): Implement. + +2013-10-06 Oleg Endo <olegendo@gcc.gnu.org> + Paolo Carlini <paolo.carlini@oracle.com> + + PR libstdc++/58625 + * include/c_global/cmath (signbit): Use __builtin_signbitf and + __builtin_signbitl. + +2013-10-03 Tim Shen <timshen91@gmail.com> + + * include/bits/regex_executor.tcc (_DFSExecutor<>::_M_dfs): Fix wrong + backup variable initialization. + +2013-10-03 John Woolverton <jdwoolverton@gmail.com> + + PR libstdc++/58604 + * include/std/vector: Fix garbled line in HP Copyright. + +2013-10-03 Marc Glisse <marc.glisse@inria.fr> + + * libsupc++/del_op.cc (operator delete): Don't test for 0 before free. + * libsupc++/del_opnt.cc (free): Only declare if freestanding. + (operator delete): Qualify free with std::. + +2013-10-02 Jonathan Wakely <jwakely.gcc@gmail.com> + Daniel Krugler <daniel.kruegler@gmail.com> + + PR libstdc++/58569 + * include/std/functional (function::_CheckResult): Move to namespace + scope and rename to __check_func_return_type. + * testsuite/20_util/function/58569.cc: New. + +2013-10-02 Jonathan Wakely <jwakely.gcc@gmail.com> + + PR libstdc++/58594 + * include/bits/shared_ptr_base.h + (_Sp_counted_ptr_inplace::_M_get_deleter()): Cast away cv-quals. + * testsuite/20_util/shared_ptr/creation/58594.cc: New. + +2013-10-02 Tim Shen <timshen91@gmail.com> + + * include/bits/regex_compiler.h + (_BracketMatcher<>::_M_add_equivalence_class): Implement it correctly. + * include/bits/regex_compiler.tcc (_BracketMatcher<>::operator()): + Add _M_equiv_set support. + * testsuite/28_regex/algorithms/regex_match/extended/ + cstring_bracket_01.cc: Add new "[[=a=]]" testcase. + +2013-10-01 Tim Shen <timshen91@gmail.com> + + * doc/xml/manual/status_cxx2011.xml: Change "is not implemented" to + "is not correctly implemented". + +2013-10-01 Tim Shen <timshen91@gmail.com> + + * doc/xml/manual/status_cxx2011.xml: Update regex status. + * include/bits/regex.h (match_results<>::begin, + match_results<>::cbegin, match_results<>::end, match_results<>::cend): + [28.10.3.13], [28.10.3.14] Always iterate the range [0, size()-2). + +2013-10-01 François Dumont <fdumont@gcc.gnu.org> + + * include/parallel/algobase.h (mismatch, equal): Provide parallel + version for N3671 overloads. + +2013-10-01 Paul Pluzhnikov <ppluzhnikov@google.com> + + * src/c++11/snprintf_lite.cc: Add missing + _GLIBCXX_{BEGIN,END}_NAMESPACE_VERSION + +2013-10-01 Joern Rennecke <joern.rennecke@embecosm.com> + + * acinclude.m4 (GLIBCXX_ENABLE_SJLJ_EXCEPTIONS): Also check for + _Unwind_SjLj_Register when deciding if to set enable_sjlj_exceptions. + * configure: Regenerate. + +2013-10-01 Tim Shen <timshen91@gmail.com> + + PR libstdc++/58576 + * include/bits/regex_automaton.tcc (_NFA<>::_M_eliminate_dummy) + (_StateSeq<>::_M_clone): Add _S_opcode_subexpr_lookahead branch. + * testsuite/28_regex/algorithms/regex_match/ecma/char/58576.cc: New. + +2013-09-30 Paolo Carlini <paolo.carlini@oracle.com> + + * include/parallel/algo.h (__find_switch): Use __binder2nd. + +2013-09-30 Chris Jefferson <chris@bubblescope.net> + + PR libstdc++/58437 + * include/bits/stl_algo.h (__move_median_first): Rename to + __move_median_to_first, change to take an addition argument. + (__unguarded_partition_pivot): Adjust. + * testsuite/performance/25_algorithms/sort.cc: New. + * testsuite/performance/25_algorithms/sort_heap.cc: Likewise. + * testsuite/performance/25_algorithms/stable_sort.cc: Likewise. + +2013-09-28 François Dumont <fdumont@gcc.gnu.org> + + * include/bits/stl_algo.h (remove_copy, remove_copy_if): Declare + inline. + (rotate_copy, stable_partition, partial_sort_copy): Likewise. + (lower_bound, upper_bound, equal_range, inplace_merge): Likewise. + (includes, next_permutation, prev_permutation): Likewise. + (replace_copy, replace_copy_if, is_sorted_until): Likewise. + (minmax_element, is_permutation, adjacent_find): Likewise. + (count, count_if, search, search_n, merge): Likewise. + (set_intersection, set_difference): Likewise. + (set_symmetric_difference, min_element, max_element): Likewise. + * include/bits/stl_algobase.h (lower_bound): Likewise. + (lexicographical_compare, mismatch): Likewise. + +2013-09-28 Tim Shen <timshen91@gmail.com> + + * include/bits/regex_scanner.tcc (_Scanner<>::_M_eat_escape_posix): + Let ordinary char escaping in POSIX be valid. + * testsuite/28_regex/basic_regex/ctors/basic/raw_string.cc: Test this + change. + +2013-09-27 François Dumont <fdumont@gcc.gnu.org> + + * include/bits/predefined_ops.h: New. + * include/bits/stl_heap.h: Include <bits/predefined_ops.h>. + (__is_heap_until, __push_heap, __adjust_heap, __pop_heap): Remove + algo duplication. + (__is_heap): Adapt. + (__make_heap): New. + (make_heap): Adapt to use latter. + (__sort_heap): New. + (sort_heap): Adapt to use latter. + * include/bits/algobase.h: Include <bits/predefined_ops.h>. + (__lexicographical_compare_impl): New. + (__lexicographical_compare<false>::__lc): Adapt to use latter. + (lexicographical_compare): Likewise. + (__lower_bound): New. + (lower_bound): Adapt to use latter. + (equal): Use _GLIBCXX_STD_A::equal in N3671 overloads. + (__mismatch): New. + (mismatch): Use latter. + * include/bits/algo.h: Include <bits/predefined_ops.h>. Remove + <functional> include. + (__move_median_first, __find, __find_if, __find_if_not): Remove + algo duplication. + (__find_end): Likewise. + (__search_n): Rename into ... + (__search_n_aux): ... this. + (__search_n): Renew, use latter. + (search_n): Use latter. + (__search): New. + (search): Use latter. + (__find_end): Likewise. + (__remove_copy_if): New. + (remove_copy): Use latter. + (__adjacent_find): New. + (adjacent_find): Use latter. + (__unique): New. + (unique): Use latter. + (__unique_copy): Remove algo duplication. + (__stable_partition): New. + (stable_partition): Use latter. + (__heap_select): Remove algo duplication, use __make_heap. + (__partial_sort): New, use latter. + (partial_sort): Use latter. + (__partial_sort_copy): New. + (partial_sort_copy): Use latter. + (__unguarded_linear_insert, __insertion_sort): Remove algo + duplication. + (__unguarded_insertion_sort, __final_insertion_sort): Likewise. + (__unguarded_partition, __unguarded_partition_pivot): Likewise. + (__partial_sort): New. + (partial_sort): Use latter. + (__sort): New. + (sort): Use latter. + (lower_bound): Use __lower_bound. + (__upper_bound): New. + (upper_bound): Use latter. + (__equal_range): New. + (equal_range): Use latter. + (__move_merge_adaptive, __move_merge_adaptive_backward): Remove + algo duplication. + (__merge_adaptive, __merge_without_buffer): Likewise. + (__inplace_merge): New. + (inplace_merge): Use latter. + (__move_merge, __merge_sort_loop, __chunk_insertion_sort): Remove + algo duplication. + (__merge_sort_with_buffer, __stable_sort_adaptive): Likewise. + (__inplace_stable_sort): Likewise. + (__include): New. + (includes): Use latter. + (__next_permutation): New. + (next_permutation): Use latter. + (__prev_permutation): New. + (prev_permutation): Use latter. + (__replace_copy_if): New. + (replace_copy): Use latter. + (__is_sorted_until): New. + (is_sorted_unitl): Use latter. + (__minmax_element): New. + (minmax_element): Use latter. + (__is_permutation): New. + (is_permutation): Use latter. + (__adjacent_find): New. + (adjacent_find): Use latter. + (__count_if): New. + (count): Use latter. + (count_if): Likewise. + (__merge): New. + (merge): Use latter. + (__stable_sort): New. + (stable_sort): Use latter. + (__set_union): New. + (set_union): Use latter. + (__set_intersection): New. + (set_intersection): Use latter. + (__set_difference): New. + (set_difference): Use latter. + (__set_symmetric_difference): New. + (set_symmetric_difference): Use latter. + (__min_element): New. + (min_element): Use latter. + (__max_element): New. + (max_element): Use latter. + * include/Makefile.am: Add predefined_ops.h. + * include/Makefile.in: Regenerate. + * include/parallel/algobase.h (equal, mismatch): Add overloads + from N3671. + * testsuite/25_algorithms/is_permutation/vectorbool.cc: New. + * testsuite/25_algorithms/adjacent_find/vectorbool.cc: Likewise. + * testsuite/25_algorithms/find/vectorbool.cc: Likewise. + * testsuite/25_algorithms/find_if/vectorbool.cc: Likewise. + * testsuite/25_algorithms/find_first_of/vectorbool.cc: Likewise. + * testsuite/25_algorithms/heap/vectorbool.cc: Likewise. + * testsuite/25_algorithms/find_end/vectorbool.cc: Likewise. + * testsuite/25_algorithms/find_if_not/vectorbool.cc: Likewise. + +2013-09-27 Jonathan Wakely <jwakely.gcc@gmail.com> + + PR libstdc++/57465 + * include/std/functional + (_Function_base::_Base_manager::_M_not_empty_function): Fix overload + for pointers. + * testsuite/20_util/function/cons/57465.cc: New. + +2013-09-26 Tim Shen <timshen91@gmail.com> + + * regex_error.h: Remove _S_error_last to follow the standard. + * regex_scanner.tcc: + (_Scanner<_FwdIter>::_M_scan_in_brace): Change error_brace to + error_badbrace. + (_Scanner<>::_M_eat_escape_posix): Extended doesn't support + back-reference. + * testsuite/28_regex/algorithms/regex_match/ecma/char/53622.cc: + Move here from ../../extended. + * testsuite/28_regex/algorithms/regex_match/ecma/char/57173.cc: + Likewise. + +2013-09-25 Marc Glisse <marc.glisse@inria.fr> + + PR libstdc++/58338 + * include/bits/forward_list.h (_Fwd_list_node_base::_M_transfer_after): + Mark as noexcept. + (_Fwd_list_iterator) [_Fwd_list_iterator, operator*, operator->, + operator++, operator==, operator!=, _M_next]: Likewise. + (_Fwd_list_const_iterator) [_Fwd_list_const_iterator, operator*, + operator->, operator++, operator==, operator!=, _M_next]: Likewise. + (operator==(const _Fwd_list_iterator&, const _Fwd_list_const_iterator&), + operator!=(const _Fwd_list_iterator&, const _Fwd_list_const_iterator&)): + Likewise. + * include/bits/hashtable_policy.h (_Hash_node_base::_Hash_node_base, + _Hash_node::_M_next, _Node_iterator_base::_Node_iterator_base, + _Node_iterator_base::_M_incr, operator==(const _Node_iterator_base&, + const _Node_iterator_base&), operator!=(const _Node_iterator_base&, + const _Node_iterator_base&)): Likewise. + (_Node_iterator) [_Node_iterator, operator*, operator->, operator++]: + Likewise. + (_Node_const_iterator) [_Node_const_iterator, operator*, operator->, + operator++]: Likewise. + * include/debug/safe_iterator.h (_Safe_iterator) [_Safe_iterator, + operator=, operator*, operator->, operator++, operator--, operator[], + operator+=, operator+, operator-=, operator-, base, operator _Iterator]: + Likewise. + (operator==(const _Safe_iterator&, const _Safe_iterator&), + operator!=(const _Safe_iterator&, const _Safe_iterator&), + operator<(const _Safe_iterator&, const _Safe_iterator&), + operator<=(const _Safe_iterator&, const _Safe_iterator&), + operator>(const _Safe_iterator&, const _Safe_iterator&), + operator>=(const _Safe_iterator&, const _Safe_iterator&), + operator-(const _Safe_iterator&, const _Safe_iterator&), + operator+(difference_type, const _Safe_iterator&)): Likewise. + * include/profile/iterator_tracker.h (__iterator_tracker) + [__iterator_tracker, base, operator _Iterator, operator->, operator++, + operator--, operator=, operator*, operator[], operator+=, operator+, + operator-=, operator-]: Likewise. + (operator==(const __iterator_tracker&, const __iterator_tracker&), + operator!=(const __iterator_tracker&, const __iterator_tracker&), + operator<(const __iterator_tracker&, const __iterator_tracker&), + operator<=(const __iterator_tracker&, const __iterator_tracker&), + operator>(const __iterator_tracker&, const __iterator_tracker&), + operator>=(const __iterator_tracker&, const __iterator_tracker&), + operator-(const __iterator_tracker&, const __iterator_tracker&), + operator+(difference_type, const __iterator_tracker&)): Likewise. + +2013-09-24 Marc Glisse <marc.glisse@inria.fr> + + PR libstdc++/58338 + PR libstdc++/56166 + * include/bits/basic_string.h (basic_string) + [basic_string(basic_string&&)]: Make the noexcept conditional. + [operator=(basic_string&&), assign(basic_string&&)]: Link to PR 58265. + [begin(), end(), rbegin(), rend(), clear]: Remove noexcept. + [pop_back]: Comment on the lack of noexcept. + * include/debug/string (basic_string) [basic_string(const _Allocator&), + basic_string(basic_string&&), begin(), end(), rbegin(), rend(), clear, + operator[](size_type), pop_back]: Comment out noexcept, until vstring + replaces basic_string. + +2013-09-24 Tim Shen <timshen91@gmail.com> + + * include/Makefile.am: Add regex.tcc. + * include/Makefile.in: Regenerate. + * include/bits/regex.h: Remove definitions to regex.tcc. + * include/bits/regex.tcc: New. + (match_results::format, regex_replace): Implement; + * include/bits/regex_compiler.h: Move _M_flags to the top of class + member list, because other members' initialization depend on it. + * include/bits/regex_compiler.tcc + (_Compiler<>::_Compiler): Adjust member initializations. + (_Compiler<>::_M_quantifier): Fix ungreedy interval quantifier. + * include/bits/regex_executor.h: Remove _RegexT from _*Executor classes. + In the future, all regex classes may refactor to *Impl style. + * include/bits/regex_executor.tcc (_Executor::_M_set_results): + Merge identical code from _*Executor classes. + * testsuite/28_regex/algorithms/regex_match/extended/ + string_dispatch_01.cc (fake_match<>): Adjust the hacking-style testcase + caller for new __get_executors interface. + * testsuite/28_regex/algorithms/regex_replace/char/basic_replace.cc: + New. + * testsuite/28_regex/match_results/format.cc: New. + * testsuite/28_regex/traits/char/lookup_collatename.cc: Remove digraph + testcase. + * testsuite/28_regex/traits/wchar_t/lookup_collatename.cc: Likewise. + +2013-09-23 Paul Pluzhnikov <ppluzhnikov@google.com> + + * src/c++11/snprintf_lite.cc (__concat_size_t): Use + unsigned long long conditionally. + +2013-09-23 Paul Pluzhnikov <ppluzhnikov@google.com> + + * src/c++11/snprintf_lite.cc (__concat_size_t): Use only + std::__int_to_char<unsigned long long>() + +2013-09-21 Paul Pluzhnikov <ppluzhnikov@google.com> + + * include/bits/functexcept.h (__throw_out_of_range_fmt): New. + * src/c++11/functexcept.cc (__throw_out_of_range_fmt): New. + * src/c++11/snprintf_lite.cc: New. + * src/c++11/Makefile.am: Add snprintf_lite.cc. + * src/c++11/Makefile.in: Regenerate. + * config/abi/pre/gnu.ver: Add _ZSt24__throw_out_of_range_fmtPKcz. + * include/std/array (at): Use __throw_out_of_range_fmt. + * include/debug/array (at): Likewise. + * include/profile/array (at): Likewise. + * include/std/bitset (_M_check_initial_position, _M_check): New. + (bitset::bitset): Use _M_check_initial_position. + (set, reset, flip, test): Use _M_check. + * include/ext/vstring.h (_M_check, at): Use __throw_out_of_range_fmt. + * include/bits/stl_vector.h (_M_range_check): Likewise. + * include/bits/stl_bvector.h (_M_range_check): Likewise. + * include/bits/stl_deque.h (_M_range_check): Likewise. + * include/bits/basic_string.h (_M_check, at): Likewise. + * testsuite/23_containers/vector/requirements/dr438/assign_neg.cc: Adjust. + * testsuite/23_containers/vector/requirements/dr438/insert_neg.cc: Likewise. + * testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc: + Likewise. + * testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc: + Likewise. + * testsuite/23_containers/deque/requirements/dr438/assign_neg.cc: Likewise. + * 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. + * testsuite/23_containers/array/tuple_interface/tuple_element_neg.cc: Likewise. + * testsuite/23_containers/array/tuple_interface/tuple_element_debug_neg.cc: + Likewise. + * testsuite/23_containers/array/tuple_interface/get_neg.cc: Likewise. + * testsuite/23_containers/array/tuple_interface/get_debug_neg.cc: Likewise. + * testsuite/util/exception/safety.h (generate): Use __throw_out_of_range_fmt. + 2013-09-20 Jakub Jelinek <jakub@redhat.com> PR testsuite/57605 @@ -314,23 +895,23 @@ * regex_automaton.h: Rearrange _NFA's layout. * include/bits/regex_compiler.h: Add _AnyMatcher and _CharMatcher. - Rearrange _BracketMatcher's layout. - (_BracketMatcher<>::_M_add_char): Use set instead of vector for - _M_char_set. - (_BracketMatcher<>::_M_add_collating_element): Likewise. - (_BracketMatcher<>::_M_make_range): Likewise. + Rearrange _BracketMatcher's layout. + (_BracketMatcher<>::_M_add_char): Use set instead of vector for + _M_char_set. + (_BracketMatcher<>::_M_add_collating_element): Likewise. + (_BracketMatcher<>::_M_make_range): Likewise. * include/bits/regex_compiler.tcc (_Compiler<>::_M_atom): Use - apropriate constructors of matchers above. + appropriate constructors of matchers above. * testsuite/28_regex/algorithms/regex_match/ecma/char/anymatcher.cc: - New. + New. * testsuite/28_regex/algorithms/regex_match/ecma/char/backref.cc: New. * testsuite/28_regex/algorithms/regex_match/ecma/char/empty_range.cc: - New. + New. * testsuite/28_regex/algorithms/regex_match/ecma/char/emptygroup.cc: - New. + New. * testsuite/28_regex/algorithms/regex_match/ecma/char/hex.cc: New. * testsuite/28_regex/algorithms/regex_match/ecma/wchar_t/anymatcher.cc: - New. + New. * testsuite/28_regex/algorithms/regex_match/ecma/wchar_t/hex.cc: New. 2013-08-30 François Dumont <fdumont@gcc.gnu.org> @@ -363,33 +944,33 @@ 2013-08-29 Tim Shen <timshen91@gmail.com> * include/bits/regex.h (basic_regex<>::assign): Don't lose _M_traits. - (regex_iterator<>::regex_iterator): Return nullptr when regex_search - failed. - (regex_token_iterator<>::_M_end_of_seq): Should be defined true when - _M_result is(not isn't) nullptr. + (regex_iterator<>::regex_iterator): Return nullptr when regex_search + failed. + (regex_token_iterator<>::_M_end_of_seq): Should be defined true when + _M_result is(not isn't) nullptr. * include/bits/regex_compiler.h: Store _Compiler::_M_traits by reference - instead of by value. + instead of by value. * include/bits/regex_executor.h (_DFSExecutor<>::_DFSExecutor): Add - _M_traits to _DFSExecutor. + _M_traits to _DFSExecutor. * include/bits/regex_executor.tcc (__get_executor<>): Pass traits to - _DFSExecutor too. + _DFSExecutor too. * testsuite/28_regex/algorithms/regex_match/extended/wstring_locale.cc: - New. + New. * testsuite/28_regex/iterators/regex_token_iterator/wchar_t/ - wstring_02.cc: New. + wstring_02.cc: New. 2013-08-26 Tim Shen <timshen91@gmail.com> * include/Makefile.am: Add regex_scanner.{h,tcc}. * include/Makefile.in: Regenerate. * include/bits/regex.h (match_search): Handle the `__first == __last` - situation correctly. + situation correctly. * include/bits/regex_compiler.h: Move _Scanner... * include/bits/regex_scanner.h: ...to here. New. * include/bits/regex_compiler.tcc: Move _Scanner... * include/bits/regex_scanner.tcc: ...to here, too. New. * include/bits/regex_executor.tcc: Use value instead of reference for - submatch. + submatch. * include/std/regex: Add regex_scanner.h * testsuite/28_regex/algorithms/regex_match/awk/cstring_01.cc: New. * testsuite/28_regex/algorithms/regex_match/basic/empty_range.cc: New. diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4 index 72b90a80252..f9d12d0cd31 100644 --- a/libstdc++-v3/acinclude.m4 +++ b/libstdc++-v3/acinclude.m4 @@ -3139,6 +3139,8 @@ EOF if AC_TRY_EVAL(ac_compile); then if grep _Unwind_SjLj_Resume conftest.s >/dev/null 2>&1 ; then enable_sjlj_exceptions=yes + elif grep _Unwind_SjLj_Register conftest.s >/dev/null 2>&1 ; then + enable_sjlj_exceptions=yes elif grep _Unwind_Resume conftest.s >/dev/null 2>&1 ; then enable_sjlj_exceptions=no elif grep __cxa_end_cleanup conftest.s >/dev/null 2>&1 ; then diff --git a/libstdc++-v3/config/abi/post/x86_64-linux-gnu/x32/baseline_symbols.txt b/libstdc++-v3/config/abi/post/x86_64-linux-gnu/x32/baseline_symbols.txt index 551e738a57c..2c822bf943a 100644 --- a/libstdc++-v3/config/abi/post/x86_64-linux-gnu/x32/baseline_symbols.txt +++ b/libstdc++-v3/config/abi/post/x86_64-linux-gnu/x32/baseline_symbols.txt @@ -403,6 +403,7 @@ FUNC:_ZNKSt15basic_streambufIwSt11char_traitsIwEE5pbaseEv@@GLIBCXX_3.4 FUNC:_ZNKSt15basic_streambufIwSt11char_traitsIwEE6getlocEv@@GLIBCXX_3.4 FUNC:_ZNKSt15basic_stringbufIcSt11char_traitsIcESaIcEE3strEv@@GLIBCXX_3.4 FUNC:_ZNKSt15basic_stringbufIwSt11char_traitsIwESaIwEE3strEv@@GLIBCXX_3.4 +FUNC:_ZNKSt17bad_function_call4whatEv@@GLIBCXX_3.4.18 FUNC:_ZNKSt18basic_stringstreamIcSt11char_traitsIcESaIcEE3strEv@@GLIBCXX_3.4 FUNC:_ZNKSt18basic_stringstreamIcSt11char_traitsIcESaIcEE5rdbufEv@@GLIBCXX_3.4 FUNC:_ZNKSt18basic_stringstreamIwSt11char_traitsIwESaIwEE3strEv@@GLIBCXX_3.4 @@ -590,6 +591,8 @@ FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE6do_putES3_RSt FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE6do_putES3_RSt8ios_basewm@@GLIBCXX_3.4 FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE6do_putES3_RSt8ios_basewx@@GLIBCXX_3.4 FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE6do_putES3_RSt8ios_basewy@@GLIBCXX_3.4 +FUNC:_ZNKSt8__detail20_Prime_rehash_policy11_M_next_bktEj@@GLIBCXX_3.4.18 +FUNC:_ZNKSt8__detail20_Prime_rehash_policy14_M_need_rehashEjjj@@GLIBCXX_3.4.18 FUNC:_ZNKSt8bad_cast4whatEv@@GLIBCXX_3.4.9 FUNC:_ZNKSt8ios_base7failure4whatEv@@GLIBCXX_3.4 FUNC:_ZNKSt8messagesIcE18_M_convert_to_charERKSs@@GLIBCXX_3.4 @@ -1207,6 +1210,7 @@ FUNC:_ZNSt11range_errorD2Ev@@GLIBCXX_3.4.15 FUNC:_ZNSt11regex_errorD0Ev@@GLIBCXX_3.4.15 FUNC:_ZNSt11regex_errorD1Ev@@GLIBCXX_3.4.15 FUNC:_ZNSt11regex_errorD2Ev@@GLIBCXX_3.4.15 +FUNC:_ZNSt11this_thread11__sleep_forENSt6chrono8durationIxSt5ratioILx1ELx1EEEENS1_IxS2_ILx1ELx1000000000EEEE@@GLIBCXX_3.4.18 FUNC:_ZNSt12__basic_fileIcE2fdEv@@GLIBCXX_3.4 FUNC:_ZNSt12__basic_fileIcE4fileEv@@GLIBCXX_3.4.1 FUNC:_ZNSt12__basic_fileIcE4openEPKcSt13_Ios_Openmodei@@GLIBCXX_3.4 @@ -1485,6 +1489,11 @@ FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEs@@GLIBCXX_3.4 FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEt@@GLIBCXX_3.4 FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEx@@GLIBCXX_3.4 FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEy@@GLIBCXX_3.4 +FUNC:_ZNSt13random_device14_M_init_pretr1ERKSs@@GLIBCXX_3.4.18 +FUNC:_ZNSt13random_device16_M_getval_pretr1Ev@@GLIBCXX_3.4.18 +FUNC:_ZNSt13random_device7_M_finiEv@@GLIBCXX_3.4.18 +FUNC:_ZNSt13random_device7_M_initERKSs@@GLIBCXX_3.4.18 +FUNC:_ZNSt13random_device9_M_getvalEv@@GLIBCXX_3.4.18 FUNC:_ZNSt13runtime_errorC1ERKSs@@GLIBCXX_3.4 FUNC:_ZNSt13runtime_errorC2ERKSs@@GLIBCXX_3.4 FUNC:_ZNSt13runtime_errorD0Ev@@GLIBCXX_3.4 @@ -1929,6 +1938,8 @@ FUNC:_ZNSt6__norm15_List_node_base7reverseEv@@GLIBCXX_3.4.9 FUNC:_ZNSt6__norm15_List_node_base8transferEPS0_S1_@@GLIBCXX_3.4.9 FUNC:_ZNSt6__norm15_List_node_base9_M_unhookEv@@GLIBCXX_3.4.14 FUNC:_ZNSt6chrono12system_clock3nowEv@@GLIBCXX_3.4.11 +FUNC:_ZNSt6chrono3_V212steady_clock3nowEv@@GLIBCXX_3.4.19 +FUNC:_ZNSt6chrono3_V212system_clock3nowEv@@GLIBCXX_3.4.19 FUNC:_ZNSt6gslice8_IndexerC1EjRKSt8valarrayIjES4_@@GLIBCXX_3.4 FUNC:_ZNSt6gslice8_IndexerC2EjRKSt8valarrayIjES4_@@GLIBCXX_3.4 FUNC:_ZNSt6locale11_M_coalesceERKS_S1_i@@GLIBCXX_3.4 @@ -2467,6 +2478,7 @@ FUNC:__cxa_guard_acquire@@CXXABI_1.3 FUNC:__cxa_guard_release@@CXXABI_1.3 FUNC:__cxa_pure_virtual@@CXXABI_1.3 FUNC:__cxa_rethrow@@CXXABI_1.3 +FUNC:__cxa_thread_atexit@@CXXABI_1.3.7 FUNC:__cxa_throw@@CXXABI_1.3 FUNC:__cxa_tm_cleanup@@CXXABI_TM_1 FUNC:__cxa_vec_cctor@@CXXABI_1.3 @@ -2491,6 +2503,7 @@ OBJECT:0:CXXABI_1.3.3 OBJECT:0:CXXABI_1.3.4 OBJECT:0:CXXABI_1.3.5 OBJECT:0:CXXABI_1.3.6 +OBJECT:0:CXXABI_1.3.7 OBJECT:0:CXXABI_TM_1 OBJECT:0:GLIBCXX_3.4 OBJECT:0:GLIBCXX_3.4.1 @@ -2502,6 +2515,8 @@ OBJECT:0:GLIBCXX_3.4.14 OBJECT:0:GLIBCXX_3.4.15 OBJECT:0:GLIBCXX_3.4.16 OBJECT:0:GLIBCXX_3.4.17 +OBJECT:0:GLIBCXX_3.4.18 +OBJECT:0:GLIBCXX_3.4.19 OBJECT:0:GLIBCXX_3.4.2 OBJECT:0:GLIBCXX_3.4.3 OBJECT:0:GLIBCXX_3.4.4 @@ -3033,6 +3048,8 @@ OBJECT:1:_ZNSt21__numeric_limits_base9is_iec559E@@GLIBCXX_3.4 OBJECT:1:_ZNSt21__numeric_limits_base9is_moduloE@@GLIBCXX_3.4 OBJECT:1:_ZNSt21__numeric_limits_base9is_signedE@@GLIBCXX_3.4 OBJECT:1:_ZNSt6chrono12system_clock12is_monotonicE@@GLIBCXX_3.4.11 +OBJECT:1:_ZNSt6chrono3_V212steady_clock9is_steadyE@@GLIBCXX_3.4.19 +OBJECT:1:_ZNSt6chrono3_V212system_clock9is_steadyE@@GLIBCXX_3.4.19 OBJECT:1:_ZSt10adopt_lock@@GLIBCXX_3.4.11 OBJECT:1:_ZSt10defer_lock@@GLIBCXX_3.4.11 OBJECT:1:_ZSt11try_to_lock@@GLIBCXX_3.4.11 diff --git a/libstdc++-v3/config/abi/pre/gnu.ver b/libstdc++-v3/config/abi/pre/gnu.ver index 8972fcfca88..d3c399f6bf2 100644 --- a/libstdc++-v3/config/abi/pre/gnu.ver +++ b/libstdc++-v3/config/abi/pre/gnu.ver @@ -1365,6 +1365,9 @@ GLIBCXX_3.4.20 { # std::get_unexpected() _ZSt14get_unexpectedv; + # std::__throw_out_of_range_fmt(char const*, ...) + _ZSt24__throw_out_of_range_fmtPKcz; + } GLIBCXX_3.4.19; # Symbols in the support library (libsupc++) have their own tag. diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure index e1672e068fd..c436cb98636 100755 --- a/libstdc++-v3/configure +++ b/libstdc++-v3/configure @@ -15070,6 +15070,8 @@ EOF test $ac_status = 0; }; then if grep _Unwind_SjLj_Resume conftest.s >/dev/null 2>&1 ; then enable_sjlj_exceptions=yes + elif grep _Unwind_SjLj_Register conftest.s >/dev/null 2>&1 ; then + enable_sjlj_exceptions=yes elif grep _Unwind_Resume conftest.s >/dev/null 2>&1 ; then enable_sjlj_exceptions=no elif grep __cxa_end_cleanup conftest.s >/dev/null 2>&1 ; then @@ -15402,7 +15404,7 @@ $as_echo "$glibcxx_cv_atomic_long_long" >&6; } # Fake what AC_TRY_COMPILE does. cat > conftest.$ac_ext << EOF -#line 15405 "configure" +#line 15407 "configure" int main() { typedef bool atomic_type; @@ -15437,7 +15439,7 @@ $as_echo "$glibcxx_cv_atomic_bool" >&6; } rm -f conftest* cat > conftest.$ac_ext << EOF -#line 15440 "configure" +#line 15442 "configure" int main() { typedef short atomic_type; @@ -15472,7 +15474,7 @@ $as_echo "$glibcxx_cv_atomic_short" >&6; } rm -f conftest* cat > conftest.$ac_ext << EOF -#line 15475 "configure" +#line 15477 "configure" int main() { // NB: _Atomic_word not necessarily int. @@ -15508,7 +15510,7 @@ $as_echo "$glibcxx_cv_atomic_int" >&6; } rm -f conftest* cat > conftest.$ac_ext << EOF -#line 15511 "configure" +#line 15513 "configure" int main() { typedef long long atomic_type; @@ -15587,7 +15589,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 15590 "configure" +#line 15592 "configure" int main() { _Decimal32 d1; @@ -15629,7 +15631,7 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu # unnecessary for this test. cat > conftest.$ac_ext << EOF -#line 15632 "configure" +#line 15634 "configure" template<typename T1, typename T2> struct same { typedef T2 type; }; @@ -15663,7 +15665,7 @@ $as_echo "$enable_int128" >&6; } rm -f conftest* cat > conftest.$ac_ext << EOF -#line 15666 "configure" +#line 15668 "configure" template<typename T1, typename T2> struct same { typedef T2 type; }; diff --git a/libstdc++-v3/doc/xml/manual/status_cxx2011.xml b/libstdc++-v3/doc/xml/manual/status_cxx2011.xml index 286a539ba76..5743c83f5a6 100644 --- a/libstdc++-v3/doc/xml/manual/status_cxx2011.xml +++ b/libstdc++-v3/doc/xml/manual/status_cxx2011.xml @@ -2179,31 +2179,27 @@ particular release. </entry> </row> <row> - <?dbhtml bgcolor="#C8B0B0" ?> <entry>28.1</entry> <entry>General</entry> - <entry>N</entry> + <entry>Y</entry> <entry/> </row> <row> - <?dbhtml bgcolor="#C8B0B0" ?> <entry>28.2</entry> <entry>Definitions</entry> - <entry>N</entry> + <entry>Y</entry> <entry/> </row> <row> - <?dbhtml bgcolor="#C8B0B0" ?> <entry>28.3</entry> <entry>Requirements</entry> - <entry>N</entry> + <entry>Y</entry> <entry/> </row> <row> - <?dbhtml bgcolor="#C8B0B0" ?> <entry>28.4</entry> <entry>Header <code><regex></code> synopsis</entry> - <entry>N</entry> + <entry>Y</entry> <entry/> </row> <row> @@ -2223,48 +2219,43 @@ particular release. <entry>28.7</entry> <entry>Class template <code>regex_traits</code></entry> <entry>Partial</entry> + <entry><code>transform_primary</code> is not correctly implemented</entry> <entry/> </row> <row> - <?dbhtml bgcolor="#B0B0B0" ?> <entry>28.8</entry> <entry>Class template <code>basic_regex</code></entry> - <entry>Partial</entry> + <entry>Y</entry> <entry/> </row> <row> - <?dbhtml bgcolor="#B0B0B0" ?> <entry>28.9</entry> <entry>Class template <code>sub_match</code></entry> - <entry>Partial</entry> + <entry>Y</entry> <entry/> </row> <row> - <?dbhtml bgcolor="#B0B0B0" ?> <entry>28.10</entry> <entry>Class template <code>match_results</code></entry> - <entry>Partial</entry> + <entry>Y</entry> <entry/> </row> <row> - <?dbhtml bgcolor="#C8B0B0" ?> <entry>28.11</entry> <entry>Regular expression algorithms</entry> - <entry>N</entry> + <entry>Y</entry> <entry/> </row> <row> - <?dbhtml bgcolor="#C8B0B0" ?> <entry>28.12</entry> <entry>Regular expression Iterators</entry> - <entry>N</entry> + <entry>Y</entry> <entry/> </row> <row> - <?dbhtml bgcolor="#C8B0B0" ?> <entry>28.13</entry> <entry>Modified ECMAScript regular expression grammar</entry> - <entry>N</entry> + <entry>Y</entry> <entry/> </row> <row> diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am index 0bceb5776a5..0ddc8b51419 100644 --- a/libstdc++-v3/include/Makefile.am +++ b/libstdc++-v3/include/Makefile.am @@ -121,11 +121,13 @@ bits_headers = \ ${bits_srcdir}/ostream_insert.h \ ${bits_srcdir}/parse_numbers.h \ ${bits_srcdir}/postypes.h \ + ${bits_srcdir}/predefined_ops.h \ ${bits_srcdir}/ptr_traits.h \ ${bits_srcdir}/random.h \ ${bits_srcdir}/random.tcc \ ${bits_srcdir}/range_access.h \ ${bits_srcdir}/regex.h \ + ${bits_srcdir}/regex.tcc \ ${bits_srcdir}/regex_constants.h \ ${bits_srcdir}/regex_error.h \ ${bits_srcdir}/regex_scanner.h \ @@ -621,6 +623,7 @@ tr2_headers = \ ${tr2_srcdir}/bool_set \ ${tr2_srcdir}/bool_set.tcc \ ${tr2_srcdir}/dynamic_bitset \ + ${tr2_srcdir}/dynamic_bitset.tcc \ ${tr2_srcdir}/ratio \ ${tr2_srcdir}/type_traits diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in index b1606397013..a1fd1d39982 100644 --- a/libstdc++-v3/include/Makefile.in +++ b/libstdc++-v3/include/Makefile.in @@ -388,11 +388,13 @@ bits_headers = \ ${bits_srcdir}/ostream_insert.h \ ${bits_srcdir}/parse_numbers.h \ ${bits_srcdir}/postypes.h \ + ${bits_srcdir}/predefined_ops.h \ ${bits_srcdir}/ptr_traits.h \ ${bits_srcdir}/random.h \ ${bits_srcdir}/random.tcc \ ${bits_srcdir}/range_access.h \ ${bits_srcdir}/regex.h \ + ${bits_srcdir}/regex.tcc \ ${bits_srcdir}/regex_constants.h \ ${bits_srcdir}/regex_error.h \ ${bits_srcdir}/regex_scanner.h \ @@ -886,6 +888,7 @@ tr2_headers = \ ${tr2_srcdir}/bool_set \ ${tr2_srcdir}/bool_set.tcc \ ${tr2_srcdir}/dynamic_bitset \ + ${tr2_srcdir}/dynamic_bitset.tcc \ ${tr2_srcdir}/ratio \ ${tr2_srcdir}/type_traits diff --git a/libstdc++-v3/include/bits/basic_string.h b/libstdc++-v3/include/bits/basic_string.h index 48904288867..db01eb7dace 100644 --- a/libstdc++-v3/include/bits/basic_string.h +++ b/libstdc++-v3/include/bits/basic_string.h @@ -321,7 +321,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_check(size_type __pos, const char* __s) const { if (__pos > this->size()) - __throw_out_of_range(__N(__s)); + __throw_out_of_range_fmt(__N("%s: __pos (which is %zu) > " + "this->size() (which is %zu)"), + __s, __pos, this->size()); return __pos; } @@ -507,7 +509,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * The newly-created string contains the exact contents of @a __str. * @a __str is a valid, but unspecified string. **/ - basic_string(basic_string&& __str) noexcept + basic_string(basic_string&& __str) +#if _GLIBCXX_FULLY_DYNAMIC_STRING == 0 + noexcept // FIXME C++11: should always be noexcept. +#endif : _M_dataplus(__str._M_dataplus) { #if _GLIBCXX_FULLY_DYNAMIC_STRING == 0 @@ -579,6 +584,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * The contents of @a str are moved into this string (without copying). * @a str is a valid, but unspecified string. **/ + // PR 58265, this should be noexcept. basic_string& operator=(basic_string&& __str) { @@ -605,7 +611,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * the %string. Unshares the string. */ iterator - begin() _GLIBCXX_NOEXCEPT + begin() // FIXME C++11: should be noexcept. { _M_leak(); return iterator(_M_data()); @@ -624,7 +630,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * character in the %string. Unshares the string. */ iterator - end() _GLIBCXX_NOEXCEPT + end() // FIXME C++11: should be noexcept. { _M_leak(); return iterator(_M_data() + this->size()); @@ -644,7 +650,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * order. Unshares the string. */ reverse_iterator - rbegin() _GLIBCXX_NOEXCEPT + rbegin() // FIXME C++11: should be noexcept. { return reverse_iterator(this->end()); } /** @@ -662,7 +668,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * element order. Unshares the string. */ reverse_iterator - rend() _GLIBCXX_NOEXCEPT + rend() // FIXME C++11: should be noexcept. { return reverse_iterator(this->begin()); } /** @@ -804,7 +810,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION */ // PR 56166: this should not throw. void - clear() _GLIBCXX_NOEXCEPT + clear() { _M_mutate(0, this->size(), 0); } /** @@ -869,7 +875,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION at(size_type __n) const { if (__n >= this->size()) - __throw_out_of_range(__N("basic_string::at")); + __throw_out_of_range_fmt(__N("basic_string::at: __n " + "(which is %zu) >= this->size() " + "(which is %zu)"), + __n, this->size()); return _M_data()[__n]; } @@ -888,7 +897,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION at(size_type __n) { if (__n >= size()) - __throw_out_of_range(__N("basic_string::at")); + __throw_out_of_range_fmt(__N("basic_string::at: __n " + "(which is %zu) >= this->size() " + "(which is %zu)"), + __n, this->size()); _M_leak(); return _M_data()[__n]; } @@ -1080,6 +1092,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * This function sets this string to the exact contents of @a __str. * @a __str is a valid, but unspecified string. */ + // PR 58265, this should be noexcept. basic_string& assign(basic_string&& __str) { @@ -1409,7 +1422,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * The string must be non-empty. */ void - pop_back() + pop_back() // FIXME C++11: should be noexcept. { erase(size()-1, 1); } #endif // C++11 diff --git a/libstdc++-v3/include/bits/forward_list.h b/libstdc++-v3/include/bits/forward_list.h index c3cee971399..9ac9d22523b 100644 --- a/libstdc++-v3/include/bits/forward_list.h +++ b/libstdc++-v3/include/bits/forward_list.h @@ -58,7 +58,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER _Fwd_list_node_base* _M_transfer_after(_Fwd_list_node_base* __begin, - _Fwd_list_node_base* __end) + _Fwd_list_node_base* __end) noexcept { _Fwd_list_node_base* __keep = __begin->_M_next; if (__end) @@ -128,30 +128,30 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER typedef ptrdiff_t difference_type; typedef std::forward_iterator_tag iterator_category; - _Fwd_list_iterator() + _Fwd_list_iterator() noexcept : _M_node() { } explicit - _Fwd_list_iterator(_Fwd_list_node_base* __n) + _Fwd_list_iterator(_Fwd_list_node_base* __n) noexcept : _M_node(__n) { } reference - operator*() const + operator*() const noexcept { return *static_cast<_Node*>(this->_M_node)->_M_valptr(); } pointer - operator->() const + operator->() const noexcept { return static_cast<_Node*>(this->_M_node)->_M_valptr(); } _Self& - operator++() + operator++() noexcept { _M_node = _M_node->_M_next; return *this; } _Self - operator++(int) + operator++(int) noexcept { _Self __tmp(*this); _M_node = _M_node->_M_next; @@ -159,15 +159,15 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER } bool - operator==(const _Self& __x) const + operator==(const _Self& __x) const noexcept { return _M_node == __x._M_node; } bool - operator!=(const _Self& __x) const + operator!=(const _Self& __x) const noexcept { return _M_node != __x._M_node; } _Self - _M_next() const + _M_next() const noexcept { if (_M_node) return _Fwd_list_iterator(_M_node->_M_next); @@ -196,33 +196,33 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER typedef ptrdiff_t difference_type; typedef std::forward_iterator_tag iterator_category; - _Fwd_list_const_iterator() + _Fwd_list_const_iterator() noexcept : _M_node() { } explicit - _Fwd_list_const_iterator(const _Fwd_list_node_base* __n) + _Fwd_list_const_iterator(const _Fwd_list_node_base* __n) noexcept : _M_node(__n) { } - _Fwd_list_const_iterator(const iterator& __iter) + _Fwd_list_const_iterator(const iterator& __iter) noexcept : _M_node(__iter._M_node) { } reference - operator*() const + operator*() const noexcept { return *static_cast<_Node*>(this->_M_node)->_M_valptr(); } pointer - operator->() const + operator->() const noexcept { return static_cast<_Node*>(this->_M_node)->_M_valptr(); } _Self& - operator++() + operator++() noexcept { _M_node = _M_node->_M_next; return *this; } _Self - operator++(int) + operator++(int) noexcept { _Self __tmp(*this); _M_node = _M_node->_M_next; @@ -230,15 +230,15 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER } bool - operator==(const _Self& __x) const + operator==(const _Self& __x) const noexcept { return _M_node == __x._M_node; } bool - operator!=(const _Self& __x) const + operator!=(const _Self& __x) const noexcept { return _M_node != __x._M_node; } _Self - _M_next() const + _M_next() const noexcept { if (this->_M_node) return _Fwd_list_const_iterator(_M_node->_M_next); @@ -255,7 +255,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER template<typename _Tp> inline bool operator==(const _Fwd_list_iterator<_Tp>& __x, - const _Fwd_list_const_iterator<_Tp>& __y) + const _Fwd_list_const_iterator<_Tp>& __y) noexcept { return __x._M_node == __y._M_node; } /** @@ -264,7 +264,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER template<typename _Tp> inline bool operator!=(const _Fwd_list_iterator<_Tp>& __x, - const _Fwd_list_const_iterator<_Tp>& __y) + const _Fwd_list_const_iterator<_Tp>& __y) noexcept { return __x._M_node != __y._M_node; } /** diff --git a/libstdc++-v3/include/bits/functexcept.h b/libstdc++-v3/include/bits/functexcept.h index 16140583077..03e2040d96a 100644 --- a/libstdc++-v3/include/bits/functexcept.h +++ b/libstdc++-v3/include/bits/functexcept.h @@ -75,6 +75,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __throw_out_of_range(const char*) __attribute__((__noreturn__)); void + __throw_out_of_range_fmt(const char*, ...) __attribute__((__noreturn__)) + __attribute__((__format__(__printf__, 1, 2))); + + void __throw_runtime_error(const char*) __attribute__((__noreturn__)); void diff --git a/libstdc++-v3/include/bits/hashtable_policy.h b/libstdc++-v3/include/bits/hashtable_policy.h index 61b852f62df..ed9e9dd870a 100644 --- a/libstdc++-v3/include/bits/hashtable_policy.h +++ b/libstdc++-v3/include/bits/hashtable_policy.h @@ -230,9 +230,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { _Hash_node_base* _M_nxt; - _Hash_node_base() : _M_nxt() { } + _Hash_node_base() noexcept : _M_nxt() { } - _Hash_node_base(_Hash_node_base* __next) : _M_nxt(__next) { } + _Hash_node_base(_Hash_node_base* __next) noexcept : _M_nxt(__next) { } }; /** @@ -281,7 +281,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION std::size_t _M_hash_code; _Hash_node* - _M_next() const { return static_cast<_Hash_node*>(this->_M_nxt); } + _M_next() const noexcept + { return static_cast<_Hash_node*>(this->_M_nxt); } }; /** @@ -293,7 +294,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION struct _Hash_node<_Value, false> : _Hash_node_value_base<_Value> { _Hash_node* - _M_next() const { return static_cast<_Hash_node*>(this->_M_nxt); } + _M_next() const noexcept + { return static_cast<_Hash_node*>(this->_M_nxt); } }; /// Base class for node iterators. @@ -304,11 +306,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __node_type* _M_cur; - _Node_iterator_base(__node_type* __p) + _Node_iterator_base(__node_type* __p) noexcept : _M_cur(__p) { } void - _M_incr() + _M_incr() noexcept { _M_cur = _M_cur->_M_next(); } }; @@ -316,12 +318,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION inline bool operator==(const _Node_iterator_base<_Value, _Cache_hash_code>& __x, const _Node_iterator_base<_Value, _Cache_hash_code >& __y) + noexcept { return __x._M_cur == __y._M_cur; } template<typename _Value, bool _Cache_hash_code> inline bool operator!=(const _Node_iterator_base<_Value, _Cache_hash_code>& __x, const _Node_iterator_base<_Value, _Cache_hash_code>& __y) + noexcept { return __x._M_cur != __y._M_cur; } /// Node iterators, used to iterate through all the hashtable. @@ -344,30 +348,30 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION using reference = typename std::conditional<__constant_iterators, const _Value&, _Value&>::type; - _Node_iterator() + _Node_iterator() noexcept : __base_type(0) { } explicit - _Node_iterator(__node_type* __p) + _Node_iterator(__node_type* __p) noexcept : __base_type(__p) { } reference - operator*() const + operator*() const noexcept { return this->_M_cur->_M_v(); } pointer - operator->() const + operator->() const noexcept { return this->_M_cur->_M_valptr(); } _Node_iterator& - operator++() + operator++() noexcept { this->_M_incr(); return *this; } _Node_iterator - operator++(int) + operator++(int) noexcept { _Node_iterator __tmp(*this); this->_M_incr(); @@ -392,34 +396,34 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typedef const _Value* pointer; typedef const _Value& reference; - _Node_const_iterator() + _Node_const_iterator() noexcept : __base_type(0) { } explicit - _Node_const_iterator(__node_type* __p) + _Node_const_iterator(__node_type* __p) noexcept : __base_type(__p) { } _Node_const_iterator(const _Node_iterator<_Value, __constant_iterators, - __cache>& __x) + __cache>& __x) noexcept : __base_type(__x._M_cur) { } reference - operator*() const + operator*() const noexcept { return this->_M_cur->_M_v(); } pointer - operator->() const + operator->() const noexcept { return this->_M_cur->_M_valptr(); } _Node_const_iterator& - operator++() + operator++() noexcept { this->_M_incr(); return *this; } _Node_const_iterator - operator++(int) + operator++(int) noexcept { _Node_const_iterator __tmp(*this); this->_M_incr(); diff --git a/libstdc++-v3/include/bits/predefined_ops.h b/libstdc++-v3/include/bits/predefined_ops.h new file mode 100644 index 00000000000..30870b76383 --- /dev/null +++ b/libstdc++-v3/include/bits/predefined_ops.h @@ -0,0 +1,304 @@ +// Default predicates for internal use -*- C++ -*- + +// Copyright (C) 2013 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. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file predefined_ops.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _GLIBCXX_PREDEFINED_OPS_H +#define _GLIBCXX_PREDEFINED_OPS_H 1 + +namespace __gnu_cxx +{ +namespace __ops +{ + struct _Iter_less_iter + { + template<typename _Iterator1, typename _Iterator2> + bool + operator()(_Iterator1 __it1, _Iterator2 __it2) const + { return *__it1 < *__it2; } + }; + + inline _Iter_less_iter + __iter_less_iter() + { return _Iter_less_iter(); } + + struct _Iter_less_val + { + template<typename _Iterator, typename _Value> + bool + operator()(_Iterator __it, _Value& __val) const + { return *__it < __val; } + }; + + inline _Iter_less_val + __iter_less_val() + { return _Iter_less_val(); } + + inline _Iter_less_val + __iter_comp_val(_Iter_less_iter) + { return _Iter_less_val(); } + + struct _Val_less_iter + { + template<typename _Value, typename _Iterator> + bool + operator()(_Value& __val, _Iterator __it) const + { return __val < *__it; } + }; + + inline _Val_less_iter + __val_less_iter() + { return _Val_less_iter(); } + + inline _Val_less_iter + __val_comp_iter(_Iter_less_iter) + { return _Val_less_iter(); } + + struct _Iter_equal_to_iter + { + template<typename _Iterator1, typename _Iterator2> + bool + operator()(_Iterator1 __it1, _Iterator2 __it2) const + { return *__it1 == *__it2; } + }; + + inline _Iter_equal_to_iter + __iter_equal_to_iter() + { return _Iter_equal_to_iter(); } + + struct _Iter_equal_to_val + { + template<typename _Iterator, typename _Value> + bool + operator()(_Iterator __it, _Value& __val) const + { return *__it == __val; } + }; + + inline _Iter_equal_to_val + __iter_equal_to_val() + { return _Iter_equal_to_val(); } + + inline _Iter_equal_to_val + __iter_comp_val(_Iter_equal_to_iter) + { return _Iter_equal_to_val(); } + + template<typename _Compare> + struct _Iter_comp_iter + { + _Compare _M_comp; + + _Iter_comp_iter(_Compare __comp) + : _M_comp(__comp) + { } + + template<typename _Iterator1, typename _Iterator2> + bool + operator()(_Iterator1 __it1, _Iterator2 __it2) + { return bool(_M_comp(*__it1, *__it2)); } + }; + + template<typename _Compare> + inline _Iter_comp_iter<_Compare> + __iter_comp_iter(_Compare __comp) + { return _Iter_comp_iter<_Compare>(__comp); } + + template<typename _Compare> + struct _Iter_comp_val + { + _Compare _M_comp; + + _Iter_comp_val(_Compare __comp) + : _M_comp(__comp) + { } + + template<typename _Iterator, typename _Value> + bool + operator()(_Iterator __it, _Value& __val) + { return bool(_M_comp(*__it, __val)); } + }; + + template<typename _Compare> + inline _Iter_comp_val<_Compare> + __iter_comp_val(_Compare __comp) + { return _Iter_comp_val<_Compare>(__comp); } + + template<typename _Compare> + inline _Iter_comp_val<_Compare> + __iter_comp_val(_Iter_comp_iter<_Compare> __comp) + { return _Iter_comp_val<_Compare>(__comp._M_comp); } + + template<typename _Compare> + struct _Val_comp_iter + { + _Compare _M_comp; + + _Val_comp_iter(_Compare __comp) + : _M_comp(__comp) + { } + + template<typename _Value, typename _Iterator> + bool + operator()(_Value& __val, _Iterator __it) + { return bool(_M_comp(__val, *__it)); } + }; + + template<typename _Compare> + inline _Val_comp_iter<_Compare> + __val_comp_iter(_Compare __comp) + { return _Val_comp_iter<_Compare>(__comp); } + + template<typename _Compare> + inline _Val_comp_iter<_Compare> + __val_comp_iter(_Iter_comp_iter<_Compare> __comp) + { return _Val_comp_iter<_Compare>(__comp._M_comp); } + + template<typename _Value> + struct _Iter_equals_val + { + _Value& _M_value; + + _Iter_equals_val(_Value& __value) + : _M_value(__value) + { } + + template<typename _Iterator> + bool + operator()(_Iterator __it) + { return *__it == _M_value; } + }; + + template<typename _Value> + inline _Iter_equals_val<_Value> + __iter_equals_val(_Value& __val) + { return _Iter_equals_val<_Value>(__val); } + + template<typename _Iterator1> + struct _Iter_equals_iter + { + typename std::iterator_traits<_Iterator1>::reference _M_ref; + + _Iter_equals_iter(_Iterator1 __it1) + : _M_ref(*__it1) + { } + + template<typename _Iterator2> + bool + operator()(_Iterator2 __it2) + { return *__it2 == _M_ref; } + }; + + template<typename _Iterator> + inline _Iter_equals_iter<_Iterator> + __iter_comp_iter(_Iter_equal_to_iter, _Iterator __it) + { return _Iter_equals_iter<_Iterator>(__it); } + + template<typename _Predicate> + struct _Iter_pred + { + _Predicate _M_pred; + + _Iter_pred(_Predicate __pred) + : _M_pred(__pred) + { } + + template<typename _Iterator> + bool + operator()(_Iterator __it) + { return bool(_M_pred(*__it)); } + }; + + template<typename _Predicate> + inline _Iter_pred<_Predicate> + __pred_iter(_Predicate __pred) + { return _Iter_pred<_Predicate>(__pred); } + + template<typename _Compare, typename _Value> + struct _Iter_comp_to_val + { + _Compare _M_comp; + _Value& _M_value; + + _Iter_comp_to_val(_Compare __comp, _Value& __value) + : _M_comp(__comp), _M_value(__value) + { } + + template<typename _Iterator> + bool + operator()(_Iterator __it) + { return bool(_M_comp(*__it, _M_value)); } + }; + + template<typename _Compare, typename _Value> + _Iter_comp_to_val<_Compare, _Value> + __iter_comp_val(_Compare __comp, _Value &__val) + { return _Iter_comp_to_val<_Compare, _Value>(__comp, __val); } + + template<typename _Compare, typename _Iterator1> + struct _Iter_comp_to_iter + { + _Compare _M_comp; + typename std::iterator_traits<_Iterator1>::reference _M_ref; + + _Iter_comp_to_iter(_Compare __comp, _Iterator1 __it1) + : _M_comp(__comp), _M_ref(*__it1) + { } + + template<typename _Iterator2> + bool + operator()(_Iterator2 __it2) + { return bool(_M_comp(*__it2, _M_ref)); } + }; + + template<typename _Compare, typename _Iterator> + inline _Iter_comp_to_iter<_Compare, _Iterator> + __iter_comp_iter(_Iter_comp_iter<_Compare> __comp, _Iterator __it) + { return _Iter_comp_to_iter<_Compare, _Iterator>(__comp._M_comp, __it); } + + template<typename _Predicate> + struct _Iter_negate + { + _Predicate _M_pred; + + _Iter_negate(_Predicate __pred) + : _M_pred(__pred) + { } + + template<typename _Iterator> + bool + operator()(_Iterator __it) + { return !bool(_M_pred(*__it)); } + }; + + template<typename _Predicate> + inline _Iter_negate<_Predicate> + __negate(_Iter_pred<_Predicate> __pred) + { return _Iter_negate<_Predicate>(__pred._M_pred); } + +} // namespace __ops +} // namespace __gnu_cxx + +#endif diff --git a/libstdc++-v3/include/bits/regex.h b/libstdc++-v3/include/bits/regex.h index 9d1438aab23..32d38b491bd 100644 --- a/libstdc++-v3/include/bits/regex.h +++ b/libstdc++-v3/include/bits/regex.h @@ -32,6 +32,24 @@ namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION +namespace __detail +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + template<typename _BiIter, typename _Alloc, + typename _CharT, typename _TraitsT, + _RegexExecutorPolicy __policy, + bool __match_mode> + bool + __regex_algo_impl(_BiIter __s, + _BiIter __e, + match_results<_BiIter, _Alloc>& __m, + const basic_regex<_CharT, _TraitsT>& __re, + regex_constants::match_flag_type __flags); + +_GLIBCXX_END_NAMESPACE_VERSION +} + /** * @addtogroup regex * @{ @@ -214,16 +232,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * is known and can be converted into a primary sort key * then returns that key, otherwise returns an empty string. * - * @todo Implement this function. + * @todo Implement this function correctly. */ template<typename _Fwd_iter> string_type transform_primary(_Fwd_iter __first, _Fwd_iter __last) const { + // TODO : this is not entirely correct. + // This function requires extra support from the platform. + // + // Read http://gcc.gnu.org/ml/libstdc++/2013-09/msg00117.html and + // http://www.open-std.org/Jtc1/sc22/wg21/docs/papers/2003/n1429.htm + // for details. typedef std::ctype<char_type> __ctype_type; const __ctype_type& __fctyp(use_facet<__ctype_type>(_M_locale)); std::vector<char_type> __s(__first, __last); - // FIXME : this is not entirely correct __fctyp.tolower(__s.data(), __s.data() + __s.size()); return this->transform(__s.data(), __s.data() + __s.size()); } @@ -343,278 +366,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION locale_type _M_locale; }; - template<typename _Ch_type> - template<typename _Fwd_iter> - typename regex_traits<_Ch_type>::string_type - regex_traits<_Ch_type>:: - lookup_collatename(_Fwd_iter __first, _Fwd_iter __last) const - { - typedef std::ctype<char_type> __ctype_type; - const __ctype_type& __fctyp(use_facet<__ctype_type>(_M_locale)); - - static const char* __collatenames[] = - { - "NUL", - "SOH", - "STX", - "ETX", - "EOT", - "ENQ", - "ACK", - "alert", - "backspace", - "tab", - "newline", - "vertical-tab", - "form-feed", - "carriage-return", - "SO", - "SI", - "DLE", - "DC1", - "DC2", - "DC3", - "DC4", - "NAK", - "SYN", - "ETB", - "CAN", - "EM", - "SUB", - "ESC", - "IS4", - "IS3", - "IS2", - "IS1", - "space", - "exclamation-mark", - "quotation-mark", - "number-sign", - "dollar-sign", - "percent-sign", - "ampersand", - "apostrophe", - "left-parenthesis", - "right-parenthesis", - "asterisk", - "plus-sign", - "comma", - "hyphen", - "period", - "slash", - "zero", - "one", - "two", - "three", - "four", - "five", - "six", - "seven", - "eight", - "nine", - "colon", - "semicolon", - "less-than-sign", - "equals-sign", - "greater-than-sign", - "question-mark", - "commercial-at", - "A", - "B", - "C", - "D", - "E", - "F", - "G", - "H", - "I", - "J", - "K", - "L", - "M", - "N", - "O", - "P", - "Q", - "R", - "S", - "T", - "U", - "V", - "W", - "X", - "Y", - "Z", - "left-square-bracket", - "backslash", - "right-square-bracket", - "circumflex", - "underscore", - "grave-accent", - "a", - "b", - "c", - "d", - "e", - "f", - "g", - "h", - "i", - "j", - "k", - "l", - "m", - "n", - "o", - "p", - "q", - "r", - "s", - "t", - "u", - "v", - "w", - "x", - "y", - "z", - "left-curly-bracket", - "vertical-line", - "right-curly-bracket", - "tilde", - "DEL", - "" - }; - - // same as boost - static const char* __digraphs[] = - { - "ae", - "Ae", - "AE", - "ch", - "Ch", - "CH", - "ll", - "Ll", - "LL", - "ss", - "Ss", - "SS", - "nj", - "Nj", - "NJ", - "dz", - "Dz", - "DZ", - "lj", - "Lj", - "LJ", - "" - }; - - std::string __s(__last - __first, '?'); - __fctyp.narrow(__first, __last, '?', &*__s.begin()); - - for (unsigned int __i = 0; *__collatenames[__i]; __i++) - if (__s == __collatenames[__i]) - return string_type(1, __fctyp.widen((char)__i)); - - for (unsigned int __i = 0; *__digraphs[__i]; __i++) - { - const char* __now = __digraphs[__i]; - if (__s == __now) - { - string_type ret(__s.size(), __fctyp.widen('?')); - __fctyp.widen(__now, __now + 2/* ouch */, &*ret.begin()); - return ret; - } - } - return string_type(); - } - - template<typename _Ch_type> - template<typename _Fwd_iter> - typename regex_traits<_Ch_type>::char_class_type - regex_traits<_Ch_type>:: - lookup_classname(_Fwd_iter __first, _Fwd_iter __last, bool __icase) const - { - typedef std::ctype<char_type> __ctype_type; - typedef std::ctype<char> __cctype_type; - typedef const pair<const char*, char_class_type> _ClassnameEntry; - const __ctype_type& __fctyp(use_facet<__ctype_type>(_M_locale)); - const __cctype_type& __cctyp(use_facet<__cctype_type>(_M_locale)); - - static _ClassnameEntry __classnames[] = - { - {"d", ctype_base::digit}, - {"w", {ctype_base::alnum, _RegexMask::_S_under}}, - {"s", ctype_base::space}, - {"alnum", ctype_base::alnum}, - {"alpha", ctype_base::alpha}, - {"blank", {0, _RegexMask::_S_blank}}, - {"cntrl", ctype_base::cntrl}, - {"digit", ctype_base::digit}, - {"graph", ctype_base::graph}, - {"lower", ctype_base::lower}, - {"print", ctype_base::print}, - {"punct", ctype_base::punct}, - {"space", ctype_base::space}, - {"upper", ctype_base::upper}, - {"xdigit", ctype_base::xdigit}, - }; - - std::string __s(__last - __first, '?'); - __fctyp.narrow(__first, __last, '?', &__s[0]); - __cctyp.tolower(&*__s.begin(), &*__s.begin() + __s.size()); - for (_ClassnameEntry* __it = __classnames; - __it < *(&__classnames + 1); - ++__it) - { - if (__s == __it->first) - { - if (__icase - && ((__it->second - & (ctype_base::lower | ctype_base::upper)) != 0)) - return ctype_base::alpha; - return __it->second; - } - } - return 0; - } - - template<typename _Ch_type> - bool - regex_traits<_Ch_type>:: - isctype(_Ch_type __c, char_class_type __f) const - { - typedef std::ctype<char_type> __ctype_type; - const __ctype_type& __fctyp(use_facet<__ctype_type>(_M_locale)); - - return __fctyp.is(__f._M_base, __c) - // [[:w:]] - || ((__f._M_extended & _RegexMask::_S_under) - && __c == __fctyp.widen('_')) - // [[:blank:]] - || ((__f._M_extended & _RegexMask::_S_blank) - && (__c == __fctyp.widen(' ') - || __c == __fctyp.widen('\t'))); - } - - template<typename _Ch_type> - int - regex_traits<_Ch_type>:: - value(_Ch_type __ch, int __radix) const - { - std::basic_istringstream<char_type> __is(string_type(1, __ch)); - int __v; - if (__radix == 8) - __is >> std::oct; - else if (__radix == 16) - __is >> std::hex; - __is >> __v; - return __is.fail() ? -1 : __v; - } - // [7.8] Class basic_regex /** * Objects of specializations of this class represent regular expressions @@ -688,8 +439,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * * @throws regex_error if @p __p is not a valid regular expression. */ - basic_regex(const _Ch_type* __p, - std::size_t __len, flag_type __f = ECMAScript) + basic_regex(const _Ch_type* __p, std::size_t __len, + flag_type __f = ECMAScript) : basic_regex(__p, __p + __len, __f) { } @@ -756,8 +507,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * * @throws regex_error if @p __l is not a valid regular expression. */ - basic_regex(initializer_list<_Ch_type> __l, - flag_type __f = ECMAScript) + basic_regex(initializer_list<_Ch_type> __l, flag_type __f = ECMAScript) : basic_regex(__l.begin(), __l.end(), __f) { } @@ -977,32 +727,26 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #endif protected: - typedef std::shared_ptr<__detail::_Automaton<_Ch_type, _Rx_traits>> + typedef std::shared_ptr<__detail::_NFA<_Ch_type, _Rx_traits>> _AutomatonPtr; template<typename _BiIter, typename _Alloc, - typename _CharT, typename _TraitsT> + typename _CharT, typename _TraitsT, + __detail::_RegexExecutorPolicy __policy> friend std::unique_ptr< __detail::_Executor<_BiIter, _Alloc, _CharT, _TraitsT>> __detail::__get_executor(_BiIter, _BiIter, - match_results<_BiIter, _Alloc>&, + std::vector<sub_match<_BiIter>, _Alloc>&, const basic_regex<_CharT, _TraitsT>&, regex_constants::match_flag_type); - template<typename _Bp, typename _Ap, typename _Cp, typename _Rp> + template<typename _Bp, typename _Ap, typename _Cp, typename _Rp, + __detail::_RegexExecutorPolicy, bool> friend bool - regex_match(_Bp, _Bp, - match_results<_Bp, _Ap>&, - const basic_regex<_Cp, _Rp>&, - regex_constants::match_flag_type); - - template<typename _Bp, typename _Ap, typename _Cp, typename _Rp> - friend bool - regex_search(_Bp, _Bp, - match_results<_Bp, _Ap>&, - const basic_regex<_Cp, _Rp>&, - regex_constants::match_flag_type); + __detail::__regex_algo_impl(_Bp, _Bp, match_results<_Bp, _Ap>&, + const basic_regex<_Cp, _Rp>&, + regex_constants::match_flag_type); template<typename, typename, typename, typename> friend class __detail::_Executor; @@ -1766,17 +1510,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * @name 10.? Public Types */ //@{ - typedef _Alloc allocator_type; typedef sub_match<_Bi_iter> value_type; typedef const value_type& const_reference; typedef const_reference reference; typedef typename _Base_type::const_iterator const_iterator; typedef const_iterator iterator; typedef typename __iter_traits::difference_type difference_type; - typedef typename __iter_traits::value_type char_type; typedef typename allocator_traits<_Alloc>::size_type size_type; - - + typedef _Alloc allocator_type; + typedef typename __iter_traits::value_type char_type; typedef std::basic_string<char_type> string_type; //@} @@ -2002,21 +1744,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION */ const_iterator cbegin() const - { return _Base_type::cbegin(); } + { return _Base_type::cbegin() + 2; } /** * @brief Gets an iterator to one-past-the-end of the collection. */ const_iterator end() const - { return !empty() ? _Base_type::end() - 2 : _Base_type::end(); } + { return _Base_type::end() - 2; } /** * @brief Gets an iterator to one-past-the-end of the collection. */ const_iterator cend() const - { return end(); } + { return _Base_type::cend(); } //@} @@ -2032,14 +1774,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @pre ready() == true - * @todo Implement this function. */ template<typename _Out_iter> _Out_iter format(_Out_iter __out, const char_type* __fmt_first, const char_type* __fmt_last, - match_flag_type __flags = regex_constants::format_default) const - { return __out; } + match_flag_type __flags = regex_constants::format_default) const; /** * @pre ready() == true @@ -2123,21 +1863,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename, typename, typename> friend class regex_iterator; - template<typename _Bp, typename _Ap, - typename _Ch_type, typename _Rx_traits> + template<typename _Bp, typename _Ap, typename _Cp, typename _Rp, + __detail::_RegexExecutorPolicy, bool> friend bool - regex_match(_Bp, _Bp, match_results<_Bp, _Ap>&, - const basic_regex<_Ch_type, - _Rx_traits>&, - regex_constants::match_flag_type); - - template<typename _Bp, typename _Ap, - typename _Ch_type, typename _Rx_traits> - friend bool - regex_search(_Bp, _Bp, match_results<_Bp, _Ap>&, - const basic_regex<_Ch_type, - _Rx_traits>&, - regex_constants::match_flag_type); + __detail::__regex_algo_impl(_Bp, _Bp, match_results<_Bp, _Ap>&, + const basic_regex<_Cp, _Rp>&, + regex_constants::match_flag_type); _Bi_iter _M_begin; bool _M_in_iterator; @@ -2223,7 +1954,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION */ template<typename _Bi_iter, typename _Alloc, typename _Ch_type, typename _Rx_traits> - bool + inline bool regex_match(_Bi_iter __s, _Bi_iter __e, match_results<_Bi_iter, _Alloc>& __m, @@ -2231,29 +1962,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION regex_constants::match_flag_type __flags = regex_constants::match_default) { - if (__re._M_automaton == nullptr) - return false; - - auto __size = __re._M_automaton->_M_sub_count(); - __size += 2; - __m.resize(__size); - for (decltype(__size) __i = 0; __i < __size; ++__i) - __m.at(__i).matched = false; - - if (__detail::__get_executor(__s, __e, __m, __re, __flags)->_M_match()) - { - for (auto __it : __m) - if (!__it.matched) - __it.first = __it.second = __e; - __m.at(__m.size()).matched = false; - __m.at(__m.size()).first = __s; - __m.at(__m.size()).second = __s; - __m.at(__m.size()+1).matched = false; - __m.at(__m.size()+1).first = __e; - __m.at(__m.size()+1).second = __e; - return true; - } - return false; + return __detail::__regex_algo_impl<_Bi_iter, _Alloc, _Ch_type, _Rx_traits, + __detail::_RegexExecutorPolicy::_S_auto, true> + (__s, __e, __m, __re, __flags); } /** @@ -2271,7 +1982,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * @throws an exception of type regex_error. */ template<typename _Bi_iter, typename _Ch_type, typename _Rx_traits> - bool + inline bool regex_match(_Bi_iter __first, _Bi_iter __last, const basic_regex<_Ch_type, _Rx_traits>& __re, regex_constants::match_flag_type __flags @@ -2389,38 +2100,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Bi_iter, typename _Alloc, typename _Ch_type, typename _Rx_traits> inline bool - regex_search(_Bi_iter __first, _Bi_iter __last, + regex_search(_Bi_iter __s, _Bi_iter __e, match_results<_Bi_iter, _Alloc>& __m, const basic_regex<_Ch_type, _Rx_traits>& __re, regex_constants::match_flag_type __flags = regex_constants::match_default) { - if (__re._M_automaton == nullptr) - return false; - - auto __size = __re._M_automaton->_M_sub_count(); - __size += 2; - __m.resize(__size); - for (decltype(__size) __i = 0; __i < __size; ++__i) - __m.at(__i).matched = false; - - if (__detail::__get_executor(__first, __last, __m, __re, __flags) - ->_M_search()) - { - for (auto __it : __m) - if (!__it.matched) - __it.first = __it.second = __last; - __m.at(__m.size()).first = __first; - __m.at(__m.size()).second = __m[0].first; - __m.at(__m.size()+1).first = __m[0].second; - __m.at(__m.size()+1).second = __last; - __m.at(__m.size()).matched = - (__m.prefix().first != __m.prefix().second); - __m.at(__m.size()+1).matched = - (__m.suffix().first != __m.suffix().second); - return true; - } - return false; + return __detail::__regex_algo_impl<_Bi_iter, _Alloc, _Ch_type, _Rx_traits, + __detail::_RegexExecutorPolicy::_S_auto, false> + (__s, __e, __m, __re, __flags); } /** @@ -2530,51 +2218,155 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // std [28.11.4] Function template regex_replace /** - * @doctodo - * @param __out - * @param __first - * @param __last - * @param __e - * @param __fmt - * @param __flags + * @brief Search for a regular expression within a range for multiple times, + and replace the matched parts through filling a format string. + * @param __out [OUT] The output iterator. + * @param __first [IN] The start of the string to search. + * @param __last [IN] One-past-the-end of the string to search. + * @param __e [IN] The regular expression to search for. + * @param __fmt [IN] The format string. + * @param __flags [IN] Search and replace policy flags. * - * @returns out + * @returns __out * @throws an exception of type regex_error. + */ + template<typename _Out_iter, typename _Bi_iter, + typename _Rx_traits, typename _Ch_type, + typename _St, typename _Sa> + inline _Out_iter + regex_replace(_Out_iter __out, _Bi_iter __first, _Bi_iter __last, + const basic_regex<_Ch_type, _Rx_traits>& __e, + const basic_string<_Ch_type, _St, _Sa>& __fmt, + regex_constants::match_flag_type __flags + = regex_constants::match_default) + { + return regex_replace(__out, __first, __last, __e, __fmt.c_str(), __flags); + } + + /** + * @brief Search for a regular expression within a range for multiple times, + and replace the matched parts through filling a format C-string. + * @param __out [OUT] The output iterator. + * @param __first [IN] The start of the string to search. + * @param __last [IN] One-past-the-end of the string to search. + * @param __e [IN] The regular expression to search for. + * @param __fmt [IN] The format C-string. + * @param __flags [IN] Search and replace policy flags. * - * @todo Implement this function. + * @returns __out + * @throws an exception of type regex_error. */ template<typename _Out_iter, typename _Bi_iter, typename _Rx_traits, typename _Ch_type> - inline _Out_iter + _Out_iter regex_replace(_Out_iter __out, _Bi_iter __first, _Bi_iter __last, const basic_regex<_Ch_type, _Rx_traits>& __e, - const basic_string<_Ch_type>& __fmt, + const _Ch_type* __fmt, + regex_constants::match_flag_type __flags + = regex_constants::match_default); + + /** + * @brief Search for a regular expression within a string for multiple times, + and replace the matched parts through filling a format string. + * @param __s [IN] The string to search and replace. + * @param __e [IN] The regular expression to search for. + * @param __fmt [IN] The format string. + * @param __flags [IN] Search and replace policy flags. + * + * @returns The string after replacing. + * @throws an exception of type regex_error. + */ + template<typename _Rx_traits, typename _Ch_type, + typename _St, typename _Sa, typename _Fst, typename _Fsa> + inline basic_string<_Ch_type, _St, _Sa> + regex_replace(const basic_string<_Ch_type, _St, _Sa>& __s, + const basic_regex<_Ch_type, _Rx_traits>& __e, + const basic_string<_Ch_type, _Fst, _Fsa>& __fmt, + regex_constants::match_flag_type __flags + = regex_constants::match_default) + { + basic_string<_Ch_type, _St, _Sa> __result; + regex_replace(std::back_inserter(__result), + __s.begin(), __s.end(), __e, __fmt, __flags); + return __result; + } + + /** + * @brief Search for a regular expression within a string for multiple times, + and replace the matched parts through filling a format C-string. + * @param __s [IN] The string to search and replace. + * @param __e [IN] The regular expression to search for. + * @param __fmt [IN] The format C-string. + * @param __flags [IN] Search and replace policy flags. + * + * @returns The string after replacing. + * @throws an exception of type regex_error. + */ + template<typename _Rx_traits, typename _Ch_type, + typename _St, typename _Sa> + inline basic_string<_Ch_type, _St, _Sa> + regex_replace(const basic_string<_Ch_type, _St, _Sa>& __s, + const basic_regex<_Ch_type, _Rx_traits>& __e, + const _Ch_type* __fmt, regex_constants::match_flag_type __flags = regex_constants::match_default) - { return __out; } + { + basic_string<_Ch_type, _St, _Sa> __result; + regex_replace(std::back_inserter(__result), + __s.begin(), __s.end(), __e, __fmt, __flags); + return __result; + } /** - * @doctodo - * @param __s - * @param __e - * @param __fmt - * @param __flags + * @brief Search for a regular expression within a C-string for multiple + times, and replace the matched parts through filling a format string. + * @param __s [IN] The C-string to search and replace. + * @param __e [IN] The regular expression to search for. + * @param __fmt [IN] The format string. + * @param __flags [IN] Search and replace policy flags. * - * @returns a copy of string @p s with replacements. + * @returns The string after replacing. + * @throws an exception of type regex_error. + */ + template<typename _Rx_traits, typename _Ch_type, + typename _St, typename _Sa> + inline basic_string<_Ch_type> + regex_replace(const _Ch_type* __s, + const basic_regex<_Ch_type, _Rx_traits>& __e, + const basic_string<_Ch_type, _St, _Sa>& __fmt, + regex_constants::match_flag_type __flags + = regex_constants::match_default) + { + basic_string<_Ch_type> __result; + regex_replace(std::back_inserter(__result), __s, + __s + char_traits<_Ch_type>::length(__s), + __e, __fmt, __flags); + return __result; + } + + /** + * @brief Search for a regular expression within a C-string for multiple + times, and replace the matched parts through filling a format C-string. + * @param __s [IN] The C-string to search and replace. + * @param __e [IN] The regular expression to search for. + * @param __fmt [IN] The format C-string. + * @param __flags [IN] Search and replace policy flags. * + * @returns The string after replacing. * @throws an exception of type regex_error. */ template<typename _Rx_traits, typename _Ch_type> inline basic_string<_Ch_type> - regex_replace(const basic_string<_Ch_type>& __s, + regex_replace(const _Ch_type* __s, const basic_regex<_Ch_type, _Rx_traits>& __e, - const basic_string<_Ch_type>& __fmt, + const _Ch_type* __fmt, regex_constants::match_flag_type __flags = regex_constants::match_default) { basic_string<_Ch_type> __result; - regex_replace(std::back_inserter(__result), - __s.begin(), __s.end(), __e, __fmt, __flags); + regex_replace(std::back_inserter(__result), __s, + __s + char_traits<_Ch_type>::length(__s), + __e, __fmt, __flags); return __result; } @@ -2685,68 +2477,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION match_results<_Bi_iter> _M_match; }; - template<typename _Bi_iter, - typename _Ch_type, - typename _Rx_traits> - bool - regex_iterator<_Bi_iter, _Ch_type, _Rx_traits>:: - operator==(const regex_iterator& __rhs) const - { - return (_M_match.empty() && __rhs._M_match.empty()) - || (_M_begin == __rhs._M_begin - && _M_end == __rhs._M_end - && _M_pregex == __rhs._M_pregex - && _M_flags == __rhs._M_flags - && _M_match[0] == __rhs._M_match[0]); - } - - template<typename _Bi_iter, - typename _Ch_type, - typename _Rx_traits> - regex_iterator<_Bi_iter, _Ch_type, _Rx_traits>& - regex_iterator<_Bi_iter, _Ch_type, _Rx_traits>:: - operator++() - { - // In all cases in which the call to regex_search returns true, - // match.prefix().first shall be equal to the previous value of - // match[0].second, and for each index i in the half-open range - // [0, match.size()) for which match[i].matched is true, - // match[i].position() shall return distance(begin, match[i].first). - // [28.12.1.4.5] - if (_M_match[0].matched) - { - auto __start = _M_match[0].second; - if (_M_match[0].first == _M_match[0].second) - if (__start == _M_end) - { - _M_match = value_type(); - return *this; - } - else - { - if (regex_search(__start, _M_end, _M_match, *_M_pregex, _M_flags - | regex_constants::match_not_null - | regex_constants::match_continuous)) - { - _M_match._M_in_iterator = true; - _M_match._M_begin = _M_begin; - return *this; - } - else - ++__start; - } - _M_flags |= regex_constants::match_prev_avail; - if (regex_search(__start, _M_end, _M_match, *_M_pregex, _M_flags)) - { - _M_match._M_in_iterator = true; - _M_match._M_begin = _M_begin; - } - else - _M_match = value_type(); - } - return *this; - } - typedef regex_iterator<const char*> cregex_iterator; typedef regex_iterator<string::const_iterator> sregex_iterator; #ifdef _GLIBCXX_USE_WCHAR_T @@ -2784,7 +2514,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * iterator of the same type. */ regex_token_iterator() - : _M_position(), _M_result(nullptr), _M_suffix(), _M_n(0), _M_subs() + : _M_position(), _M_subs(), _M_suffix(), _M_n(0), _M_result(nullptr), + _M_has_m1(false) { } /** @@ -2869,8 +2600,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * @param __rhs [IN] A %regex_token_iterator to copy. */ regex_token_iterator(const regex_token_iterator& __rhs) - : _M_position(__rhs.position), _M_subs(__rhs.subs), _M_n(__rhs.N), - _M_result(__rhs.result), _M_suffix(__rhs.suffix), + : _M_position(__rhs._M_position), _M_subs(__rhs._M_subs), + _M_suffix(__rhs._M_suffix), _M_n(__rhs._M_n), _M_result(__rhs._M_result), _M_has_m1(__rhs._M_has_m1) { if (__rhs._M_result == &__rhs._M_suffix) @@ -2947,114 +2678,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_end_of_seq() { return _M_result == nullptr; } - _Position _M_position; - const value_type* _M_result; + _Position _M_position; + std::vector<int> _M_subs; value_type _M_suffix; std::size_t _M_n; - std::vector<int> _M_subs; + const value_type* _M_result; // Show whether _M_subs contains -1 bool _M_has_m1; }; - template<typename _Bi_iter, - typename _Ch_type, - typename _Rx_traits> - regex_token_iterator<_Bi_iter, _Ch_type, _Rx_traits>& - regex_token_iterator<_Bi_iter, _Ch_type, _Rx_traits>:: - operator=(const regex_token_iterator& __rhs) - { - _M_position = __rhs._M_position; - _M_subs = __rhs._M_subs; - _M_n = __rhs._M_n; - _M_result = __rhs._M_result; - _M_suffix = __rhs._M_suffix; - _M_has_m1 = __rhs._M_has_m1; - if (__rhs._M_result == &__rhs._M_suffix) - _M_result = &_M_suffix; - } - - template<typename _Bi_iter, - typename _Ch_type, - typename _Rx_traits> - bool - regex_token_iterator<_Bi_iter, _Ch_type, _Rx_traits>:: - operator==(const regex_token_iterator& __rhs) const - { - if (_M_end_of_seq() && __rhs._M_end_of_seq()) - return true; - if (_M_suffix.matched && __rhs._M_suffix.matched - && _M_suffix == __rhs._M_suffix) - return true; - if (_M_end_of_seq() || _M_suffix.matched - || __rhs._M_end_of_seq() || __rhs._M_suffix.matched) - return false; - return _M_position == __rhs._M_position - && _M_n == __rhs._M_n - && _M_subs == __rhs._M_subs; - } - - template<typename _Bi_iter, - typename _Ch_type, - typename _Rx_traits> - regex_token_iterator<_Bi_iter, _Ch_type, _Rx_traits>& - regex_token_iterator<_Bi_iter, _Ch_type, _Rx_traits>:: - operator++() - { - _Position __prev = _M_position; - if (_M_suffix.matched) - *this = regex_token_iterator(); - else if (_M_n + 1 < _M_subs.size()) - { - _M_n++; - _M_result = &_M_current_match(); - } - else - { - _M_n = 0; - ++_M_position; - if (_M_position != _Position()) - _M_result = &_M_current_match(); - else if (_M_has_m1 && __prev->suffix().length() != 0) - { - _M_suffix.matched = true; - _M_suffix.first = __prev->suffix().first; - _M_suffix.second = __prev->suffix().second; - _M_result = &_M_suffix; - } - else - *this = regex_token_iterator(); - } - return *this; - } - - template<typename _Bi_iter, - typename _Ch_type, - typename _Rx_traits> - void - regex_token_iterator<_Bi_iter, _Ch_type, _Rx_traits>:: - _M_init(_Bi_iter __a, _Bi_iter __b) - { - _M_has_m1 = false; - for (auto __it : _M_subs) - if (__it == -1) - { - _M_has_m1 = true; - break; - } - if (_M_position != _Position()) - _M_result = &_M_current_match(); - else if (_M_has_m1) - { - _M_suffix.matched = true; - _M_suffix.first = __a; - _M_suffix.second = __b; - _M_result = &_M_suffix; - } - else - _M_result = nullptr; - } - /** @brief Token iterator for C-style NULL-terminated strings. */ typedef regex_token_iterator<const char*> cregex_token_iterator; @@ -3073,3 +2706,4 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _GLIBCXX_END_NAMESPACE_VERSION } // namespace +#include <bits/regex.tcc> diff --git a/libstdc++-v3/include/bits/regex.tcc b/libstdc++-v3/include/bits/regex.tcc new file mode 100644 index 00000000000..7028480ed77 --- /dev/null +++ b/libstdc++-v3/include/bits/regex.tcc @@ -0,0 +1,675 @@ +// class template regex -*- C++ -*- + +// Copyright (C) 2013 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. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** + * @file bits/regex.tcc + * This is an internal header file, included by other library headers. + * Do not attempt to use it directly. @headername{regex} + */ + +namespace std _GLIBCXX_VISIBILITY(default) +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + +namespace __detail +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + // Result of merging regex_match and regex_search. + // + // __policy now can be _S_auto (auto dispatch) and _S_alternate (use + // the other one if possible, for test purpose). + // + // That __match_mode is true means regex_match, else regex_search. + template<typename _BiIter, typename _Alloc, + typename _CharT, typename _TraitsT, + _RegexExecutorPolicy __policy, + bool __match_mode> + bool + __regex_algo_impl(_BiIter __s, + _BiIter __e, + match_results<_BiIter, _Alloc>& __m, + const basic_regex<_CharT, _TraitsT>& __re, + regex_constants::match_flag_type __flags) + { + if (__re._M_automaton == nullptr) + return false; + + typename match_results<_BiIter, _Alloc>::_Base_type& __res = __m; + __res.resize(__re._M_automaton->_M_sub_count() + 2); + for (auto& __it : __res) + __it.matched = false; + + auto __executor = __get_executor<_BiIter, _Alloc, _CharT, _TraitsT, + __policy>(__s, __e, __res, __re, __flags); + + bool __ret; + if (__match_mode) + __ret = __executor->_M_match(); + else + __ret = __executor->_M_search(); + if (__ret) + { + for (auto __it : __res) + if (!__it.matched) + __it.first = __it.second = __e; + auto& __pre = __res[__res.size()-2]; + auto& __suf = __res[__res.size()-1]; + if (__match_mode) + { + __pre.matched = false; + __pre.first = __s; + __pre.second = __s; + __suf.matched = false; + __suf.first = __e; + __suf.second = __e; + } + else + { + __pre.first = __s; + __pre.second = __res[0].first; + __pre.matched = (__pre.first != __pre.second); + __suf.first = __res[0].second; + __suf.second = __e; + __suf.matched = (__suf.first != __suf.second); + } + if (__re.flags() & regex_constants::nosubs) + __res.resize(3); + } + return __ret; + } + +_GLIBCXX_END_NAMESPACE_VERSION +} + + template<typename _Ch_type> + template<typename _Fwd_iter> + typename regex_traits<_Ch_type>::string_type + regex_traits<_Ch_type>:: + lookup_collatename(_Fwd_iter __first, _Fwd_iter __last) const + { + typedef std::ctype<char_type> __ctype_type; + const __ctype_type& __fctyp(use_facet<__ctype_type>(_M_locale)); + + static const char* __collatenames[] = + { + "NUL", + "SOH", + "STX", + "ETX", + "EOT", + "ENQ", + "ACK", + "alert", + "backspace", + "tab", + "newline", + "vertical-tab", + "form-feed", + "carriage-return", + "SO", + "SI", + "DLE", + "DC1", + "DC2", + "DC3", + "DC4", + "NAK", + "SYN", + "ETB", + "CAN", + "EM", + "SUB", + "ESC", + "IS4", + "IS3", + "IS2", + "IS1", + "space", + "exclamation-mark", + "quotation-mark", + "number-sign", + "dollar-sign", + "percent-sign", + "ampersand", + "apostrophe", + "left-parenthesis", + "right-parenthesis", + "asterisk", + "plus-sign", + "comma", + "hyphen", + "period", + "slash", + "zero", + "one", + "two", + "three", + "four", + "five", + "six", + "seven", + "eight", + "nine", + "colon", + "semicolon", + "less-than-sign", + "equals-sign", + "greater-than-sign", + "question-mark", + "commercial-at", + "A", + "B", + "C", + "D", + "E", + "F", + "G", + "H", + "I", + "J", + "K", + "L", + "M", + "N", + "O", + "P", + "Q", + "R", + "S", + "T", + "U", + "V", + "W", + "X", + "Y", + "Z", + "left-square-bracket", + "backslash", + "right-square-bracket", + "circumflex", + "underscore", + "grave-accent", + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "left-curly-bracket", + "vertical-line", + "right-curly-bracket", + "tilde", + "DEL", + "" + }; + + // same as boost + //static const char* __digraphs[] = + // { + // "ae", + // "Ae", + // "AE", + // "ch", + // "Ch", + // "CH", + // "ll", + // "Ll", + // "LL", + // "ss", + // "Ss", + // "SS", + // "nj", + // "Nj", + // "NJ", + // "dz", + // "Dz", + // "DZ", + // "lj", + // "Lj", + // "LJ", + // "" + // }; + + std::string __s(__last - __first, '?'); + __fctyp.narrow(__first, __last, '?', &*__s.begin()); + + for (unsigned int __i = 0; *__collatenames[__i]; __i++) + if (__s == __collatenames[__i]) + return string_type(1, __fctyp.widen(static_cast<char>(__i))); + + //for (unsigned int __i = 0; *__digraphs[__i]; __i++) + // { + // const char* __now = __digraphs[__i]; + // if (__s == __now) + // { + // string_type ret(__s.size(), __fctyp.widen('?')); + // __fctyp.widen(__now, __now + 2/* ouch */, &*ret.begin()); + // return ret; + // } + // } + return string_type(); + } + + template<typename _Ch_type> + template<typename _Fwd_iter> + typename regex_traits<_Ch_type>::char_class_type + regex_traits<_Ch_type>:: + lookup_classname(_Fwd_iter __first, _Fwd_iter __last, bool __icase) const + { + typedef std::ctype<char_type> __ctype_type; + typedef std::ctype<char> __cctype_type; + typedef const pair<const char*, char_class_type> _ClassnameEntry; + const __ctype_type& __fctyp(use_facet<__ctype_type>(_M_locale)); + const __cctype_type& __cctyp(use_facet<__cctype_type>(_M_locale)); + + static _ClassnameEntry __classnames[] = + { + {"d", ctype_base::digit}, + {"w", {ctype_base::alnum, _RegexMask::_S_under}}, + {"s", ctype_base::space}, + {"alnum", ctype_base::alnum}, + {"alpha", ctype_base::alpha}, + {"blank", {0, _RegexMask::_S_blank}}, + {"cntrl", ctype_base::cntrl}, + {"digit", ctype_base::digit}, + {"graph", ctype_base::graph}, + {"lower", ctype_base::lower}, + {"print", ctype_base::print}, + {"punct", ctype_base::punct}, + {"space", ctype_base::space}, + {"upper", ctype_base::upper}, + {"xdigit", ctype_base::xdigit}, + }; + + std::string __s(__last - __first, '?'); + __fctyp.narrow(__first, __last, '?', &__s[0]); + __cctyp.tolower(&*__s.begin(), &*__s.begin() + __s.size()); + for (_ClassnameEntry* __it = __classnames; + __it < *(&__classnames + 1); + ++__it) + { + if (__s == __it->first) + { + if (__icase + && ((__it->second + & (ctype_base::lower | ctype_base::upper)) != 0)) + return ctype_base::alpha; + return __it->second; + } + } + return 0; + } + + template<typename _Ch_type> + bool + regex_traits<_Ch_type>:: + isctype(_Ch_type __c, char_class_type __f) const + { + typedef std::ctype<char_type> __ctype_type; + const __ctype_type& __fctyp(use_facet<__ctype_type>(_M_locale)); + + return __fctyp.is(__f._M_base, __c) + // [[:w:]] + || ((__f._M_extended & _RegexMask::_S_under) + && __c == __fctyp.widen('_')) + // [[:blank:]] + || ((__f._M_extended & _RegexMask::_S_blank) + && (__c == __fctyp.widen(' ') + || __c == __fctyp.widen('\t'))); + } + + template<typename _Ch_type> + int + regex_traits<_Ch_type>:: + value(_Ch_type __ch, int __radix) const + { + std::basic_istringstream<char_type> __is(string_type(1, __ch)); + long __v; + if (__radix == 8) + __is >> std::oct; + else if (__radix == 16) + __is >> std::hex; + __is >> __v; + return __is.fail() ? -1 : __v; + } + + template<typename _Bi_iter, typename _Alloc> + template<typename _Out_iter> + _Out_iter match_results<_Bi_iter, _Alloc>:: + format(_Out_iter __out, + const match_results<_Bi_iter, _Alloc>::char_type* __fmt_first, + const match_results<_Bi_iter, _Alloc>::char_type* __fmt_last, + match_flag_type __flags) const + { + _GLIBCXX_DEBUG_ASSERT( ready() ); + regex_traits<char_type> __traits; + typedef std::ctype<char_type> __ctype_type; + const __ctype_type& + __fctyp(use_facet<__ctype_type>(__traits.getloc())); + + auto __output = [&](size_t __idx) + { + auto& __sub = _Base_type::operator[](__idx); + if (__sub.matched) + std::copy(__sub.first, __sub.second, __out); + }; + + if (__flags & regex_constants::format_sed) + { + for (; __fmt_first != __fmt_last;) + if (*__fmt_first == '&') + { + __output(0); + ++__fmt_first; + } + else if (*__fmt_first == '\\') + { + if (++__fmt_first != __fmt_last + && __fctyp.is(__ctype_type::digit, *__fmt_first)) + __output(__traits.value(*__fmt_first++, 10)); + else + *__out++ = '\\'; + } + else + *__out++ = *__fmt_first++; + } + else + { + while (1) + { + auto __next = std::find(__fmt_first, __fmt_last, '$'); + if (__next == __fmt_last) + break; + + std::copy(__fmt_first, __next, __out); + + auto __eat = [&](char __ch) -> bool + { + if (*__next == __ch) + { + ++__next; + return true; + } + return false; + }; + + if (++__next == __fmt_last) + *__out++ = '$'; + else if (__eat('$')) + *__out++ = '$'; + else if (__eat('&')) + __output(0); + else if (__eat('`')) + __output(_Base_type::size()-2); + else if (__eat('\'')) + __output(_Base_type::size()-1); + else if (__fctyp.is(__ctype_type::digit, *__next)) + { + long __num = __traits.value(*__next, 10); + if (++__next != __fmt_last + && __fctyp.is(__ctype_type::digit, *__next)) + { + __num *= 10; + __num += __traits.value(*__next++, 10); + } + if (0 <= __num && __num < this->size()) + __output(__num); + } + else + *__out++ = '$'; + __fmt_first = __next; + } + std::copy(__fmt_first, __fmt_last, __out); + } + return __out; + } + + template<typename _Out_iter, typename _Bi_iter, + typename _Rx_traits, typename _Ch_type> + _Out_iter + regex_replace(_Out_iter __out, _Bi_iter __first, _Bi_iter __last, + const basic_regex<_Ch_type, _Rx_traits>& __e, + const _Ch_type* __fmt, + regex_constants::match_flag_type __flags) + { + typedef regex_iterator<_Bi_iter, _Ch_type, _Rx_traits> _IterT; + _IterT __i(__first, __last, __e, __flags); + _IterT __end; + if (__i == __end) + { + if (!(__flags & regex_constants::format_no_copy)) + std::copy(__first, __last, __out); + } + else + { + sub_match<_Bi_iter> __last; + auto __len = char_traits<_Ch_type>::length(__fmt); + for (; __i != __end; ++__i) + { + if (!(__flags & regex_constants::format_no_copy)) + std::copy(__i->prefix().first, __i->prefix().second, __out); + __out = __i->format(__out, __fmt, __fmt + __len, __flags); + __last = __i->suffix(); + if (__flags & regex_constants::format_first_only) + break; + } + if (!(__flags & regex_constants::format_no_copy)) + std::copy(__last.first, __last.second, __out); + } + return __out; + } + + template<typename _Bi_iter, + typename _Ch_type, + typename _Rx_traits> + bool + regex_iterator<_Bi_iter, _Ch_type, _Rx_traits>:: + operator==(const regex_iterator& __rhs) const + { + return (_M_match.empty() && __rhs._M_match.empty()) + || (_M_begin == __rhs._M_begin + && _M_end == __rhs._M_end + && _M_pregex == __rhs._M_pregex + && _M_flags == __rhs._M_flags + && _M_match[0] == __rhs._M_match[0]); + } + + template<typename _Bi_iter, + typename _Ch_type, + typename _Rx_traits> + regex_iterator<_Bi_iter, _Ch_type, _Rx_traits>& + regex_iterator<_Bi_iter, _Ch_type, _Rx_traits>:: + operator++() + { + // In all cases in which the call to regex_search returns true, + // match.prefix().first shall be equal to the previous value of + // match[0].second, and for each index i in the half-open range + // [0, match.size()) for which match[i].matched is true, + // match[i].position() shall return distance(begin, match[i].first). + // [28.12.1.4.5] + if (_M_match[0].matched) + { + auto __start = _M_match[0].second; + auto __prefix_first = _M_match[0].second; + if (_M_match[0].first == _M_match[0].second) + { + if (__start == _M_end) + { + _M_match = value_type(); + return *this; + } + else + { + if (regex_search(__start, _M_end, _M_match, *_M_pregex, + _M_flags + | regex_constants::match_not_null + | regex_constants::match_continuous)) + { + _GLIBCXX_DEBUG_ASSERT(_M_match[0].matched); + _M_match.at(_M_match.size()).first = __prefix_first; + _M_match._M_in_iterator = true; + _M_match._M_begin = _M_begin; + return *this; + } + else + ++__start; + } + } + _M_flags |= regex_constants::match_prev_avail; + if (regex_search(__start, _M_end, _M_match, *_M_pregex, _M_flags)) + { + _GLIBCXX_DEBUG_ASSERT(_M_match[0].matched); + _M_match.at(_M_match.size()).first = __prefix_first; + _M_match._M_in_iterator = true; + _M_match._M_begin = _M_begin; + } + else + _M_match = value_type(); + } + return *this; + } + + template<typename _Bi_iter, + typename _Ch_type, + typename _Rx_traits> + regex_token_iterator<_Bi_iter, _Ch_type, _Rx_traits>& + regex_token_iterator<_Bi_iter, _Ch_type, _Rx_traits>:: + operator=(const regex_token_iterator& __rhs) + { + _M_position = __rhs._M_position; + _M_subs = __rhs._M_subs; + _M_n = __rhs._M_n; + _M_result = __rhs._M_result; + _M_suffix = __rhs._M_suffix; + _M_has_m1 = __rhs._M_has_m1; + if (__rhs._M_result == &__rhs._M_suffix) + _M_result = &_M_suffix; + return *this; + } + + template<typename _Bi_iter, + typename _Ch_type, + typename _Rx_traits> + bool + regex_token_iterator<_Bi_iter, _Ch_type, _Rx_traits>:: + operator==(const regex_token_iterator& __rhs) const + { + if (_M_end_of_seq() && __rhs._M_end_of_seq()) + return true; + if (_M_suffix.matched && __rhs._M_suffix.matched + && _M_suffix == __rhs._M_suffix) + return true; + if (_M_end_of_seq() || _M_suffix.matched + || __rhs._M_end_of_seq() || __rhs._M_suffix.matched) + return false; + return _M_position == __rhs._M_position + && _M_n == __rhs._M_n + && _M_subs == __rhs._M_subs; + } + + template<typename _Bi_iter, + typename _Ch_type, + typename _Rx_traits> + regex_token_iterator<_Bi_iter, _Ch_type, _Rx_traits>& + regex_token_iterator<_Bi_iter, _Ch_type, _Rx_traits>:: + operator++() + { + _Position __prev = _M_position; + if (_M_suffix.matched) + *this = regex_token_iterator(); + else if (_M_n + 1 < _M_subs.size()) + { + _M_n++; + _M_result = &_M_current_match(); + } + else + { + _M_n = 0; + ++_M_position; + if (_M_position != _Position()) + _M_result = &_M_current_match(); + else if (_M_has_m1 && __prev->suffix().length() != 0) + { + _M_suffix.matched = true; + _M_suffix.first = __prev->suffix().first; + _M_suffix.second = __prev->suffix().second; + _M_result = &_M_suffix; + } + else + *this = regex_token_iterator(); + } + return *this; + } + + template<typename _Bi_iter, + typename _Ch_type, + typename _Rx_traits> + void + regex_token_iterator<_Bi_iter, _Ch_type, _Rx_traits>:: + _M_init(_Bi_iter __a, _Bi_iter __b) + { + _M_has_m1 = false; + for (auto __it : _M_subs) + if (__it == -1) + { + _M_has_m1 = true; + break; + } + if (_M_position != _Position()) + _M_result = &_M_current_match(); + else if (_M_has_m1) + { + _M_suffix.matched = true; + _M_suffix.first = __a; + _M_suffix.second = __b; + _M_result = &_M_suffix; + } + else + _M_result = nullptr; + } + +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace + diff --git a/libstdc++-v3/include/bits/regex_automaton.h b/libstdc++-v3/include/bits/regex_automaton.h index 94a14ce96aa..4fb555680ba 100644 --- a/libstdc++-v3/include/bits/regex_automaton.h +++ b/libstdc++-v3/include/bits/regex_automaton.h @@ -40,7 +40,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * @{ */ - typedef int _StateIdT; + typedef long _StateIdT; typedef std::set<_StateIdT> _StateSet; static const _StateIdT _S_invalid_state_id = -1; @@ -49,7 +49,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /// Operation codes that define the type of transitions within the base NFA /// that represents the regular expression. - enum _Opcode + enum _Opcode : int { _S_opcode_unknown, _S_opcode_alternative, @@ -69,15 +69,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION class _State { public: - typedef int _OpcodeT; typedef _Matcher<_CharT> _MatcherT; - _OpcodeT _M_opcode; // type of outgoing transition + _Opcode _M_opcode; // type of outgoing transition _StateIdT _M_next; // outgoing transition union // Since they are mutually exclusive. { - unsigned int _M_subexpr; // for _S_opcode_subexpr_* - unsigned int _M_backref_index; // for _S_opcode_backref + size_t _M_subexpr; // for _S_opcode_subexpr_* + size_t _M_backref_index; // for _S_opcode_backref struct { // for _S_opcode_alternative. @@ -91,7 +90,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION }; _MatcherT _M_matches; // for _S_opcode_match - explicit _State(_OpcodeT __opcode) + explicit _State(_Opcode __opcode) : _M_opcode(__opcode), _M_next(_S_invalid_state_id) { } @@ -105,37 +104,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #endif }; - /// Base class for, um, automata. Could be an NFA or a DFA. Your choice. - template<typename _CharT, typename _TraitsT> - class _Automaton - { - public: - typedef unsigned int _SizeT; - - public: - virtual _SizeT - _M_sub_count() const = 0; - -#ifdef _GLIBCXX_DEBUG - virtual std::ostream& - _M_dot(std::ostream& __ostr) const = 0; -#endif - }; - template<typename _CharT, typename _TraitsT> class _NFA - : public _Automaton<_CharT, _TraitsT>, - public std::vector<_State<_CharT, _TraitsT>> + : public std::vector<_State<_CharT, _TraitsT>> { public: typedef _State<_CharT, _TraitsT> _StateT; typedef const _Matcher<_CharT>& _MatcherT; - typedef unsigned int _SizeT; + typedef size_t _SizeT; typedef regex_constants::syntax_option_type _FlagT; _NFA(_FlagT __f) : _M_flags(__f), _M_start_state(0), _M_subexpr_count(0), - _M_has_backref(false), _M_quant_count(0) + _M_quant_count(0), _M_has_backref(false) { } _FlagT @@ -203,7 +184,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } _StateIdT - _M_insert_backref(unsigned int __index); + _M_insert_backref(size_t __index); _StateIdT _M_insert_line_begin() @@ -250,7 +231,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_dot(std::ostream& __ostr) const; #endif - std::vector<unsigned int> _M_paren_stack; + std::vector<size_t> _M_paren_stack; _StateSet _M_accepting_states; _FlagT _M_flags; _StateIdT _M_start_state; diff --git a/libstdc++-v3/include/bits/regex_automaton.tcc b/libstdc++-v3/include/bits/regex_automaton.tcc index 13af984c273..c15e3e99545 100644 --- a/libstdc++-v3/include/bits/regex_automaton.tcc +++ b/libstdc++-v3/include/bits/regex_automaton.tcc @@ -137,7 +137,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { __ostr << "digraph _Nfa {\n" << " rankdir=LR;\n"; - for (unsigned int __i = 0; __i < this->size(); ++__i) + for (size_t __i = 0; __i < this->size(); ++__i) { this->at(__i)._M_dot(__ostr, __i); } __ostr << "}\n"; return __ostr; @@ -146,7 +146,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _CharT, typename _TraitsT> _StateIdT _NFA<_CharT, _TraitsT>:: - _M_insert_backref(unsigned int __index) + _M_insert_backref(size_t __index) { // To figure out whether a backref is valid, a stack is used to store // unfinished sub-expressions. For example, when parsing @@ -175,7 +175,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION while (__it._M_next >= 0 && (*this)[__it._M_next]._M_opcode == _S_opcode_dummy) __it._M_next = (*this)[__it._M_next]._M_next; - if (__it._M_opcode == _S_opcode_alternative) + if (__it._M_opcode == _S_opcode_alternative + || __it._M_opcode == _S_opcode_subexpr_lookahead) while (__it._M_alt >= 0 && (*this)[__it._M_alt]._M_opcode == _S_opcode_dummy) __it._M_alt = (*this)[__it._M_alt]._M_next; @@ -201,7 +202,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION continue; if (__m.count(__dup._M_next) == 0) __stack.push(__dup._M_next); - if (__dup._M_opcode == _S_opcode_alternative) + if (__dup._M_opcode == _S_opcode_alternative + || __dup._M_opcode == _S_opcode_subexpr_lookahead) if (__m.count(__dup._M_alt) == 0) __stack.push(__dup._M_alt); } @@ -213,7 +215,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _GLIBCXX_DEBUG_ASSERT(__m.count(__ref._M_next)); __ref._M_next = __m[__ref._M_next]; } - if (__ref._M_opcode == _S_opcode_alternative) + if (__ref._M_opcode == _S_opcode_alternative + || __ref._M_opcode == _S_opcode_subexpr_lookahead) if (__ref._M_alt != -1) { _GLIBCXX_DEBUG_ASSERT(__m.count(__ref._M_alt)); diff --git a/libstdc++-v3/include/bits/regex_compiler.h b/libstdc++-v3/include/bits/regex_compiler.h index 3b85d3a46c3..7e4e6adafd5 100644 --- a/libstdc++-v3/include/bits/regex_compiler.h +++ b/libstdc++-v3/include/bits/regex_compiler.h @@ -120,13 +120,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return ret; } + _FlagT _M_flags; const _TraitsT& _M_traits; const _CtypeT& _M_ctype; _ScannerT _M_scanner; _RegexT _M_nfa; _StringT _M_value; _StackT _M_stack; - _FlagT _M_flags; }; template<typename _CharT, typename _TraitsT> @@ -156,7 +156,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION explicit _CharMatcher(_CharT __ch, const _TraitsT& __traits, _FlagT __flags) - : _M_ch(_M_translate(__ch)), _M_traits(__traits), _M_flags(__flags) + : _M_traits(__traits), _M_flags(__flags), _M_ch(_M_translate(__ch)) { } bool @@ -189,8 +189,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _BracketMatcher(bool __is_non_matching, const _TraitsT& __traits, _FlagT __flags) - : _M_is_non_matching(__is_non_matching), _M_traits(__traits), - _M_flags(__flags), _M_class_set(0) + : _M_traits(__traits), _M_class_set(0), _M_flags(__flags), + _M_is_non_matching(__is_non_matching) { } bool @@ -207,26 +207,30 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __s.data() + __s.size()); if (__st.empty()) __throw_regex_error(regex_constants::error_collate); - // TODO: digraph _M_char_set.insert(_M_translate(__st[0])); } void _M_add_equivalence_class(const _StringT& __s) { - _M_add_character_class( - _M_traits.transform_primary(__s.data(), - __s.data() + __s.size())); + auto __st = _M_traits.lookup_collatename(__s.data(), + __s.data() + __s.size()); + if (__st.empty()) + __throw_regex_error(regex_constants::error_collate); + __st = _M_traits.transform_primary(__st.data(), + __st.data() + __st.size()); + _M_equiv_set.insert(__st); } void _M_add_character_class(const _StringT& __s) { - auto __st = _M_traits. - lookup_classname(__s.data(), __s.data() + __s.size(), _M_is_icase()); - if (__st == 0) + auto __mask = _M_traits.lookup_classname(__s.data(), + __s.data() + __s.size(), + _M_is_icase()); + if (__mask == 0) __throw_regex_error(regex_constants::error_ctype); - _M_class_set |= __st; + _M_class_set |= __mask; } void @@ -261,6 +265,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } std::set<_CharT> _M_char_set; + std::set<_StringT> _M_equiv_set; std::set<pair<_StringT, _StringT>> _M_range_set; const _TraitsT& _M_traits; _CharClassT _M_class_set; diff --git a/libstdc++-v3/include/bits/regex_compiler.tcc b/libstdc++-v3/include/bits/regex_compiler.tcc index 7f9a19af2d9..e3764b8d82a 100644 --- a/libstdc++-v3/include/bits/regex_compiler.tcc +++ b/libstdc++-v3/include/bits/regex_compiler.tcc @@ -63,9 +63,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _Compiler<_FwdIter, _CharT, _TraitsT>:: _Compiler(_FwdIter __b, _FwdIter __e, const _TraitsT& __traits, _FlagT __flags) - : _M_traits(__traits), _M_scanner(__b, __e, __flags, _M_traits.getloc()), - _M_ctype(std::use_facet<std::ctype<_CharT>>(_M_traits.getloc())), - _M_nfa(__flags), _M_flags(__flags) + : _M_flags((__flags + & (regex_constants::ECMAScript + | regex_constants::basic + | regex_constants::extended + | regex_constants::grep + | regex_constants::egrep + | regex_constants::awk)) + ? __flags + : __flags | regex_constants::ECMAScript), + _M_traits(__traits), + _M_ctype(std::use_facet<std::ctype<_CharT>>(_M_traits.getloc())), + _M_scanner(__b, __e, _M_flags, _M_traits.getloc()), + _M_nfa(_M_flags) { _StateSeqT __r(_M_nfa, _M_nfa._M_start()); __r._M_append(_M_nfa._M_insert_subexpr_begin()); @@ -85,7 +95,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_disjunction() { this->_M_alternative(); - // TODO empty alternative like, um, "(|asdf)" while (_M_match_token(_ScannerT::_S_token_or)) { _StateSeqT __alt1 = _M_pop(); @@ -170,7 +179,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _Compiler<_FwdIter, _CharT, _TraitsT>:: _M_quantifier() { - bool __neg = regex_constants::ECMAScript; + bool __neg = (_M_flags & regex_constants::ECMAScript); auto __init = [this, &__neg]() { if (_M_stack.empty()) @@ -207,53 +216,66 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } else if (_M_match_token(_ScannerT::_S_token_interval_begin)) { - __init(); + if (_M_stack.empty()) + __throw_regex_error(regex_constants::error_badrepeat); if (!_M_match_token(_ScannerT::_S_token_dup_count)) __throw_regex_error(regex_constants::error_badbrace); _StateSeqT __r(_M_pop()); _StateSeqT __e(_M_nfa, _M_nfa._M_insert_dummy()); - int __min_rep = _M_cur_int_value(10); + long __min_rep = _M_cur_int_value(10); + bool __infi = false; + long __n; + // {3 - for (int __i = 0; __i < __min_rep; ++__i) - __e._M_append(__r._M_clone()); if (_M_match_token(_ScannerT::_S_token_comma)) if (_M_match_token(_ScannerT::_S_token_dup_count)) // {3,7} - { - int __n = _M_cur_int_value(10) - __min_rep; - if (__n < 0) - __throw_regex_error(regex_constants::error_badbrace); - auto __end = _M_nfa._M_insert_dummy(); - // _M_alt is the "match more" branch, and _M_next is the - // "match less" one. Switch _M_alt and _M_next of all created - // nodes. This is a hacking but IMO works well. - std::stack<_StateIdT> __stack; - for (int __i = 0; __i < __n; ++__i) - { - auto __tmp = __r._M_clone(); - auto __alt = _M_nfa._M_insert_alt(__tmp._M_start, - __end, __neg); - __stack.push(__alt); - __e._M_append(_StateSeqT(_M_nfa, __alt, __tmp._M_end)); - } - __e._M_append(__end); - while (!__stack.empty()) - { - auto& __tmp = _M_nfa[__stack.top()]; - __stack.pop(); - swap(__tmp._M_next, __tmp._M_alt); - } - } - else // {3,} - { - auto __tmp = __r._M_clone(); - _StateSeqT __s(_M_nfa, - _M_nfa._M_insert_alt(_S_invalid_state_id, - __tmp._M_start, __neg)); - __tmp._M_append(__s); - __e._M_append(__s); - } + __n = _M_cur_int_value(10) - __min_rep; + else + __infi = true; + else + __n = 0; if (!_M_match_token(_ScannerT::_S_token_interval_end)) __throw_regex_error(regex_constants::error_brace); + + __neg = __neg && _M_match_token(_ScannerT::_S_token_opt); + + for (long __i = 0; __i < __min_rep; ++__i) + __e._M_append(__r._M_clone()); + + if (__infi) + { + auto __tmp = __r._M_clone(); + _StateSeqT __s(_M_nfa, + _M_nfa._M_insert_alt(_S_invalid_state_id, + __tmp._M_start, __neg)); + __tmp._M_append(__s); + __e._M_append(__s); + } + else + { + if (__n < 0) + __throw_regex_error(regex_constants::error_badbrace); + auto __end = _M_nfa._M_insert_dummy(); + // _M_alt is the "match more" branch, and _M_next is the + // "match less" one. Switch _M_alt and _M_next of all created + // nodes. This is a hacking but IMO works well. + std::stack<_StateIdT> __stack; + for (long __i = 0; __i < __n; ++__i) + { + auto __tmp = __r._M_clone(); + auto __alt = _M_nfa._M_insert_alt(__tmp._M_start, + __end, __neg); + __stack.push(__alt); + __e._M_append(_StateSeqT(_M_nfa, __alt, __tmp._M_end)); + } + __e._M_append(__end); + while (!__stack.empty()) + { + auto& __tmp = _M_nfa[__stack.top()]; + __stack.pop(); + swap(__tmp._M_next, __tmp._M_alt); + } + } _M_stack.push(__e); } } @@ -296,7 +318,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } else if (_M_match_token(_ScannerT::_S_token_subexpr_begin)) { - int __mark = _M_nfa._M_sub_count(); _StateSeqT __r(_M_nfa, _M_nfa._M_insert_subexpr_begin()); this->_M_disjunction(); if (!_M_match_token(_ScannerT::_S_token_subexpr_end)) @@ -403,7 +424,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _Compiler<_FwdIter, _CharT, _TraitsT>:: _M_cur_int_value(int __radix) { - int __v = 0; + long __v = 0; for (typename _StringT::size_type __i = 0; __i < _M_value.length(); ++__i) __v =__v * __radix + _M_traits.value(_M_value[__i], __radix); @@ -415,9 +436,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION operator()(_CharT __ch) const { bool __ret = false; - if (_M_traits.isctype(__ch, _M_class_set)) - __ret = true; - else if (_M_char_set.count(_M_translate(__ch))) + if (_M_traits.isctype(__ch, _M_class_set) + || _M_char_set.count(_M_translate(__ch)) + || _M_equiv_set.count(_M_traits.transform_primary(&__ch, &__ch+1))) __ret = true; else { diff --git a/libstdc++-v3/include/bits/regex_error.h b/libstdc++-v3/include/bits/regex_error.h index 7f06727bfae..a39a8ea1a8f 100644 --- a/libstdc++-v3/include/bits/regex_error.h +++ b/libstdc++-v3/include/bits/regex_error.h @@ -61,7 +61,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _S_error_badrepeat, _S_error_complexity, _S_error_stack, - _S_error_last }; /** The expression contained an invalid collating element name. */ diff --git a/libstdc++-v3/include/bits/regex_executor.h b/libstdc++-v3/include/bits/regex_executor.h index b8e9266f910..6d9a83e8c5c 100644 --- a/libstdc++-v3/include/bits/regex_executor.h +++ b/libstdc++-v3/include/bits/regex_executor.h @@ -62,7 +62,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { public: typedef basic_regex<_CharT, _TraitsT> _RegexT; - typedef match_results<_BiIter, _Alloc> _ResultsT; typedef std::vector<sub_match<_BiIter>, _Alloc> _ResultsVec; typedef regex_constants::match_flag_type _FlagT; typedef typename _TraitsT::char_class_type _ClassT; @@ -70,14 +69,22 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION public: _Executor(_BiIter __begin, _BiIter __end, - _ResultsT& __results, + _ResultsVec& __results, const _RegexT& __re, _FlagT __flags) : _M_begin(__begin), _M_end(__end), - _M_results(__results), _M_re(__re), - _M_flags(__flags) + _M_results(__results), + _M_flags((__flags & regex_constants::match_prev_avail) + ? (__flags + & ~regex_constants::match_not_bol + & ~regex_constants::match_not_bow) + : __flags) + { } + + virtual + ~_Executor() { } // Set matched when string exactly match the pattern. @@ -99,22 +106,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } bool - _M_search() - { - if (_M_flags & regex_constants::match_continuous) - return _M_search_from_first(); - auto __cur = _M_begin; - do - { - _M_match_mode = false; - _M_init(__cur); - if (_M_main()) - return true; - } - // Continue when __cur == _M_end - while (__cur++ != _M_end); - return false; - } + _M_search(); bool _M_is_word(_CharT __ch) const @@ -142,8 +134,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION bool _M_word_boundry(_State<_CharT, _TraitsT> __state) const; + virtual std::unique_ptr<_Executor> + _M_clone() const = 0; + + // Return whether now match the given sub-NFA. bool - _M_lookahead(_State<_CharT, _TraitsT> __state) const; + _M_lookahead(_State<_CharT, _TraitsT> __state) const + { + auto __sub = this->_M_clone(); + __sub->_M_set_start(__state._M_alt); + return __sub->_M_search_from_first(); + } + + void + _M_set_results(_ResultsVec& __cur_results); public: virtual void @@ -159,8 +163,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION const _BiIter _M_begin; const _BiIter _M_end; const _RegexT& _M_re; - _ResultsT& _M_results; - const _FlagT _M_flags; + _ResultsVec& _M_results; + _FlagT _M_flags; bool _M_match_mode; }; @@ -175,8 +179,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // TODO: This approach is exponentially slow for certain input. // Try to compile the NFA to a DFA. // - // Time complexity: exponential - // Space complexity: O(__end - __begin) + // Time complexity: o(match_length), O(2^(_M_nfa->size())) + // Space complexity: \theta(match_results.size() + match_length) template<typename _BiIter, typename _Alloc, typename _CharT, typename _TraitsT> class _DFSExecutor @@ -186,27 +190,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typedef _Executor<_BiIter, _Alloc, _CharT, _TraitsT> _BaseT; typedef _NFA<_CharT, _TraitsT> _NFAT; typedef typename _BaseT::_RegexT _RegexT; - typedef typename _BaseT::_ResultsT _ResultsT; typedef typename _BaseT::_ResultsVec _ResultsVec; typedef typename _BaseT::_FlagT _FlagT; public: _DFSExecutor(_BiIter __begin, _BiIter __end, - _ResultsT& __results, + _ResultsVec& __results, const _RegexT& __re, _FlagT __flags) : _BaseT(__begin, __end, __results, __re, __flags), - _M_nfa(*std::static_pointer_cast<_NFA<_CharT, _TraitsT>> - (__re._M_automaton)), - _M_start_state(_M_nfa._M_start()) + _M_nfa(__re._M_automaton), _M_start_state(_M_nfa->_M_start()) { } private: void _M_init(_BiIter __cur) { - _M_cur_results.resize(_M_nfa._M_sub_count() + 2); + _M_cur_results.resize(_M_nfa->_M_sub_count() + 2); this->_M_current = __cur; } @@ -221,10 +222,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION bool _M_dfs(_StateIdT __start); + std::unique_ptr<_BaseT> + _M_clone() const + { + return std::unique_ptr<_BaseT>(new _DFSExecutor(this->_M_current, + this->_M_end, + this->_M_results, + this->_M_re, + this->_M_flags)); + } + // To record current solution. - _ResultsVec _M_cur_results; - const _NFAT& _M_nfa; - _StateIdT _M_start_state; + std::shared_ptr<_NFAT> _M_nfa; + _ResultsVec _M_cur_results; + _StateIdT _M_start_state; }; // Like the DFS approach, it try every possible state transition; Unlike DFS, @@ -238,8 +249,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // matching head. When states transit, solutions will be compared and // deduplicated(based on which greedy mode we have). // - // Time complexity: O((__end - __begin) * _M_nfa.size()) - // Space complexity: O(_M_nfa.size() * _M_nfa.mark_count()) + // Time complexity: o(match_length * (quantifier_number + // + match_results.size()) + // O(match_length * _M_nfa->size() + // * (quantifier_number + match_results.size()) + // Space complexity: o(quantifier_number + match_results.size()) + // O(_M_nfa->size() + // * (quantifier_number + match_results.size()) template<typename _BiIter, typename _Alloc, typename _CharT, typename _TraitsT> class _BFSExecutor @@ -249,7 +265,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typedef _Executor<_BiIter, _Alloc, _CharT, _TraitsT> _BaseT; typedef _NFA<_CharT, _TraitsT> _NFAT; typedef typename _BaseT::_RegexT _RegexT; - typedef typename _BaseT::_ResultsT _ResultsT; typedef typename _BaseT::_ResultsVec _ResultsVec; typedef typename _BaseT::_FlagT _FlagT; // Here's a solution for greedy/ungreedy mode in BFS approach. We need to @@ -264,8 +279,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // greedy policy. // // The definition of `greedy`: - // For the sequence of quantifiers in NFA sorted by there start position, - // now maintain a vector in every matching state, with equal length to + // For the sequence of quantifiers in NFA sorted by their start positions, + // now maintain a vector in every matching state, with length equal to // quantifier seq, recording repeating times of every quantifier. Now to // compare two matching states, we just lexically compare these two // vectors. To win the compare(to survive), one matching state needs to @@ -277,26 +292,26 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // operator<() for lexicographical_compare will emit the answer. // // When two vectors equal, it means the `where`, `when` and quantifier - // counts are identical, and indicates the same solution; so just return - // false. + // counts are identical, and indicates the same solution; so + // _ResultsEntry::operator<() just return false. struct _ResultsEntry : private _ResultsVec { public: - _ResultsEntry(unsigned int __res_sz, unsigned int __sz) + _ResultsEntry(size_t __res_sz, size_t __sz) : _ResultsVec(__res_sz), _M_quant_keys(__sz) { } void - resize(unsigned int __n) + resize(size_t __n) { _ResultsVec::resize(__n); } - unsigned int + size_t size() { return _ResultsVec::size(); } sub_match<_BiIter>& - operator[](unsigned int __idx) + operator[](size_t __idx) { return _ResultsVec::operator[](__idx); } bool @@ -311,10 +326,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } void - _M_inc(unsigned int __idx, bool __neg) + _M_inc(size_t __idx, bool __neg) { _M_quant_keys[__idx] += __neg ? 1 : -1; } - _ResultsVec + _ResultsVec& _M_get() { return *this; } @@ -323,30 +338,68 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION }; typedef std::unique_ptr<_ResultsEntry> _ResultsPtr; + class _TodoList + { + public: + explicit + _TodoList(size_t __sz) + : _M_states(), _M_exists(__sz, false) + { } + + void _M_push(_StateIdT __u) + { + _GLIBCXX_DEBUG_ASSERT(__u < _M_exists.size()); + if (!_M_exists[__u]) + { + _M_exists[__u] = true; + _M_states.push_back(__u); + } + } + + _StateIdT _M_pop() + { + auto __ret = _M_states.back(); + _M_states.pop_back(); + _M_exists[__ret] = false; + return __ret; + } + + bool _M_empty() const + { return _M_states.empty(); } + + void _M_clear() + { + _M_states.clear(); + _M_exists.assign(_M_exists.size(), false); + } + + private: + std::vector<_StateIdT> _M_states; + std::vector<bool> _M_exists; + }; + public: _BFSExecutor(_BiIter __begin, _BiIter __end, - _ResultsT& __results, + _ResultsVec& __results, const _RegexT& __re, _FlagT __flags) : _BaseT(__begin, __end, __results, __re, __flags), - _M_nfa(*std::static_pointer_cast<_NFA<_CharT, _TraitsT>> - (__re._M_automaton)), - _M_start_state(_M_nfa._M_start()) + _M_nfa(__re._M_automaton), _M_match_stack(_M_nfa->size()), + _M_stack(_M_nfa->size()), _M_start_state(_M_nfa->_M_start()) { } private: void _M_init(_BiIter __cur) { - _GLIBCXX_DEBUG_ASSERT(this->_M_start_state != _S_invalid_state_id); this->_M_current = __cur; _M_covered.clear(); _ResultsVec& __res(this->_M_results); _M_covered[this->_M_start_state] = _ResultsPtr(new _ResultsEntry(__res.size(), - _M_nfa._M_quant_count)); - _M_e_closure(); + _M_nfa->_M_quant_count)); + _M_stack._M_push(this->_M_start_state); } void @@ -365,22 +418,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION bool _M_includes_some(); + std::unique_ptr<_BaseT> + _M_clone() const + { + return std::unique_ptr<_BaseT>(new _BFSExecutor(this->_M_current, + this->_M_end, + this->_M_results, + this->_M_re, + this->_M_flags)); + } + + std::shared_ptr<_NFAT> _M_nfa; std::map<_StateIdT, _ResultsPtr> _M_covered; + _TodoList _M_match_stack; + _TodoList _M_stack; + _StateIdT _M_start_state; // To record global optimal solution. _ResultsPtr _M_cur_results; - const _NFAT& _M_nfa; - _StateIdT _M_start_state; }; - template<typename _BiIter, typename _Alloc, - typename _CharT, typename _TraitsT> - std::unique_ptr<_Executor<_BiIter, _Alloc, _CharT, _TraitsT>> - __get_executor(_BiIter __b, - _BiIter __e, - match_results<_BiIter, _Alloc>& __m, - const basic_regex<_CharT, _TraitsT>& __re, - regex_constants::match_flag_type __flags); - //@} regex-detail _GLIBCXX_END_NAMESPACE_VERSION } // namespace __detail diff --git a/libstdc++-v3/include/bits/regex_executor.tcc b/libstdc++-v3/include/bits/regex_executor.tcc index af2455b8a4e..7c084add031 100644 --- a/libstdc++-v3/include/bits/regex_executor.tcc +++ b/libstdc++-v3/include/bits/regex_executor.tcc @@ -28,6 +28,13 @@ * Do not attempt to use it directly. @headername{regex} */ +// See below __get_executor to get what this is talking about. The default +// value 1 indicated a conservative optimization without giving up worst case +// performance. +#ifndef _GLIBCXX_REGEX_DFS_QUANTIFIERS_LIMIT +#define _GLIBCXX_REGEX_DFS_QUANTIFIERS_LIMIT 1 +#endif + namespace std _GLIBCXX_VISIBILITY(default) { namespace __detail @@ -36,14 +43,31 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _BiIter, typename _Alloc, typename _CharT, typename _TraitsT> + bool _Executor<_BiIter, _Alloc, _CharT, _TraitsT>:: + _M_search() + { + if (_M_flags & regex_constants::match_continuous) + return _M_search_from_first(); + auto __cur = _M_begin; + do + { + _M_match_mode = false; + _M_init(__cur); + if (_M_main()) + return true; + } + // Continue when __cur == _M_end + while (__cur++ != _M_end); + return false; + } + + template<typename _BiIter, typename _Alloc, + typename _CharT, typename _TraitsT> bool _DFSExecutor<_BiIter, _Alloc, _CharT, _TraitsT>:: _M_dfs(_StateIdT __i) { - if (__i == _S_invalid_state_id) - // This is not that certain. Need deeper investigate. - return false; auto& __current = this->_M_current; - const auto& __state = _M_nfa[__i]; + const auto& __state = (*_M_nfa)[__i]; bool __ret = false; switch (__state._M_opcode) { @@ -66,7 +90,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION if (!_M_cur_results[__state._M_subexpr].matched || _M_cur_results[__state._M_subexpr].first != __current) { - auto __back = __current; + auto __back = _M_cur_results[__state._M_subexpr].first; _M_cur_results[__state._M_subexpr].first = __current; __ret = _M_dfs(__state._M_next); _M_cur_results[__state._M_subexpr].first = __back; @@ -128,15 +152,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION if (this->_M_re._M_traits.transform(__submatch.first, __submatch.second) == this->_M_re._M_traits.transform(__current, __last)) - if (__last != __current) - { - auto __backup = __current; - __current = __last; + { + if (__last != __current) + { + auto __backup = __current; + __current = __last; + __ret = _M_dfs(__state._M_next); + __current = __backup; + } + else __ret = _M_dfs(__state._M_next); - __current = __backup; - } - else - __ret = _M_dfs(__state._M_next); + } } break; case _S_opcode_accept: @@ -148,17 +174,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION && (this->_M_flags & regex_constants::match_not_null)) __ret = false; if (__ret) - { - _ResultsVec& __res(this->_M_results); - if (this->_M_re.flags() & regex_constants::nosubs) - { - _M_cur_results.resize(3); // truncate - __res.resize(3); - } - for (unsigned int __i = 0; __i < _M_cur_results.size(); ++__i) - if (_M_cur_results[__i].matched) - __res[__i] = _M_cur_results[__i]; - } + this->_M_set_results(_M_cur_results); break; default: _GLIBCXX_DEBUG_ASSERT(false); @@ -171,6 +187,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION bool _BFSExecutor<_BiIter, _Alloc, _CharT, _TraitsT>:: _M_main() { + _M_e_closure(); bool __ret = false; if (!this->_M_match_mode && !(this->_M_flags & regex_constants::match_not_null)) @@ -179,6 +196,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { _M_move(); ++this->_M_current; + if (_M_stack._M_empty()) + break; _M_e_closure(); if (!this->_M_match_mode) // To keep regex_search greedy, no "return true" here. @@ -187,18 +206,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION if (this->_M_match_mode) __ret = _M_includes_some(); if (__ret) - { - _ResultsVec& __res(this->_M_results); - if (this->_M_re.flags() & regex_constants::nosubs) - { - // truncate - _M_cur_results->resize(3); - __res.resize(3); - } - for (unsigned int __i = 0; __i < _M_cur_results->size(); ++__i) - if ((*_M_cur_results)[__i].matched) - __res[__i] = (*_M_cur_results)[__i]; - } + this->_M_set_results(_M_cur_results->_M_get()); + _M_match_stack._M_clear(); + _GLIBCXX_DEBUG_ASSERT(_M_stack._M_empty()); return __ret; } @@ -207,42 +217,34 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION void _BFSExecutor<_BiIter, _Alloc, _CharT, _TraitsT>:: _M_e_closure() { - std::queue<_StateIdT> __q; - std::vector<bool> __in_q(_M_nfa.size(), false); auto& __current = this->_M_current; - for (auto& __it : _M_covered) + while (!_M_stack._M_empty()) { - __in_q[__it.first] = true; - __q.push(__it.first); - } - while (!__q.empty()) - { - auto __u = __q.front(); - __q.pop(); - __in_q[__u] = false; - const auto& __state = _M_nfa[__u]; + auto __u = _M_stack._M_pop(); + _GLIBCXX_DEBUG_ASSERT(_M_covered.count(__u)); + const auto& __state = (*_M_nfa)[__u]; // Can be implemented using method, but there will be too many // arguments. I would use macro function before C++11, but lambda is // a better choice, since hopefully compiler can inline it. - auto __add_visited_state = [&](_StateIdT __v) + auto __add_visited_state = [=](_StateIdT __v) { - if (__v == _S_invalid_state_id) - return; - if (_M_covered.count(__u) != 0 - && (_M_covered.count(__v) == 0 - || *_M_covered[__u] < *_M_covered[__v])) + if (_M_covered.count(__v) == 0) { _M_covered[__v] = _ResultsPtr(new _ResultsEntry(*_M_covered[__u])); + _M_stack._M_push(__v); + return; + } + auto& __cu = _M_covered[__u]; + auto& __cv = _M_covered[__v]; + if (*__cu < *__cv) + { + __cv = _ResultsPtr(new _ResultsEntry(*__cu)); // if a state is updated, it's outgoing neighbors should be // reconsidered too. Push them to the queue. - if (!__in_q[__v]) - { - __in_q[__v] = true; - __q.push(__v); - } + _M_stack._M_push(__v); } }; @@ -254,13 +256,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION case _S_opcode_alternative: { __add_visited_state(__state._M_next); - auto __back = - _M_covered[__u]->_M_quant_keys[__state._M_quant_index]; - _M_covered[__u]->_M_inc(__state._M_quant_index, - __state._M_neg); + auto& __cu = *_M_covered[__u]; + auto __back = __cu._M_quant_keys[__state._M_quant_index]; + __cu._M_inc(__state._M_quant_index, __state._M_neg); __add_visited_state(__state._M_alt); - _M_covered[__u]->_M_quant_keys[__state._M_quant_index] - = __back; + __cu._M_quant_keys[__state._M_quant_index] = __back; } break; case _S_opcode_subexpr_begin: @@ -302,6 +302,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __add_visited_state(__state._M_next); break; case _S_opcode_match: + _M_match_stack._M_push(__u); break; case _S_opcode_accept: break; @@ -317,15 +318,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_move() { decltype(_M_covered) __next; - for (auto& __it : _M_covered) + while (!_M_match_stack._M_empty()) { - const auto& __state = _M_nfa[__it.first]; - if (__state._M_opcode == _S_opcode_match - && __state._M_matches(*this->_M_current)) - if (__state._M_next != _S_invalid_state_id) - if (__next.count(__state._M_next) == 0 - || *__it.second < *__next[__state._M_next]) - __next[__state._M_next] = move(__it.second); + auto __u = _M_match_stack._M_pop(); + const auto& __state = (*_M_nfa)[__u]; + auto& __cu = _M_covered[__u]; + if (__state._M_matches(*this->_M_current) + && (__next.count(__state._M_next) == 0 + || *__cu < *__next[__state._M_next])) + { + __next[__state._M_next] = std::move(__cu); + _M_stack._M_push(__state._M_next); + } } _M_covered = move(__next); } @@ -335,31 +339,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION bool _BFSExecutor<_BiIter, _Alloc, _CharT, _TraitsT>:: _M_includes_some() { - auto& __s = _M_nfa._M_final_states(); - auto& __t = _M_covered; bool __succ = false; - if (__s.size() > 0 && __t.size() > 0) - { - auto __first = __s.begin(); - auto __second = __t.begin(); - while (__first != __s.end() && __second != __t.end()) - { - if (*__first < __second->first) - ++__first; - else if (*__first > __second->first) - ++__second; - else - { - if (_M_cur_results == nullptr - || *__second->second < *_M_cur_results) - _M_cur_results = - _ResultsPtr(new _ResultsEntry(*__second->second)); - __succ = true; - ++__first; - ++__second; - } - } - } + for (auto __u : _M_nfa->_M_final_states()) + if (_M_covered.count(__u)) + { + __succ = true; + auto& __cu = _M_covered[__u]; + if (_M_cur_results == nullptr || *__cu < *_M_cur_results) + _M_cur_results = _ResultsPtr(new _ResultsEntry(*__cu)); + } return __succ; } @@ -374,39 +362,53 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION auto __pre = _M_current; --__pre; if (!(_M_at_begin() && _M_at_end())) - if (_M_at_begin()) - __ans = _M_is_word(*_M_current) - && !(_M_flags & regex_constants::match_not_bow); - else if (_M_at_end()) - __ans = _M_is_word(*__pre) - && !(_M_flags & regex_constants::match_not_eow); - else - __ans = _M_is_word(*_M_current) - != _M_is_word(*__pre); + { + if (_M_at_begin()) + __ans = _M_is_word(*_M_current) + && !(_M_flags & regex_constants::match_not_bow); + else if (_M_at_end()) + __ans = _M_is_word(*__pre) + && !(_M_flags & regex_constants::match_not_eow); + else + __ans = _M_is_word(*_M_current) + != _M_is_word(*__pre); + } return __ans; } - // Return whether now match the given sub-NFA. template<typename _BiIter, typename _Alloc, typename _CharT, typename _TraitsT> - bool _Executor<_BiIter, _Alloc, _CharT, _TraitsT>:: - _M_lookahead(_State<_CharT, _TraitsT> __state) const + void _Executor<_BiIter, _Alloc, _CharT, _TraitsT>:: + _M_set_results(_ResultsVec& __cur_results) { - auto __sub = __get_executor(this->_M_current, - this->_M_end, - this->_M_results, - this->_M_re, - this->_M_flags); - __sub->_M_set_start(__state._M_alt); - return __sub->_M_search_from_first(); + for (size_t __i = 0; __i < __cur_results.size(); ++__i) + if (__cur_results[__i].matched) + _M_results[__i] = __cur_results[__i]; } + enum class _RegexExecutorPolicy : int + { _S_auto, _S_alternate }; + + // This function decide which executor to use under given circumstances. + // The _S_auto policy now is the following: if a NFA has no back-references + // and has more than _GLIBCXX_REGEX_DFS_QUANTIFIERS_LIMIT quantifiers + // (*, +, ?), the _BFSExecutor will be used, other wise _DFSExecutor. This is + // because _DFSExecutor has a exponential upper bound, but better best-case + // performace. Meanwhile, _BFSExecutor can effectively prevent from + // exponential-long time matching (which must contains many quantifiers), but + // it's slower in average. + // + // For simple regex, _BFSExecutor could be 2 or more times slower than + // _DFSExecutor. + // + // Of course, _BFSExecutor cannot handle back-references. template<typename _BiIter, typename _Alloc, - typename _CharT, typename _TraitsT> + typename _CharT, typename _TraitsT, + _RegexExecutorPolicy __policy> std::unique_ptr<_Executor<_BiIter, _Alloc, _CharT, _TraitsT>> __get_executor(_BiIter __b, _BiIter __e, - match_results<_BiIter, _Alloc>& __m, + std::vector<sub_match<_BiIter>, _Alloc>& __m, const basic_regex<_CharT, _TraitsT>& __re, regex_constants::match_flag_type __flags) { @@ -414,11 +416,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _ExecutorPtr; typedef _DFSExecutor<_BiIter, _Alloc, _CharT, _TraitsT> _DFSExecutorT; typedef _BFSExecutor<_BiIter, _Alloc, _CharT, _TraitsT> _BFSExecutorT; - auto __p = std::static_pointer_cast<_NFA<_CharT, _TraitsT>> - (__re._M_automaton); - if (__p->_M_has_backref) - return _ExecutorPtr(new _DFSExecutorT(__b, __e, __m, __re, __flags)); - return _ExecutorPtr(new _BFSExecutorT(__b, __e, __m, __re, __flags)); + if (!__re._M_automaton->_M_has_backref + && (__policy == _RegexExecutorPolicy::_S_alternate + || __re._M_automaton->_M_quant_count + > _GLIBCXX_REGEX_DFS_QUANTIFIERS_LIMIT)) + return _ExecutorPtr(new _BFSExecutorT(__b, __e, __m, __re, __flags)); + return _ExecutorPtr(new _DFSExecutorT(__b, __e, __m, __re, __flags)); } _GLIBCXX_END_NAMESPACE_VERSION diff --git a/libstdc++-v3/include/bits/regex_scanner.tcc b/libstdc++-v3/include/bits/regex_scanner.tcc index abdbcc64f1f..f6cef6a04c2 100644 --- a/libstdc++-v3/include/bits/regex_scanner.tcc +++ b/libstdc++-v3/include/bits/regex_scanner.tcc @@ -56,8 +56,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _Scanner<_FwdIter>:: _Scanner(_FwdIter __begin, _FwdIter __end, _FlagT __flags, std::locale __loc) - : _M_current(__begin) , _M_end(__end) , _M_flags(__flags), - _M_ctype(std::use_facet<_CtypeT>(__loc)), _M_state(_S_state_normal), + : _M_state(_S_state_normal), _M_current(__begin), _M_end(__end), + _M_flags(__flags), + _M_ctype(std::use_facet<_CtypeT>(__loc)), _M_at_bracket_start(false), _M_token_map { @@ -94,9 +95,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION {'t', '\t'}, {'v', '\v'}, }, - _M_escape_map(_M_is_ecma() - ? _M_ecma_escape_map - : _M_awk_escape_map), _M_ecma_spec_char { '^', @@ -138,14 +136,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION '^', '$', }, - _M_eat_escape(_M_is_ecma() - ? &_Scanner::_M_eat_escape_ecma - : &_Scanner::_M_eat_escape_posix), + _M_escape_map(_M_is_ecma() + ? _M_ecma_escape_map + : _M_awk_escape_map), _M_spec_char(_M_is_ecma() ? _M_ecma_spec_char : _M_is_basic() ? _M_basic_spec_char - : _M_extended_spec_char) + : _M_extended_spec_char), + _M_eat_escape(_M_is_ecma() + ? &_Scanner::_M_eat_escape_ecma + : &_Scanner::_M_eat_escape_posix) { _M_advance(); } template<typename _FwdIter> @@ -243,9 +244,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_state = _S_state_in_brace; _M_token = _S_token_interval_begin; } - else if (_M_spec_char.count(__c) - && __c != ']' - && __c != '}' + else if ((_M_spec_char.count(_M_ctype.narrow(__c, '\0')) + && __c != ']' + && __c != '}') || (_M_is_grep() && __c == '\n')) _M_token = _M_token_map.at(__c); else @@ -345,7 +346,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ++_M_current; } else - __throw_regex_error(regex_constants::error_brace); + __throw_regex_error(regex_constants::error_badbrace); } else if (__c == '}') { @@ -353,7 +354,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_token = _S_token_interval_end; } else - __throw_regex_error(regex_constants::error_brace); + __throw_regex_error(regex_constants::error_badbrace); } template<typename _FwdIter> @@ -366,7 +367,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION auto __c = *_M_current++; - if (_M_escape_map.count(__c) + if (_M_escape_map.count(_M_ctype.narrow(__c, '\0')) && (__c != 'b' || _M_state == _S_state_in_bracket)) { _M_token = _S_token_ord_char; @@ -428,6 +429,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } } + // Differences between styles: + // 1) Extended doesn't support backref, but basic does. template<typename _FwdIter> void _Scanner<_FwdIter>:: @@ -438,7 +441,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION auto __c = *_M_current; - if (_M_spec_char.count(__c)) + if (_M_spec_char.count(_M_ctype.narrow(__c, '\0'))) { _M_token = _S_token_ord_char; _M_value.assign(1, __c); @@ -449,13 +452,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_eat_escape_awk(); return; } - else if (_M_ctype.is(_CtypeT::digit, __c) && __c != '0') + else if (_M_is_basic() && _M_ctype.is(_CtypeT::digit, __c) && __c != '0') { _M_token = _S_token_backref; _M_value.assign(1, __c); } else - __throw_regex_error(regex_constants::error_escape); + { +#ifdef __STRICT_ANSI__ + __throw_regex_error(regex_constants::error_escape); +#else + _M_token = _S_token_ord_char; + _M_value.assign(1, __c); +#endif + } ++_M_current; } @@ -466,7 +476,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { auto __c = *_M_current++; - if (_M_escape_map.count(__c)) + if (_M_escape_map.count(_M_ctype.narrow(__c, '\0'))) { _M_token = _S_token_ord_char; _M_value.assign(1, _M_escape_map.at(__c)); @@ -506,10 +516,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION || *_M_current++ != __ch || _M_current == _M_end // skip __ch || *_M_current++ != ']') // skip ']' - if (__ch == ':') - __throw_regex_error(regex_constants::error_ctype); - else - __throw_regex_error(regex_constants::error_collate); + { + if (__ch == ':') + __throw_regex_error(regex_constants::error_ctype); + else + __throw_regex_error(regex_constants::error_collate); + } } #ifdef _GLIBCXX_DEBUG diff --git a/libstdc++-v3/include/bits/shared_ptr_base.h b/libstdc++-v3/include/bits/shared_ptr_base.h index fb19d0887dc..911dd928c0b 100644 --- a/libstdc++-v3/include/bits/shared_ptr_base.h +++ b/libstdc++-v3/include/bits/shared_ptr_base.h @@ -459,10 +459,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_get_deleter(const std::type_info& __ti) noexcept { #ifdef __GXX_RTTI - return __ti == typeid(_Sp_make_shared_tag) ? _M_ptr() : nullptr; -#else - return nullptr; + if (__ti == typeid(_Sp_make_shared_tag)) + return const_cast<typename remove_cv<_Tp>::type*>(_M_ptr()); #endif + return nullptr; } private: @@ -495,29 +495,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } template<typename _Ptr, typename _Deleter> - __shared_count(_Ptr __p, _Deleter __d) : _M_pi(0) - { - // The allocator's value_type doesn't matter, will rebind it anyway. - typedef std::allocator<int> _Alloc; - typedef _Sp_counted_deleter<_Ptr, _Deleter, _Alloc, _Lp> _Sp_cd_type; - typedef typename allocator_traits<_Alloc>::template - rebind_traits<_Sp_cd_type> _Alloc_traits; - typename _Alloc_traits::allocator_type __a; - _Sp_cd_type* __mem = 0; - __try - { - __mem = _Alloc_traits::allocate(__a, 1); - _Alloc_traits::construct(__a, __mem, __p, std::move(__d)); - _M_pi = __mem; - } - __catch(...) - { - __d(__p); // Call _Deleter on __p. - if (__mem) - _Alloc_traits::deallocate(__a, __mem, 1); - __throw_exception_again; - } - } + __shared_count(_Ptr __p, _Deleter __d) + : __shared_count(__p, std::move(__d), allocator<void>()) + { } template<typename _Ptr, typename _Deleter, typename _Alloc> __shared_count(_Ptr __p, _Deleter __d, _Alloc __a) : _M_pi(0) @@ -576,16 +556,29 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // Special case for unique_ptr<_Tp,_Del> to provide the strong guarantee. template<typename _Tp, typename _Del> explicit - __shared_count(std::unique_ptr<_Tp, _Del>&& __r) - : _M_pi(_S_create_from_up(std::move(__r))) - { __r.release(); } + __shared_count(std::unique_ptr<_Tp, _Del>&& __r) : _M_pi(0) + { + using _Ptr = typename unique_ptr<_Tp, _Del>::pointer; + using _Del2 = typename conditional<is_reference<_Del>::value, + reference_wrapper<typename remove_reference<_Del>::type>, + _Del>::type; + using _Sp_cd_type + = _Sp_counted_deleter<_Ptr, _Del2, allocator<void>, _Lp>; + using _Alloc = allocator<_Sp_cd_type>; + using _Alloc_traits = allocator_traits<_Alloc>; + _Alloc __a; + _Sp_cd_type* __mem = _Alloc_traits::allocate(__a, 1); + _Alloc_traits::construct(__a, __mem, __r.release(), + __r.get_deleter()); // non-throwing + _M_pi = __mem; + } // Throw bad_weak_ptr when __r._M_get_use_count() == 0. explicit __shared_count(const __weak_count<_Lp>& __r); ~__shared_count() noexcept { - if (_M_pi != 0) + if (_M_pi != nullptr) _M_pi->_M_release(); } @@ -647,28 +640,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION private: friend class __weak_count<_Lp>; - template<typename _Tp, typename _Del> - static _Sp_counted_base<_Lp>* - _S_create_from_up(std::unique_ptr<_Tp, _Del>&& __r, - typename std::enable_if<!std::is_reference<_Del>::value>::type* = 0) - { - typedef typename unique_ptr<_Tp, _Del>::pointer _Ptr; - return new _Sp_counted_deleter<_Ptr, _Del, std::allocator<void>, - _Lp>(__r.get(), __r.get_deleter()); - } - - template<typename _Tp, typename _Del> - static _Sp_counted_base<_Lp>* - _S_create_from_up(std::unique_ptr<_Tp, _Del>&& __r, - typename std::enable_if<std::is_reference<_Del>::value>::type* = 0) - { - typedef typename unique_ptr<_Tp, _Del>::pointer _Ptr; - typedef typename std::remove_reference<_Del>::type _Del1; - typedef std::reference_wrapper<_Del1> _Del2; - return new _Sp_counted_deleter<_Ptr, _Del2, std::allocator<void>, - _Lp>(__r.get(), std::ref(__r.get_deleter())); - } - _Sp_counted_base<_Lp>* _M_pi; }; diff --git a/libstdc++-v3/include/bits/stl_algo.h b/libstdc++-v3/include/bits/stl_algo.h index b06211e0100..b21d748b0bd 100644 --- a/libstdc++-v3/include/bits/stl_algo.h +++ b/libstdc++-v3/include/bits/stl_algo.h @@ -60,10 +60,10 @@ #include <bits/algorithmfwd.h> #include <bits/stl_heap.h> #include <bits/stl_tempbuf.h> // for _Temporary_buffer +#include <bits/predefined_ops.h> #if __cplusplus >= 201103L #include <random> // for std::uniform_int_distribution -#include <functional> // for std::bind #endif // See concept_check.h for the __glibcxx_*_requires macros. @@ -72,129 +72,41 @@ namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION - /// Swaps the median value of *__a, *__b and *__c to *__a - template<typename _Iterator> - void - __move_median_first(_Iterator __a, _Iterator __b, _Iterator __c) - { - // concept requirements - __glibcxx_function_requires(_LessThanComparableConcept< - typename iterator_traits<_Iterator>::value_type>) - - if (*__a < *__b) - { - if (*__b < *__c) - std::iter_swap(__a, __b); - else if (*__a < *__c) - std::iter_swap(__a, __c); - } - else if (*__a < *__c) - return; - else if (*__b < *__c) - std::iter_swap(__a, __c); - else - std::iter_swap(__a, __b); - } - - /// Swaps the median value of *__a, *__b and *__c under __comp to *__a + /// Swaps the median value of *__a, *__b and *__c under __comp to *__result template<typename _Iterator, typename _Compare> void - __move_median_first(_Iterator __a, _Iterator __b, _Iterator __c, - _Compare __comp) + __move_median_to_first(_Iterator __result,_Iterator __a, _Iterator __b, + _Iterator __c, _Compare __comp) { - // concept requirements - __glibcxx_function_requires(_BinaryFunctionConcept<_Compare, bool, - typename iterator_traits<_Iterator>::value_type, - typename iterator_traits<_Iterator>::value_type>) - - if (__comp(*__a, *__b)) + if (__comp(__a, __b)) { - if (__comp(*__b, *__c)) - std::iter_swap(__a, __b); - else if (__comp(*__a, *__c)) - std::iter_swap(__a, __c); + if (__comp(__b, __c)) + std::iter_swap(__result, __b); + else if (__comp(__a, __c)) + std::iter_swap(__result, __c); + else + std::iter_swap(__result, __a); } - else if (__comp(*__a, *__c)) - return; - else if (__comp(*__b, *__c)) - std::iter_swap(__a, __c); + else if (__comp(__a, __c)) + std::iter_swap(__result, __a); + else if (__comp(__b, __c)) + std::iter_swap(__result, __c); else - std::iter_swap(__a, __b); + std::iter_swap(__result, __b); } - // for_each - - /// This is an overload used by find() for the Input Iterator case. - template<typename _InputIterator, typename _Tp> - inline _InputIterator - __find(_InputIterator __first, _InputIterator __last, - const _Tp& __val, input_iterator_tag) - { - while (__first != __last && !(*__first == __val)) - ++__first; - return __first; - } - - /// This is an overload used by find_if() for the Input Iterator case. + /// This is an overload used by find algos for the Input Iterator case. template<typename _InputIterator, typename _Predicate> inline _InputIterator __find_if(_InputIterator __first, _InputIterator __last, _Predicate __pred, input_iterator_tag) { - while (__first != __last && !bool(__pred(*__first))) + while (__first != __last && !__pred(__first)) ++__first; return __first; } - /// This is an overload used by find() for the RAI case. - template<typename _RandomAccessIterator, typename _Tp> - _RandomAccessIterator - __find(_RandomAccessIterator __first, _RandomAccessIterator __last, - const _Tp& __val, random_access_iterator_tag) - { - typename iterator_traits<_RandomAccessIterator>::difference_type - __trip_count = (__last - __first) >> 2; - - for (; __trip_count > 0; --__trip_count) - { - if (*__first == __val) - return __first; - ++__first; - - if (*__first == __val) - return __first; - ++__first; - - if (*__first == __val) - return __first; - ++__first; - - if (*__first == __val) - return __first; - ++__first; - } - - switch (__last - __first) - { - case 3: - if (*__first == __val) - return __first; - ++__first; - case 2: - if (*__first == __val) - return __first; - ++__first; - case 1: - if (*__first == __val) - return __first; - ++__first; - case 0: - default: - return __last; - } - } - - /// This is an overload used by find_if() for the RAI case. + /// This is an overload used by find algos for the RAI case. template<typename _RandomAccessIterator, typename _Predicate> _RandomAccessIterator __find_if(_RandomAccessIterator __first, _RandomAccessIterator __last, @@ -205,19 +117,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION for (; __trip_count > 0; --__trip_count) { - if (__pred(*__first)) + if (__pred(__first)) return __first; ++__first; - if (__pred(*__first)) + if (__pred(__first)) return __first; ++__first; - if (__pred(*__first)) + if (__pred(__first)) return __first; ++__first; - if (__pred(*__first)) + if (__pred(__first)) return __first; ++__first; } @@ -225,15 +137,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION switch (__last - __first) { case 3: - if (__pred(*__first)) + if (__pred(__first)) return __first; ++__first; case 2: - if (__pred(*__first)) + if (__pred(__first)) return __first; ++__first; case 1: - if (__pred(*__first)) + if (__pred(__first)) return __first; ++__first; case 0: @@ -242,63 +154,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } } - /// This is an overload used by find_if_not() for the Input Iterator case. - template<typename _InputIterator, typename _Predicate> - inline _InputIterator - __find_if_not(_InputIterator __first, _InputIterator __last, - _Predicate __pred, input_iterator_tag) - { - while (__first != __last && bool(__pred(*__first))) - ++__first; - return __first; - } - - /// This is an overload used by find_if_not() for the RAI case. - template<typename _RandomAccessIterator, typename _Predicate> - _RandomAccessIterator - __find_if_not(_RandomAccessIterator __first, _RandomAccessIterator __last, - _Predicate __pred, random_access_iterator_tag) + template<typename _Iterator, typename _Predicate> + inline _Iterator + __find_if(_Iterator __first, _Iterator __last, _Predicate __pred) { - typename iterator_traits<_RandomAccessIterator>::difference_type - __trip_count = (__last - __first) >> 2; - - for (; __trip_count > 0; --__trip_count) - { - if (!bool(__pred(*__first))) - return __first; - ++__first; - - if (!bool(__pred(*__first))) - return __first; - ++__first; - - if (!bool(__pred(*__first))) - return __first; - ++__first; - - if (!bool(__pred(*__first))) - return __first; - ++__first; - } - - switch (__last - __first) - { - case 3: - if (!bool(__pred(*__first))) - return __first; - ++__first; - case 2: - if (!bool(__pred(*__first))) - return __first; - ++__first; - case 1: - if (!bool(__pred(*__first))) - return __first; - ++__first; - case 0: - default: - return __last; - } + return __find_if(__first, __last, __pred, + std::__iterator_category(__first)); } /// Provided for stable_partition to use. @@ -307,8 +168,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __find_if_not(_InputIterator __first, _InputIterator __last, _Predicate __pred) { - return std::__find_if_not(__first, __last, __pred, - std::__iterator_category(__first)); + return std::__find_if(__first, __last, + __gnu_cxx::__ops::__negate(__pred), + std::__iterator_category(__first)); } /// Like find_if_not(), but uses and updates a count of the @@ -319,7 +181,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __find_if_not_n(_InputIterator __first, _Distance& __len, _Predicate __pred) { for (; __len; --__len, ++__first) - if (!bool(__pred(*__first))) + if (!__pred(__first)) break; return __first; } @@ -337,98 +199,73 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // count_if // search - /** - * This is an uglified - * search_n(_ForwardIterator, _ForwardIterator, _Integer, const _Tp&) - * overloaded for forward iterators. - */ - template<typename _ForwardIterator, typename _Integer, typename _Tp> - _ForwardIterator - __search_n(_ForwardIterator __first, _ForwardIterator __last, - _Integer __count, const _Tp& __val, - std::forward_iterator_tag) + template<typename _ForwardIterator1, typename _ForwardIterator2, + typename _BinaryPredicate> + _ForwardIterator1 + __search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2, + _BinaryPredicate __predicate) { - __first = _GLIBCXX_STD_A::find(__first, __last, __val); - while (__first != __last) - { - typename iterator_traits<_ForwardIterator>::difference_type - __n = __count; - _ForwardIterator __i = __first; - ++__i; - while (__i != __last && __n != 1 && *__i == __val) - { - ++__i; - --__n; - } - if (__n == 1) - return __first; - if (__i == __last) - return __last; - __first = _GLIBCXX_STD_A::find(++__i, __last, __val); - } - return __last; - } + // Test for empty ranges + if (__first1 == __last1 || __first2 == __last2) + return __first1; - /** - * This is an uglified - * search_n(_ForwardIterator, _ForwardIterator, _Integer, const _Tp&) - * overloaded for random access iterators. - */ - template<typename _RandomAccessIter, typename _Integer, typename _Tp> - _RandomAccessIter - __search_n(_RandomAccessIter __first, _RandomAccessIter __last, - _Integer __count, const _Tp& __val, - std::random_access_iterator_tag) - { - - typedef typename std::iterator_traits<_RandomAccessIter>::difference_type - _DistanceType; + // Test for a pattern of length 1. + _ForwardIterator2 __p1(__first2); + if (++__p1 == __last2) + return std::__find_if(__first1, __last1, + __gnu_cxx::__ops::__iter_comp_iter(__predicate, __first2)); - _DistanceType __tailSize = __last - __first; - _DistanceType __remainder = __count; + // General case. + _ForwardIterator2 __p; + _ForwardIterator1 __current = __first1; - while (__remainder <= __tailSize) // the main loop... + for (;;) { - __first += __remainder; - __tailSize -= __remainder; - // __first here is always pointing to one past the last element of - // next possible match. - _RandomAccessIter __backTrack = __first; - while (*--__backTrack == __val) + __first1 = + std::__find_if(__first1, __last1, + __gnu_cxx::__ops::__iter_comp_iter(__predicate, __first2)); + + if (__first1 == __last1) + return __last1; + + __p = __p1; + __current = __first1; + if (++__current == __last1) + return __last1; + + while (__predicate(__current, __p)) { - if (--__remainder == 0) - return (__first - __count); // Success + if (++__p == __last2) + return __first1; + if (++__current == __last1) + return __last1; } - __remainder = __count + 1 - (__first - __backTrack); + ++__first1; } - return __last; // Failure + return __first1; } // search_n /** - * This is an uglified - * search_n(_ForwardIterator, _ForwardIterator, _Integer, const _Tp&, - * _BinaryPredicate) - * overloaded for forward iterators. + * This is an helper function for search_n overloaded for forward iterators. */ - template<typename _ForwardIterator, typename _Integer, typename _Tp, - typename _BinaryPredicate> + template<typename _ForwardIterator, typename _Integer, + typename _UnaryPredicate> _ForwardIterator - __search_n(_ForwardIterator __first, _ForwardIterator __last, - _Integer __count, const _Tp& __val, - _BinaryPredicate __binary_pred, std::forward_iterator_tag) + __search_n_aux(_ForwardIterator __first, _ForwardIterator __last, + _Integer __count, _UnaryPredicate __unary_pred, + std::forward_iterator_tag) { - while (__first != __last && !bool(__binary_pred(*__first, __val))) - ++__first; - + __first = std::__find_if(__first, __last, __unary_pred); while (__first != __last) { typename iterator_traits<_ForwardIterator>::difference_type __n = __count; _ForwardIterator __i = __first; ++__i; - while (__i != __last && __n != 1 && bool(__binary_pred(*__i, __val))) + while (__i != __last && __n != 1 && __unary_pred(__i)) { ++__i; --__n; @@ -437,28 +274,22 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return __first; if (__i == __last) return __last; - __first = ++__i; - while (__first != __last - && !bool(__binary_pred(*__first, __val))) - ++__first; + __first = std::__find_if(++__i, __last, __unary_pred); } return __last; } /** - * This is an uglified - * search_n(_ForwardIterator, _ForwardIterator, _Integer, const _Tp&, - * _BinaryPredicate) - * overloaded for random access iterators. + * This is an helper function for search_n overloaded for random access + * iterators. */ - template<typename _RandomAccessIter, typename _Integer, typename _Tp, - typename _BinaryPredicate> + template<typename _RandomAccessIter, typename _Integer, + typename _UnaryPredicate> _RandomAccessIter - __search_n(_RandomAccessIter __first, _RandomAccessIter __last, - _Integer __count, const _Tp& __val, - _BinaryPredicate __binary_pred, std::random_access_iterator_tag) + __search_n_aux(_RandomAccessIter __first, _RandomAccessIter __last, + _Integer __count, _UnaryPredicate __unary_pred, + std::random_access_iterator_tag) { - typedef typename std::iterator_traits<_RandomAccessIter>::difference_type _DistanceType; @@ -472,7 +303,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // __first here is always pointing to one past the last element of // next possible match. _RandomAccessIter __backTrack = __first; - while (__binary_pred(*--__backTrack, __val)) + while (__unary_pred(--__backTrack)) { if (--__remainder == 0) return (__first - __count); // Success @@ -482,34 +313,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return __last; // Failure } - // find_end for forward iterators. - template<typename _ForwardIterator1, typename _ForwardIterator2> - _ForwardIterator1 - __find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator2 __last2, - forward_iterator_tag, forward_iterator_tag) + template<typename _ForwardIterator, typename _Integer, + typename _UnaryPredicate> + _ForwardIterator + __search_n(_ForwardIterator __first, _ForwardIterator __last, + _Integer __count, + _UnaryPredicate __unary_pred) { - if (__first2 == __last2) - return __last1; - else - { - _ForwardIterator1 __result = __last1; - while (1) - { - _ForwardIterator1 __new_result - = _GLIBCXX_STD_A::search(__first1, __last1, __first2, __last2); - if (__new_result == __last1) - return __result; - else - { - __result = __new_result; - __first1 = __new_result; - ++__first1; - } - } - } + if (__count <= 0) + return __first; + + if (__count == 1) + return std::__find_if(__first, __last, __unary_pred); + + return std::__search_n_aux(__first, __last, __count, __unary_pred, + std::__iterator_category(__first)); } + // find_end for forward iterators. template<typename _ForwardIterator1, typename _ForwardIterator2, typename _BinaryPredicate> _ForwardIterator1 @@ -520,61 +341,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { if (__first2 == __last2) return __last1; - else + + _ForwardIterator1 __result = __last1; + while (1) { - _ForwardIterator1 __result = __last1; - while (1) + _ForwardIterator1 __new_result + = std::__search(__first1, __last1, __first2, __last2, __comp); + if (__new_result == __last1) + return __result; + else { - _ForwardIterator1 __new_result - = _GLIBCXX_STD_A::search(__first1, __last1, __first2, - __last2, __comp); - if (__new_result == __last1) - return __result; - else - { - __result = __new_result; - __first1 = __new_result; - ++__first1; - } + __result = __new_result; + __first1 = __new_result; + ++__first1; } } } // find_end for bidirectional iterators (much faster). - template<typename _BidirectionalIterator1, typename _BidirectionalIterator2> - _BidirectionalIterator1 - __find_end(_BidirectionalIterator1 __first1, - _BidirectionalIterator1 __last1, - _BidirectionalIterator2 __first2, - _BidirectionalIterator2 __last2, - bidirectional_iterator_tag, bidirectional_iterator_tag) - { - // concept requirements - __glibcxx_function_requires(_BidirectionalIteratorConcept< - _BidirectionalIterator1>) - __glibcxx_function_requires(_BidirectionalIteratorConcept< - _BidirectionalIterator2>) - - typedef reverse_iterator<_BidirectionalIterator1> _RevIterator1; - typedef reverse_iterator<_BidirectionalIterator2> _RevIterator2; - - _RevIterator1 __rlast1(__first1); - _RevIterator2 __rlast2(__first2); - _RevIterator1 __rresult = _GLIBCXX_STD_A::search(_RevIterator1(__last1), - __rlast1, - _RevIterator2(__last2), - __rlast2); - - if (__rresult == __rlast1) - return __last1; - else - { - _BidirectionalIterator1 __result = __rresult.base(); - std::advance(__result, -std::distance(__first2, __last2)); - return __result; - } - } - template<typename _BidirectionalIterator1, typename _BidirectionalIterator2, typename _BinaryPredicate> _BidirectionalIterator1 @@ -596,9 +380,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _RevIterator1 __rlast1(__first1); _RevIterator2 __rlast2(__first2); - _RevIterator1 __rresult = std::search(_RevIterator1(__last1), __rlast1, - _RevIterator2(__last2), __rlast2, - __comp); + _RevIterator1 __rresult = std::__search(_RevIterator1(__last1), __rlast1, + _RevIterator2(__last2), __rlast2, + __comp); if (__rresult == __rlast1) return __last1; @@ -627,7 +411,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * [__first2,__last2) and returns an iterator to the __first * element of the sub-sequence, or @p __last1 if the sub-sequence * is not found. The sub-sequence will be the last such - * subsequence contained in [__first,__last1). + * subsequence contained in [__first1,__last1). * * Because the sub-sequence must lie completely within the range @p * [__first1,__last1) it must start at a position less than @p @@ -652,7 +436,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return std::__find_end(__first1, __last1, __first2, __last2, std::__iterator_category(__first1), - std::__iterator_category(__first2)); + std::__iterator_category(__first2), + __gnu_cxx::__ops::__iter_equal_to_iter()); } /** @@ -702,7 +487,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return std::__find_end(__first1, __last1, __first2, __last2, std::__iterator_category(__first1), std::__iterator_category(__first2), - __comp); + __gnu_cxx::__ops::__iter_comp_iter(__comp)); } #if __cplusplus >= 201103L @@ -778,7 +563,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, typename iterator_traits<_InputIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); - return std::__find_if_not(__first, __last, __pred); + return std::__find_if_not(__first, __last, + __gnu_cxx::__ops::__pred_iter(__pred)); } /** @@ -847,6 +633,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } #endif + template<typename _InputIterator, typename _OutputIterator, + typename _Predicate> + _OutputIterator + __remove_copy_if(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, _Predicate __pred) + { + for (; __first != __last; ++__first) + if (!__pred(__first)) + { + *__result = *__first; + ++__result; + } + return __result; + } /** * @brief Copy a sequence, removing elements of a given value. @@ -863,7 +663,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * are copied is unchanged. */ template<typename _InputIterator, typename _OutputIterator, typename _Tp> - _OutputIterator + inline _OutputIterator remove_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, const _Tp& __value) { @@ -875,13 +675,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typename iterator_traits<_InputIterator>::value_type, _Tp>) __glibcxx_requires_valid_range(__first, __last); - for (; __first != __last; ++__first) - if (!(*__first == __value)) - { - *__result = *__first; - ++__result; - } - return __result; + return std::__remove_copy_if(__first, __last, __result, + __gnu_cxx::__ops::__iter_equals_val(__value)); } /** @@ -901,7 +696,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION */ template<typename _InputIterator, typename _OutputIterator, typename _Predicate> - _OutputIterator + inline _OutputIterator remove_copy_if(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _Predicate __pred) { @@ -913,13 +708,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typename iterator_traits<_InputIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); - for (; __first != __last; ++__first) - if (!bool(__pred(*__first))) - { - *__result = *__first; - ++__result; - } - return __result; + return std::__remove_copy_if(__first, __last, __result, + __gnu_cxx::__ops::__pred_iter(__pred)); } #if __cplusplus >= 201103L @@ -961,7 +751,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return __result; } - template<typename _InputIterator, typename _Size, typename _OutputIterator> _OutputIterator __copy_n(_InputIterator __first, _Size __n, @@ -1063,6 +852,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } #endif + template<typename _ForwardIterator, typename _Predicate> + _ForwardIterator + __remove_if(_ForwardIterator __first, _ForwardIterator __last, + _Predicate __pred) + { + __first = std::__find_if(__first, __last, __pred); + if (__first == __last) + return __first; + _ForwardIterator __result = __first; + ++__first; + for (; __first != __last; ++__first) + if (!__pred(__first)) + { + *__result = _GLIBCXX_MOVE(*__first); + ++__result; + } + return __result; + } + /** * @brief Remove elements from a sequence. * @ingroup mutating_algorithms @@ -1081,7 +889,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * are still present, but their value is unspecified. */ template<typename _ForwardIterator, typename _Tp> - _ForwardIterator + inline _ForwardIterator remove(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { @@ -1092,18 +900,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typename iterator_traits<_ForwardIterator>::value_type, _Tp>) __glibcxx_requires_valid_range(__first, __last); - __first = _GLIBCXX_STD_A::find(__first, __last, __value); - if(__first == __last) - return __first; - _ForwardIterator __result = __first; - ++__first; - for(; __first != __last; ++__first) - if(!(*__first == __value)) - { - *__result = _GLIBCXX_MOVE(*__first); - ++__result; - } - return __result; + return std::__remove_if(__first, __last, + __gnu_cxx::__ops::__iter_equals_val(__value)); } /** @@ -1124,7 +922,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * are still present, but their value is unspecified. */ template<typename _ForwardIterator, typename _Predicate> - _ForwardIterator + inline _ForwardIterator remove_if(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) { @@ -1135,18 +933,44 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typename iterator_traits<_ForwardIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); - __first = _GLIBCXX_STD_A::find_if(__first, __last, __pred); - if(__first == __last) - return __first; - _ForwardIterator __result = __first; + return std::__remove_if(__first, __last, + __gnu_cxx::__ops::__pred_iter(__pred)); + } + + template<typename _ForwardIterator, typename _BinaryPredicate> + _ForwardIterator + __adjacent_find(_ForwardIterator __first, _ForwardIterator __last, + _BinaryPredicate __binary_pred) + { + if (__first == __last) + return __last; + _ForwardIterator __next = __first; + while (++__next != __last) + { + if (__binary_pred(__first, __next)) + return __first; + __first = __next; + } + return __last; + } + + template<typename _ForwardIterator, typename _BinaryPredicate> + _ForwardIterator + __unique(_ForwardIterator __first, _ForwardIterator __last, + _BinaryPredicate __binary_pred) + { + // Skip the beginning, if already unique. + __first = std::__adjacent_find(__first, __last, __binary_pred); + if (__first == __last) + return __last; + + // Do the real copy work. + _ForwardIterator __dest = __first; ++__first; - for(; __first != __last; ++__first) - if(!bool(__pred(*__first))) - { - *__result = _GLIBCXX_MOVE(*__first); - ++__result; - } - return __result; + while (++__first != __last) + if (!__binary_pred(__dest, __first)) + *++__dest = _GLIBCXX_MOVE(*__first); + return ++__dest; } /** @@ -1164,7 +988,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * are still present, but their value is unspecified. */ template<typename _ForwardIterator> - _ForwardIterator + inline _ForwardIterator unique(_ForwardIterator __first, _ForwardIterator __last) { // concept requirements @@ -1174,18 +998,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typename iterator_traits<_ForwardIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); - // Skip the beginning, if already unique. - __first = _GLIBCXX_STD_A::adjacent_find(__first, __last); - if (__first == __last) - return __last; - - // Do the real copy work. - _ForwardIterator __dest = __first; - ++__first; - while (++__first != __last) - if (!(*__dest == *__first)) - *++__dest = _GLIBCXX_MOVE(*__first); - return ++__dest; + return std::__unique(__first, __last, + __gnu_cxx::__ops::__iter_equal_to_iter()); } /** @@ -1204,7 +1018,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * are still present, but their value is unspecified. */ template<typename _ForwardIterator, typename _BinaryPredicate> - _ForwardIterator + inline _ForwardIterator unique(_ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __binary_pred) { @@ -1216,83 +1030,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typename iterator_traits<_ForwardIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); - // Skip the beginning, if already unique. - __first = _GLIBCXX_STD_A::adjacent_find(__first, __last, __binary_pred); - if (__first == __last) - return __last; - - // Do the real copy work. - _ForwardIterator __dest = __first; - ++__first; - while (++__first != __last) - if (!bool(__binary_pred(*__dest, *__first))) - *++__dest = _GLIBCXX_MOVE(*__first); - return ++__dest; - } - - /** - * This is an uglified unique_copy(_InputIterator, _InputIterator, - * _OutputIterator) - * overloaded for forward iterators and output iterator as result. - */ - template<typename _ForwardIterator, typename _OutputIterator> - _OutputIterator - __unique_copy(_ForwardIterator __first, _ForwardIterator __last, - _OutputIterator __result, - forward_iterator_tag, output_iterator_tag) - { - // concept requirements -- taken care of in dispatching function - _ForwardIterator __next = __first; - *__result = *__first; - while (++__next != __last) - if (!(*__first == *__next)) - { - __first = __next; - *++__result = *__first; - } - return ++__result; - } - - /** - * This is an uglified unique_copy(_InputIterator, _InputIterator, - * _OutputIterator) - * overloaded for input iterators and output iterator as result. - */ - template<typename _InputIterator, typename _OutputIterator> - _OutputIterator - __unique_copy(_InputIterator __first, _InputIterator __last, - _OutputIterator __result, - input_iterator_tag, output_iterator_tag) - { - // concept requirements -- taken care of in dispatching function - typename iterator_traits<_InputIterator>::value_type __value = *__first; - *__result = __value; - while (++__first != __last) - if (!(__value == *__first)) - { - __value = *__first; - *++__result = __value; - } - return ++__result; - } - - /** - * This is an uglified unique_copy(_InputIterator, _InputIterator, - * _OutputIterator) - * overloaded for input iterators and forward iterator as result. - */ - template<typename _InputIterator, typename _ForwardIterator> - _ForwardIterator - __unique_copy(_InputIterator __first, _InputIterator __last, - _ForwardIterator __result, - input_iterator_tag, forward_iterator_tag) - { - // concept requirements -- taken care of in dispatching function - *__result = *__first; - while (++__first != __last) - if (!(*__result == *__first)) - *++__result = *__first; - return ++__result; + return std::__unique(__first, __last, + __gnu_cxx::__ops::__iter_comp_iter(__binary_pred)); } /** @@ -1316,7 +1055,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _ForwardIterator __next = __first; *__result = *__first; while (++__next != __last) - if (!bool(__binary_pred(*__first, *__next))) + if (!__binary_pred(__first, __next)) { __first = __next; *++__result = *__first; @@ -1343,9 +1082,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typename iterator_traits<_InputIterator>::value_type>) typename iterator_traits<_InputIterator>::value_type __value = *__first; + __decltype(__gnu_cxx::__ops::__iter_comp_val(__binary_pred)) + __rebound_pred + = __gnu_cxx::__ops::__iter_comp_val(__binary_pred); *__result = __value; while (++__first != __last) - if (!bool(__binary_pred(__value, *__first))) + if (!__rebound_pred(__first, __value)) { __value = *__first; *++__result = __value; @@ -1370,10 +1112,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, typename iterator_traits<_ForwardIterator>::value_type, typename iterator_traits<_InputIterator>::value_type>) - *__result = *__first; while (++__first != __last) - if (!bool(__binary_pred(*__result, *__first))) + if (!__binary_pred(__result, __first)) *++__result = *__first; return ++__result; } @@ -1675,9 +1416,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __glibcxx_requires_valid_range(__first, __middle); __glibcxx_requires_valid_range(__middle, __last); - typedef typename iterator_traits<_ForwardIterator>::iterator_category - _IterType; - std::__rotate(__first, __middle, __last, _IterType()); + std::__rotate(__first, __middle, __last, + std::__iterator_category(__first)); } /** @@ -1701,7 +1441,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * for each @p n in the range @p [0,__last-__first). */ template<typename _ForwardIterator, typename _OutputIterator> - _OutputIterator + inline _OutputIterator rotate_copy(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last, _OutputIterator __result) { @@ -1800,10 +1540,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } /// This is a helper function... - /// Requires __first != __last and !__pred(*__first) + /// Requires __first != __last and !__pred(__first) /// and __len == distance(__first, __last). /// - /// !__pred(*__first) allows us to guarantee that we don't + /// !__pred(__first) allows us to guarantee that we don't /// move-assign an element onto itself. template<typename _ForwardIterator, typename _Pointer, typename _Predicate, typename _Distance> @@ -1818,14 +1558,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { _ForwardIterator __result1 = __first; _Pointer __result2 = __buffer; - // The precondition guarantees that !__pred(*__first), so + // The precondition guarantees that !__pred(__first), so // move that element to the buffer before starting the loop. // This ensures that we only call __pred once per element. *__result2 = _GLIBCXX_MOVE(*__first); ++__result2; ++__first; for (; __first != __last; ++__first) - if (__pred(*__first)) + if (__pred(__first)) { *__result1 = _GLIBCXX_MOVE(*__first); ++__result1; @@ -1862,6 +1602,34 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } } + template<typename _ForwardIterator, typename _Predicate> + _ForwardIterator + __stable_partition(_ForwardIterator __first, _ForwardIterator __last, + _Predicate __pred) + { + __first = std::__find_if_not(__first, __last, __pred); + + if (__first == __last) + return __first; + + typedef typename iterator_traits<_ForwardIterator>::value_type + _ValueType; + typedef typename iterator_traits<_ForwardIterator>::difference_type + _DistanceType; + + _Temporary_buffer<_ForwardIterator, _ValueType> __buf(__first, __last); + if (__buf.size() > 0) + return + std::__stable_partition_adaptive(__first, __last, __pred, + _DistanceType(__buf.requested_size()), + __buf.begin(), + _DistanceType(__buf.size())); + else + return + std::__inplace_stable_partition(__first, __pred, + _DistanceType(__buf.requested_size())); + } + /** * @brief Move elements for which a predicate is true to the beginning * of a sequence, preserving relative ordering. @@ -1880,7 +1648,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * relative ordering after calling @p stable_partition(). */ template<typename _ForwardIterator, typename _Predicate> - _ForwardIterator + inline _ForwardIterator stable_partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) { @@ -1891,43 +1659,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typename iterator_traits<_ForwardIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); - __first = std::__find_if_not(__first, __last, __pred); - - if (__first == __last) - return __first; - else - { - typedef typename iterator_traits<_ForwardIterator>::value_type - _ValueType; - typedef typename iterator_traits<_ForwardIterator>::difference_type - _DistanceType; - - _Temporary_buffer<_ForwardIterator, _ValueType> __buf(__first, - __last); - if (__buf.size() > 0) - return - std::__stable_partition_adaptive(__first, __last, __pred, - _DistanceType(__buf.requested_size()), - __buf.begin(), - _DistanceType(__buf.size())); - else - return - std::__inplace_stable_partition(__first, __pred, - _DistanceType(__buf.requested_size())); - } - } - - /// This is a helper function for the sort routines. - template<typename _RandomAccessIterator> - void - __heap_select(_RandomAccessIterator __first, - _RandomAccessIterator __middle, - _RandomAccessIterator __last) - { - std::make_heap(__first, __middle); - for (_RandomAccessIterator __i = __middle; __i < __last; ++__i) - if (*__i < *__first) - std::__pop_heap(__first, __middle, __i); + return std::__stable_partition(__first, __last, + __gnu_cxx::__ops::__pred_iter(__pred)); } /// This is a helper function for the sort routines. @@ -1937,14 +1670,51 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _RandomAccessIterator __middle, _RandomAccessIterator __last, _Compare __comp) { - std::make_heap(__first, __middle, __comp); + std::__make_heap(__first, __middle, __comp); for (_RandomAccessIterator __i = __middle; __i < __last; ++__i) - if (__comp(*__i, *__first)) + if (__comp(__i, __first)) std::__pop_heap(__first, __middle, __i, __comp); } // partial_sort + template<typename _InputIterator, typename _RandomAccessIterator, + typename _Compare> + _RandomAccessIterator + __partial_sort_copy(_InputIterator __first, _InputIterator __last, + _RandomAccessIterator __result_first, + _RandomAccessIterator __result_last, + _Compare __comp) + { + typedef typename iterator_traits<_InputIterator>::value_type + _InputValueType; + typedef iterator_traits<_RandomAccessIterator> _RItTraits; + typedef typename _RItTraits::difference_type _DistanceType; + + if (__result_first == __result_last) + return __result_last; + _RandomAccessIterator __result_real_last = __result_first; + while (__first != __last && __result_real_last != __result_last) + { + *__result_real_last = *__first; + ++__result_real_last; + ++__first; + } + + std::__make_heap(__result_first, __result_real_last, __comp); + while (__first != __last) + { + if (__comp(__first, __result_first)) + std::__adjust_heap(__result_first, _DistanceType(0), + _DistanceType(__result_real_last + - __result_first), + _InputValueType(*__first), __comp); + ++__first; + } + std::__sort_heap(__result_first, __result_real_last, __comp); + return __result_real_last; + } + /** * @brief Copy the smallest elements of a sequence. * @ingroup sorting_algorithms @@ -1964,7 +1734,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * The value returned is @p __result_first+N. */ template<typename _InputIterator, typename _RandomAccessIterator> - _RandomAccessIterator + inline _RandomAccessIterator partial_sort_copy(_InputIterator __first, _InputIterator __last, _RandomAccessIterator __result_first, _RandomAccessIterator __result_last) @@ -1986,27 +1756,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __glibcxx_requires_valid_range(__first, __last); __glibcxx_requires_valid_range(__result_first, __result_last); - if (__result_first == __result_last) - return __result_last; - _RandomAccessIterator __result_real_last = __result_first; - while(__first != __last && __result_real_last != __result_last) - { - *__result_real_last = *__first; - ++__result_real_last; - ++__first; - } - std::make_heap(__result_first, __result_real_last); - while (__first != __last) - { - if (*__first < *__result_first) - std::__adjust_heap(__result_first, _DistanceType(0), - _DistanceType(__result_real_last - - __result_first), - _InputValueType(*__first)); - ++__first; - } - std::sort_heap(__result_first, __result_real_last); - return __result_real_last; + return std::__partial_sort_copy(__first, __last, + __result_first, __result_last, + __gnu_cxx::__ops::__iter_less_iter()); } /** @@ -2029,8 +1781,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * @p __comp(*j,*i) is false. * The value returned is @p __result_first+N. */ - template<typename _InputIterator, typename _RandomAccessIterator, typename _Compare> - _RandomAccessIterator + template<typename _InputIterator, typename _RandomAccessIterator, + typename _Compare> + inline _RandomAccessIterator partial_sort_copy(_InputIterator __first, _InputIterator __last, _RandomAccessIterator __result_first, _RandomAccessIterator __result_last, @@ -2056,46 +1809,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __glibcxx_requires_valid_range(__first, __last); __glibcxx_requires_valid_range(__result_first, __result_last); - if (__result_first == __result_last) - return __result_last; - _RandomAccessIterator __result_real_last = __result_first; - while(__first != __last && __result_real_last != __result_last) - { - *__result_real_last = *__first; - ++__result_real_last; - ++__first; - } - std::make_heap(__result_first, __result_real_last, __comp); - while (__first != __last) - { - if (__comp(*__first, *__result_first)) - std::__adjust_heap(__result_first, _DistanceType(0), - _DistanceType(__result_real_last - - __result_first), - _InputValueType(*__first), - __comp); - ++__first; - } - std::sort_heap(__result_first, __result_real_last, __comp); - return __result_real_last; - } - - /// This is a helper function for the sort routine. - template<typename _RandomAccessIterator> - void - __unguarded_linear_insert(_RandomAccessIterator __last) - { - typename iterator_traits<_RandomAccessIterator>::value_type - __val = _GLIBCXX_MOVE(*__last); - _RandomAccessIterator __next = __last; - --__next; - while (__val < *__next) - { - *__last = _GLIBCXX_MOVE(*__next); - __last = __next; - --__next; - } - *__last = _GLIBCXX_MOVE(__val); + return std::__partial_sort_copy(__first, __last, + __result_first, __result_last, + __gnu_cxx::__ops::__iter_comp_iter(__comp)); } /// This is a helper function for the sort routine. @@ -2108,7 +1824,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __val = _GLIBCXX_MOVE(*__last); _RandomAccessIterator __next = __last; --__next; - while (__comp(__val, *__next)) + while (__comp(__val, __next)) { *__last = _GLIBCXX_MOVE(*__next); __last = __next; @@ -2118,29 +1834,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } /// This is a helper function for the sort routine. - template<typename _RandomAccessIterator> - void - __insertion_sort(_RandomAccessIterator __first, - _RandomAccessIterator __last) - { - if (__first == __last) - return; - - for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i) - { - if (*__i < *__first) - { - typename iterator_traits<_RandomAccessIterator>::value_type - __val = _GLIBCXX_MOVE(*__i); - _GLIBCXX_MOVE_BACKWARD3(__first, __i, __i + 1); - *__first = _GLIBCXX_MOVE(__val); - } - else - std::__unguarded_linear_insert(__i); - } - } - - /// This is a helper function for the sort routine. template<typename _RandomAccessIterator, typename _Compare> void __insertion_sort(_RandomAccessIterator __first, @@ -2150,7 +1843,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i) { - if (__comp(*__i, *__first)) + if (__comp(__i, __first)) { typename iterator_traits<_RandomAccessIterator>::value_type __val = _GLIBCXX_MOVE(*__i); @@ -2158,34 +1851,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION *__first = _GLIBCXX_MOVE(__val); } else - std::__unguarded_linear_insert(__i, __comp); + std::__unguarded_linear_insert(__i, + __gnu_cxx::__ops::__val_comp_iter(__comp)); } } /// This is a helper function for the sort routine. - template<typename _RandomAccessIterator> - inline void - __unguarded_insertion_sort(_RandomAccessIterator __first, - _RandomAccessIterator __last) - { - typedef typename iterator_traits<_RandomAccessIterator>::value_type - _ValueType; - - for (_RandomAccessIterator __i = __first; __i != __last; ++__i) - std::__unguarded_linear_insert(__i); - } - - /// This is a helper function for the sort routine. template<typename _RandomAccessIterator, typename _Compare> inline void __unguarded_insertion_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { - typedef typename iterator_traits<_RandomAccessIterator>::value_type - _ValueType; - for (_RandomAccessIterator __i = __first; __i != __last; ++__i) - std::__unguarded_linear_insert(__i, __comp); + std::__unguarded_linear_insert(__i, + __gnu_cxx::__ops::__val_comp_iter(__comp)); } /** @@ -2195,21 +1874,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION enum { _S_threshold = 16 }; /// This is a helper function for the sort routine. - template<typename _RandomAccessIterator> - void - __final_insertion_sort(_RandomAccessIterator __first, - _RandomAccessIterator __last) - { - if (__last - __first > int(_S_threshold)) - { - std::__insertion_sort(__first, __first + int(_S_threshold)); - std::__unguarded_insertion_sort(__first + int(_S_threshold), __last); - } - else - std::__insertion_sort(__first, __last); - } - - /// This is a helper function for the sort routine. template<typename _RandomAccessIterator, typename _Compare> void __final_insertion_sort(_RandomAccessIterator __first, @@ -2226,38 +1890,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } /// This is a helper function... - template<typename _RandomAccessIterator, typename _Tp> - _RandomAccessIterator - __unguarded_partition(_RandomAccessIterator __first, - _RandomAccessIterator __last, const _Tp& __pivot) - { - while (true) - { - while (*__first < __pivot) - ++__first; - --__last; - while (__pivot < *__last) - --__last; - if (!(__first < __last)) - return __first; - std::iter_swap(__first, __last); - ++__first; - } - } - - /// This is a helper function... - template<typename _RandomAccessIterator, typename _Tp, typename _Compare> + template<typename _RandomAccessIterator, typename _Compare> _RandomAccessIterator __unguarded_partition(_RandomAccessIterator __first, _RandomAccessIterator __last, - const _Tp& __pivot, _Compare __comp) + _RandomAccessIterator __pivot, _Compare __comp) { while (true) { - while (__comp(*__first, __pivot)) + while (__comp(__first, __pivot)) ++__first; --__last; - while (__comp(__pivot, *__last)) + while (__comp(__pivot, __last)) --__last; if (!(__first < __last)) return __first; @@ -2267,48 +1911,26 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } /// This is a helper function... - template<typename _RandomAccessIterator> - inline _RandomAccessIterator - __unguarded_partition_pivot(_RandomAccessIterator __first, - _RandomAccessIterator __last) - { - _RandomAccessIterator __mid = __first + (__last - __first) / 2; - std::__move_median_first(__first, __mid, (__last - 1)); - return std::__unguarded_partition(__first + 1, __last, *__first); - } - - - /// This is a helper function... template<typename _RandomAccessIterator, typename _Compare> inline _RandomAccessIterator __unguarded_partition_pivot(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { _RandomAccessIterator __mid = __first + (__last - __first) / 2; - std::__move_median_first(__first, __mid, (__last - 1), __comp); - return std::__unguarded_partition(__first + 1, __last, *__first, __comp); + std::__move_median_to_first(__first, __first + 1, __mid, __last - 1, + __comp); + return std::__unguarded_partition(__first + 1, __last, __first, __comp); } - /// This is a helper function for the sort routine. - template<typename _RandomAccessIterator, typename _Size> - void - __introsort_loop(_RandomAccessIterator __first, - _RandomAccessIterator __last, - _Size __depth_limit) + template<typename _RandomAccessIterator, typename _Compare> + inline void + __partial_sort(_RandomAccessIterator __first, + _RandomAccessIterator __middle, + _RandomAccessIterator __last, + _Compare __comp) { - while (__last - __first > int(_S_threshold)) - { - if (__depth_limit == 0) - { - _GLIBCXX_STD_A::partial_sort(__first, __last, __last); - return; - } - --__depth_limit; - _RandomAccessIterator __cut = - std::__unguarded_partition_pivot(__first, __last); - std::__introsort_loop(__cut, __last, __depth_limit); - __last = __cut; - } + std::__heap_select(__first, __middle, __last, __comp); + std::__sort_heap(__first, __middle, __comp); } /// This is a helper function for the sort routine. @@ -2322,7 +1944,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { if (__depth_limit == 0) { - _GLIBCXX_STD_A::partial_sort(__first, __last, __last, __comp); + std::__partial_sort(__first, __last, __last, __comp); return; } --__depth_limit; @@ -2335,33 +1957,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // sort - template<typename _RandomAccessIterator, typename _Size> - void - __introselect(_RandomAccessIterator __first, _RandomAccessIterator __nth, - _RandomAccessIterator __last, _Size __depth_limit) + template<typename _RandomAccessIterator, typename _Compare> + inline void + __sort(_RandomAccessIterator __first, _RandomAccessIterator __last, + _Compare __comp) { - typedef typename iterator_traits<_RandomAccessIterator>::value_type - _ValueType; - - while (__last - __first > 3) + if (__first != __last) { - if (__depth_limit == 0) - { - std::__heap_select(__first, __nth + 1, __last); - - // Place the nth largest element in its final position. - std::iter_swap(__first, __nth); - return; - } - --__depth_limit; - _RandomAccessIterator __cut = - std::__unguarded_partition_pivot(__first, __last); - if (__cut <= __nth) - __first = __cut; - else - __last = __cut; + std::__introsort_loop(__first, __last, + std::__lg(__last - __first) * 2, + __comp); + std::__final_insertion_sort(__first, __last, __comp); } - std::__insertion_sort(__first, __last); } template<typename _RandomAccessIterator, typename _Size, typename _Compare> @@ -2370,9 +1977,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _RandomAccessIterator __last, _Size __depth_limit, _Compare __comp) { - typedef typename iterator_traits<_RandomAccessIterator>::value_type - _ValueType; - while (__last - __first > 3) { if (__depth_limit == 0) @@ -2414,14 +2018,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * the function used for the initial sort. */ template<typename _ForwardIterator, typename _Tp, typename _Compare> - _ForwardIterator + inline _ForwardIterator lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __val, _Compare __comp) { typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; - typedef typename iterator_traits<_ForwardIterator>::difference_type - _DistanceType; // concept requirements __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) @@ -2430,6 +2032,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __glibcxx_requires_partitioned_lower_pred(__first, __last, __val, __comp); + return std::__lower_bound(__first, __last, __val, + __gnu_cxx::__ops::__iter_comp_val(__comp)); + } + + template<typename _ForwardIterator, typename _Tp, typename _Compare> + _ForwardIterator + __upper_bound(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __val, _Compare __comp) + { + typedef typename iterator_traits<_ForwardIterator>::difference_type + _DistanceType; + _DistanceType __len = std::distance(__first, __last); while (__len > 0) @@ -2437,14 +2051,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _DistanceType __half = __len >> 1; _ForwardIterator __middle = __first; std::advance(__middle, __half); - if (__comp(*__middle, __val)) + if (__comp(__val, __middle)) + __len = __half; + else { __first = __middle; ++__first; __len = __len - __half - 1; } - else - __len = __half; } return __first; } @@ -2461,37 +2075,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * @ingroup binary_search_algorithms */ template<typename _ForwardIterator, typename _Tp> - _ForwardIterator + inline _ForwardIterator upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __val) { typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; - typedef typename iterator_traits<_ForwardIterator>::difference_type - _DistanceType; // concept requirements __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) __glibcxx_function_requires(_LessThanOpConcept<_Tp, _ValueType>) __glibcxx_requires_partitioned_upper(__first, __last, __val); - _DistanceType __len = std::distance(__first, __last); - - while (__len > 0) - { - _DistanceType __half = __len >> 1; - _ForwardIterator __middle = __first; - std::advance(__middle, __half); - if (__val < *__middle) - __len = __half; - else - { - __first = __middle; - ++__first; - __len = __len - __half - 1; - } - } - return __first; + return std::__upper_bound(__first, __last, __val, + __gnu_cxx::__ops::__val_less_iter()); } /** @@ -2510,14 +2107,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * the function used for the initial sort. */ template<typename _ForwardIterator, typename _Tp, typename _Compare> - _ForwardIterator + inline _ForwardIterator upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __val, _Compare __comp) { typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; - typedef typename iterator_traits<_ForwardIterator>::difference_type - _DistanceType; // concept requirements __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) @@ -2526,6 +2121,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __glibcxx_requires_partitioned_upper_pred(__first, __last, __val, __comp); + return std::__upper_bound(__first, __last, __val, + __gnu_cxx::__ops::__val_comp_iter(__comp)); + } + + template<typename _ForwardIterator, typename _Tp, + typename _CompareItTp, typename _CompareTpIt> + pair<_ForwardIterator, _ForwardIterator> + __equal_range(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __val, + _CompareItTp __comp_it_val, _CompareTpIt __comp_val_it) + { + typedef typename iterator_traits<_ForwardIterator>::difference_type + _DistanceType; + _DistanceType __len = std::distance(__first, __last); while (__len > 0) @@ -2533,16 +2142,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _DistanceType __half = __len >> 1; _ForwardIterator __middle = __first; std::advance(__middle, __half); - if (__comp(__val, *__middle)) - __len = __half; - else + if (__comp_it_val(__middle, __val)) { __first = __middle; ++__first; __len = __len - __half - 1; } + else if (__comp_val_it(__val, __middle)) + __len = __half; + else + { + _ForwardIterator __left + = std::__lower_bound(__first, __middle, __val, __comp_it_val); + std::advance(__first, __len); + _ForwardIterator __right + = std::__upper_bound(++__middle, __first, __val, __comp_val_it); + return pair<_ForwardIterator, _ForwardIterator>(__left, __right); + } } - return __first; + return pair<_ForwardIterator, _ForwardIterator>(__first, __first); } /** @@ -2563,48 +2181,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * but does not actually call those functions. */ template<typename _ForwardIterator, typename _Tp> - pair<_ForwardIterator, _ForwardIterator> + inline pair<_ForwardIterator, _ForwardIterator> equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __val) { typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; - typedef typename iterator_traits<_ForwardIterator>::difference_type - _DistanceType; // concept requirements __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) __glibcxx_function_requires(_LessThanOpConcept<_ValueType, _Tp>) - __glibcxx_function_requires(_LessThanOpConcept<_Tp, _ValueType>) + __glibcxx_function_requires(_LessThanOpConcept<_Tp, _ValueType>) __glibcxx_requires_partitioned_lower(__first, __last, __val); __glibcxx_requires_partitioned_upper(__first, __last, __val); - _DistanceType __len = std::distance(__first, __last); - - while (__len > 0) - { - _DistanceType __half = __len >> 1; - _ForwardIterator __middle = __first; - std::advance(__middle, __half); - if (*__middle < __val) - { - __first = __middle; - ++__first; - __len = __len - __half - 1; - } - else if (__val < *__middle) - __len = __half; - else - { - _ForwardIterator __left = std::lower_bound(__first, __middle, - __val); - std::advance(__first, __len); - _ForwardIterator __right = std::upper_bound(++__middle, __first, - __val); - return pair<_ForwardIterator, _ForwardIterator>(__left, __right); - } - } - return pair<_ForwardIterator, _ForwardIterator>(__first, __first); + return std::__equal_range(__first, __last, __val, + __gnu_cxx::__ops::__iter_less_val(), + __gnu_cxx::__ops::__val_less_iter()); } /** @@ -2625,14 +2218,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * but does not actually call those functions. */ template<typename _ForwardIterator, typename _Tp, typename _Compare> - pair<_ForwardIterator, _ForwardIterator> + inline pair<_ForwardIterator, _ForwardIterator> equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __val, _Compare __comp) { typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; - typedef typename iterator_traits<_ForwardIterator>::difference_type - _DistanceType; // concept requirements __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) @@ -2645,32 +2236,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __glibcxx_requires_partitioned_upper_pred(__first, __last, __val, __comp); - _DistanceType __len = std::distance(__first, __last); - - while (__len > 0) - { - _DistanceType __half = __len >> 1; - _ForwardIterator __middle = __first; - std::advance(__middle, __half); - if (__comp(*__middle, __val)) - { - __first = __middle; - ++__first; - __len = __len - __half - 1; - } - else if (__comp(__val, *__middle)) - __len = __half; - else - { - _ForwardIterator __left = std::lower_bound(__first, __middle, - __val, __comp); - std::advance(__first, __len); - _ForwardIterator __right = std::upper_bound(++__middle, __first, - __val, __comp); - return pair<_ForwardIterator, _ForwardIterator>(__left, __right); - } - } - return pair<_ForwardIterator, _ForwardIterator>(__first, __first); + return std::__equal_range(__first, __last, __val, + __gnu_cxx::__ops::__iter_comp_val(__comp), + __gnu_cxx::__ops::__val_comp_iter(__comp)); } /** @@ -2699,7 +2267,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __glibcxx_requires_partitioned_lower(__first, __last, __val); __glibcxx_requires_partitioned_upper(__first, __last, __val); - _ForwardIterator __i = std::lower_bound(__first, __last, __val); + _ForwardIterator __i + = std::__lower_bound(__first, __last, __val, + __gnu_cxx::__ops::__iter_less_val()); return __i != __last && !(__val < *__i); } @@ -2735,7 +2305,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __glibcxx_requires_partitioned_upper_pred(__first, __last, __val, __comp); - _ForwardIterator __i = std::lower_bound(__first, __last, __val, __comp); + _ForwardIterator __i + = std::__lower_bound(__first, __last, __val, + __gnu_cxx::__ops::__iter_comp_val(__comp)); return __i != __last && !bool(__comp(__val, *__i)); } @@ -2743,32 +2315,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /// This is a helper function for the __merge_adaptive routines. template<typename _InputIterator1, typename _InputIterator2, - typename _OutputIterator> - void - __move_merge_adaptive(_InputIterator1 __first1, _InputIterator1 __last1, - _InputIterator2 __first2, _InputIterator2 __last2, - _OutputIterator __result) - { - while (__first1 != __last1 && __first2 != __last2) - { - if (*__first2 < *__first1) - { - *__result = _GLIBCXX_MOVE(*__first2); - ++__first2; - } - else - { - *__result = _GLIBCXX_MOVE(*__first1); - ++__first1; - } - ++__result; - } - if (__first1 != __last1) - _GLIBCXX_MOVE3(__first1, __last1, __result); - } - - /// This is a helper function for the __merge_adaptive routines. - template<typename _InputIterator1, typename _InputIterator2, typename _OutputIterator, typename _Compare> void __move_merge_adaptive(_InputIterator1 __first1, _InputIterator1 __last1, @@ -2777,7 +2323,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { while (__first1 != __last1 && __first2 != __last2) { - if (__comp(*__first2, *__first1)) + if (__comp(__first2, __first1)) { *__result = _GLIBCXX_MOVE(*__first2); ++__first2; @@ -2795,48 +2341,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /// This is a helper function for the __merge_adaptive routines. template<typename _BidirectionalIterator1, typename _BidirectionalIterator2, - typename _BidirectionalIterator3> - void - __move_merge_adaptive_backward(_BidirectionalIterator1 __first1, - _BidirectionalIterator1 __last1, - _BidirectionalIterator2 __first2, - _BidirectionalIterator2 __last2, - _BidirectionalIterator3 __result) - { - if (__first1 == __last1) - { - _GLIBCXX_MOVE_BACKWARD3(__first2, __last2, __result); - return; - } - else if (__first2 == __last2) - return; - - --__last1; - --__last2; - while (true) - { - if (*__last2 < *__last1) - { - *--__result = _GLIBCXX_MOVE(*__last1); - if (__first1 == __last1) - { - _GLIBCXX_MOVE_BACKWARD3(__first2, ++__last2, __result); - return; - } - --__last1; - } - else - { - *--__result = _GLIBCXX_MOVE(*__last2); - if (__first2 == __last2) - return; - --__last2; - } - } - } - - /// This is a helper function for the __merge_adaptive routines. - template<typename _BidirectionalIterator1, typename _BidirectionalIterator2, typename _BidirectionalIterator3, typename _Compare> void __move_merge_adaptive_backward(_BidirectionalIterator1 __first1, @@ -2858,7 +2362,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION --__last2; while (true) { - if (__comp(*__last2, *__last1)) + if (__comp(__last2, __last1)) { *--__result = _GLIBCXX_MOVE(*__last1); if (__first1 == __last1) @@ -2921,62 +2425,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } /// This is a helper function for the merge routines. - template<typename _BidirectionalIterator, typename _Distance, - typename _Pointer> - void - __merge_adaptive(_BidirectionalIterator __first, - _BidirectionalIterator __middle, - _BidirectionalIterator __last, - _Distance __len1, _Distance __len2, - _Pointer __buffer, _Distance __buffer_size) - { - if (__len1 <= __len2 && __len1 <= __buffer_size) - { - _Pointer __buffer_end = _GLIBCXX_MOVE3(__first, __middle, __buffer); - std::__move_merge_adaptive(__buffer, __buffer_end, __middle, __last, - __first); - } - else if (__len2 <= __buffer_size) - { - _Pointer __buffer_end = _GLIBCXX_MOVE3(__middle, __last, __buffer); - std::__move_merge_adaptive_backward(__first, __middle, __buffer, - __buffer_end, __last); - } - else - { - _BidirectionalIterator __first_cut = __first; - _BidirectionalIterator __second_cut = __middle; - _Distance __len11 = 0; - _Distance __len22 = 0; - if (__len1 > __len2) - { - __len11 = __len1 / 2; - std::advance(__first_cut, __len11); - __second_cut = std::lower_bound(__middle, __last, - *__first_cut); - __len22 = std::distance(__middle, __second_cut); - } - else - { - __len22 = __len2 / 2; - std::advance(__second_cut, __len22); - __first_cut = std::upper_bound(__first, __middle, - *__second_cut); - __len11 = std::distance(__first, __first_cut); - } - _BidirectionalIterator __new_middle = - std::__rotate_adaptive(__first_cut, __middle, __second_cut, - __len1 - __len11, __len22, __buffer, - __buffer_size); - std::__merge_adaptive(__first, __first_cut, __new_middle, __len11, - __len22, __buffer, __buffer_size); - std::__merge_adaptive(__new_middle, __second_cut, __last, - __len1 - __len11, - __len2 - __len22, __buffer, __buffer_size); - } - } - - /// This is a helper function for the merge routines. template<typename _BidirectionalIterator, typename _Distance, typename _Pointer, typename _Compare> void @@ -3009,22 +2457,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { __len11 = __len1 / 2; std::advance(__first_cut, __len11); - __second_cut = std::lower_bound(__middle, __last, *__first_cut, - __comp); + __second_cut + = std::__lower_bound(__middle, __last, *__first_cut, + __gnu_cxx::__ops::__iter_comp_val(__comp)); __len22 = std::distance(__middle, __second_cut); } else { __len22 = __len2 / 2; std::advance(__second_cut, __len22); - __first_cut = std::upper_bound(__first, __middle, *__second_cut, - __comp); + __first_cut + = std::__upper_bound(__first, __middle, *__second_cut, + __gnu_cxx::__ops::__val_comp_iter(__comp)); __len11 = std::distance(__first, __first_cut); } - _BidirectionalIterator __new_middle = - std::__rotate_adaptive(__first_cut, __middle, __second_cut, - __len1 - __len11, __len22, __buffer, - __buffer_size); + _BidirectionalIterator __new_middle + = std::__rotate_adaptive(__first_cut, __middle, __second_cut, + __len1 - __len11, __len22, __buffer, + __buffer_size); std::__merge_adaptive(__first, __first_cut, __new_middle, __len11, __len22, __buffer, __buffer_size, __comp); std::__merge_adaptive(__new_middle, __second_cut, __last, @@ -3035,49 +2485,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } /// This is a helper function for the merge routines. - template<typename _BidirectionalIterator, typename _Distance> - void - __merge_without_buffer(_BidirectionalIterator __first, - _BidirectionalIterator __middle, - _BidirectionalIterator __last, - _Distance __len1, _Distance __len2) - { - if (__len1 == 0 || __len2 == 0) - return; - if (__len1 + __len2 == 2) - { - if (*__middle < *__first) - std::iter_swap(__first, __middle); - return; - } - _BidirectionalIterator __first_cut = __first; - _BidirectionalIterator __second_cut = __middle; - _Distance __len11 = 0; - _Distance __len22 = 0; - if (__len1 > __len2) - { - __len11 = __len1 / 2; - std::advance(__first_cut, __len11); - __second_cut = std::lower_bound(__middle, __last, *__first_cut); - __len22 = std::distance(__middle, __second_cut); - } - else - { - __len22 = __len2 / 2; - std::advance(__second_cut, __len22); - __first_cut = std::upper_bound(__first, __middle, *__second_cut); - __len11 = std::distance(__first, __first_cut); - } - std::rotate(__first_cut, __middle, __second_cut); - _BidirectionalIterator __new_middle = __first_cut; - std::advance(__new_middle, std::distance(__middle, __second_cut)); - std::__merge_without_buffer(__first, __first_cut, __new_middle, - __len11, __len22); - std::__merge_without_buffer(__new_middle, __second_cut, __last, - __len1 - __len11, __len2 - __len22); - } - - /// This is a helper function for the merge routines. template<typename _BidirectionalIterator, typename _Distance, typename _Compare> void @@ -3091,7 +2498,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return; if (__len1 + __len2 == 2) { - if (__comp(*__middle, *__first)) + if (__comp(__middle, __first)) std::iter_swap(__first, __middle); return; } @@ -3103,16 +2510,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { __len11 = __len1 / 2; std::advance(__first_cut, __len11); - __second_cut = std::lower_bound(__middle, __last, *__first_cut, - __comp); + __second_cut + = std::__lower_bound(__middle, __last, *__first_cut, + __gnu_cxx::__ops::__iter_comp_val(__comp)); __len22 = std::distance(__middle, __second_cut); } else { __len22 = __len2 / 2; std::advance(__second_cut, __len22); - __first_cut = std::upper_bound(__first, __middle, *__second_cut, - __comp); + __first_cut + = std::__upper_bound(__first, __middle, *__second_cut, + __gnu_cxx::__ops::__val_comp_iter(__comp)); __len11 = std::distance(__first, __first_cut); } std::rotate(__first_cut, __middle, __second_cut); @@ -3124,6 +2533,36 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __len1 - __len11, __len2 - __len22, __comp); } + template<typename _BidirectionalIterator, typename _Compare> + void + __inplace_merge(_BidirectionalIterator __first, + _BidirectionalIterator __middle, + _BidirectionalIterator __last, + _Compare __comp) + { + typedef typename iterator_traits<_BidirectionalIterator>::value_type + _ValueType; + typedef typename iterator_traits<_BidirectionalIterator>::difference_type + _DistanceType; + + if (__first == __middle || __middle == __last) + return; + + const _DistanceType __len1 = std::distance(__first, __middle); + const _DistanceType __len2 = std::distance(__middle, __last); + + typedef _Temporary_buffer<_BidirectionalIterator, _ValueType> _TmpBuf; + _TmpBuf __buf(__first, __last); + + if (__buf.begin() == 0) + std::__merge_without_buffer + (__first, __middle, __last, __len1, __len2, __comp); + else + std::__merge_adaptive + (__first, __middle, __last, __len1, __len2, __buf.begin(), + _DistanceType(__buf.size()), __comp); + } + /** * @brief Merges two sorted ranges in place. * @ingroup sorting_algorithms @@ -3143,36 +2582,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * distance(__first,__last). */ template<typename _BidirectionalIterator> - void + inline void inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last) { - typedef typename iterator_traits<_BidirectionalIterator>::value_type - _ValueType; - typedef typename iterator_traits<_BidirectionalIterator>::difference_type - _DistanceType; - // concept requirements __glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept< _BidirectionalIterator>) - __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>) + __glibcxx_function_requires(_LessThanComparableConcept< + typename iterator_traits<_BidirectionalIterator>::value_type>) __glibcxx_requires_sorted(__first, __middle); __glibcxx_requires_sorted(__middle, __last); - if (__first == __middle || __middle == __last) - return; - - _DistanceType __len1 = std::distance(__first, __middle); - _DistanceType __len2 = std::distance(__middle, __last); - - _Temporary_buffer<_BidirectionalIterator, _ValueType> __buf(__first, - __last); - if (__buf.begin() == 0) - std::__merge_without_buffer(__first, __middle, __last, __len1, __len2); - else - std::__merge_adaptive(__first, __middle, __last, __len1, __len2, - __buf.begin(), _DistanceType(__buf.size())); + std::__inplace_merge(__first, __middle, __last, + __gnu_cxx::__ops::__iter_less_iter()); } /** @@ -3198,81 +2622,37 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * the function used for the initial sort. */ template<typename _BidirectionalIterator, typename _Compare> - void + inline void inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last, _Compare __comp) { - typedef typename iterator_traits<_BidirectionalIterator>::value_type - _ValueType; - typedef typename iterator_traits<_BidirectionalIterator>::difference_type - _DistanceType; - // concept requirements __glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept< _BidirectionalIterator>) __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, - _ValueType, _ValueType>) + typename iterator_traits<_BidirectionalIterator>::value_type, + typename iterator_traits<_BidirectionalIterator>::value_type>) __glibcxx_requires_sorted_pred(__first, __middle, __comp); __glibcxx_requires_sorted_pred(__middle, __last, __comp); - if (__first == __middle || __middle == __last) - return; - - const _DistanceType __len1 = std::distance(__first, __middle); - const _DistanceType __len2 = std::distance(__middle, __last); - - _Temporary_buffer<_BidirectionalIterator, _ValueType> __buf(__first, - __last); - if (__buf.begin() == 0) - std::__merge_without_buffer(__first, __middle, __last, __len1, - __len2, __comp); - else - std::__merge_adaptive(__first, __middle, __last, __len1, __len2, - __buf.begin(), _DistanceType(__buf.size()), - __comp); + std::__inplace_merge(__first, __middle, __last, + __gnu_cxx::__ops::__iter_comp_iter(__comp)); } /// This is a helper function for the __merge_sort_loop routines. - template<typename _InputIterator1, typename _InputIterator2, - typename _OutputIterator> - _OutputIterator - __move_merge(_InputIterator1 __first1, _InputIterator1 __last1, - _InputIterator2 __first2, _InputIterator2 __last2, - _OutputIterator __result) - { - while (__first1 != __last1 && __first2 != __last2) - { - if (*__first2 < *__first1) - { - *__result = _GLIBCXX_MOVE(*__first2); - ++__first2; - } - else - { - *__result = _GLIBCXX_MOVE(*__first1); - ++__first1; - } - ++__result; - } - return _GLIBCXX_MOVE3(__first2, __last2, - _GLIBCXX_MOVE3(__first1, __last1, - __result)); - } - - /// This is a helper function for the __merge_sort_loop routines. - template<typename _InputIterator1, typename _InputIterator2, - typename _OutputIterator, typename _Compare> + template<typename _InputIterator, typename _OutputIterator, + typename _Compare> _OutputIterator - __move_merge(_InputIterator1 __first1, _InputIterator1 __last1, - _InputIterator2 __first2, _InputIterator2 __last2, + __move_merge(_InputIterator __first1, _InputIterator __last1, + _InputIterator __first2, _InputIterator __last2, _OutputIterator __result, _Compare __comp) { while (__first1 != __last1 && __first2 != __last2) { - if (__comp(*__first2, *__first1)) + if (__comp(__first2, __first1)) { *__result = _GLIBCXX_MOVE(*__first2); ++__first2; @@ -3290,29 +2670,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } template<typename _RandomAccessIterator1, typename _RandomAccessIterator2, - typename _Distance> - void - __merge_sort_loop(_RandomAccessIterator1 __first, - _RandomAccessIterator1 __last, - _RandomAccessIterator2 __result, - _Distance __step_size) - { - const _Distance __two_step = 2 * __step_size; - - while (__last - __first >= __two_step) - { - __result = std::__move_merge(__first, __first + __step_size, - __first + __step_size, - __first + __two_step, __result); - __first += __two_step; - } - - __step_size = std::min(_Distance(__last - __first), __step_size); - std::__move_merge(__first, __first + __step_size, - __first + __step_size, __last, __result); - } - - template<typename _RandomAccessIterator1, typename _RandomAccessIterator2, typename _Distance, typename _Compare> void __merge_sort_loop(_RandomAccessIterator1 __first, @@ -3332,24 +2689,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } __step_size = std::min(_Distance(__last - __first), __step_size); - std::__move_merge(__first,__first + __step_size, + std::__move_merge(__first, __first + __step_size, __first + __step_size, __last, __result, __comp); } - template<typename _RandomAccessIterator, typename _Distance> - void - __chunk_insertion_sort(_RandomAccessIterator __first, - _RandomAccessIterator __last, - _Distance __chunk_size) - { - while (__last - __first >= __chunk_size) - { - std::__insertion_sort(__first, __first + __chunk_size); - __first += __chunk_size; - } - std::__insertion_sort(__first, __last); - } - template<typename _RandomAccessIterator, typename _Distance, typename _Compare> void @@ -3367,30 +2710,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION enum { _S_chunk_size = 7 }; - template<typename _RandomAccessIterator, typename _Pointer> - void - __merge_sort_with_buffer(_RandomAccessIterator __first, - _RandomAccessIterator __last, - _Pointer __buffer) - { - typedef typename iterator_traits<_RandomAccessIterator>::difference_type - _Distance; - - const _Distance __len = __last - __first; - const _Pointer __buffer_last = __buffer + __len; - - _Distance __step_size = _S_chunk_size; - std::__chunk_insertion_sort(__first, __last, __step_size); - - while (__step_size < __len) - { - std::__merge_sort_loop(__first, __last, __buffer, __step_size); - __step_size *= 2; - std::__merge_sort_loop(__buffer, __buffer_last, __first, __step_size); - __step_size *= 2; - } - } - template<typename _RandomAccessIterator, typename _Pointer, typename _Compare> void __merge_sort_with_buffer(_RandomAccessIterator __first, @@ -3418,33 +2737,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } template<typename _RandomAccessIterator, typename _Pointer, - typename _Distance> - void - __stable_sort_adaptive(_RandomAccessIterator __first, - _RandomAccessIterator __last, - _Pointer __buffer, _Distance __buffer_size) - { - const _Distance __len = (__last - __first + 1) / 2; - const _RandomAccessIterator __middle = __first + __len; - if (__len > __buffer_size) - { - std::__stable_sort_adaptive(__first, __middle, - __buffer, __buffer_size); - std::__stable_sort_adaptive(__middle, __last, - __buffer, __buffer_size); - } - else - { - std::__merge_sort_with_buffer(__first, __middle, __buffer); - std::__merge_sort_with_buffer(__middle, __last, __buffer); - } - std::__merge_adaptive(__first, __middle, __last, - _Distance(__middle - __first), - _Distance(__last - __middle), - __buffer, __buffer_size); - } - - template<typename _RandomAccessIterator, typename _Pointer, typename _Distance, typename _Compare> void __stable_sort_adaptive(_RandomAccessIterator __first, @@ -3474,25 +2766,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } /// This is a helper function for the stable sorting routines. - template<typename _RandomAccessIterator> - void - __inplace_stable_sort(_RandomAccessIterator __first, - _RandomAccessIterator __last) - { - if (__last - __first < 15) - { - std::__insertion_sort(__first, __last); - return; - } - _RandomAccessIterator __middle = __first + (__last - __first) / 2; - std::__inplace_stable_sort(__first, __middle); - std::__inplace_stable_sort(__middle, __last); - std::__merge_without_buffer(__first, __middle, __last, - __middle - __first, - __last - __middle); - } - - /// This is a helper function for the stable sorting routines. template<typename _RandomAccessIterator, typename _Compare> void __inplace_stable_sort(_RandomAccessIterator __first, @@ -3519,6 +2792,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // that their input ranges are sorted and the postcondition that their output // ranges are sorted. + template<typename _InputIterator1, typename _InputIterator2, + typename _Compare> + bool + __includes(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, + _Compare __comp) + { + while (__first1 != __last1 && __first2 != __last2) + if (__comp(__first2, __first1)) + return false; + else if (__comp(__first1, __first2)) + ++__first1; + else + ++__first1, ++__first2; + + return __first2 == __last2; + } + /** * @brief Determines whether all elements of a sequence exists in a range. * @param __first1 Start of search range. @@ -3538,32 +2829,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * returned. */ template<typename _InputIterator1, typename _InputIterator2> - bool + inline bool includes(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) { - typedef typename iterator_traits<_InputIterator1>::value_type - _ValueType1; - typedef typename iterator_traits<_InputIterator2>::value_type - _ValueType2; - // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) - __glibcxx_function_requires(_LessThanOpConcept<_ValueType1, _ValueType2>) - __glibcxx_function_requires(_LessThanOpConcept<_ValueType2, _ValueType1>) + __glibcxx_function_requires(_LessThanOpConcept< + typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_function_requires(_LessThanOpConcept< + typename iterator_traits<_InputIterator2>::value_type, + typename iterator_traits<_InputIterator1>::value_type>) __glibcxx_requires_sorted_set(__first1, __last1, __first2); __glibcxx_requires_sorted_set(__first2, __last2, __first1); - while (__first1 != __last1 && __first2 != __last2) - if (*__first2 < *__first1) - return false; - else if(*__first1 < *__first2) - ++__first1; - else - ++__first1, ++__first2; - - return __first2 == __last2; + return std::__includes(__first1, __last1, __first2, __last2, + __gnu_cxx::__ops::__iter_less_iter()); } /** @@ -3589,35 +2872,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION */ template<typename _InputIterator1, typename _InputIterator2, typename _Compare> - bool + inline bool includes(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _Compare __comp) { - typedef typename iterator_traits<_InputIterator1>::value_type - _ValueType1; - typedef typename iterator_traits<_InputIterator2>::value_type - _ValueType2; - // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, - _ValueType1, _ValueType2>) + typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>) __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, - _ValueType2, _ValueType1>) + typename iterator_traits<_InputIterator2>::value_type, + typename iterator_traits<_InputIterator1>::value_type>) __glibcxx_requires_sorted_set_pred(__first1, __last1, __first2, __comp); __glibcxx_requires_sorted_set_pred(__first2, __last2, __first1, __comp); - while (__first1 != __last1 && __first2 != __last2) - if (__comp(*__first2, *__first1)) - return false; - else if(__comp(*__first1, *__first2)) - ++__first1; - else - ++__first1, ++__first2; - - return __first2 == __last2; + return std::__includes(__first1, __last1, __first2, __last2, + __gnu_cxx::__ops::__iter_comp_iter(__comp)); } // nth_element @@ -3630,30 +2903,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // min_element // max_element - /** - * @brief Permute range into the next @e dictionary ordering. - * @ingroup sorting_algorithms - * @param __first Start of range. - * @param __last End of range. - * @return False if wrapped to first permutation, true otherwise. - * - * Treats all permutations of the range as a set of @e dictionary sorted - * sequences. Permutes the current sequence into the next one of this set. - * Returns true if there are more sequences to generate. If the sequence - * is the largest of the set, the smallest is generated and false returned. - */ - template<typename _BidirectionalIterator> + template<typename _BidirectionalIterator, typename _Compare> bool - next_permutation(_BidirectionalIterator __first, - _BidirectionalIterator __last) + __next_permutation(_BidirectionalIterator __first, + _BidirectionalIterator __last, _Compare __comp) { - // concept requirements - __glibcxx_function_requires(_BidirectionalIteratorConcept< - _BidirectionalIterator>) - __glibcxx_function_requires(_LessThanComparableConcept< - typename iterator_traits<_BidirectionalIterator>::value_type>) - __glibcxx_requires_valid_range(__first, __last); - if (__first == __last) return false; _BidirectionalIterator __i = __first; @@ -3667,24 +2921,54 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { _BidirectionalIterator __ii = __i; --__i; - if (*__i < *__ii) + if (__comp(__i, __ii)) { _BidirectionalIterator __j = __last; - while (!(*__i < *--__j)) + while (!__comp(__i, --__j)) {} std::iter_swap(__i, __j); - std::reverse(__ii, __last); + std::__reverse(__ii, __last, + std::__iterator_category(__first)); return true; } if (__i == __first) { - std::reverse(__first, __last); + std::__reverse(__first, __last, + std::__iterator_category(__first)); return false; } } } /** + * @brief Permute range into the next @e dictionary ordering. + * @ingroup sorting_algorithms + * @param __first Start of range. + * @param __last End of range. + * @return False if wrapped to first permutation, true otherwise. + * + * Treats all permutations of the range as a set of @e dictionary sorted + * sequences. Permutes the current sequence into the next one of this set. + * Returns true if there are more sequences to generate. If the sequence + * is the largest of the set, the smallest is generated and false returned. + */ + template<typename _BidirectionalIterator> + inline bool + next_permutation(_BidirectionalIterator __first, + _BidirectionalIterator __last) + { + // concept requirements + __glibcxx_function_requires(_BidirectionalIteratorConcept< + _BidirectionalIterator>) + __glibcxx_function_requires(_LessThanComparableConcept< + typename iterator_traits<_BidirectionalIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + return std::__next_permutation + (__first, __last, __gnu_cxx::__ops::__iter_less_iter()); + } + + /** * @brief Permute range into the next @e dictionary ordering using * comparison functor. * @ingroup sorting_algorithms @@ -3700,7 +2984,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * smallest is generated and false returned. */ template<typename _BidirectionalIterator, typename _Compare> - bool + inline bool next_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp) { @@ -3712,6 +2996,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typename iterator_traits<_BidirectionalIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); + return std::__next_permutation + (__first, __last, __gnu_cxx::__ops::__iter_comp_iter(__comp)); + } + + template<typename _BidirectionalIterator, typename _Compare> + bool + __prev_permutation(_BidirectionalIterator __first, + _BidirectionalIterator __last, _Compare __comp) + { if (__first == __last) return false; _BidirectionalIterator __i = __first; @@ -3725,18 +3018,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { _BidirectionalIterator __ii = __i; --__i; - if (__comp(*__i, *__ii)) + if (__comp(__ii, __i)) { _BidirectionalIterator __j = __last; - while (!bool(__comp(*__i, *--__j))) + while (!__comp(--__j, __i)) {} std::iter_swap(__i, __j); - std::reverse(__ii, __last); + std::__reverse(__ii, __last, + std::__iterator_category(__first)); return true; } if (__i == __first) { - std::reverse(__first, __last); + std::__reverse(__first, __last, + std::__iterator_category(__first)); return false; } } @@ -3756,7 +3051,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * returned. */ template<typename _BidirectionalIterator> - bool + inline bool prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last) { @@ -3767,34 +3062,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typename iterator_traits<_BidirectionalIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); - if (__first == __last) - return false; - _BidirectionalIterator __i = __first; - ++__i; - if (__i == __last) - return false; - __i = __last; - --__i; - - for(;;) - { - _BidirectionalIterator __ii = __i; - --__i; - if (*__ii < *__i) - { - _BidirectionalIterator __j = __last; - while (!(*--__j < *__i)) - {} - std::iter_swap(__i, __j); - std::reverse(__ii, __last); - return true; - } - if (__i == __first) - { - std::reverse(__first, __last); - return false; - } - } + return std::__prev_permutation(__first, __last, + __gnu_cxx::__ops::__iter_less_iter()); } /** @@ -3813,7 +3082,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * the largest is generated and false returned. */ template<typename _BidirectionalIterator, typename _Compare> - bool + inline bool prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp) { @@ -3825,39 +3094,28 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typename iterator_traits<_BidirectionalIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); - if (__first == __last) - return false; - _BidirectionalIterator __i = __first; - ++__i; - if (__i == __last) - return false; - __i = __last; - --__i; - - for(;;) - { - _BidirectionalIterator __ii = __i; - --__i; - if (__comp(*__ii, *__i)) - { - _BidirectionalIterator __j = __last; - while (!bool(__comp(*--__j, *__i))) - {} - std::iter_swap(__i, __j); - std::reverse(__ii, __last); - return true; - } - if (__i == __first) - { - std::reverse(__first, __last); - return false; - } - } + return std::__prev_permutation(__first, __last, + __gnu_cxx::__ops::__iter_comp_iter(__comp)); } // replace // replace_if + template<typename _InputIterator, typename _OutputIterator, + typename _Predicate, typename _Tp> + _OutputIterator + __replace_copy_if(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, + _Predicate __pred, const _Tp& __new_value) + { + for (; __first != __last; ++__first, ++__result) + if (__pred(__first)) + *__result = __new_value; + else + *__result = *__first; + return __result; + } + /** * @brief Copy a sequence, replacing each element of one value with another * value. @@ -3873,7 +3131,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * equal to @p __old_value with @p __new_value. */ template<typename _InputIterator, typename _OutputIterator, typename _Tp> - _OutputIterator + inline _OutputIterator replace_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, const _Tp& __old_value, const _Tp& __new_value) @@ -3886,12 +3144,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typename iterator_traits<_InputIterator>::value_type, _Tp>) __glibcxx_requires_valid_range(__first, __last); - for (; __first != __last; ++__first, ++__result) - if (*__first == __old_value) - *__result = __new_value; - else - *__result = *__first; - return __result; + return std::__replace_copy_if(__first, __last, __result, + __gnu_cxx::__ops::__iter_equals_val(__old_value), + __new_value); } /** @@ -3911,7 +3166,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION */ template<typename _InputIterator, typename _OutputIterator, typename _Predicate, typename _Tp> - _OutputIterator + inline _OutputIterator replace_copy_if(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _Predicate __pred, const _Tp& __new_value) @@ -3924,12 +3179,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typename iterator_traits<_InputIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); - for (; __first != __last; ++__first, ++__result) - if (__pred(*__first)) - *__result = __new_value; - else - *__result = *__first; - return __result; + return std::__replace_copy_if(__first, __last, __result, + __gnu_cxx::__ops::__pred_iter(__pred), + __new_value); + } + + template<typename _InputIterator, typename _Predicate> + typename iterator_traits<_InputIterator>::difference_type + __count_if(_InputIterator __first, _InputIterator __last, _Predicate __pred) + { + typename iterator_traits<_InputIterator>::difference_type __n = 0; + for (; __first != __last; ++__first) + if (__pred(__first)) + ++__n; + return __n; } #if __cplusplus >= 201103L @@ -3960,6 +3223,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _Compare __comp) { return std::is_sorted_until(__first, __last, __comp) == __last; } + template<typename _ForwardIterator, typename _Compare> + _ForwardIterator + __is_sorted_until(_ForwardIterator __first, _ForwardIterator __last, + _Compare __comp) + { + if (__first == __last) + return __last; + + _ForwardIterator __next = __first; + for (++__next; __next != __last; __first = __next, ++__next) + if (__comp(__next, __first)) + return __next; + return __next; + } + /** * @brief Determines the end of a sorted sequence. * @ingroup sorting_algorithms @@ -3969,7 +3247,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * for which the range [__first, i) is sorted. */ template<typename _ForwardIterator> - _ForwardIterator + inline _ForwardIterator is_sorted_until(_ForwardIterator __first, _ForwardIterator __last) { // concept requirements @@ -3978,14 +3256,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typename iterator_traits<_ForwardIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); - if (__first == __last) - return __last; - - _ForwardIterator __next = __first; - for (++__next; __next != __last; __first = __next, ++__next) - if (*__next < *__first) - return __next; - return __next; + return std::__is_sorted_until(__first, __last, + __gnu_cxx::__ops::__iter_less_iter()); } /** @@ -3998,7 +3270,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * for which the range [__first, i) is sorted. */ template<typename _ForwardIterator, typename _Compare> - _ForwardIterator + inline _ForwardIterator is_sorted_until(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { @@ -4009,14 +3281,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typename iterator_traits<_ForwardIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); - if (__first == __last) - return __last; - - _ForwardIterator __next = __first; - for (++__next; __next != __last; __first = __next, ++__next) - if (__comp(*__next, *__first)) - return __next; - return __next; + return std::__is_sorted_until(__first, __last, + __gnu_cxx::__ops::__iter_comp_iter(__comp)); } /** @@ -4055,34 +3321,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION : pair<const _Tp&, const _Tp&>(__a, __b); } - /** - * @brief Return a pair of iterators pointing to the minimum and maximum - * elements in a range. - * @ingroup sorting_algorithms - * @param __first Start of range. - * @param __last End of range. - * @return make_pair(m, M), where m is the first iterator i in - * [__first, __last) such that no other element in the range is - * smaller, and where M is the last iterator i in [__first, __last) - * such that no other element in the range is larger. - */ - template<typename _ForwardIterator> + template<typename _ForwardIterator, typename _Compare> pair<_ForwardIterator, _ForwardIterator> - minmax_element(_ForwardIterator __first, _ForwardIterator __last) + __minmax_element(_ForwardIterator __first, _ForwardIterator __last, + _Compare __comp) { - // concept requirements - __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) - __glibcxx_function_requires(_LessThanComparableConcept< - typename iterator_traits<_ForwardIterator>::value_type>) - __glibcxx_requires_valid_range(__first, __last); - _ForwardIterator __next = __first; if (__first == __last || ++__next == __last) return std::make_pair(__first, __first); _ForwardIterator __min, __max; - if (*__next < *__first) + if (__comp(__next, __first)) { __min = __next; __max = __first; @@ -4101,25 +3351,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __next = __first; if (++__next == __last) { - if (*__first < *__min) + if (__comp(__first, __min)) __min = __first; - else if (!(*__first < *__max)) + else if (!__comp(__first, __max)) __max = __first; break; } - if (*__next < *__first) + if (__comp(__next, __first)) { - if (*__next < *__min) + if (__comp(__next, __min)) __min = __next; - if (!(*__first < *__max)) + if (!__comp(__first, __max)) __max = __first; } else { - if (*__first < *__min) + if (__comp(__first, __min)) __min = __first; - if (!(*__next < *__max)) + if (!__comp(__next, __max)) __max = __next; } @@ -4136,6 +3386,31 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * @ingroup sorting_algorithms * @param __first Start of range. * @param __last End of range. + * @return make_pair(m, M), where m is the first iterator i in + * [__first, __last) such that no other element in the range is + * smaller, and where M is the last iterator i in [__first, __last) + * such that no other element in the range is larger. + */ + template<typename _ForwardIterator> + inline pair<_ForwardIterator, _ForwardIterator> + minmax_element(_ForwardIterator __first, _ForwardIterator __last) + { + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_LessThanComparableConcept< + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + return std::__minmax_element(__first, __last, + __gnu_cxx::__ops::__iter_less_iter()); + } + + /** + * @brief Return a pair of iterators pointing to the minimum and maximum + * elements in a range. + * @ingroup sorting_algorithms + * @param __first Start of range. + * @param __last End of range. * @param __comp Comparison functor. * @return make_pair(m, M), where m is the first iterator i in * [__first, __last) such that no other element in the range is @@ -4143,7 +3418,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * such that no other element in the range is larger. */ template<typename _ForwardIterator, typename _Compare> - pair<_ForwardIterator, _ForwardIterator> + inline pair<_ForwardIterator, _ForwardIterator> minmax_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { @@ -4154,58 +3429,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typename iterator_traits<_ForwardIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); - _ForwardIterator __next = __first; - if (__first == __last - || ++__next == __last) - return std::make_pair(__first, __first); - - _ForwardIterator __min, __max; - if (__comp(*__next, *__first)) - { - __min = __next; - __max = __first; - } - else - { - __min = __first; - __max = __next; - } - - __first = __next; - ++__first; - - while (__first != __last) - { - __next = __first; - if (++__next == __last) - { - if (__comp(*__first, *__min)) - __min = __first; - else if (!__comp(*__first, *__max)) - __max = __first; - break; - } - - if (__comp(*__next, *__first)) - { - if (__comp(*__next, *__min)) - __min = __next; - if (!__comp(*__first, *__max)) - __max = __first; - } - else - { - if (__comp(*__first, *__min)) - __min = __first; - if (!__comp(*__next, *__max)) - __max = __next; - } - - __first = __next; - ++__first; - } - - return std::make_pair(__min, __max); + return std::__minmax_element(__first, __last, + __gnu_cxx::__ops::__iter_comp_iter(__comp)); } // N2722 + DR 915. @@ -4247,27 +3472,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return std::make_pair(*__p.first, *__p.second); } - /** - * @brief Checks whether a permutaion of the second sequence is equal - * to the first sequence. - * @ingroup non_mutating_algorithms - * @param __first1 Start of first range. - * @param __last1 End of first range. - * @param __first2 Start of second range. - * @return true if there exists a permutation of the elements in the range - * [__first2, __first2 + (__last1 - __first1)), beginning with - * ForwardIterator2 begin, such that equal(__first1, __last1, begin) - * returns true; otherwise, returns false. - */ - template<typename _ForwardIterator1, typename _ForwardIterator2> + template<typename _ForwardIterator1, typename _ForwardIterator2, + typename _BinaryPredicate> bool - is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2) + __is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _BinaryPredicate __pred) { // Efficiently compare identical prefixes: O(N) if sequences // have the same elements in the same order. for (; __first1 != __last1; ++__first1, ++__first2) - if (!(*__first1 == *__first2)) + if (!__pred(__first1, __first2)) break; if (__first1 == __last1) @@ -4279,12 +3493,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION std::advance(__last2, std::distance(__first1, __last1)); for (_ForwardIterator1 __scan = __first1; __scan != __last1; ++__scan) { - if (__scan != _GLIBCXX_STD_A::find(__first1, __scan, *__scan)) + if (__scan != std::__find_if(__first1, __scan, + __gnu_cxx::__ops::__iter_comp_iter(__pred, __scan))) continue; // We've seen this one before. - - auto __matches = std::count(__first2, __last2, *__scan); - if (0 == __matches - || std::count(__scan, __last1, *__scan) != __matches) + + auto __matches + = std::__count_if(__first2, __last2, + __gnu_cxx::__ops::__iter_comp_iter(__pred, __scan)); + if (0 == __matches || + std::__count_if(__scan, __last1, + __gnu_cxx::__ops::__iter_comp_iter(__pred, __scan)) + != __matches) return false; } return true; @@ -4297,6 +3516,35 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * @param __first1 Start of first range. * @param __last1 End of first range. * @param __first2 Start of second range. + * @return true if there exists a permutation of the elements in the range + * [__first2, __first2 + (__last1 - __first1)), beginning with + * ForwardIterator2 begin, such that equal(__first1, __last1, begin) + * returns true; otherwise, returns false. + */ + template<typename _ForwardIterator1, typename _ForwardIterator2> + inline bool + is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2) + { + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator1>) + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator2>) + __glibcxx_function_requires(_EqualOpConcept< + typename iterator_traits<_ForwardIterator1>::value_type, + typename iterator_traits<_ForwardIterator2>::value_type>) + __glibcxx_requires_valid_range(__first1, __last1); + + return std::__is_permutation(__first1, __last1, __first2, + __gnu_cxx::__ops::__iter_equal_to_iter()); + } + + /** + * @brief Checks whether a permutation of the second sequence is equal + * to the first sequence. + * @ingroup non_mutating_algorithms + * @param __first1 Start of first range. + * @param __last1 End of first range. + * @param __first2 Start of second range. * @param __pred A binary predicate. * @return true if there exists a permutation of the elements in * the range [__first2, __first2 + (__last1 - __first1)), @@ -4306,42 +3554,83 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION */ template<typename _ForwardIterator1, typename _ForwardIterator2, typename _BinaryPredicate> - bool + inline bool is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _BinaryPredicate __pred) { + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator1>) + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator2>) + __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, + typename iterator_traits<_ForwardIterator1>::value_type, + typename iterator_traits<_ForwardIterator2>::value_type>) + __glibcxx_requires_valid_range(__first1, __last1); + + return std::__is_permutation(__first1, __last1, __first2, + __gnu_cxx::__ops::__iter_comp_iter(__pred)); + } + +#if __cplusplus > 201103L + template<typename _ForwardIterator1, typename _ForwardIterator2, + typename _BinaryPredicate> + bool + __is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2, + _BinaryPredicate __pred) + { + using _Cat1 + = typename iterator_traits<_ForwardIterator1>::iterator_category; + using _Cat2 + = typename iterator_traits<_ForwardIterator2>::iterator_category; + using _It1_is_RA = is_same<_Cat1, random_access_iterator_tag>; + using _It2_is_RA = is_same<_Cat2, random_access_iterator_tag>; + constexpr bool __ra_iters = _It1_is_RA() && _It2_is_RA(); + if (__ra_iters) + { + auto __d1 = std::distance(__first1, __last1); + auto __d2 = std::distance(__first2, __last2); + if (__d1 != __d2) + return false; + } + // Efficiently compare identical prefixes: O(N) if sequences // have the same elements in the same order. for (; __first1 != __last1; ++__first1, ++__first2) - if (!bool(__pred(*__first1, *__first2))) + if (!__pred(__first1, __first2)) break; - if (__first1 == __last1) - return true; + if (__ra_iters) + { + if (__first1 == __last1) + return true; + } + else + { + auto __d1 = std::distance(__first1, __last1); + auto __d2 = std::distance(__first2, __last2); + if (__d1 == 0 && __d2 == 0) + return true; + if (__d1 != __d2) + return false; + } - // Establish __last2 assuming equal ranges by iterating over the - // rest of the list. - _ForwardIterator2 __last2 = __first2; - std::advance(__last2, std::distance(__first1, __last1)); for (_ForwardIterator1 __scan = __first1; __scan != __last1; ++__scan) { - using std::placeholders::_1; - - if (__scan != _GLIBCXX_STD_A::find_if(__first1, __scan, - std::bind(__pred, _1, *__scan))) + if (__scan != std::__find_if(__first1, __scan, + __gnu_cxx::__ops::__iter_comp_iter(__pred, __scan))) continue; // We've seen this one before. - - auto __matches = std::count_if(__first2, __last2, - std::bind(__pred, _1, *__scan)); + + auto __matches = std::__count_if(__first2, __last2, + __gnu_cxx::__ops::__iter_comp_iter(__pred, __scan)); if (0 == __matches - || std::count_if(__scan, __last1, - std::bind(__pred, _1, *__scan)) != __matches) + || std::__count_if(__scan, __last1, + __gnu_cxx::__ops::__iter_comp_iter(__pred, __scan)) + != __matches) return false; } return true; } -#if __cplusplus > 201103L /** * @brief Checks whether a permutaion of the second sequence is equal * to the first sequence. @@ -4356,47 +3645,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * otherwise, returns false. */ template<typename _ForwardIterator1, typename _ForwardIterator2> - bool + inline bool is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2) { - using _Cat1 - = typename iterator_traits<_ForwardIterator1>::iterator_category; - using _Cat2 - = typename iterator_traits<_ForwardIterator2>::iterator_category; - using _It1_is_RA = is_same<_Cat1, random_access_iterator_tag>; - using _It2_is_RA = is_same<_Cat2, random_access_iterator_tag>; - if (_It1_is_RA() && _It2_is_RA()) - { - auto __d1 = std::distance(__first1, __last1); - auto __d2 = std::distance(__first2, __last2); - if (__d1 != __d2) - return false; - } - - // Efficiently compare identical prefixes: O(N) if sequences - // have the same elements in the same order. - for (; __first1 != __last1 && __first2 != __last2; ++__first1, ++__first2) - if (!(*__first1 == *__first2)) - break; - - if (__first1 == __last1 && __first2 == __last2) - return true; - - if (std::distance(__first1, __last1) != std::distance(__first2, __last2)) - return false; - - for (auto __scan = __first1; __scan != __last1; ++__scan) - { - if (__scan != _GLIBCXX_STD_A::find(__first1, __scan, *__scan)) - continue; // We've seen this one before. + __glibcxx_requires_valid_range(__first1, __last1); + __glibcxx_requires_valid_range(__first2, __last2); - auto __matches = std::count(__first2, __last2, *__scan); - if (0 == __matches - || std::count(__scan, __last1, *__scan) != __matches) - return false; - } - return true; + return + std::__is_permutation(__first1, __last1, __first2, __last2, + __gnu_cxx::__ops::__iter_equal_to_iter()); } /** @@ -4415,63 +3673,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION */ template<typename _ForwardIterator1, typename _ForwardIterator2, typename _BinaryPredicate> - bool + inline bool is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __pred) { - using _Cat1 - = typename iterator_traits<_ForwardIterator1>::iterator_category; - using _Cat2 - = typename iterator_traits<_ForwardIterator2>::iterator_category; - using _It1_is_RA = is_same<_Cat1, random_access_iterator_tag>; - using _It2_is_RA = is_same<_Cat2, random_access_iterator_tag>; - constexpr bool __ra_iters = _It1_is_RA() && _It2_is_RA(); - if (__ra_iters) - { - auto __d1 = std::distance(__first1, __last1); - auto __d2 = std::distance(__first2, __last2); - if (__d1 != __d2) - return false; - } - - // Efficiently compare identical prefixes: O(N) if sequences - // have the same elements in the same order. - for (; __first1 != __last1; ++__first1, ++__first2) - if (!bool(__pred(*__first1, *__first2))) - break; - - if (__ra_iters) - { - if (__first1 == __last1) - return true; - } - else - { - auto __d1 = std::distance(__first1, __last1); - auto __d2 = std::distance(__first2, __last2); - if (__d1 == 0 && __d2 == 0) - return true; - if (__d1 != __d2) - return false; - } - - for (_ForwardIterator1 __scan = __first1; __scan != __last1; ++__scan) - { - using std::placeholders::_1; - - if (__scan != _GLIBCXX_STD_A::find_if(__first1, __scan, - std::bind(__pred, _1, *__scan))) - continue; // We've seen this one before. + __glibcxx_requires_valid_range(__first1, __last1); + __glibcxx_requires_valid_range(__first2, __last2); - auto __matches = std::count_if(__first2, __last2, - std::bind(__pred, _1, *__scan)); - if (0 == __matches - || std::count_if(__scan, __last1, - std::bind(__pred, _1, *__scan)) != __matches) - return false; - } - return true; + return std::__is_permutation(__first1, __last1, __first2, __last2, + __gnu_cxx::__ops::__iter_comp_iter(__pred)); } #endif @@ -4564,8 +3775,8 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO __glibcxx_function_requires(_EqualOpConcept< typename iterator_traits<_InputIterator>::value_type, _Tp>) __glibcxx_requires_valid_range(__first, __last); - return std::__find(__first, __last, __val, - std::__iterator_category(__first)); + return std::__find_if(__first, __last, + __gnu_cxx::__ops::__iter_equals_val(__val)); } /** @@ -4588,8 +3799,9 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, typename iterator_traits<_InputIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); - return std::__find_if(__first, __last, __pred, - std::__iterator_category(__first)); + + return std::__find_if(__first, __last, + __gnu_cxx::__ops::__pred_iter(__pred)); } /** @@ -4681,7 +3893,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO * or @p __last if no such iterator exists. */ template<typename _ForwardIterator> - _ForwardIterator + inline _ForwardIterator adjacent_find(_ForwardIterator __first, _ForwardIterator __last) { // concept requirements @@ -4689,16 +3901,9 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO __glibcxx_function_requires(_EqualityComparableConcept< typename iterator_traits<_ForwardIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); - if (__first == __last) - return __last; - _ForwardIterator __next = __first; - while(++__next != __last) - { - if (*__first == *__next) - return __first; - __first = __next; - } - return __last; + + return std::__adjacent_find(__first, __last, + __gnu_cxx::__ops::__iter_equal_to_iter()); } /** @@ -4713,7 +3918,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO * exists. */ template<typename _ForwardIterator, typename _BinaryPredicate> - _ForwardIterator + inline _ForwardIterator adjacent_find(_ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __binary_pred) { @@ -4723,16 +3928,9 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO typename iterator_traits<_ForwardIterator>::value_type, typename iterator_traits<_ForwardIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); - if (__first == __last) - return __last; - _ForwardIterator __next = __first; - while(++__next != __last) - { - if (__binary_pred(*__first, *__next)) - return __first; - __first = __next; - } - return __last; + + return std::__adjacent_find(__first, __last, + __gnu_cxx::__ops::__iter_comp_iter(__binary_pred)); } /** @@ -4745,19 +3943,17 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO * for which @c *i == @p __value */ template<typename _InputIterator, typename _Tp> - typename iterator_traits<_InputIterator>::difference_type + inline typename iterator_traits<_InputIterator>::difference_type count(_InputIterator __first, _InputIterator __last, const _Tp& __value) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) __glibcxx_function_requires(_EqualOpConcept< - typename iterator_traits<_InputIterator>::value_type, _Tp>) + typename iterator_traits<_InputIterator>::value_type, _Tp>) __glibcxx_requires_valid_range(__first, __last); - typename iterator_traits<_InputIterator>::difference_type __n = 0; - for (; __first != __last; ++__first) - if (*__first == __value) - ++__n; - return __n; + + return std::__count_if(__first, __last, + __gnu_cxx::__ops::__iter_equals_val(__value)); } /** @@ -4770,7 +3966,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO * for which @p __pred(*i) is true. */ template<typename _InputIterator, typename _Predicate> - typename iterator_traits<_InputIterator>::difference_type + inline typename iterator_traits<_InputIterator>::difference_type count_if(_InputIterator __first, _InputIterator __last, _Predicate __pred) { // concept requirements @@ -4778,11 +3974,9 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, typename iterator_traits<_InputIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); - typename iterator_traits<_InputIterator>::difference_type __n = 0; - for (; __first != __last; ++__first) - if (__pred(*__first)) - ++__n; - return __n; + + return std::__count_if(__first, __last, + __gnu_cxx::__ops::__pred_iter(__pred)); } /** @@ -4812,7 +4006,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO * @p [__first1,__last1-(__last2-__first2)) */ template<typename _ForwardIterator1, typename _ForwardIterator2> - _ForwardIterator1 + inline _ForwardIterator1 search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2) { @@ -4825,40 +4019,8 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO __glibcxx_requires_valid_range(__first1, __last1); __glibcxx_requires_valid_range(__first2, __last2); - // Test for empty ranges - if (__first1 == __last1 || __first2 == __last2) - return __first1; - - // Test for a pattern of length 1. - _ForwardIterator2 __p1(__first2); - if (++__p1 == __last2) - return _GLIBCXX_STD_A::find(__first1, __last1, *__first2); - - // General case. - _ForwardIterator2 __p; - _ForwardIterator1 __current = __first1; - - for (;;) - { - __first1 = _GLIBCXX_STD_A::find(__first1, __last1, *__first2); - if (__first1 == __last1) - return __last1; - - __p = __p1; - __current = __first1; - if (++__current == __last1) - return __last1; - - while (*__current == *__p) - { - if (++__p == __last2) - return __first1; - if (++__current == __last1) - return __last1; - } - ++__first1; - } - return __first1; + return std::__search(__first1, __last1, __first2, __last2, + __gnu_cxx::__ops::__iter_equal_to_iter()); } /** @@ -4884,7 +4046,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO */ template<typename _ForwardIterator1, typename _ForwardIterator2, typename _BinaryPredicate> - _ForwardIterator1 + inline _ForwardIterator1 search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __predicate) @@ -4898,50 +4060,10 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO __glibcxx_requires_valid_range(__first1, __last1); __glibcxx_requires_valid_range(__first2, __last2); - // Test for empty ranges - if (__first1 == __last1 || __first2 == __last2) - return __first1; - - // Test for a pattern of length 1. - _ForwardIterator2 __p1(__first2); - if (++__p1 == __last2) - { - while (__first1 != __last1 - && !bool(__predicate(*__first1, *__first2))) - ++__first1; - return __first1; - } - - // General case. - _ForwardIterator2 __p; - _ForwardIterator1 __current = __first1; - - for (;;) - { - while (__first1 != __last1 - && !bool(__predicate(*__first1, *__first2))) - ++__first1; - if (__first1 == __last1) - return __last1; - - __p = __p1; - __current = __first1; - if (++__current == __last1) - return __last1; - - while (__predicate(*__current, *__p)) - { - if (++__p == __last2) - return __first1; - if (++__current == __last1) - return __last1; - } - ++__first1; - } - return __first1; + return std::__search(__first1, __last1, __first2, __last2, + __gnu_cxx::__ops::__iter_comp_iter(__predicate)); } - /** * @brief Search a sequence for a number of consecutive values. * @ingroup non_mutating_algorithms @@ -4958,22 +4080,18 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO * equal to @p __val. */ template<typename _ForwardIterator, typename _Integer, typename _Tp> - _ForwardIterator + inline _ForwardIterator search_n(_ForwardIterator __first, _ForwardIterator __last, _Integer __count, const _Tp& __val) { // concept requirements __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) __glibcxx_function_requires(_EqualOpConcept< - typename iterator_traits<_ForwardIterator>::value_type, _Tp>) + typename iterator_traits<_ForwardIterator>::value_type, _Tp>) __glibcxx_requires_valid_range(__first, __last); - if (__count <= 0) - return __first; - if (__count == 1) - return _GLIBCXX_STD_A::find(__first, __last, __val); - return std::__search_n(__first, __last, __count, __val, - std::__iterator_category(__first)); + return std::__search_n(__first, __last, __count, + __gnu_cxx::__ops::__iter_equals_val(__val)); } @@ -4996,7 +4114,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO */ template<typename _ForwardIterator, typename _Integer, typename _Tp, typename _BinaryPredicate> - _ForwardIterator + inline _ForwardIterator search_n(_ForwardIterator __first, _ForwardIterator __last, _Integer __count, const _Tp& __val, _BinaryPredicate __binary_pred) @@ -5007,16 +4125,8 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO typename iterator_traits<_ForwardIterator>::value_type, _Tp>) __glibcxx_requires_valid_range(__first, __last); - if (__count <= 0) - return __first; - if (__count == 1) - { - while (__first != __last && !bool(__binary_pred(*__first, __val))) - ++__first; - return __first; - } - return std::__search_n(__first, __last, __count, __val, __binary_pred, - std::__iterator_category(__first)); + return std::__search_n(__first, __last, __count, + __gnu_cxx::__ops::__iter_comp_val(__binary_pred, __val)); } @@ -5216,7 +4326,6 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO return __first; } - /** * @brief Copy a sequence, removing consecutive duplicate values. * @ingroup mutating_algorithms @@ -5254,6 +4363,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO if (__first == __last) return __result; return std::__unique_copy(__first, __last, __result, + __gnu_cxx::__ops::__iter_equal_to_iter(), std::__iterator_category(__first), std::__iterator_category(__result)); } @@ -5292,12 +4402,12 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO if (__first == __last) return __result; - return std::__unique_copy(__first, __last, __result, __binary_pred, + return std::__unique_copy(__first, __last, __result, + __gnu_cxx::__ops::__iter_comp_iter(__binary_pred), std::__iterator_category(__first), std::__iterator_category(__result)); } - /** * @brief Randomly shuffle the elements of a sequence. * @ingroup mutating_algorithms @@ -5390,7 +4500,6 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO } - /** * @brief Sort the smallest elements of a sequence. * @ingroup sorting_algorithms @@ -5413,18 +4522,16 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO _RandomAccessIterator __middle, _RandomAccessIterator __last) { - typedef typename iterator_traits<_RandomAccessIterator>::value_type - _ValueType; - // concept requirements __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< _RandomAccessIterator>) - __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>) + __glibcxx_function_requires(_LessThanComparableConcept< + typename iterator_traits<_RandomAccessIterator>::value_type>) __glibcxx_requires_valid_range(__first, __middle); __glibcxx_requires_valid_range(__middle, __last); - std::__heap_select(__first, __middle, __last); - std::sort_heap(__first, __middle); + std::__partial_sort(__first, __middle, __last, + __gnu_cxx::__ops::__iter_less_iter()); } /** @@ -5453,19 +4560,17 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO _RandomAccessIterator __last, _Compare __comp) { - typedef typename iterator_traits<_RandomAccessIterator>::value_type - _ValueType; - // concept requirements __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< _RandomAccessIterator>) __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, - _ValueType, _ValueType>) + typename iterator_traits<_RandomAccessIterator>::value_type, + typename iterator_traits<_RandomAccessIterator>::value_type>) __glibcxx_requires_valid_range(__first, __middle); __glibcxx_requires_valid_range(__middle, __last); - std::__heap_select(__first, __middle, __last, __comp); - std::sort_heap(__first, __middle, __comp); + std::__partial_sort(__first, __middle, __last, + __gnu_cxx::__ops::__iter_comp_iter(__comp)); } /** @@ -5488,13 +4593,11 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last) { - typedef typename iterator_traits<_RandomAccessIterator>::value_type - _ValueType; - // concept requirements __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< _RandomAccessIterator>) - __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>) + __glibcxx_function_requires(_LessThanComparableConcept< + typename iterator_traits<_RandomAccessIterator>::value_type>) __glibcxx_requires_valid_range(__first, __nth); __glibcxx_requires_valid_range(__nth, __last); @@ -5502,7 +4605,8 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO return; std::__introselect(__first, __nth, __last, - std::__lg(__last - __first) * 2); + std::__lg(__last - __first) * 2, + __gnu_cxx::__ops::__iter_less_iter()); } /** @@ -5527,14 +4631,12 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last, _Compare __comp) { - typedef typename iterator_traits<_RandomAccessIterator>::value_type - _ValueType; - // concept requirements __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< _RandomAccessIterator>) __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, - _ValueType, _ValueType>) + typename iterator_traits<_RandomAccessIterator>::value_type, + typename iterator_traits<_RandomAccessIterator>::value_type>) __glibcxx_requires_valid_range(__first, __nth); __glibcxx_requires_valid_range(__nth, __last); @@ -5542,10 +4644,10 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO return; std::__introselect(__first, __nth, __last, - std::__lg(__last - __first) * 2, __comp); + std::__lg(__last - __first) * 2, + __gnu_cxx::__ops::__iter_comp_iter(__comp)); } - /** * @brief Sort the elements of a sequence. * @ingroup sorting_algorithms @@ -5564,21 +4666,14 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO inline void sort(_RandomAccessIterator __first, _RandomAccessIterator __last) { - typedef typename iterator_traits<_RandomAccessIterator>::value_type - _ValueType; - // concept requirements __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< _RandomAccessIterator>) - __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>) + __glibcxx_function_requires(_LessThanComparableConcept< + typename iterator_traits<_RandomAccessIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); - if (__first != __last) - { - std::__introsort_loop(__first, __last, - std::__lg(__last - __first) * 2); - std::__final_insertion_sort(__first, __last); - } + std::__sort(__first, __last, __gnu_cxx::__ops::__iter_less_iter()); } /** @@ -5601,22 +4696,40 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { - typedef typename iterator_traits<_RandomAccessIterator>::value_type - _ValueType; - // concept requirements __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< _RandomAccessIterator>) - __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, _ValueType, - _ValueType>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + typename iterator_traits<_RandomAccessIterator>::value_type, + typename iterator_traits<_RandomAccessIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); - if (__first != __last) + std::__sort(__first, __last, __gnu_cxx::__ops::__iter_comp_iter(__comp)); + } + + template<typename _InputIterator1, typename _InputIterator2, + typename _OutputIterator, typename _Compare> + _OutputIterator + __merge(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, + _OutputIterator __result, _Compare __comp) + { + while (__first1 != __last1 && __first2 != __last2) { - std::__introsort_loop(__first, __last, - std::__lg(__last - __first) * 2, __comp); - std::__final_insertion_sort(__first, __last, __comp); + if (__comp(__first2, __first1)) + { + *__result = *__first2; + ++__first2; + } + else + { + *__result = *__first1; + ++__first1; + } + ++__result; } + return std::copy(__first2, __last2, + std::copy(__first1, __last1, __result)); } /** @@ -5640,43 +4753,27 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO */ template<typename _InputIterator1, typename _InputIterator2, typename _OutputIterator> - _OutputIterator + inline _OutputIterator merge(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result) { - typedef typename iterator_traits<_InputIterator1>::value_type - _ValueType1; - typedef typename iterator_traits<_InputIterator2>::value_type - _ValueType2; - // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, - _ValueType1>) + typename iterator_traits<_InputIterator1>::value_type>) __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, - _ValueType2>) - __glibcxx_function_requires(_LessThanOpConcept<_ValueType2, _ValueType1>) + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_function_requires(_LessThanOpConcept< + typename iterator_traits<_InputIterator2>::value_type, + typename iterator_traits<_InputIterator1>::value_type>) __glibcxx_requires_sorted_set(__first1, __last1, __first2); __glibcxx_requires_sorted_set(__first2, __last2, __first1); - while (__first1 != __last1 && __first2 != __last2) - { - if (*__first2 < *__first1) - { - *__result = *__first2; - ++__first2; - } - else - { - *__result = *__first1; - ++__first1; - } - ++__result; - } - return std::copy(__first2, __last2, std::copy(__first1, __last1, - __result)); + return _GLIBCXX_STD_A::__merge(__first1, __last1, + __first2, __last2, __result, + __gnu_cxx::__ops::__iter_less_iter()); } /** @@ -5704,46 +4801,48 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO */ template<typename _InputIterator1, typename _InputIterator2, typename _OutputIterator, typename _Compare> - _OutputIterator + inline _OutputIterator merge(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) { - typedef typename iterator_traits<_InputIterator1>::value_type - _ValueType1; - typedef typename iterator_traits<_InputIterator2>::value_type - _ValueType2; - // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, - _ValueType1>) + typename iterator_traits<_InputIterator1>::value_type>) __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, - _ValueType2>) + typename iterator_traits<_InputIterator2>::value_type>) __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, - _ValueType2, _ValueType1>) + typename iterator_traits<_InputIterator2>::value_type, + typename iterator_traits<_InputIterator1>::value_type>) __glibcxx_requires_sorted_set_pred(__first1, __last1, __first2, __comp); __glibcxx_requires_sorted_set_pred(__first2, __last2, __first1, __comp); - while (__first1 != __last1 && __first2 != __last2) - { - if (__comp(*__first2, *__first1)) - { - *__result = *__first2; - ++__first2; - } - else - { - *__result = *__first1; - ++__first1; - } - ++__result; - } - return std::copy(__first2, __last2, std::copy(__first1, __last1, - __result)); + return _GLIBCXX_STD_A::__merge(__first1, __last1, + __first2, __last2, __result, + __gnu_cxx::__ops::__iter_comp_iter(__comp)); } + template<typename _RandomAccessIterator, typename _Compare> + inline void + __stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, + _Compare __comp) + { + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + typedef typename iterator_traits<_RandomAccessIterator>::difference_type + _DistanceType; + + typedef _Temporary_buffer<_RandomAccessIterator, _ValueType> _TmpBuf; + _TmpBuf __buf(__first, __last); + + if (__buf.begin() == 0) + std::__inplace_stable_sort(__first, __last, __comp); + else + std::__stable_sort_adaptive(__first, __last, __buf.begin(), + _DistanceType(__buf.size()), __comp); + } /** * @brief Sort the elements of a sequence, preserving the relative order @@ -5766,24 +4865,15 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO inline void stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last) { - typedef typename iterator_traits<_RandomAccessIterator>::value_type - _ValueType; - typedef typename iterator_traits<_RandomAccessIterator>::difference_type - _DistanceType; - // concept requirements __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< _RandomAccessIterator>) - __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>) + __glibcxx_function_requires(_LessThanComparableConcept< + typename iterator_traits<_RandomAccessIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); - _Temporary_buffer<_RandomAccessIterator, _ValueType> __buf(__first, - __last); - if (__buf.begin() == 0) - std::__inplace_stable_sort(__first, __last); - else - std::__stable_sort_adaptive(__first, __last, __buf.begin(), - _DistanceType(__buf.size())); + _GLIBCXX_STD_A::__stable_sort(__first, __last, + __gnu_cxx::__ops::__iter_less_iter()); } /** @@ -5809,28 +4899,49 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { - typedef typename iterator_traits<_RandomAccessIterator>::value_type - _ValueType; - typedef typename iterator_traits<_RandomAccessIterator>::difference_type - _DistanceType; - // concept requirements __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< _RandomAccessIterator>) __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, - _ValueType, - _ValueType>) + typename iterator_traits<_RandomAccessIterator>::value_type, + typename iterator_traits<_RandomAccessIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); - _Temporary_buffer<_RandomAccessIterator, _ValueType> __buf(__first, - __last); - if (__buf.begin() == 0) - std::__inplace_stable_sort(__first, __last, __comp); - else - std::__stable_sort_adaptive(__first, __last, __buf.begin(), - _DistanceType(__buf.size()), __comp); + _GLIBCXX_STD_A::__stable_sort(__first, __last, + __gnu_cxx::__ops::__iter_comp_iter(__comp)); } + template<typename _InputIterator1, typename _InputIterator2, + typename _OutputIterator, + typename _Compare> + _OutputIterator + __set_union(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, + _OutputIterator __result, _Compare __comp) + { + while (__first1 != __last1 && __first2 != __last2) + { + if (__comp(__first1, __first2)) + { + *__result = *__first1; + ++__first1; + } + else if (__comp(__first2, __first1)) + { + *__result = *__first2; + ++__first2; + } + else + { + *__result = *__first1; + ++__first1; + ++__first2; + } + ++__result; + } + return std::copy(__first2, __last2, + std::copy(__first1, __last1, __result)); + } /** * @brief Return the union of two sorted ranges. @@ -5852,50 +4963,30 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO */ template<typename _InputIterator1, typename _InputIterator2, typename _OutputIterator> - _OutputIterator + inline _OutputIterator set_union(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result) { - typedef typename iterator_traits<_InputIterator1>::value_type - _ValueType1; - typedef typename iterator_traits<_InputIterator2>::value_type - _ValueType2; - // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, - _ValueType1>) + typename iterator_traits<_InputIterator1>::value_type>) __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, - _ValueType2>) - __glibcxx_function_requires(_LessThanOpConcept<_ValueType1, _ValueType2>) - __glibcxx_function_requires(_LessThanOpConcept<_ValueType2, _ValueType1>) + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_function_requires(_LessThanOpConcept< + typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_function_requires(_LessThanOpConcept< + typename iterator_traits<_InputIterator2>::value_type, + typename iterator_traits<_InputIterator1>::value_type>) __glibcxx_requires_sorted_set(__first1, __last1, __first2); __glibcxx_requires_sorted_set(__first2, __last2, __first1); - while (__first1 != __last1 && __first2 != __last2) - { - if (*__first1 < *__first2) - { - *__result = *__first1; - ++__first1; - } - else if (*__first2 < *__first1) - { - *__result = *__first2; - ++__first2; - } - else - { - *__result = *__first1; - ++__first1; - ++__first2; - } - ++__result; - } - return std::copy(__first2, __last2, std::copy(__first1, __last1, - __result)); + return _GLIBCXX_STD_A::__set_union(__first1, __last1, + __first2, __last2, __result, + __gnu_cxx::__ops::__iter_less_iter()); } /** @@ -5919,52 +5010,53 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO */ template<typename _InputIterator1, typename _InputIterator2, typename _OutputIterator, typename _Compare> - _OutputIterator + inline _OutputIterator set_union(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) { - typedef typename iterator_traits<_InputIterator1>::value_type - _ValueType1; - typedef typename iterator_traits<_InputIterator2>::value_type - _ValueType2; - // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, - _ValueType1>) + typename iterator_traits<_InputIterator1>::value_type>) __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, - _ValueType2>) + typename iterator_traits<_InputIterator2>::value_type>) __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, - _ValueType1, _ValueType2>) + typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>) __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, - _ValueType2, _ValueType1>) + typename iterator_traits<_InputIterator2>::value_type, + typename iterator_traits<_InputIterator1>::value_type>) __glibcxx_requires_sorted_set_pred(__first1, __last1, __first2, __comp); __glibcxx_requires_sorted_set_pred(__first2, __last2, __first1, __comp); + return _GLIBCXX_STD_A::__set_union(__first1, __last1, + __first2, __last2, __result, + __gnu_cxx::__ops::__iter_comp_iter(__comp)); + } + + template<typename _InputIterator1, typename _InputIterator2, + typename _OutputIterator, + typename _Compare> + _OutputIterator + __set_intersection(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, + _OutputIterator __result, _Compare __comp) + { while (__first1 != __last1 && __first2 != __last2) - { - if (__comp(*__first1, *__first2)) - { - *__result = *__first1; - ++__first1; - } - else if (__comp(*__first2, *__first1)) - { - *__result = *__first2; - ++__first2; - } - else - { - *__result = *__first1; - ++__first1; - ++__first2; - } - ++__result; - } - return std::copy(__first2, __last2, std::copy(__first1, __last1, - __result)); + if (__comp(__first1, __first2)) + ++__first1; + else if (__comp(__first2, __first1)) + ++__first2; + else + { + *__result = *__first1; + ++__first1; + ++__first2; + ++__result; + } + return __result; } /** @@ -5986,39 +5078,28 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO */ template<typename _InputIterator1, typename _InputIterator2, typename _OutputIterator> - _OutputIterator + inline _OutputIterator set_intersection(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result) { - typedef typename iterator_traits<_InputIterator1>::value_type - _ValueType1; - typedef typename iterator_traits<_InputIterator2>::value_type - _ValueType2; - // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, - _ValueType1>) - __glibcxx_function_requires(_LessThanOpConcept<_ValueType1, _ValueType2>) - __glibcxx_function_requires(_LessThanOpConcept<_ValueType2, _ValueType1>) + typename iterator_traits<_InputIterator1>::value_type>) + __glibcxx_function_requires(_LessThanOpConcept< + typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_function_requires(_LessThanOpConcept< + typename iterator_traits<_InputIterator2>::value_type, + typename iterator_traits<_InputIterator1>::value_type>) __glibcxx_requires_sorted_set(__first1, __last1, __first2); __glibcxx_requires_sorted_set(__first2, __last2, __first1); - while (__first1 != __last1 && __first2 != __last2) - if (*__first1 < *__first2) - ++__first1; - else if (*__first2 < *__first1) - ++__first2; - else - { - *__result = *__first1; - ++__first1; - ++__first2; - ++__result; - } - return __result; + return _GLIBCXX_STD_A::__set_intersection(__first1, __last1, + __first2, __last2, __result, + __gnu_cxx::__ops::__iter_less_iter()); } /** @@ -6043,41 +5124,53 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO */ template<typename _InputIterator1, typename _InputIterator2, typename _OutputIterator, typename _Compare> - _OutputIterator + inline _OutputIterator set_intersection(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) { - typedef typename iterator_traits<_InputIterator1>::value_type - _ValueType1; - typedef typename iterator_traits<_InputIterator2>::value_type - _ValueType2; - // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, - _ValueType1>) + typename iterator_traits<_InputIterator1>::value_type>) __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, - _ValueType1, _ValueType2>) + typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>) __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, - _ValueType2, _ValueType1>) + typename iterator_traits<_InputIterator2>::value_type, + typename iterator_traits<_InputIterator1>::value_type>) __glibcxx_requires_sorted_set_pred(__first1, __last1, __first2, __comp); __glibcxx_requires_sorted_set_pred(__first2, __last2, __first1, __comp); + return _GLIBCXX_STD_A::__set_intersection(__first1, __last1, + __first2, __last2, __result, + __gnu_cxx::__ops::__iter_comp_iter(__comp)); + } + + template<typename _InputIterator1, typename _InputIterator2, + typename _OutputIterator, + typename _Compare> + _OutputIterator + __set_difference(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, + _OutputIterator __result, _Compare __comp) + { while (__first1 != __last1 && __first2 != __last2) - if (__comp(*__first1, *__first2)) - ++__first1; - else if (__comp(*__first2, *__first1)) + if (__comp(__first1, __first2)) + { + *__result = *__first1; + ++__first1; + ++__result; + } + else if (__comp(__first2, __first1)) ++__first2; else { - *__result = *__first1; ++__first1; ++__first2; - ++__result; } - return __result; + return std::copy(__first1, __last1, __result); } /** @@ -6101,41 +5194,28 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO */ template<typename _InputIterator1, typename _InputIterator2, typename _OutputIterator> - _OutputIterator + inline _OutputIterator set_difference(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result) { - typedef typename iterator_traits<_InputIterator1>::value_type - _ValueType1; - typedef typename iterator_traits<_InputIterator2>::value_type - _ValueType2; - // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, - _ValueType1>) - __glibcxx_function_requires(_LessThanOpConcept<_ValueType1, _ValueType2>) - __glibcxx_function_requires(_LessThanOpConcept<_ValueType2, _ValueType1>) + typename iterator_traits<_InputIterator1>::value_type>) + __glibcxx_function_requires(_LessThanOpConcept< + typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_function_requires(_LessThanOpConcept< + typename iterator_traits<_InputIterator2>::value_type, + typename iterator_traits<_InputIterator1>::value_type>) __glibcxx_requires_sorted_set(__first1, __last1, __first2); __glibcxx_requires_sorted_set(__first2, __last2, __first1); - while (__first1 != __last1 && __first2 != __last2) - if (*__first1 < *__first2) - { - *__result = *__first1; - ++__first1; - ++__result; - } - else if (*__first2 < *__first1) - ++__first2; - else - { - ++__first1; - ++__first2; - } - return std::copy(__first1, __last1, __result); + return _GLIBCXX_STD_A::__set_difference(__first1, __last1, + __first2, __last2, __result, + __gnu_cxx::__ops::__iter_less_iter()); } /** @@ -6162,43 +5242,61 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO */ template<typename _InputIterator1, typename _InputIterator2, typename _OutputIterator, typename _Compare> - _OutputIterator + inline _OutputIterator set_difference(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) { - typedef typename iterator_traits<_InputIterator1>::value_type - _ValueType1; - typedef typename iterator_traits<_InputIterator2>::value_type - _ValueType2; - // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, - _ValueType1>) + typename iterator_traits<_InputIterator1>::value_type>) __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, - _ValueType1, _ValueType2>) + typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>) __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, - _ValueType2, _ValueType1>) + typename iterator_traits<_InputIterator2>::value_type, + typename iterator_traits<_InputIterator1>::value_type>) __glibcxx_requires_sorted_set_pred(__first1, __last1, __first2, __comp); __glibcxx_requires_sorted_set_pred(__first2, __last2, __first1, __comp); + return _GLIBCXX_STD_A::__set_difference(__first1, __last1, + __first2, __last2, __result, + __gnu_cxx::__ops::__iter_comp_iter(__comp)); + } + + template<typename _InputIterator1, typename _InputIterator2, + typename _OutputIterator, + typename _Compare> + _OutputIterator + __set_symmetric_difference(_InputIterator1 __first1, + _InputIterator1 __last1, + _InputIterator2 __first2, + _InputIterator2 __last2, + _OutputIterator __result, + _Compare __comp) + { while (__first1 != __last1 && __first2 != __last2) - if (__comp(*__first1, *__first2)) + if (__comp(__first1, __first2)) { *__result = *__first1; ++__first1; ++__result; } - else if (__comp(*__first2, *__first1)) - ++__first2; + else if (__comp(__first2, __first1)) + { + *__result = *__first2; + ++__first2; + ++__result; + } else { ++__first1; ++__first2; } - return std::copy(__first1, __last1, __result); + return std::copy(__first2, __last2, + std::copy(__first1, __last1, __result)); } /** @@ -6220,48 +5318,30 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO */ template<typename _InputIterator1, typename _InputIterator2, typename _OutputIterator> - _OutputIterator + inline _OutputIterator set_symmetric_difference(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result) { - typedef typename iterator_traits<_InputIterator1>::value_type - _ValueType1; - typedef typename iterator_traits<_InputIterator2>::value_type - _ValueType2; - // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, - _ValueType1>) + typename iterator_traits<_InputIterator1>::value_type>) __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, - _ValueType2>) - __glibcxx_function_requires(_LessThanOpConcept<_ValueType1, _ValueType2>) - __glibcxx_function_requires(_LessThanOpConcept<_ValueType2, _ValueType1>) + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_function_requires(_LessThanOpConcept< + typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_function_requires(_LessThanOpConcept< + typename iterator_traits<_InputIterator2>::value_type, + typename iterator_traits<_InputIterator1>::value_type>) __glibcxx_requires_sorted_set(__first1, __last1, __first2); __glibcxx_requires_sorted_set(__first2, __last2, __first1); - while (__first1 != __last1 && __first2 != __last2) - if (*__first1 < *__first2) - { - *__result = *__first1; - ++__first1; - ++__result; - } - else if (*__first2 < *__first1) - { - *__result = *__first2; - ++__first2; - ++__result; - } - else - { - ++__first1; - ++__first2; - } - return std::copy(__first2, __last2, std::copy(__first1, - __last1, __result)); + return _GLIBCXX_STD_A::__set_symmetric_difference(__first1, __last1, + __first2, __last2, __result, + __gnu_cxx::__ops::__iter_less_iter()); } /** @@ -6286,53 +5366,46 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO */ template<typename _InputIterator1, typename _InputIterator2, typename _OutputIterator, typename _Compare> - _OutputIterator + inline _OutputIterator set_symmetric_difference(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) { - typedef typename iterator_traits<_InputIterator1>::value_type - _ValueType1; - typedef typename iterator_traits<_InputIterator2>::value_type - _ValueType2; - // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, - _ValueType1>) + typename iterator_traits<_InputIterator1>::value_type>) __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, - _ValueType2>) + typename iterator_traits<_InputIterator2>::value_type>) __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, - _ValueType1, _ValueType2>) + typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>) __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, - _ValueType2, _ValueType1>) + typename iterator_traits<_InputIterator2>::value_type, + typename iterator_traits<_InputIterator1>::value_type>) __glibcxx_requires_sorted_set_pred(__first1, __last1, __first2, __comp); __glibcxx_requires_sorted_set_pred(__first2, __last2, __first1, __comp); - while (__first1 != __last1 && __first2 != __last2) - if (__comp(*__first1, *__first2)) - { - *__result = *__first1; - ++__first1; - ++__result; - } - else if (__comp(*__first2, *__first1)) - { - *__result = *__first2; - ++__first2; - ++__result; - } - else - { - ++__first1; - ++__first2; - } - return std::copy(__first2, __last2, - std::copy(__first1, __last1, __result)); + return _GLIBCXX_STD_A::__set_symmetric_difference(__first1, __last1, + __first2, __last2, __result, + __gnu_cxx::__ops::__iter_comp_iter(__comp)); } + template<typename _ForwardIterator, typename _Compare> + _ForwardIterator + __min_element(_ForwardIterator __first, _ForwardIterator __last, + _Compare __comp) + { + if (__first == __last) + return __first; + _ForwardIterator __result = __first; + while (++__first != __last) + if (__comp(__first, __result)) + __result = __first; + return __result; + } /** * @brief Return the minimum element in a range. @@ -6343,7 +5416,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO */ template<typename _ForwardIterator> _ForwardIterator - min_element(_ForwardIterator __first, _ForwardIterator __last) + inline min_element(_ForwardIterator __first, _ForwardIterator __last) { // concept requirements __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) @@ -6351,13 +5424,8 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO typename iterator_traits<_ForwardIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); - if (__first == __last) - return __first; - _ForwardIterator __result = __first; - while (++__first != __last) - if (*__first < *__result) - __result = __first; - return __result; + return _GLIBCXX_STD_A::__min_element(__first, __last, + __gnu_cxx::__ops::__iter_less_iter()); } /** @@ -6370,7 +5438,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO * according to __comp. */ template<typename _ForwardIterator, typename _Compare> - _ForwardIterator + inline _ForwardIterator min_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { @@ -6381,11 +5449,19 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO typename iterator_traits<_ForwardIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); - if (__first == __last) - return __first; + return _GLIBCXX_STD_A::__min_element(__first, __last, + __gnu_cxx::__ops::__iter_comp_iter(__comp)); + } + + template<typename _ForwardIterator, typename _Compare> + _ForwardIterator + __max_element(_ForwardIterator __first, _ForwardIterator __last, + _Compare __comp) + { + if (__first == __last) return __first; _ForwardIterator __result = __first; while (++__first != __last) - if (__comp(*__first, *__result)) + if (__comp(__result, __first)) __result = __first; return __result; } @@ -6398,7 +5474,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO * @return Iterator referencing the first instance of the largest value. */ template<typename _ForwardIterator> - _ForwardIterator + inline _ForwardIterator max_element(_ForwardIterator __first, _ForwardIterator __last) { // concept requirements @@ -6407,13 +5483,8 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO typename iterator_traits<_ForwardIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); - if (__first == __last) - return __first; - _ForwardIterator __result = __first; - while (++__first != __last) - if (*__result < *__first) - __result = __first; - return __result; + return _GLIBCXX_STD_A::__max_element(__first, __last, + __gnu_cxx::__ops::__iter_less_iter()); } /** @@ -6426,7 +5497,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO * according to __comp. */ template<typename _ForwardIterator, typename _Compare> - _ForwardIterator + inline _ForwardIterator max_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { @@ -6437,12 +5508,8 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO typename iterator_traits<_ForwardIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); - if (__first == __last) return __first; - _ForwardIterator __result = __first; - while (++__first != __last) - if (__comp(*__result, *__first)) - __result = __first; - return __result; + return _GLIBCXX_STD_A::__max_element(__first, __last, + __gnu_cxx::__ops::__iter_comp_iter(__comp)); } _GLIBCXX_END_NAMESPACE_ALGO diff --git a/libstdc++-v3/include/bits/stl_algobase.h b/libstdc++-v3/include/bits/stl_algobase.h index 1c889356460..a7432da150c 100644 --- a/libstdc++-v3/include/bits/stl_algobase.h +++ b/libstdc++-v3/include/bits/stl_algobase.h @@ -68,6 +68,7 @@ #include <bits/concept_check.h> #include <debug/debug.h> #include <bits/move.h> // For std::swap and _GLIBCXX_MOVE +#include <bits/predefined_ops.h> namespace std _GLIBCXX_VISIBILITY(default) { @@ -862,6 +863,28 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return true; } }; + template<typename _II1, typename _II2, typename _Compare> + bool + __lexicographical_compare_impl(_II1 __first1, _II1 __last1, + _II2 __first2, _II2 __last2, + _Compare __comp) + { + typedef typename iterator_traits<_II1>::iterator_category _Category1; + typedef typename iterator_traits<_II2>::iterator_category _Category2; + typedef std::__lc_rai<_Category1, _Category2> __rai_type; + + __last1 = __rai_type::__newlast1(__first1, __last1, __first2, __last2); + for (; __first1 != __last1 && __rai_type::__cnd2(__first2, __last2); + ++__first1, ++__first2) + { + if (__comp(__first1, __first2)) + return true; + if (__comp(__first2, __first1)) + return false; + } + return __first1 == __last1 && __first2 != __last2; + } + template<bool _BoolType> struct __lexicographical_compare { @@ -875,21 +898,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __lexicographical_compare<_BoolType>:: __lc(_II1 __first1, _II1 __last1, _II2 __first2, _II2 __last2) { - typedef typename iterator_traits<_II1>::iterator_category _Category1; - typedef typename iterator_traits<_II2>::iterator_category _Category2; - typedef std::__lc_rai<_Category1, _Category2> __rai_type; - - __last1 = __rai_type::__newlast1(__first1, __last1, - __first2, __last2); - for (; __first1 != __last1 && __rai_type::__cnd2(__first2, __last2); - ++__first1, ++__first2) - { - if (*__first1 < *__first2) - return true; - if (*__first2 < *__first1) - return false; - } - return __first1 == __last1 && __first2 != __last2; + return std::__lexicographical_compare_impl(__first1, __last1, + __first2, __last2, + __gnu_cxx::__ops::__iter_less_iter()); } template<> @@ -926,34 +937,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __first2, __last2); } - /** - * @brief Finds the first position in which @a val could be inserted - * without changing the ordering. - * @param __first An iterator. - * @param __last Another iterator. - * @param __val The search term. - * @return An iterator pointing to the first element <em>not less - * than</em> @a val, or end() if every element is less than - * @a val. - * @ingroup binary_search_algorithms - */ - template<typename _ForwardIterator, typename _Tp> + template<typename _ForwardIterator, typename _Tp, typename _Compare> _ForwardIterator - lower_bound(_ForwardIterator __first, _ForwardIterator __last, - const _Tp& __val) + __lower_bound(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __val, _Compare __comp) { -#ifdef _GLIBCXX_CONCEPT_CHECKS - typedef typename iterator_traits<_ForwardIterator>::value_type - _ValueType; -#endif typedef typename iterator_traits<_ForwardIterator>::difference_type _DistanceType; - // concept requirements - __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) - __glibcxx_function_requires(_LessThanOpConcept<_ValueType, _Tp>) - __glibcxx_requires_partitioned_lower(__first, __last, __val); - _DistanceType __len = std::distance(__first, __last); while (__len > 0) @@ -961,7 +952,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _DistanceType __half = __len >> 1; _ForwardIterator __middle = __first; std::advance(__middle, __half); - if (*__middle < __val) + if (__comp(__middle, __val)) { __first = __middle; ++__first; @@ -973,6 +964,32 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return __first; } + /** + * @brief Finds the first position in which @a val could be inserted + * without changing the ordering. + * @param __first An iterator. + * @param __last Another iterator. + * @param __val The search term. + * @return An iterator pointing to the first element <em>not less + * than</em> @a val, or end() if every element is less than + * @a val. + * @ingroup binary_search_algorithms + */ + template<typename _ForwardIterator, typename _Tp> + inline _ForwardIterator + lower_bound(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __val) + { + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_LessThanOpConcept< + typename iterator_traits<_ForwardIterator>::value_type, _Tp>) + __glibcxx_requires_partitioned_lower(__first, __last, __val); + + return std::__lower_bound(__first, __last, __val, + __gnu_cxx::__ops::__iter_less_val()); + } + /// This is a helper function for the sort routines and for random.tcc. // Precondition: __n > 0. inline _GLIBCXX_CONSTEXPR int @@ -1100,7 +1117,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO auto __d2 = std::distance(__first2, __last2); if (__d1 != __d2) return false; - return std::equal(__first1, __last1, __first2); + return _GLIBCXX_STD_A::equal(__first1, __last1, __first2); } for (; __first1 != __last1 && __first2 != __last2; ++__first1, ++__first2) @@ -1146,7 +1163,8 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO auto __d2 = std::distance(__first2, __last2); if (__d1 != __d2) return false; - return std::equal(__first1, __last1, __first2, __binary_pred); + return _GLIBCXX_STD_A::equal(__first1, __last1, __first2, + __binary_pred); } for (; __first1 != __last1 && __first2 != __last2; ++__first1, ++__first2) @@ -1208,30 +1226,33 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO * comp parameter instead of @c <. */ template<typename _II1, typename _II2, typename _Compare> - bool + inline bool lexicographical_compare(_II1 __first1, _II1 __last1, _II2 __first2, _II2 __last2, _Compare __comp) { - typedef typename iterator_traits<_II1>::iterator_category _Category1; - typedef typename iterator_traits<_II2>::iterator_category _Category2; - typedef std::__lc_rai<_Category1, _Category2> __rai_type; - // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_II1>) __glibcxx_function_requires(_InputIteratorConcept<_II2>) __glibcxx_requires_valid_range(__first1, __last1); __glibcxx_requires_valid_range(__first2, __last2); - __last1 = __rai_type::__newlast1(__first1, __last1, __first2, __last2); - for (; __first1 != __last1 && __rai_type::__cnd2(__first2, __last2); - ++__first1, ++__first2) - { - if (__comp(*__first1, *__first2)) - return true; - if (__comp(*__first2, *__first1)) - return false; - } - return __first1 == __last1 && __first2 != __last2; + return std::__lexicographical_compare_impl + (__first1, __last1, __first2, __last2, + __gnu_cxx::__ops::__iter_comp_iter(__comp)); + } + + template<typename _InputIterator1, typename _InputIterator2, + typename _BinaryPredicate> + pair<_InputIterator1, _InputIterator2> + __mismatch(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _BinaryPredicate __binary_pred) + { + while (__first1 != __last1 && __binary_pred(__first1, __first2)) + { + ++__first1; + ++__first2; + } + return pair<_InputIterator1, _InputIterator2>(__first1, __first2); } /** @@ -1248,7 +1269,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO * to by the iterators are not equal. */ template<typename _InputIterator1, typename _InputIterator2> - pair<_InputIterator1, _InputIterator2> + inline pair<_InputIterator1, _InputIterator2> mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2) { @@ -1260,12 +1281,8 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO typename iterator_traits<_InputIterator2>::value_type>) __glibcxx_requires_valid_range(__first1, __last1); - while (__first1 != __last1 && *__first1 == *__first2) - { - ++__first1; - ++__first2; - } - return pair<_InputIterator1, _InputIterator2>(__first1, __first2); + return _GLIBCXX_STD_A::__mismatch(__first1, __last1, __first2, + __gnu_cxx::__ops::__iter_equal_to_iter()); } /** @@ -1286,7 +1303,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO */ template<typename _InputIterator1, typename _InputIterator2, typename _BinaryPredicate> - pair<_InputIterator1, _InputIterator2> + inline pair<_InputIterator1, _InputIterator2> mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _BinaryPredicate __binary_pred) { @@ -1295,7 +1312,21 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) __glibcxx_requires_valid_range(__first1, __last1); - while (__first1 != __last1 && bool(__binary_pred(*__first1, *__first2))) + return _GLIBCXX_STD_A::__mismatch(__first1, __last1, __first2, + __gnu_cxx::__ops::__iter_comp_iter(__binary_pred)); + } + +#if __cplusplus > 201103L + + template<typename _InputIterator1, typename _InputIterator2, + typename _BinaryPredicate> + pair<_InputIterator1, _InputIterator2> + __mismatch(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, + _BinaryPredicate __binary_pred) + { + while (__first1 != __last1 && __first2 != __last2 + && __binary_pred(__first1, __first2)) { ++__first1; ++__first2; @@ -1303,7 +1334,6 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO return pair<_InputIterator1, _InputIterator2>(__first1, __first2); } -#if __cplusplus > 201103L /** * @brief Finds the places in ranges which don't match. * @ingroup non_mutating_algorithms @@ -1319,7 +1349,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO * to by the iterators are not equal. */ template<typename _InputIterator1, typename _InputIterator2> - pair<_InputIterator1, _InputIterator2> + inline pair<_InputIterator1, _InputIterator2> mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) { @@ -1332,13 +1362,8 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO __glibcxx_requires_valid_range(__first1, __last1); __glibcxx_requires_valid_range(__first2, __last2); - while (__first1 != __last1 && __first2 != __last2 - && *__first1 == *__first2) - { - ++__first1; - ++__first2; - } - return pair<_InputIterator1, _InputIterator2>(__first1, __first2); + return _GLIBCXX_STD_A::__mismatch(__first1, __last1, __first2, __last2, + __gnu_cxx::__ops::__iter_equal_to_iter()); } /** @@ -1360,7 +1385,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO */ template<typename _InputIterator1, typename _InputIterator2, typename _BinaryPredicate> - pair<_InputIterator1, _InputIterator2> + inline pair<_InputIterator1, _InputIterator2> mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _BinaryPredicate __binary_pred) @@ -1371,13 +1396,8 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO __glibcxx_requires_valid_range(__first1, __last1); __glibcxx_requires_valid_range(__first2, __last2); - while (__first1 != __last1 && __first2 != __last2 - && bool(__binary_pred(*__first1, *__first2))) - { - ++__first1; - ++__first2; - } - return pair<_InputIterator1, _InputIterator2>(__first1, __first2); + return _GLIBCXX_STD_A::__mismatch(__first1, __last1, __first2, __last2, + __gnu_cxx::__ops::__iter_comp_iter(__binary_pred)); } #endif diff --git a/libstdc++-v3/include/bits/stl_bvector.h b/libstdc++-v3/include/bits/stl_bvector.h index 468fad0dbd0..8e4b0230614 100644 --- a/libstdc++-v3/include/bits/stl_bvector.h +++ b/libstdc++-v3/include/bits/stl_bvector.h @@ -785,7 +785,10 @@ template<typename _Alloc> _M_range_check(size_type __n) const { if (__n >= this->size()) - __throw_out_of_range(__N("vector<bool>::_M_range_check")); + __throw_out_of_range_fmt(__N("vector<bool>::_M_range_check: __n " + "(which is %zu) >= this->size() " + "(which is %zu)"), + __n, this->size()); } public: diff --git a/libstdc++-v3/include/bits/stl_deque.h b/libstdc++-v3/include/bits/stl_deque.h index 98556f59848..ca9e4179b06 100644 --- a/libstdc++-v3/include/bits/stl_deque.h +++ b/libstdc++-v3/include/bits/stl_deque.h @@ -1264,7 +1264,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER _M_range_check(size_type __n) const { if (__n >= this->size()) - __throw_out_of_range(__N("deque::_M_range_check")); + __throw_out_of_range_fmt(__N("deque::_M_range_check: __n " + "(which is %zu)>= this->size() " + "(which is %zu)"), + __n, this->size()); } public: diff --git a/libstdc++-v3/include/bits/stl_heap.h b/libstdc++-v3/include/bits/stl_heap.h index 807a8cf0525..a0c51ff7a1f 100644 --- a/libstdc++-v3/include/bits/stl_heap.h +++ b/libstdc++-v3/include/bits/stl_heap.h @@ -57,6 +57,7 @@ #include <debug/debug.h> #include <bits/move.h> +#include <bits/predefined_ops.h> namespace std _GLIBCXX_VISIBILITY(default) { @@ -67,21 +68,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * @ingroup sorting_algorithms */ - template<typename _RandomAccessIterator, typename _Distance> - _Distance - __is_heap_until(_RandomAccessIterator __first, _Distance __n) - { - _Distance __parent = 0; - for (_Distance __child = 1; __child < __n; ++__child) - { - if (__first[__parent] < __first[__child]) - return __child; - if ((__child & 1) == 0) - ++__parent; - } - return __n; - } - template<typename _RandomAccessIterator, typename _Distance, typename _Compare> _Distance @@ -91,7 +77,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _Distance __parent = 0; for (_Distance __child = 1; __child < __n; ++__child) { - if (__comp(__first[__parent], __first[__child])) + if (__comp(__first + __parent, __first + __child)) return __child; if ((__child & 1) == 0) ++__parent; @@ -104,13 +90,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _RandomAccessIterator, typename _Distance> inline bool __is_heap(_RandomAccessIterator __first, _Distance __n) - { return std::__is_heap_until(__first, __n) == __n; } + { + return std::__is_heap_until(__first, __n, + __gnu_cxx::__ops::__iter_less_iter()) == __n; + } template<typename _RandomAccessIterator, typename _Compare, typename _Distance> inline bool __is_heap(_RandomAccessIterator __first, _Compare __comp, _Distance __n) - { return std::__is_heap_until(__first, __n, __comp) == __n; } + { + return std::__is_heap_until(__first, __n, + __gnu_cxx::__ops::__iter_comp_iter(__comp)) == __n; + } template<typename _RandomAccessIterator> inline bool @@ -126,13 +118,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // Heap-manipulation functions: push_heap, pop_heap, make_heap, sort_heap, // + is_heap and is_heap_until in C++0x. - template<typename _RandomAccessIterator, typename _Distance, typename _Tp> + template<typename _RandomAccessIterator, typename _Distance, typename _Tp, + typename _Compare> void __push_heap(_RandomAccessIterator __first, - _Distance __holeIndex, _Distance __topIndex, _Tp __value) + _Distance __holeIndex, _Distance __topIndex, _Tp __value, + _Compare __comp) { _Distance __parent = (__holeIndex - 1) / 2; - while (__holeIndex > __topIndex && *(__first + __parent) < __value) + while (__holeIndex > __topIndex && __comp(__first + __parent, __value)) { *(__first + __holeIndex) = _GLIBCXX_MOVE(*(__first + __parent)); __holeIndex = __parent; @@ -169,24 +163,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _ValueType __value = _GLIBCXX_MOVE(*(__last - 1)); std::__push_heap(__first, _DistanceType((__last - __first) - 1), - _DistanceType(0), _GLIBCXX_MOVE(__value)); - } - - template<typename _RandomAccessIterator, typename _Distance, typename _Tp, - typename _Compare> - void - __push_heap(_RandomAccessIterator __first, _Distance __holeIndex, - _Distance __topIndex, _Tp __value, _Compare __comp) - { - _Distance __parent = (__holeIndex - 1) / 2; - while (__holeIndex > __topIndex - && __comp(*(__first + __parent), __value)) - { - *(__first + __holeIndex) = _GLIBCXX_MOVE(*(__first + __parent)); - __holeIndex = __parent; - __parent = (__holeIndex - 1) / 2; - } - *(__first + __holeIndex) = _GLIBCXX_MOVE(__value); + _DistanceType(0), _GLIBCXX_MOVE(__value), + __gnu_cxx::__ops::__iter_less_val()); } /** @@ -219,20 +197,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _ValueType __value = _GLIBCXX_MOVE(*(__last - 1)); std::__push_heap(__first, _DistanceType((__last - __first) - 1), - _DistanceType(0), _GLIBCXX_MOVE(__value), __comp); + _DistanceType(0), _GLIBCXX_MOVE(__value), + __gnu_cxx::__ops::__iter_comp_val(__comp)); } - template<typename _RandomAccessIterator, typename _Distance, typename _Tp> + template<typename _RandomAccessIterator, typename _Distance, + typename _Tp, typename _Compare> void __adjust_heap(_RandomAccessIterator __first, _Distance __holeIndex, - _Distance __len, _Tp __value) + _Distance __len, _Tp __value, _Compare __comp) { const _Distance __topIndex = __holeIndex; _Distance __secondChild = __holeIndex; while (__secondChild < (__len - 1) / 2) { __secondChild = 2 * (__secondChild + 1); - if (*(__first + __secondChild) < *(__first + (__secondChild - 1))) + if (__comp(__first + __secondChild, + __first + (__secondChild - 1))) __secondChild--; *(__first + __holeIndex) = _GLIBCXX_MOVE(*(__first + __secondChild)); __holeIndex = __secondChild; @@ -244,14 +225,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION + (__secondChild - 1))); __holeIndex = __secondChild - 1; } - std::__push_heap(__first, __holeIndex, __topIndex, - _GLIBCXX_MOVE(__value)); + std::__push_heap(__first, __holeIndex, __topIndex, + _GLIBCXX_MOVE(__value), + __gnu_cxx::__ops::__iter_comp_val(__comp)); } - template<typename _RandomAccessIterator> + template<typename _RandomAccessIterator, typename _Compare> inline void __pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, - _RandomAccessIterator __result) + _RandomAccessIterator __result, _Compare __comp) { typedef typename iterator_traits<_RandomAccessIterator>::value_type _ValueType; @@ -262,7 +244,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION *__result = _GLIBCXX_MOVE(*__first); std::__adjust_heap(__first, _DistanceType(0), _DistanceType(__last - __first), - _GLIBCXX_MOVE(__value)); + _GLIBCXX_MOVE(__value), __comp); } /** @@ -294,55 +276,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION if (__last - __first > 1) { --__last; - std::__pop_heap(__first, __last, __last); + std::__pop_heap(__first, __last, __last, + __gnu_cxx::__ops::__iter_less_iter()); } } - template<typename _RandomAccessIterator, typename _Distance, - typename _Tp, typename _Compare> - void - __adjust_heap(_RandomAccessIterator __first, _Distance __holeIndex, - _Distance __len, _Tp __value, _Compare __comp) - { - const _Distance __topIndex = __holeIndex; - _Distance __secondChild = __holeIndex; - while (__secondChild < (__len - 1) / 2) - { - __secondChild = 2 * (__secondChild + 1); - if (__comp(*(__first + __secondChild), - *(__first + (__secondChild - 1)))) - __secondChild--; - *(__first + __holeIndex) = _GLIBCXX_MOVE(*(__first + __secondChild)); - __holeIndex = __secondChild; - } - if ((__len & 1) == 0 && __secondChild == (__len - 2) / 2) - { - __secondChild = 2 * (__secondChild + 1); - *(__first + __holeIndex) = _GLIBCXX_MOVE(*(__first - + (__secondChild - 1))); - __holeIndex = __secondChild - 1; - } - std::__push_heap(__first, __holeIndex, __topIndex, - _GLIBCXX_MOVE(__value), __comp); - } - - template<typename _RandomAccessIterator, typename _Compare> - inline void - __pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, - _RandomAccessIterator __result, _Compare __comp) - { - typedef typename iterator_traits<_RandomAccessIterator>::value_type - _ValueType; - typedef typename iterator_traits<_RandomAccessIterator>::difference_type - _DistanceType; - - _ValueType __value = _GLIBCXX_MOVE(*__result); - *__result = _GLIBCXX_MOVE(*__first); - std::__adjust_heap(__first, _DistanceType(0), - _DistanceType(__last - __first), - _GLIBCXX_MOVE(__value), __comp); - } - /** * @brief Pop an element off a heap using comparison functor. * @param __first Start of heap. @@ -369,33 +307,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION if (__last - __first > 1) { --__last; - std::__pop_heap(__first, __last, __last, __comp); + std::__pop_heap(__first, __last, __last, + __gnu_cxx::__ops::__iter_comp_iter(__comp)); } } - /** - * @brief Construct a heap over a range. - * @param __first Start of heap. - * @param __last End of heap. - * @ingroup heap_algorithms - * - * This operation makes the elements in [__first,__last) into a heap. - */ - template<typename _RandomAccessIterator> + template<typename _RandomAccessIterator, typename _Compare> void - make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) + __make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, + _Compare __comp) { typedef typename iterator_traits<_RandomAccessIterator>::value_type _ValueType; typedef typename iterator_traits<_RandomAccessIterator>::difference_type _DistanceType; - // concept requirements - __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< - _RandomAccessIterator>) - __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>) - __glibcxx_requires_valid_range(__first, __last); - if (__last - __first < 2) return; @@ -404,12 +330,36 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION while (true) { _ValueType __value = _GLIBCXX_MOVE(*(__first + __parent)); - std::__adjust_heap(__first, __parent, __len, _GLIBCXX_MOVE(__value)); + std::__adjust_heap(__first, __parent, __len, _GLIBCXX_MOVE(__value), + __comp); if (__parent == 0) return; __parent--; } } + + /** + * @brief Construct a heap over a range. + * @param __first Start of heap. + * @param __last End of heap. + * @ingroup heap_algorithms + * + * This operation makes the elements in [__first,__last) into a heap. + */ + template<typename _RandomAccessIterator> + inline void + make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) + { + // concept requirements + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_function_requires(_LessThanComparableConcept< + typename iterator_traits<_RandomAccessIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + std::__make_heap(__first, __last, + __gnu_cxx::__ops::__iter_less_iter()); + } /** * @brief Construct a heap over a range using comparison functor. @@ -422,33 +372,28 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * Comparisons are made using __comp. */ template<typename _RandomAccessIterator, typename _Compare> - void + inline void make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { - typedef typename iterator_traits<_RandomAccessIterator>::value_type - _ValueType; - typedef typename iterator_traits<_RandomAccessIterator>::difference_type - _DistanceType; - // concept requirements __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< _RandomAccessIterator>) __glibcxx_requires_valid_range(__first, __last); - if (__last - __first < 2) - return; + std::__make_heap(__first, __last, + __gnu_cxx::__ops::__iter_comp_iter(__comp)); + } - const _DistanceType __len = __last - __first; - _DistanceType __parent = (__len - 2) / 2; - while (true) + template<typename _RandomAccessIterator, typename _Compare> + void + __sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, + _Compare __comp) + { + while (__last - __first > 1) { - _ValueType __value = _GLIBCXX_MOVE(*(__first + __parent)); - std::__adjust_heap(__first, __parent, __len, _GLIBCXX_MOVE(__value), - __comp); - if (__parent == 0) - return; - __parent--; + --__last; + std::__pop_heap(__first, __last, __last, __comp); } } @@ -461,7 +406,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * This operation sorts the valid heap in the range [__first,__last). */ template<typename _RandomAccessIterator> - void + inline void sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) { // concept requirements @@ -472,11 +417,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __glibcxx_requires_valid_range(__first, __last); __glibcxx_requires_heap(__first, __last); - while (__last - __first > 1) - { - --__last; - std::__pop_heap(__first, __last, __last); - } + std::__sort_heap(__first, __last, + __gnu_cxx::__ops::__iter_less_iter()); } /** @@ -490,7 +432,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * Comparisons are made using __comp. */ template<typename _RandomAccessIterator, typename _Compare> - void + inline void sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { @@ -500,11 +442,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __glibcxx_requires_valid_range(__first, __last); __glibcxx_requires_heap_pred(__first, __last, __comp); - while (__last - __first > 1) - { - --__last; - std::__pop_heap(__first, __last, __last, __comp); - } + std::__sort_heap(__first, __last, + __gnu_cxx::__ops::__iter_comp_iter(__comp)); } #if __cplusplus >= 201103L @@ -529,8 +468,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typename iterator_traits<_RandomAccessIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); - return __first + std::__is_heap_until(__first, std::distance(__first, - __last)); + return __first + + std::__is_heap_until(__first, std::distance(__first, __last), + __gnu_cxx::__ops::__iter_less_iter()); } /** @@ -554,9 +494,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _RandomAccessIterator>) __glibcxx_requires_valid_range(__first, __last); - return __first + std::__is_heap_until(__first, std::distance(__first, - __last), - __comp); + return __first + + std::__is_heap_until(__first, std::distance(__first, __last), + __gnu_cxx::__ops::__iter_comp_iter(__comp)); } /** diff --git a/libstdc++-v3/include/bits/stl_vector.h b/libstdc++-v3/include/bits/stl_vector.h index 03850b5e28f..376f39af216 100644 --- a/libstdc++-v3/include/bits/stl_vector.h +++ b/libstdc++-v3/include/bits/stl_vector.h @@ -785,7 +785,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER _M_range_check(size_type __n) const { if (__n >= this->size()) - __throw_out_of_range(__N("vector::_M_range_check")); + __throw_out_of_range_fmt(__N("vector::_M_range_check: __n " + "(which is %zu) >= this->size() " + "(which is %zu)"), + __n, this->size()); } public: diff --git a/libstdc++-v3/include/c_global/cmath b/libstdc++-v3/include/c_global/cmath index b438585eb44..2641118e7b1 100644 --- a/libstdc++-v3/include/c_global/cmath +++ b/libstdc++-v3/include/c_global/cmath @@ -650,9 +650,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION isnormal(_Tp __x) { return __x != 0 ? true : false; } + // The front-end doesn't provide a type generic builtin (libstdc++/58625). constexpr bool signbit(float __x) - { return __builtin_signbit(__x); } + { return __builtin_signbitf(__x); } constexpr bool signbit(double __x) @@ -660,7 +661,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION constexpr bool signbit(long double __x) - { return __builtin_signbit(__x); } + { return __builtin_signbitl(__x); } template<typename _Tp> constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, diff --git a/libstdc++-v3/include/debug/array b/libstdc++-v3/include/debug/array index d3eea853856..6ee23846518 100644 --- a/libstdc++-v3/include/debug/array +++ b/libstdc++-v3/include/debug/array @@ -165,7 +165,10 @@ namespace __debug at(size_type __n) { if (__n >= _Nm) - std::__throw_out_of_range(__N("array::at")); + std::__throw_out_of_range_fmt(__N("array::at: __n " + "(which is %zu) >= _Nm " + "(which is %zu)"), + __n, _Nm); return _AT_Type::_S_ref(_M_elems, __n); } @@ -175,7 +178,9 @@ namespace __debug // Result of conditional expression must be an lvalue so use // boolean ? lvalue : (throw-expr, lvalue) return __n < _Nm ? _AT_Type::_S_ref(_M_elems, __n) - : (std::__throw_out_of_range(__N("array::at")), + : (std::__throw_out_of_range_fmt(__N("array::at: __n (which is %zu) " + ">= _Nm (which is %zu)"), + __n, _Nm), _AT_Type::_S_ref(_M_elems, 0)); } diff --git a/libstdc++-v3/include/debug/safe_iterator.h b/libstdc++-v3/include/debug/safe_iterator.h index a1f7651b1bd..d5adefd0ace 100644 --- a/libstdc++-v3/include/debug/safe_iterator.h +++ b/libstdc++-v3/include/debug/safe_iterator.h @@ -139,7 +139,7 @@ namespace __gnu_debug typedef typename _Traits::pointer pointer; /// @post the iterator is singular and unattached - _Safe_iterator() : _M_current() { } + _Safe_iterator() _GLIBCXX_NOEXCEPT : _M_current() { } /** * @brief Safe iterator construction from an unsafe iterator and @@ -149,6 +149,7 @@ namespace __gnu_debug * @post this is not singular */ _Safe_iterator(const _Iterator& __i, const _Sequence* __seq) + _GLIBCXX_NOEXCEPT : _Safe_iterator_base(__seq, _M_constant()), _M_current(__i) { _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(), @@ -159,7 +160,7 @@ namespace __gnu_debug /** * @brief Copy construction. */ - _Safe_iterator(const _Safe_iterator& __x) + _Safe_iterator(const _Safe_iterator& __x) _GLIBCXX_NOEXCEPT : _Safe_iterator_base(__x, _M_constant()), _M_current(__x._M_current) { // _GLIBCXX_RESOLVE_LIB_DEFECTS @@ -176,7 +177,7 @@ namespace __gnu_debug * @brief Move construction. * @post __x is singular and unattached */ - _Safe_iterator(_Safe_iterator&& __x) : _M_current() + _Safe_iterator(_Safe_iterator&& __x) noexcept : _M_current() { _GLIBCXX_DEBUG_VERIFY(!__x._M_singular() || __x._M_current == _Iterator(), @@ -198,7 +199,7 @@ namespace __gnu_debug const _Safe_iterator<_MutableIterator, typename __gnu_cxx::__enable_if<(std::__are_same<_MutableIterator, typename _Sequence::iterator::iterator_type>::__value), - _Sequence>::__type>& __x) + _Sequence>::__type>& __x) _GLIBCXX_NOEXCEPT : _Safe_iterator_base(__x, _M_constant()), _M_current(__x.base()) { // _GLIBCXX_RESOLVE_LIB_DEFECTS @@ -214,7 +215,7 @@ namespace __gnu_debug * @brief Copy assignment. */ _Safe_iterator& - operator=(const _Safe_iterator& __x) + operator=(const _Safe_iterator& __x) _GLIBCXX_NOEXCEPT { // _GLIBCXX_RESOLVE_LIB_DEFECTS // DR 408. Is vector<reverse_iterator<char*> > forbidden? @@ -234,7 +235,7 @@ namespace __gnu_debug * @post __x is singular and unattached */ _Safe_iterator& - operator=(_Safe_iterator&& __x) + operator=(_Safe_iterator&& __x) noexcept { _GLIBCXX_DEBUG_VERIFY(this != &__x, _M_message(__msg_self_move_assign) @@ -257,7 +258,7 @@ namespace __gnu_debug * @pre iterator is dereferenceable */ reference - operator*() const + operator*() const _GLIBCXX_NOEXCEPT { _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(), _M_message(__msg_bad_deref) @@ -271,7 +272,7 @@ namespace __gnu_debug * @todo Make this correct w.r.t. iterators that return proxies */ pointer - operator->() const + operator->() const _GLIBCXX_NOEXCEPT { _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(), _M_message(__msg_bad_deref) @@ -285,7 +286,7 @@ namespace __gnu_debug * @pre iterator is incrementable */ _Safe_iterator& - operator++() + operator++() _GLIBCXX_NOEXCEPT { _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(), _M_message(__msg_bad_inc) @@ -299,7 +300,7 @@ namespace __gnu_debug * @pre iterator is incrementable */ _Safe_iterator - operator++(int) + operator++(int) _GLIBCXX_NOEXCEPT { _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(), _M_message(__msg_bad_inc) @@ -315,7 +316,7 @@ namespace __gnu_debug * @pre iterator is decrementable */ _Safe_iterator& - operator--() + operator--() _GLIBCXX_NOEXCEPT { _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(), _M_message(__msg_bad_dec) @@ -329,7 +330,7 @@ namespace __gnu_debug * @pre iterator is decrementable */ _Safe_iterator - operator--(int) + operator--(int) _GLIBCXX_NOEXCEPT { _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(), _M_message(__msg_bad_dec) @@ -341,7 +342,7 @@ namespace __gnu_debug // ------ Random access iterator requirements ------ reference - operator[](const difference_type& __n) const + operator[](const difference_type& __n) const _GLIBCXX_NOEXCEPT { _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n) && this->_M_can_advance(__n+1), @@ -352,7 +353,7 @@ namespace __gnu_debug } _Safe_iterator& - operator+=(const difference_type& __n) + operator+=(const difference_type& __n) _GLIBCXX_NOEXCEPT { _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n), _M_message(__msg_advance_oob) @@ -362,7 +363,7 @@ namespace __gnu_debug } _Safe_iterator - operator+(const difference_type& __n) const + operator+(const difference_type& __n) const _GLIBCXX_NOEXCEPT { _Safe_iterator __tmp(*this); __tmp += __n; @@ -370,7 +371,7 @@ namespace __gnu_debug } _Safe_iterator& - operator-=(const difference_type& __n) + operator-=(const difference_type& __n) _GLIBCXX_NOEXCEPT { _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(-__n), _M_message(__msg_retreat_oob) @@ -380,7 +381,7 @@ namespace __gnu_debug } _Safe_iterator - operator-(const difference_type& __n) const + operator-(const difference_type& __n) const _GLIBCXX_NOEXCEPT { _Safe_iterator __tmp(*this); __tmp -= __n; @@ -392,13 +393,13 @@ namespace __gnu_debug * @brief Return the underlying iterator */ _Iterator - base() const { return _M_current; } + base() const _GLIBCXX_NOEXCEPT { return _M_current; } /** * @brief Conversion to underlying non-debug iterator to allow * better interaction with non-debug containers. */ - operator _Iterator() const { return _M_current; } + operator _Iterator() const _GLIBCXX_NOEXCEPT { return _M_current; } /** Attach iterator to the given sequence. */ void @@ -482,6 +483,7 @@ namespace __gnu_debug inline bool operator==(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, const _Safe_iterator<_IteratorR, _Sequence>& __rhs) + _GLIBCXX_NOEXCEPT { _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), _M_message(__msg_iter_compare_bad) @@ -498,6 +500,7 @@ namespace __gnu_debug inline bool operator==(const _Safe_iterator<_Iterator, _Sequence>& __lhs, const _Safe_iterator<_Iterator, _Sequence>& __rhs) + _GLIBCXX_NOEXCEPT { _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), _M_message(__msg_iter_compare_bad) @@ -514,6 +517,7 @@ namespace __gnu_debug inline bool operator!=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, const _Safe_iterator<_IteratorR, _Sequence>& __rhs) + _GLIBCXX_NOEXCEPT { _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), _M_message(__msg_iter_compare_bad) @@ -530,6 +534,7 @@ namespace __gnu_debug inline bool operator!=(const _Safe_iterator<_Iterator, _Sequence>& __lhs, const _Safe_iterator<_Iterator, _Sequence>& __rhs) + _GLIBCXX_NOEXCEPT { _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), _M_message(__msg_iter_compare_bad) @@ -546,6 +551,7 @@ namespace __gnu_debug inline bool operator<(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, const _Safe_iterator<_IteratorR, _Sequence>& __rhs) + _GLIBCXX_NOEXCEPT { _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), _M_message(__msg_iter_order_bad) @@ -562,6 +568,7 @@ namespace __gnu_debug inline bool operator<(const _Safe_iterator<_Iterator, _Sequence>& __lhs, const _Safe_iterator<_Iterator, _Sequence>& __rhs) + _GLIBCXX_NOEXCEPT { _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), _M_message(__msg_iter_order_bad) @@ -578,6 +585,7 @@ namespace __gnu_debug inline bool operator<=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, const _Safe_iterator<_IteratorR, _Sequence>& __rhs) + _GLIBCXX_NOEXCEPT { _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), _M_message(__msg_iter_order_bad) @@ -594,6 +602,7 @@ namespace __gnu_debug inline bool operator<=(const _Safe_iterator<_Iterator, _Sequence>& __lhs, const _Safe_iterator<_Iterator, _Sequence>& __rhs) + _GLIBCXX_NOEXCEPT { _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), _M_message(__msg_iter_order_bad) @@ -610,6 +619,7 @@ namespace __gnu_debug inline bool operator>(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, const _Safe_iterator<_IteratorR, _Sequence>& __rhs) + _GLIBCXX_NOEXCEPT { _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), _M_message(__msg_iter_order_bad) @@ -626,6 +636,7 @@ namespace __gnu_debug inline bool operator>(const _Safe_iterator<_Iterator, _Sequence>& __lhs, const _Safe_iterator<_Iterator, _Sequence>& __rhs) + _GLIBCXX_NOEXCEPT { _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), _M_message(__msg_iter_order_bad) @@ -642,6 +653,7 @@ namespace __gnu_debug inline bool operator>=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, const _Safe_iterator<_IteratorR, _Sequence>& __rhs) + _GLIBCXX_NOEXCEPT { _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), _M_message(__msg_iter_order_bad) @@ -658,6 +670,7 @@ namespace __gnu_debug inline bool operator>=(const _Safe_iterator<_Iterator, _Sequence>& __lhs, const _Safe_iterator<_Iterator, _Sequence>& __rhs) + _GLIBCXX_NOEXCEPT { _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), _M_message(__msg_iter_order_bad) @@ -678,6 +691,7 @@ namespace __gnu_debug inline typename _Safe_iterator<_IteratorL, _Sequence>::difference_type operator-(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, const _Safe_iterator<_IteratorR, _Sequence>& __rhs) + _GLIBCXX_NOEXCEPT { _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), _M_message(__msg_distance_bad) @@ -694,6 +708,7 @@ namespace __gnu_debug inline typename _Safe_iterator<_Iterator, _Sequence>::difference_type operator-(const _Safe_iterator<_Iterator, _Sequence>& __lhs, const _Safe_iterator<_Iterator, _Sequence>& __rhs) + _GLIBCXX_NOEXCEPT { _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), _M_message(__msg_distance_bad) @@ -709,7 +724,7 @@ namespace __gnu_debug template<typename _Iterator, typename _Sequence> inline _Safe_iterator<_Iterator, _Sequence> operator+(typename _Safe_iterator<_Iterator,_Sequence>::difference_type __n, - const _Safe_iterator<_Iterator, _Sequence>& __i) + const _Safe_iterator<_Iterator, _Sequence>& __i) _GLIBCXX_NOEXCEPT { return __i + __n; } } // namespace __gnu_debug diff --git a/libstdc++-v3/include/debug/string b/libstdc++-v3/include/debug/string index 925575e662a..6d2c5395ade 100644 --- a/libstdc++-v3/include/debug/string +++ b/libstdc++-v3/include/debug/string @@ -70,7 +70,7 @@ namespace __gnu_debug // 21.3.1 construct/copy/destroy: explicit basic_string(const _Allocator& __a = _Allocator()) - _GLIBCXX_NOEXCEPT + // _GLIBCXX_NOEXCEPT : _Base(__a) { } @@ -114,7 +114,7 @@ namespace __gnu_debug { } #if __cplusplus >= 201103L - basic_string(basic_string&& __str) noexcept + basic_string(basic_string&& __str) // noexcept : _Base(std::move(__str)) { } @@ -172,7 +172,7 @@ namespace __gnu_debug // 21.3.2 iterators: iterator - begin() _GLIBCXX_NOEXCEPT + begin() // _GLIBCXX_NOEXCEPT { return iterator(_Base::begin(), this); } const_iterator @@ -180,7 +180,7 @@ namespace __gnu_debug { return const_iterator(_Base::begin(), this); } iterator - end() _GLIBCXX_NOEXCEPT + end() // _GLIBCXX_NOEXCEPT { return iterator(_Base::end(), this); } const_iterator @@ -188,7 +188,7 @@ namespace __gnu_debug { return const_iterator(_Base::end(), this); } reverse_iterator - rbegin() _GLIBCXX_NOEXCEPT + rbegin() // _GLIBCXX_NOEXCEPT { return reverse_iterator(end()); } const_reverse_iterator @@ -196,7 +196,7 @@ namespace __gnu_debug { return const_reverse_iterator(end()); } reverse_iterator - rend() _GLIBCXX_NOEXCEPT + rend() // _GLIBCXX_NOEXCEPT { return reverse_iterator(begin()); } const_reverse_iterator @@ -258,7 +258,7 @@ namespace __gnu_debug using _Base::reserve; void - clear() _GLIBCXX_NOEXCEPT + clear() // _GLIBCXX_NOEXCEPT { _Base::clear(); this->_M_invalidate_all(); @@ -279,7 +279,7 @@ namespace __gnu_debug } reference - operator[](size_type __pos) _GLIBCXX_NOEXCEPT + operator[](size_type __pos) // _GLIBCXX_NOEXCEPT { #ifdef _GLIBCXX_DEBUG_PEDANTIC __glibcxx_check_subscript(__pos); @@ -583,7 +583,7 @@ namespace __gnu_debug #if __cplusplus >= 201103L void - pop_back() noexcept + pop_back() // noexcept { __glibcxx_check_nonempty(); _Base::pop_back(); diff --git a/libstdc++-v3/include/ext/vstring.h b/libstdc++-v3/include/ext/vstring.h index bd93c803c23..8eb8597c804 100644 --- a/libstdc++-v3/include/ext/vstring.h +++ b/libstdc++-v3/include/ext/vstring.h @@ -85,7 +85,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_check(size_type __pos, const char* __s) const { if (__pos > this->size()) - std::__throw_out_of_range(__N(__s)); + std::__throw_out_of_range_fmt(__N("%s: __pos (which is %zu) > " + "this->size() (which is %zu)"), + __s, __pos, this->size()); return __pos; } @@ -575,7 +577,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION at(size_type __n) const { if (__n >= this->size()) - std::__throw_out_of_range(__N("__versa_string::at")); + std::__throw_out_of_range_fmt(__N("__versa_string::at: __n " + "(which is %zu) >= this->size() " + "(which is %zu)"), + __n, this->size()); return this->_M_data()[__n]; } @@ -594,7 +599,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION at(size_type __n) { if (__n >= this->size()) - std::__throw_out_of_range(__N("__versa_string::at")); + std::__throw_out_of_range_fmt(__N("__versa_string::at: __n " + "(which is %zu) >= this->size() " + "(which is %zu)"), + __n, this->size()); this->_M_leak(); return this->_M_data()[__n]; } diff --git a/libstdc++-v3/include/parallel/algo.h b/libstdc++-v3/include/parallel/algo.h index 00c24e5638c..13a35a7e046 100644 --- a/libstdc++-v3/include/parallel/algo.h +++ b/libstdc++-v3/include/parallel/algo.h @@ -150,7 +150,9 @@ namespace __parallel if (_GLIBCXX_PARALLEL_CONDITION(true)) { - std::binder2nd<__gnu_parallel::_EqualTo<_ValueType, const _Tp&> > + __gnu_parallel::__binder2nd<__gnu_parallel::_EqualTo<_ValueType, + const _Tp&>, + _ValueType, const _Tp&, bool> __comp(__gnu_parallel::_EqualTo<_ValueType, const _Tp&>(), __val); return __gnu_parallel::__find_template( __begin, __end, __begin, __comp, diff --git a/libstdc++-v3/include/parallel/algobase.h b/libstdc++-v3/include/parallel/algobase.h index e3737cc8f70..1acb63e921b 100644 --- a/libstdc++-v3/include/parallel/algobase.h +++ b/libstdc++-v3/include/parallel/algobase.h @@ -94,17 +94,13 @@ namespace __parallel inline pair<_IIter1, _IIter2> mismatch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2) { - typedef std::iterator_traits<_IIter1> _Iterator1Traits; - typedef std::iterator_traits<_IIter2> _Iterator2Traits; - typedef typename _Iterator1Traits::value_type _ValueType1; - typedef typename _Iterator2Traits::value_type _ValueType2; - typedef typename _Iterator1Traits::iterator_category _IteratorCategory1; - typedef typename _Iterator2Traits::iterator_category _IteratorCategory2; - - typedef __gnu_parallel::_EqualTo<_ValueType1, _ValueType2> _EqualTo; + typedef __gnu_parallel::_EqualTo< + typename std::iterator_traits<_IIter1>::value_type, + typename std::iterator_traits<_IIter2>::value_type> _EqualTo; return __mismatch_switch(__begin1, __end1, __begin2, _EqualTo(), - _IteratorCategory1(), _IteratorCategory2()); + std::__iterator_category(__begin1), + std::__iterator_category(__begin2)); } // Public interface @@ -113,14 +109,94 @@ namespace __parallel mismatch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _Predicate __pred) { - typedef std::iterator_traits<_IIter1> _Iterator1Traits; - typedef std::iterator_traits<_IIter2> _Iterator2Traits; - typedef typename _Iterator1Traits::iterator_category _IteratorCategory1; - typedef typename _Iterator2Traits::iterator_category _IteratorCategory2; - return __mismatch_switch(__begin1, __end1, __begin2, __pred, - _IteratorCategory1(), _IteratorCategory2()); + std::__iterator_category(__begin1), + std::__iterator_category(__begin2)); + } + +#if __cplusplus > 201103L + // Sequential fallback. + template<typename _InputIterator1, typename _InputIterator2> + inline pair<_InputIterator1, _InputIterator2> + mismatch(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, + __gnu_parallel::sequential_tag) + { return _GLIBCXX_STD_A::mismatch(__first1, __last1, __first2, __last2); } + + // Sequential fallback. + template<typename _InputIterator1, typename _InputIterator2, + typename _BinaryPredicate> + inline pair<_InputIterator1, _InputIterator2> + mismatch(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, + _BinaryPredicate __binary_pred, + __gnu_parallel::sequential_tag) + { + return _GLIBCXX_STD_A::mismatch(__first1, __last1, __first2, __last2, + __binary_pred); + } + + // Sequential fallback for input iterator case + template<typename _IIter1, typename _IIter2, + typename _Predicate, typename _IteratorTag1, typename _IteratorTag2> + inline pair<_IIter1, _IIter2> + __mismatch_switch(_IIter1 __begin1, _IIter1 __end1, + _IIter2 __begin2, _IIter2 __end2, _Predicate __pred, + _IteratorTag1, _IteratorTag2) + { + return _GLIBCXX_STD_A::mismatch(__begin1, __end1, + __begin2, __end2, __pred); + } + + // Parallel mismatch for random access iterators + template<typename _RAIter1, typename _RAIter2, typename _Predicate> + pair<_RAIter1, _RAIter2> + __mismatch_switch(_RAIter1 __begin1, _RAIter1 __end1, + _RAIter2 __begin2, _RAIter2 __end2, _Predicate __pred, + random_access_iterator_tag, random_access_iterator_tag) + { + if (_GLIBCXX_PARALLEL_CONDITION(true)) + { + if ((__end2 - __begin2) < (__end1 - __begin1)) + __end1 = __begin1 + (__end2 - __begin2); + + _RAIter1 __res = + __gnu_parallel::__find_template(__begin1, __end1, __begin2, __pred, + __gnu_parallel:: + __mismatch_selector()).first; + return make_pair(__res , __begin2 + (__res - __begin1)); + } + else + return _GLIBCXX_STD_A::mismatch(__begin1, __end1, + __begin2, __end2, __pred); + } + + template<typename _IIter1, typename _IIter2> + inline pair<_IIter1, _IIter2> + mismatch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2) + { + typedef __gnu_parallel::_EqualTo< + typename std::iterator_traits<_IIter1>::value_type, + typename std::iterator_traits<_IIter2>::value_type> _EqualTo; + + return __mismatch_switch(__begin1, __end1, __begin2, __end2, _EqualTo(), + std::__iterator_category(__begin1), + std::__iterator_category(__begin2)); + } + + template<typename _InputIterator1, typename _InputIterator2, + typename _BinaryPredicate> + inline pair<_InputIterator1, _InputIterator2> + mismatch(_InputIterator1 __begin1, _InputIterator1 __end1, + _InputIterator2 __begin2, _InputIterator2 __end2, + _BinaryPredicate __binary_pred) + { + return __mismatch_switch(__begin1, __end1, __begin2, __end2, + __binary_pred, + std::__iterator_category(__begin1), + std::__iterator_category(__begin2)); } +#endif // Sequential fallback template<typename _IIter1, typename _IIter2> @@ -155,6 +231,84 @@ namespace __parallel == __end1; } +#if __cplusplus > 201103L + // Sequential fallback + template<typename _IIter1, typename _IIter2> + inline bool + equal(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, + __gnu_parallel::sequential_tag) + { + return _GLIBCXX_STD_A::equal(__begin1, __end1, __begin2, __end2); + } + + // Sequential fallback + template<typename _IIter1, typename _IIter2, typename _BinaryPredicate> + inline bool + equal(_IIter1 __begin1, _IIter1 __end1, + _IIter2 __begin2, _IIter2 __end2, _BinaryPredicate __binary_pred, + __gnu_parallel::sequential_tag) + { + return _GLIBCXX_STD_A::equal(__begin1, __end1, __begin2, __end2, + __binary_pred); + } + + // Sequential fallback for input iterator case + template<typename _IIter1, typename _IIter2, + typename _Predicate, typename _IteratorTag1, typename _IteratorTag2> + inline bool + __equal_switch(_IIter1 __begin1, _IIter1 __end1, + _IIter2 __begin2, _IIter2 __end2, _Predicate __pred, + _IteratorTag1, _IteratorTag2) + { + return _GLIBCXX_STD_A::equal(__begin1, __end1, + __begin2, __end2, __pred); + } + + // Parallel equal for random access iterators + template<typename _RAIter1, typename _RAIter2, typename _Predicate> + inline bool + __equal_switch(_RAIter1 __begin1, _RAIter1 __end1, + _RAIter2 __begin2, _RAIter2 __end2, _Predicate __pred, + random_access_iterator_tag, random_access_iterator_tag) + { + if (_GLIBCXX_PARALLEL_CONDITION(true)) + { + if (std::distance(__begin1, __end1) + != std::distance(__begin2, __end2)) + return false; + + return __gnu_parallel::mismatch(__begin1, __end1, __begin2, __end2, + __pred).first == __end1; + } + else + return _GLIBCXX_STD_A::equal(__begin1, __end1, + __begin2, __end2, __pred); + } + + template<typename _IIter1, typename _IIter2> + inline bool + equal(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2) + { + typedef __gnu_parallel::_EqualTo< + typename std::iterator_traits<_IIter1>::value_type, + typename std::iterator_traits<_IIter2>::value_type> _EqualTo; + + return __equal_switch(__begin1, __end1, __begin2, __end2, _EqualTo(), + std::__iterator_category(__begin1), + std::__iterator_category(__begin2)); + } + + template<typename _IIter1, typename _IIter2, typename _BinaryPredicate> + inline bool + equal(_IIter1 __begin1, _IIter1 __end1, + _IIter2 __begin2, _IIter2 __end2, _BinaryPredicate __binary_pred) + { + return __equal_switch(__begin1, __end1, __begin2, __end2, __binary_pred, + std::__iterator_category(__begin1), + std::__iterator_category(__begin2)); + } +#endif + // Sequential fallback template<typename _IIter1, typename _IIter2> inline bool diff --git a/libstdc++-v3/include/profile/array b/libstdc++-v3/include/profile/array index 33bdc952096..138ad311ed7 100644 --- a/libstdc++-v3/include/profile/array +++ b/libstdc++-v3/include/profile/array @@ -138,7 +138,10 @@ namespace __profile at(size_type __n) { if (__n >= _Nm) - std::__throw_out_of_range(__N("array::at")); + std::__throw_out_of_range_fmt(__N("array::at: __n " + "(which is %zu) >= _Nm " + "(which is %zu)"), + __n, _Nm); return _AT_Type::_S_ref(_M_elems, __n); } @@ -148,7 +151,9 @@ namespace __profile // Result of conditional expression must be an lvalue so use // boolean ? lvalue : (throw-expr, lvalue) return __n < _Nm ? _AT_Type::_S_ref(_M_elems, __n) - : (std::__throw_out_of_range(__N("array::at")), + : (std::__throw_out_of_range_fmt(__N("array::at: __n (which is %zu) " + ">= _Nm (which is %zu)"), + __n, _Nm), _AT_Type::_S_ref(_M_elems, 0)); } diff --git a/libstdc++-v3/include/profile/iterator_tracker.h b/libstdc++-v3/include/profile/iterator_tracker.h index 251eff7355f..c016f20db8b 100644 --- a/libstdc++-v3/include/profile/iterator_tracker.h +++ b/libstdc++-v3/include/profile/iterator_tracker.h @@ -56,13 +56,14 @@ namespace __profile typedef typename _Traits::reference reference; typedef typename _Traits::pointer pointer; - __iterator_tracker() + __iterator_tracker() _GLIBCXX_NOEXCEPT : _M_current(), _M_ds(0) { } - __iterator_tracker(const _Iterator& __i, const _Sequence* __seq) + __iterator_tracker(const _Iterator& __i, const _Sequence* __seq) + _GLIBCXX_NOEXCEPT : _M_current(__i), _M_ds(__seq) { } - __iterator_tracker(const __iterator_tracker& __x) + __iterator_tracker(const __iterator_tracker& __x) _GLIBCXX_NOEXCEPT : _M_current(__x._M_current), _M_ds(__x._M_ds) { } template<typename _MutableIterator> @@ -70,23 +71,23 @@ namespace __profile typename __gnu_cxx::__enable_if <(std::__are_same<_MutableIterator, typename _Sequence::iterator::_Base_iterator>::__value), - _Sequence>::__type>& __x) + _Sequence>::__type>& __x) _GLIBCXX_NOEXCEPT : _M_current(__x.base()), _M_ds(__x._M_get_sequence()) { } _Iterator - base() const { return _M_current; } + base() const _GLIBCXX_NOEXCEPT { return _M_current; } /** * @brief Conversion to underlying non-debug iterator to allow * better interaction with non-profile containers. */ - operator _Iterator() const { return _M_current; } + operator _Iterator() const _GLIBCXX_NOEXCEPT { return _M_current; } pointer - operator->() const { return &*_M_current; } + operator->() const _GLIBCXX_NOEXCEPT { return &*_M_current; } __iterator_tracker& - operator++() + operator++() _GLIBCXX_NOEXCEPT { _M_ds->_M_profile_iterate(); ++_M_current; @@ -94,7 +95,7 @@ namespace __profile } __iterator_tracker - operator++(int) + operator++(int) _GLIBCXX_NOEXCEPT { _M_ds->_M_profile_iterate(); __iterator_tracker __tmp(*this); @@ -103,7 +104,7 @@ namespace __profile } __iterator_tracker& - operator--() + operator--() _GLIBCXX_NOEXCEPT { _M_ds->_M_profile_iterate(1); --_M_current; @@ -111,7 +112,7 @@ namespace __profile } __iterator_tracker - operator--(int) + operator--(int) _GLIBCXX_NOEXCEPT { _M_ds->_M_profile_iterate(1); __iterator_tracker __tmp(*this); @@ -120,30 +121,30 @@ namespace __profile } __iterator_tracker& - operator=(const __iterator_tracker& __x) + operator=(const __iterator_tracker& __x) _GLIBCXX_NOEXCEPT { _M_current = __x._M_current; return *this; } reference - operator*() const + operator*() const _GLIBCXX_NOEXCEPT { return *_M_current; } // ------ Random access iterator requirements ------ reference - operator[](const difference_type& __n) const + operator[](const difference_type& __n) const _GLIBCXX_NOEXCEPT { return _M_current[__n]; } __iterator_tracker& - operator+=(const difference_type& __n) + operator+=(const difference_type& __n) _GLIBCXX_NOEXCEPT { _M_current += __n; return *this; } __iterator_tracker - operator+(const difference_type& __n) const + operator+(const difference_type& __n) const _GLIBCXX_NOEXCEPT { __iterator_tracker __tmp(*this); __tmp += __n; @@ -151,14 +152,14 @@ namespace __profile } __iterator_tracker& - operator-=(const difference_type& __n) + operator-=(const difference_type& __n) _GLIBCXX_NOEXCEPT { _M_current += -__n; return *this; } __iterator_tracker - operator-(const difference_type& __n) const + operator-(const difference_type& __n) const _GLIBCXX_NOEXCEPT { __iterator_tracker __tmp(*this); __tmp -= __n; @@ -178,72 +179,84 @@ namespace __profile inline bool operator==(const __iterator_tracker<_IteratorL, _Sequence>& __lhs, const __iterator_tracker<_IteratorR, _Sequence>& __rhs) + _GLIBCXX_NOEXCEPT { return __lhs.base() == __rhs.base(); } template<typename _Iterator, typename _Sequence> inline bool operator==(const __iterator_tracker<_Iterator, _Sequence>& __lhs, const __iterator_tracker<_Iterator, _Sequence>& __rhs) + _GLIBCXX_NOEXCEPT { return __lhs.base() == __rhs.base(); } template<typename _IteratorL, typename _IteratorR, typename _Sequence> inline bool operator!=(const __iterator_tracker<_IteratorL, _Sequence>& __lhs, const __iterator_tracker<_IteratorR, _Sequence>& __rhs) + _GLIBCXX_NOEXCEPT { return __lhs.base() != __rhs.base(); } template<typename _Iterator, typename _Sequence> inline bool operator!=(const __iterator_tracker<_Iterator, _Sequence>& __lhs, const __iterator_tracker<_Iterator, _Sequence>& __rhs) + _GLIBCXX_NOEXCEPT { return __lhs.base() != __rhs.base(); } template<typename _IteratorL, typename _IteratorR, typename _Sequence> inline bool operator<(const __iterator_tracker<_IteratorL, _Sequence>& __lhs, const __iterator_tracker<_IteratorR, _Sequence>& __rhs) + _GLIBCXX_NOEXCEPT { return __lhs.base() < __rhs.base(); } template<typename _Iterator, typename _Sequence> inline bool operator<(const __iterator_tracker<_Iterator, _Sequence>& __lhs, const __iterator_tracker<_Iterator, _Sequence>& __rhs) + _GLIBCXX_NOEXCEPT { return __lhs.base() < __rhs.base(); } template<typename _IteratorL, typename _IteratorR, typename _Sequence> inline bool operator<=(const __iterator_tracker<_IteratorL, _Sequence>& __lhs, const __iterator_tracker<_IteratorR, _Sequence>& __rhs) + _GLIBCXX_NOEXCEPT { return __lhs.base() <= __rhs.base(); } template<typename _Iterator, typename _Sequence> inline bool operator<=(const __iterator_tracker<_Iterator, _Sequence>& __lhs, const __iterator_tracker<_Iterator, _Sequence>& __rhs) + _GLIBCXX_NOEXCEPT { return __lhs.base() <= __rhs.base(); } template<typename _IteratorL, typename _IteratorR, typename _Sequence> inline bool operator>(const __iterator_tracker<_IteratorL, _Sequence>& __lhs, const __iterator_tracker<_IteratorR, _Sequence>& __rhs) + _GLIBCXX_NOEXCEPT { return __lhs.base() > __rhs.base(); } template<typename _Iterator, typename _Sequence> inline bool operator>(const __iterator_tracker<_Iterator, _Sequence>& __lhs, const __iterator_tracker<_Iterator, _Sequence>& __rhs) + _GLIBCXX_NOEXCEPT { return __lhs.base() > __rhs.base(); } template<typename _IteratorL, typename _IteratorR, typename _Sequence> inline bool operator>=(const __iterator_tracker<_IteratorL, _Sequence>& __lhs, const __iterator_tracker<_IteratorR, _Sequence>& __rhs) + _GLIBCXX_NOEXCEPT { return __lhs.base() >= __rhs.base(); } template<typename _Iterator, typename _Sequence> inline bool operator>=(const __iterator_tracker<_Iterator, _Sequence>& __lhs, const __iterator_tracker<_Iterator, _Sequence>& __rhs) + _GLIBCXX_NOEXCEPT { return __lhs.base() >= __rhs.base(); } // _GLIBCXX_RESOLVE_LIB_DEFECTS @@ -254,12 +267,14 @@ namespace __profile inline typename __iterator_tracker<_IteratorL, _Sequence>::difference_type operator-(const __iterator_tracker<_IteratorL, _Sequence>& __lhs, const __iterator_tracker<_IteratorR, _Sequence>& __rhs) + _GLIBCXX_NOEXCEPT { return __lhs.base() - __rhs.base(); } template<typename _Iterator, typename _Sequence> inline typename __iterator_tracker<_Iterator, _Sequence>::difference_type operator-(const __iterator_tracker<_Iterator, _Sequence>& __lhs, const __iterator_tracker<_Iterator, _Sequence>& __rhs) + _GLIBCXX_NOEXCEPT { return __lhs.base() - __rhs.base(); } template<typename _Iterator, typename _Sequence> @@ -267,6 +282,7 @@ namespace __profile operator+(typename __iterator_tracker<_Iterator,_Sequence>::difference_type __n, const __iterator_tracker<_Iterator, _Sequence>& __i) + _GLIBCXX_NOEXCEPT { return __i + __n; } } // namespace __profile diff --git a/libstdc++-v3/include/std/array b/libstdc++-v3/include/std/array index 86e8aee14ba..673d0e4b18d 100644 --- a/libstdc++-v3/include/std/array +++ b/libstdc++-v3/include/std/array @@ -180,7 +180,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER at(size_type __n) { if (__n >= _Nm) - std::__throw_out_of_range(__N("array::at")); + std::__throw_out_of_range_fmt(__N("array::at: __n (which is %zu) " + ">= _Nm (which is %zu)"), + __n, _Nm); return _AT_Type::_S_ref(_M_elems, __n); } @@ -190,7 +192,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER // Result of conditional expression must be an lvalue so use // boolean ? lvalue : (throw-expr, lvalue) return __n < _Nm ? _AT_Type::_S_ref(_M_elems, __n) - : (std::__throw_out_of_range(__N("array::at")), + : (std::__throw_out_of_range_fmt(__N("array::at: __n (which is %zu) " + ">= _Nm (which is %zu)"), + __n, _Nm), _AT_Type::_S_ref(_M_elems, 0)); } diff --git a/libstdc++-v3/include/std/bitset b/libstdc++-v3/include/std/bitset index 1da6baf332f..708a434af9e 100644 --- a/libstdc++-v3/include/std/bitset +++ b/libstdc++-v3/include/std/bitset @@ -752,6 +752,26 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER typedef _Base_bitset<_GLIBCXX_BITSET_WORDS(_Nb)> _Base; typedef unsigned long _WordT; + template<class _CharT, class _Traits, class _Alloc> + void + _M_check_initial_position(const std::basic_string<_CharT, _Traits, _Alloc>& __s, + size_t __position) const + { + if (__position > __s.size()) + __throw_out_of_range_fmt(__N("bitset::bitset: __position " + "(which is %zu) > __s.size() " + "(which is %zu)"), + __position, __s.size()); + } + + void _M_check(size_t __position, const char *__s) const + { + if (__position >= _Nb) + __throw_out_of_range_fmt(__N("%s: __position (which is %zu) " + ">= _Nb (which is %zu)"), + __s, __position, _Nb); + } + void _M_do_sanitize() _GLIBCXX_NOEXCEPT { @@ -867,9 +887,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER size_t __position = 0) : _Base() { - if (__position > __s.size()) - __throw_out_of_range(__N("bitset::bitset initial position " - "not valid")); + _M_check_initial_position(__s, __position); _M_copy_from_string(__s, __position, std::basic_string<_CharT, _Traits, _Alloc>::npos, _CharT('0'), _CharT('1')); @@ -890,9 +908,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER size_t __position, size_t __n) : _Base() { - if (__position > __s.size()) - __throw_out_of_range(__N("bitset::bitset initial position " - "not valid")); + _M_check_initial_position(__s, __position); _M_copy_from_string(__s, __position, __n, _CharT('0'), _CharT('1')); } @@ -904,9 +920,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER _CharT __zero, _CharT __one = _CharT('1')) : _Base() { - if (__position > __s.size()) - __throw_out_of_range(__N("bitset::bitset initial position " - "not valid")); + _M_check_initial_position(__s, __position); _M_copy_from_string(__s, __position, __n, __zero, __one); } @@ -1067,8 +1081,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER bitset<_Nb>& set(size_t __position, bool __val = true) { - if (__position >= _Nb) - __throw_out_of_range(__N("bitset::set")); + this->_M_check(__position, __N("bitset::set")); return _Unchecked_set(__position, __val); } @@ -1092,8 +1105,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER bitset<_Nb>& reset(size_t __position) { - if (__position >= _Nb) - __throw_out_of_range(__N("bitset::reset")); + this->_M_check(__position, __N("bitset::reset")); return _Unchecked_reset(__position); } @@ -1116,8 +1128,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER bitset<_Nb>& flip(size_t __position) { - if (__position >= _Nb) - __throw_out_of_range(__N("bitset::flip")); + this->_M_check(__position, __N("bitset::flip")); return _Unchecked_flip(__position); } @@ -1302,8 +1313,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER bool test(size_t __position) const { - if (__position >= _Nb) - __throw_out_of_range(__N("bitset::test")); + this->_M_check(__position, __N("bitset::test")); return _Unchecked_test(__position); } diff --git a/libstdc++-v3/include/std/functional b/libstdc++-v3/include/std/functional index 63ba77793fd..eaa4509a420 100644 --- a/libstdc++-v3/include/std/functional +++ b/libstdc++-v3/include/std/functional @@ -1932,7 +1932,7 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type) template<typename _Tp> static bool - _M_not_empty_function(const _Tp*& __fp) + _M_not_empty_function(_Tp* const& __fp) { return __fp; } template<typename _Class, typename _Tp> @@ -2128,6 +2128,10 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type) } }; + template<typename _From, typename _To> + using __check_func_return_type + = __or_<is_void<_To>, is_convertible<_From, _To>>; + /** * @brief Primary class template for std::function. * @ingroup functors @@ -2145,16 +2149,8 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type) using _Invoke = decltype(__callable_functor(std::declval<_Functor&>()) (std::declval<_ArgTypes>()...) ); - template<typename _CallRes, typename _Res1> - struct _CheckResult - : is_convertible<_CallRes, _Res1> { }; - - template<typename _CallRes> - struct _CheckResult<_CallRes, void> - : true_type { }; - template<typename _Functor> - using _Callable = _CheckResult<_Invoke<_Functor>, _Res>; + using _Callable = __check_func_return_type<_Invoke<_Functor>, _Res>; template<typename _Cond, typename _Tp> using _Requires = typename enable_if<_Cond::value, _Tp>::type; diff --git a/libstdc++-v3/include/std/vector b/libstdc++-v3/include/std/vector index a01c5e72c8d..00cf8bbfd05 100644 --- a/libstdc++-v3/include/std/vector +++ b/libstdc++-v3/include/std/vector @@ -33,7 +33,7 @@ * that both that copyright notice and this permission notice appear * in supporting documentation. Hewlett-Packard Company makes no * representations about the suitability of this software for any - ded "as is" without express or implied warranty. + * purpose. It is provided "as is" without express or implied warranty. * * * Copyright (c) 1996 diff --git a/libstdc++-v3/include/tr2/dynamic_bitset b/libstdc++-v3/include/tr2/dynamic_bitset index ebe9dc28095..5cd05f53c54 100644 --- a/libstdc++-v3/include/tr2/dynamic_bitset +++ b/libstdc++-v3/include/tr2/dynamic_bitset @@ -137,7 +137,12 @@ public: if (__nbits % _S_bits_per_block > 0) ++__sz; if (__sz != this->_M_w.size()) - this->_M_w.resize(__sz); + { + block_type __val = 0; + if (__value) + __val = std::numeric_limits<block_type>::max(); + this->_M_w.resize(__sz, __val); + } } allocator_type @@ -246,7 +251,7 @@ public: bool _M_is_equal(const __dynamic_bitset_base& __x) const { - if (__x.size() == this->size()) + if (__x._M_w.size() == this->_M_w.size()) { for (size_t __i = 0; __i < this->_M_w.size(); ++__i) if (this->_M_w[__i] != __x._M_w[__i]) @@ -260,7 +265,7 @@ public: bool _M_is_less(const __dynamic_bitset_base& __x) const { - if (__x.size() == this->size()) + if (__x._M_w.size() == this->_M_w.size()) { for (size_t __i = this->_M_w.size(); __i > 0; --__i) { @@ -297,9 +302,9 @@ public: bool _M_is_subset_of(const __dynamic_bitset_base& __b) { - if (__b.size() == this->size()) + if (__b._M_w.size() == this->_M_w.size()) { - for (size_t __i = 0; __i < _M_w.size(); ++__i) + for (size_t __i = 0; __i < this->_M_w.size(); ++__i) if (this->_M_w[__i] != (this->_M_w[__i] | __b._M_w[__i])) return false; return true; @@ -364,140 +369,6 @@ public: } }; - // Definitions of non-inline functions from __dynamic_bitset_base. - template<typename _WordT, typename _Alloc> - void - __dynamic_bitset_base<_WordT, _Alloc>::_M_do_left_shift(size_t __shift) - { - if (__builtin_expect(__shift != 0, 1)) - { - const size_t __wshift = __shift / _S_bits_per_block; - const size_t __offset = __shift % _S_bits_per_block; - - if (__offset == 0) - for (size_t __n = this->_M_w.size() - 1; __n >= __wshift; --__n) - this->_M_w[__n] = this->_M_w[__n - __wshift]; - else - { - const size_t __sub_offset = _S_bits_per_block - __offset; - for (size_t __n = _M_w.size() - 1; __n > __wshift; --__n) - this->_M_w[__n] = ((this->_M_w[__n - __wshift] << __offset) - | (this->_M_w[__n - __wshift - 1] >> __sub_offset)); - this->_M_w[__wshift] = this->_M_w[0] << __offset; - } - - //// std::fill(this->_M_w.begin(), this->_M_w.begin() + __wshift, - //// static_cast<_WordT>(0)); - } - } - - template<typename _WordT, typename _Alloc> - void - __dynamic_bitset_base<_WordT, _Alloc>::_M_do_right_shift(size_t __shift) - { - if (__builtin_expect(__shift != 0, 1)) - { - const size_t __wshift = __shift / _S_bits_per_block; - const size_t __offset = __shift % _S_bits_per_block; - const size_t __limit = this->_M_w.size() - __wshift - 1; - - if (__offset == 0) - for (size_t __n = 0; __n <= __limit; ++__n) - this->_M_w[__n] = this->_M_w[__n + __wshift]; - else - { - const size_t __sub_offset = (_S_bits_per_block - - __offset); - for (size_t __n = 0; __n < __limit; ++__n) - this->_M_w[__n] = ((this->_M_w[__n + __wshift] >> __offset) - | (this->_M_w[__n + __wshift + 1] << __sub_offset)); - this->_M_w[__limit] = this->_M_w[_M_w.size()-1] >> __offset; - } - - ////std::fill(this->_M_w.begin() + __limit + 1, this->_M_w.end(), - //// static_cast<_WordT>(0)); - } - } - - template<typename _WordT, typename _Alloc> - unsigned long - __dynamic_bitset_base<_WordT, _Alloc>::_M_do_to_ulong() const - { - size_t __n = sizeof(unsigned long) / sizeof(block_type); - for (size_t __i = __n; __i < this->_M_w.size(); ++__i) - if (this->_M_w[__i]) - __throw_overflow_error(__N("__dynamic_bitset_base::_M_do_to_ulong")); - unsigned long __res = 0UL; - for (size_t __i = 0; __i < __n && __i < this->_M_w.size(); ++__i) - __res += this->_M_w[__i] << (__i * _S_bits_per_block); - return __res; - } - - template<typename _WordT, typename _Alloc> - unsigned long long - __dynamic_bitset_base<_WordT, _Alloc>::_M_do_to_ullong() const - { - size_t __n = sizeof(unsigned long long) / sizeof(block_type); - for (size_t __i = __n; __i < this->_M_w.size(); ++__i) - if (this->_M_w[__i]) - __throw_overflow_error(__N("__dynamic_bitset_base::_M_do_to_ullong")); - unsigned long long __res = 0ULL; - for (size_t __i = 0; __i < __n && __i < this->_M_w.size(); ++__i) - __res += this->_M_w[__i] << (__i * _S_bits_per_block); - return __res; - } - - template<typename _WordT, typename _Alloc> - size_t - __dynamic_bitset_base<_WordT, _Alloc> - ::_M_do_find_first(size_t __not_found) const - { - for (size_t __i = 0; __i < this->_M_w.size(); ++__i) - { - _WordT __thisword = this->_M_w[__i]; - if (__thisword != static_cast<_WordT>(0)) - return (__i * _S_bits_per_block - + __builtin_ctzl(__thisword)); - } - // not found, so return an indication of failure. - return __not_found; - } - - template<typename _WordT, typename _Alloc> - size_t - __dynamic_bitset_base<_WordT, _Alloc> - ::_M_do_find_next(size_t __prev, size_t __not_found) const - { - // make bound inclusive - ++__prev; - - // check out of bounds - if (__prev >= this->_M_w.size() * _S_bits_per_block) - return __not_found; - - // search first word - size_t __i = _S_whichword(__prev); - _WordT __thisword = this->_M_w[__i]; - - // mask off bits below bound - __thisword &= (~static_cast<_WordT>(0)) << _S_whichbit(__prev); - - if (__thisword != static_cast<_WordT>(0)) - return (__i * _S_bits_per_block - + __builtin_ctzl(__thisword)); - - // check subsequent words - for (++__i; __i < this->_M_w.size(); ++__i) - { - __thisword = this->_M_w[__i]; - if (__thisword != static_cast<_WordT>(0)) - return (__i * _S_bits_per_block - + __builtin_ctzl(__thisword)); - } - // not found, so return an indication of failure. - return __not_found; - } // end _M_do_find_next - /** * @brief The %dynamic_bitset class represents a sequence of bits. * @@ -594,6 +465,15 @@ public: this->_M_hiword() &= ~((~static_cast<block_type>(0)) << __shift); } + // Set the unused bits in the uppermost word. + void + _M_do_fill() + { + size_type __shift = this->_M_Nb % bits_per_block; + if (__shift > 0) + this->_M_hiword() |= ((~static_cast<block_type>(0)) << __shift); + } + /** * These versions of single-bit set, reset, flip, and test * do no range checking. @@ -847,6 +727,8 @@ public: void resize(size_type __nbits, bool __value = false) { + if (__value) + this->_M_do_fill(); this->_M_resize(__nbits, __value); this->_M_Nb = __nbits; this->_M_do_sanitize(); @@ -1240,33 +1122,21 @@ public: bool is_proper_subset_of(const dynamic_bitset& __b) const { return this->_M_is_proper_subset_of(__b); } - }; - // Definitions of non-inline member functions. - template<typename _WordT, typename _Alloc> - template<typename _CharT, typename _Traits> - void - dynamic_bitset<_WordT, _Alloc>:: - _M_copy_from_ptr(const _CharT* __str, size_t __len, - size_t __pos, size_t __n, _CharT __zero, _CharT __one) - { - reset(); - const size_t __nbits = std::min(_M_Nb, std::min(__n, __len - __pos)); - for (size_t __i = __nbits; __i > 0; --__i) - { - const _CharT __c = __str[__pos + __nbits - __i]; - if (_Traits::eq(__c, __zero)) - ; - else if (_Traits::eq(__c, __one)) - _M_unchecked_set(__i - 1); - else - __throw_invalid_argument(__N("dynamic_bitset::_M_copy_from_ptr")); - } - } + friend bool + operator==(const dynamic_bitset<_WordT, _Alloc>& __lhs, + const dynamic_bitset<_WordT, _Alloc>& __rhs) + { return __lhs._M_is_equal(__rhs); } + + friend bool + operator<(const dynamic_bitset<_WordT, _Alloc>& __lhs, + const dynamic_bitset<_WordT, _Alloc>& __rhs) + { return __lhs._M_is_less(__rhs); } + }; template<typename _WordT, typename _Alloc> template<typename _CharT, typename _Traits, typename _Alloc1> - void + inline void dynamic_bitset<_WordT, _Alloc>:: _M_copy_to_string(std::basic_string<_CharT, _Traits, _Alloc1>& __str, _CharT __zero, _CharT __one) const @@ -1280,38 +1150,27 @@ public: //@{ /// These comparisons for equality/inequality are, well, @e bitwise. - template<typename _WordT, typename _Alloc> - bool - operator==(const dynamic_bitset<_WordT, _Alloc>& __lhs, - const dynamic_bitset<_WordT, _Alloc>& __rhs) - { return __lhs._M_is_equal(__rhs); } template<typename _WordT, typename _Alloc> - bool + inline bool operator!=(const dynamic_bitset<_WordT, _Alloc>& __lhs, const dynamic_bitset<_WordT, _Alloc>& __rhs) - { return !__lhs._M_is_equal(__rhs); } - - template<typename _WordT, typename _Alloc> - bool - operator<(const dynamic_bitset<_WordT, _Alloc>& __lhs, - const dynamic_bitset<_WordT, _Alloc>& __rhs) - { return __lhs._M_is_less(__rhs); } + { return !(__lhs == __rhs); } template<typename _WordT, typename _Alloc> - bool + inline bool operator<=(const dynamic_bitset<_WordT, _Alloc>& __lhs, const dynamic_bitset<_WordT, _Alloc>& __rhs) { return !(__lhs > __rhs); } template<typename _WordT, typename _Alloc> - bool + inline bool operator>(const dynamic_bitset<_WordT, _Alloc>& __lhs, const dynamic_bitset<_WordT, _Alloc>& __rhs) { return __rhs < __lhs; } template<typename _WordT, typename _Alloc> - bool + inline bool operator>=(const dynamic_bitset<_WordT, _Alloc>& __lhs, const dynamic_bitset<_WordT, _Alloc>& __rhs) { return !(__lhs < __rhs); } @@ -1368,8 +1227,9 @@ public: } //@} - //@{ /** + * @defgroup Global I/O operators for bitsets. + * @{ * @brief Global I/O operators for bitsets. * * Direct I/O between streams and bitsets is supported. Output is @@ -1377,81 +1237,9 @@ public: * and '1' characters. The %dynamic_bitset will grow as necessary * to hold the string of bits. */ - template<typename _CharT, typename _Traits, - typename _WordT, typename _Alloc> - std::basic_istream<_CharT, _Traits>& - operator>>(std::basic_istream<_CharT, _Traits>& __is, - dynamic_bitset<_WordT, _Alloc>& __x) - { - typedef typename _Traits::char_type char_type; - typedef std::basic_istream<_CharT, _Traits> __istream_type; - typedef typename __istream_type::ios_base __ios_base; - - std::basic_string<_CharT, _Traits> __tmp; - __tmp.reserve(__x.size()); - - const char_type __zero = __is.widen('0'); - const char_type __one = __is.widen('1'); - - typename __ios_base::iostate __state = __ios_base::goodbit; - typename __istream_type::sentry __sentry(__is); - if (__sentry) - { - __try - { - while (1) - { - static typename _Traits::int_type __eof = _Traits::eof(); - - typename _Traits::int_type __c1 = __is.rdbuf()->sbumpc(); - if (_Traits::eq_int_type(__c1, __eof)) - { - __state |= __ios_base::eofbit; - break; - } - else - { - const char_type __c2 = _Traits::to_char_type(__c1); - if (_Traits::eq(__c2, __zero)) - __tmp.push_back(__zero); - else if (_Traits::eq(__c2, __one)) - __tmp.push_back(__one); - else if (_Traits:: - eq_int_type(__is.rdbuf()->sputbackc(__c2), - __eof)) - { - __state |= __ios_base::failbit; - break; - } - else - break; - } - } - } - __catch(__cxxabiv1::__forced_unwind&) - { - __is._M_setstate(__ios_base::badbit); - __throw_exception_again; - } - __catch(...) - { __is._M_setstate(__ios_base::badbit); } - } - - __x.resize(__tmp.size()); - - if (__tmp.empty() && __x.size()) - __state |= __ios_base::failbit; - else - __x._M_copy_from_string(__tmp, static_cast<size_t>(0), __x.size(), - __zero, __one); - if (__state) - __is.setstate(__state); - return __is; - } - template <typename _CharT, typename _Traits, typename _WordT, typename _Alloc> - std::basic_ostream<_CharT, _Traits>& + inline std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const dynamic_bitset<_WordT, _Alloc>& __x) { @@ -1461,12 +1249,14 @@ public: __x._M_copy_to_string(__tmp, __ct.widen('0'), __ct.widen('1')); return __os << __tmp; } - //@} + /** + * @} + */ _GLIBCXX_END_NAMESPACE_VERSION } // tr2 } // std -#undef _GLIBCXX_BITSET_BITS_PER_WORD +#include <tr2/dynamic_bitset.tcc> #endif /* _GLIBCXX_TR2_DYNAMIC_BITSET */ diff --git a/libstdc++-v3/include/tr2/dynamic_bitset.tcc b/libstdc++-v3/include/tr2/dynamic_bitset.tcc new file mode 100644 index 00000000000..016fdf0bd82 --- /dev/null +++ b/libstdc++-v3/include/tr2/dynamic_bitset.tcc @@ -0,0 +1,286 @@ +// TR2 <dynamic_bitset> -*- C++ -*- + +// Copyright (C) 2009-2013 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. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file tr2/dynamic_bitset.tcc + * This is an internal header file, included by other library headers. + * Do not attempt to use it directly. @headername{tr2/dynamic_bitset} + */ + +#ifndef _GLIBCXX_TR2_DYNAMIC_BITSET_TCC +#define _GLIBCXX_TR2_DYNAMIC_BITSET_TCC 1 + +#pragma GCC system_header + +namespace std _GLIBCXX_VISIBILITY(default) +{ +namespace tr2 +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + // Definitions of non-inline functions from __dynamic_bitset_base. + template<typename _WordT, typename _Alloc> + void + __dynamic_bitset_base<_WordT, _Alloc>::_M_do_left_shift(size_t __shift) + { + if (__builtin_expect(__shift != 0, 1)) + { + const size_t __wshift = __shift / _S_bits_per_block; + const size_t __offset = __shift % _S_bits_per_block; + + if (__offset == 0) + for (size_t __n = this->_M_w.size() - 1; __n >= __wshift; --__n) + this->_M_w[__n] = this->_M_w[__n - __wshift]; + else + { + const size_t __sub_offset = _S_bits_per_block - __offset; + for (size_t __n = _M_w.size() - 1; __n > __wshift; --__n) + this->_M_w[__n] = ((this->_M_w[__n - __wshift] << __offset) + | (this->_M_w[__n - __wshift - 1] >> __sub_offset)); + this->_M_w[__wshift] = this->_M_w[0] << __offset; + } + + //// std::fill(this->_M_w.begin(), this->_M_w.begin() + __wshift, + //// static_cast<_WordT>(0)); + } + } + + template<typename _WordT, typename _Alloc> + void + __dynamic_bitset_base<_WordT, _Alloc>::_M_do_right_shift(size_t __shift) + { + if (__builtin_expect(__shift != 0, 1)) + { + const size_t __wshift = __shift / _S_bits_per_block; + const size_t __offset = __shift % _S_bits_per_block; + const size_t __limit = this->_M_w.size() - __wshift - 1; + + if (__offset == 0) + for (size_t __n = 0; __n <= __limit; ++__n) + this->_M_w[__n] = this->_M_w[__n + __wshift]; + else + { + const size_t __sub_offset = (_S_bits_per_block + - __offset); + for (size_t __n = 0; __n < __limit; ++__n) + this->_M_w[__n] = ((this->_M_w[__n + __wshift] >> __offset) + | (this->_M_w[__n + __wshift + 1] << __sub_offset)); + this->_M_w[__limit] = this->_M_w[_M_w.size()-1] >> __offset; + } + + ////std::fill(this->_M_w.begin() + __limit + 1, this->_M_w.end(), + //// static_cast<_WordT>(0)); + } + } + + template<typename _WordT, typename _Alloc> + unsigned long + __dynamic_bitset_base<_WordT, _Alloc>::_M_do_to_ulong() const + { + size_t __n = sizeof(unsigned long) / sizeof(block_type); + for (size_t __i = __n; __i < this->_M_w.size(); ++__i) + if (this->_M_w[__i]) + __throw_overflow_error(__N("__dynamic_bitset_base::_M_do_to_ulong")); + unsigned long __res = 0UL; + for (size_t __i = 0; __i < __n && __i < this->_M_w.size(); ++__i) + __res += this->_M_w[__i] << (__i * _S_bits_per_block); + return __res; + } + + template<typename _WordT, typename _Alloc> + unsigned long long + __dynamic_bitset_base<_WordT, _Alloc>::_M_do_to_ullong() const + { + size_t __n = sizeof(unsigned long long) / sizeof(block_type); + for (size_t __i = __n; __i < this->_M_w.size(); ++__i) + if (this->_M_w[__i]) + __throw_overflow_error(__N("__dynamic_bitset_base::_M_do_to_ullong")); + unsigned long long __res = 0ULL; + for (size_t __i = 0; __i < __n && __i < this->_M_w.size(); ++__i) + __res += this->_M_w[__i] << (__i * _S_bits_per_block); + return __res; + } + + template<typename _WordT, typename _Alloc> + size_t + __dynamic_bitset_base<_WordT, _Alloc> + ::_M_do_find_first(size_t __not_found) const + { + for (size_t __i = 0; __i < this->_M_w.size(); ++__i) + { + _WordT __thisword = this->_M_w[__i]; + if (__thisword != static_cast<_WordT>(0)) + return (__i * _S_bits_per_block + + __builtin_ctzl(__thisword)); + } + // not found, so return an indication of failure. + return __not_found; + } + + template<typename _WordT, typename _Alloc> + size_t + __dynamic_bitset_base<_WordT, _Alloc> + ::_M_do_find_next(size_t __prev, size_t __not_found) const + { + // make bound inclusive + ++__prev; + + // check out of bounds + if (__prev >= this->_M_w.size() * _S_bits_per_block) + return __not_found; + + // search first word + size_t __i = _S_whichword(__prev); + _WordT __thisword = this->_M_w[__i]; + + // mask off bits below bound + __thisword &= (~static_cast<_WordT>(0)) << _S_whichbit(__prev); + + if (__thisword != static_cast<_WordT>(0)) + return (__i * _S_bits_per_block + + __builtin_ctzl(__thisword)); + + // check subsequent words + for (++__i; __i < this->_M_w.size(); ++__i) + { + __thisword = this->_M_w[__i]; + if (__thisword != static_cast<_WordT>(0)) + return (__i * _S_bits_per_block + + __builtin_ctzl(__thisword)); + } + // not found, so return an indication of failure. + return __not_found; + } // end _M_do_find_next + + // Definitions of non-inline member functions. + template<typename _WordT, typename _Alloc> + template<typename _CharT, typename _Traits> + void + dynamic_bitset<_WordT, _Alloc>:: + _M_copy_from_ptr(const _CharT* __str, size_t __len, + size_t __pos, size_t __n, _CharT __zero, _CharT __one) + { + reset(); + const size_t __nbits = std::min(_M_Nb, std::min(__n, __len - __pos)); + for (size_t __i = __nbits; __i > 0; --__i) + { + const _CharT __c = __str[__pos + __nbits - __i]; + if (_Traits::eq(__c, __zero)) + ; + else if (_Traits::eq(__c, __one)) + _M_unchecked_set(__i - 1); + else + __throw_invalid_argument(__N("dynamic_bitset::_M_copy_from_ptr")); + } + } + + /** + * @defgroup Global I/O operators for bitsets. + * @{ + * @brief Global I/O operators for bitsets. + * + * Direct I/O between streams and bitsets is supported. Output is + * straightforward. Input will skip whitespace and only accept '0' + * and '1' characters. The %dynamic_bitset will grow as necessary + * to hold the string of bits. + */ + template<typename _CharT, typename _Traits, + typename _WordT, typename _Alloc> + std::basic_istream<_CharT, _Traits>& + operator>>(std::basic_istream<_CharT, _Traits>& __is, + dynamic_bitset<_WordT, _Alloc>& __x) + { + typedef typename _Traits::char_type char_type; + typedef std::basic_istream<_CharT, _Traits> __istream_type; + typedef typename __istream_type::ios_base __ios_base; + + std::basic_string<_CharT, _Traits> __tmp; + __tmp.reserve(__x.size()); + + const char_type __zero = __is.widen('0'); + const char_type __one = __is.widen('1'); + + typename __ios_base::iostate __state = __ios_base::goodbit; + typename __istream_type::sentry __sentry(__is); + if (__sentry) + { + __try + { + while (1) + { + static typename _Traits::int_type __eof = _Traits::eof(); + + typename _Traits::int_type __c1 = __is.rdbuf()->sbumpc(); + if (_Traits::eq_int_type(__c1, __eof)) + { + __state |= __ios_base::eofbit; + break; + } + else + { + const char_type __c2 = _Traits::to_char_type(__c1); + if (_Traits::eq(__c2, __zero)) + __tmp.push_back(__zero); + else if (_Traits::eq(__c2, __one)) + __tmp.push_back(__one); + else if (_Traits:: + eq_int_type(__is.rdbuf()->sputbackc(__c2), + __eof)) + { + __state |= __ios_base::failbit; + break; + } + else + break; + } + } + } + __catch(__cxxabiv1::__forced_unwind&) + { + __is._M_setstate(__ios_base::badbit); + __throw_exception_again; + } + __catch(...) + { __is._M_setstate(__ios_base::badbit); } + } + + __x.resize(__tmp.size()); + + if (__tmp.empty() && __x.size()) + __state |= __ios_base::failbit; + else + __x._M_copy_from_string(__tmp, static_cast<size_t>(0), __x.size(), + __zero, __one); + if (__state) + __is.setstate(__state); + return __is; + } + /** + * @} + */ + +_GLIBCXX_END_NAMESPACE_VERSION +} // tr2 +} // std + +#endif /* _GLIBCXX_TR2_DYNAMIC_BITSET_TCC */ diff --git a/libstdc++-v3/libsupc++/del_op.cc b/libstdc++-v3/libsupc++/del_op.cc index 2d860e18622..ee446c36f14 100644 --- a/libstdc++-v3/libsupc++/del_op.cc +++ b/libstdc++-v3/libsupc++/del_op.cc @@ -43,6 +43,5 @@ _GLIBCXX_END_NAMESPACE_VERSION _GLIBCXX_WEAK_DEFINITION void operator delete(void* ptr) _GLIBCXX_USE_NOEXCEPT { - if (ptr) - std::free(ptr); + std::free(ptr); } diff --git a/libstdc++-v3/libsupc++/del_opnt.cc b/libstdc++-v3/libsupc++/del_opnt.cc index bb37191caed..a04ea401b1c 100644 --- a/libstdc++-v3/libsupc++/del_opnt.cc +++ b/libstdc++-v3/libsupc++/del_opnt.cc @@ -24,12 +24,24 @@ // <http://www.gnu.org/licenses/>. #include <bits/c++config.h> -#include "new" -extern "C" void free (void *); +#if !_GLIBCXX_HOSTED +// A freestanding C runtime may not provide "free" -- but there is no +// other reasonable way to implement "operator delete". +namespace std +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + extern "C" void free(void*); +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace +#else +# include <cstdlib> +#endif + +#include "new" _GLIBCXX_WEAK_DEFINITION void operator delete (void *ptr, const std::nothrow_t&) _GLIBCXX_USE_NOEXCEPT { - free (ptr); + std::free(ptr); } diff --git a/libstdc++-v3/src/c++11/Makefile.am b/libstdc++-v3/src/c++11/Makefile.am index 58d3025f0e7..7dda9483b7b 100644 --- a/libstdc++-v3/src/c++11/Makefile.am +++ b/libstdc++-v3/src/c++11/Makefile.am @@ -42,6 +42,7 @@ sources = \ random.cc \ regex.cc \ shared_ptr.cc \ + snprintf_lite.cc \ system_error.cc \ thread.cc diff --git a/libstdc++-v3/src/c++11/Makefile.in b/libstdc++-v3/src/c++11/Makefile.in index 5daae3edf69..83b7bd155b9 100644 --- a/libstdc++-v3/src/c++11/Makefile.in +++ b/libstdc++-v3/src/c++11/Makefile.in @@ -70,7 +70,8 @@ libc__11convenience_la_LIBADD = am__objects_1 = chrono.lo condition_variable.lo debug.lo \ functexcept.lo functional.lo future.lo hash_c++0x.lo \ hashtable_c++0x.lo limits.lo mutex.lo placeholders.lo \ - random.lo regex.lo shared_ptr.lo system_error.lo thread.lo + random.lo regex.lo shared_ptr.lo snprintf_lite.lo \ + system_error.lo thread.lo @ENABLE_EXTERN_TEMPLATE_TRUE@am__objects_2 = fstream-inst.lo \ @ENABLE_EXTERN_TEMPLATE_TRUE@ string-inst.lo wstring-inst.lo am_libc__11convenience_la_OBJECTS = $(am__objects_1) $(am__objects_2) @@ -324,6 +325,7 @@ sources = \ random.cc \ regex.cc \ shared_ptr.cc \ + snprintf_lite.cc \ system_error.cc \ thread.cc diff --git a/libstdc++-v3/src/c++11/functexcept.cc b/libstdc++-v3/src/c++11/functexcept.cc index b0c1804ae04..b18f8ad5706 100644 --- a/libstdc++-v3/src/c++11/functexcept.cc +++ b/libstdc++-v3/src/c++11/functexcept.cc @@ -31,6 +31,7 @@ #include <future> #include <functional> #include <bits/regex_error.h> +#include <stdarg.h> #ifdef _GLIBCXX_USE_NLS # include <libintl.h> @@ -39,6 +40,12 @@ # define _(msgid) (msgid) #endif +namespace __gnu_cxx +{ + int __snprintf_lite(char *__buf, size_t __bufsize, const char *__fmt, + va_list __ap); +} + namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION @@ -80,6 +87,22 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { _GLIBCXX_THROW_OR_ABORT(out_of_range(_(__s))); } void + __throw_out_of_range_fmt(const char* __fmt, ...) + { + const size_t __len = __builtin_strlen(__fmt); + // We expect at most 2 numbers, and 1 short string. The additional + // 512 bytes should provide more than enough space for expansion. + const size_t __alloca_size = __len + 512; + char *const __s = static_cast<char*>(__builtin_alloca(__alloca_size)); + va_list __ap; + + va_start(__ap, __fmt); + __gnu_cxx::__snprintf_lite(__s, __alloca_size, __fmt, __ap); + _GLIBCXX_THROW_OR_ABORT(out_of_range(_(__s))); + va_end(__ap); // Not reached. + } + + void __throw_runtime_error(const char* __s __attribute__((unused))) { _GLIBCXX_THROW_OR_ABORT(runtime_error(_(__s))); } diff --git a/libstdc++-v3/src/c++11/snprintf_lite.cc b/libstdc++-v3/src/c++11/snprintf_lite.cc new file mode 100644 index 00000000000..492df316018 --- /dev/null +++ b/libstdc++-v3/src/c++11/snprintf_lite.cc @@ -0,0 +1,161 @@ +// Debugging support -*- C++ -*- + +// Copyright (C) 2013 Free Software Foundation, Inc. +// +// This file is part of GCC. +// +// GCC 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. +// +// GCC 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. +// +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +#include <stdarg.h> +#include <bits/functexcept.h> +#include <bits/locale_facets.h> + +namespace std { +_GLIBCXX_BEGIN_NAMESPACE_VERSION + template<typename _CharT, typename _ValueT> + int + __int_to_char(_CharT* __bufend, _ValueT __v, const _CharT* __lit, + ios_base::fmtflags __flags, bool __dec); +_GLIBCXX_END_NAMESPACE_VERSION +} + +namespace __gnu_cxx { + + // Private helper to throw logic error if snprintf_lite runs out + // of space (which is not expected to ever happen). + // NUL-terminates __buf. + void + __throw_insufficient_space(const char *__buf, const char *__bufend) + __attribute__((__noreturn__)); + + void + __throw_insufficient_space(const char *__buf, const char *__bufend) + { + // Include space for trailing NUL. + const size_t __len = __bufend - __buf + 1; + + const char __err[] = "not enough space for format expansion " + "(Please submit full bug report at http://gcc.gnu.org/bugs.html):\n "; + const size_t __errlen = sizeof(__err) - 1; + + char *const __e + = static_cast<char*>(__builtin_alloca(__errlen + __len)); + + __builtin_memcpy(__e, __err, __errlen); + __builtin_memcpy(__e + __errlen, __buf, __len - 1); + __e[__errlen + __len - 1] = '\0'; + std::__throw_logic_error(__e); + } + + + // Private routine to append decimal representation of VAL to the given + // BUFFER, but not more than BUFSIZE characters. + // Does not NUL-terminate the output buffer. + // Returns number of characters appended, or -1 if BUFSIZE is too small. + int __concat_size_t(char *__buf, size_t __bufsize, size_t __val) + { + // __int_to_char is explicitly instantiated and available only for + // some, but not all, types. See locale-inst.cc. +#ifdef _GLIBCXX_USE_LONG_LONG + unsigned long long __val2 = __val; +#else + unsigned long __val2 = __val; +#endif + // Long enough for decimal representation. + int __ilen = 3 * sizeof(__val2); + char *__cs = static_cast<char*>(__builtin_alloca(__ilen)); + size_t __len = std::__int_to_char(__cs + __ilen, __val2, + std::__num_base::_S_atoms_out, + std::ios_base::dec, true); + if (__bufsize < __len) + return -1; + + __builtin_memcpy(__buf, __cs + __ilen - __len, __len); + return __len; + } + + + // Private routine to print into __buf arguments according to format, + // not to exceed __bufsize. + // Only '%%', '%s' and '%zu' format specifiers are understood. + // Returns number of characters printed (excluding terminating NUL). + // Always NUL-terminates __buf. + // Throws logic_error on insufficient space. + int __snprintf_lite(char *__buf, size_t __bufsize, const char *__fmt, + va_list __ap) + { + char *__d = __buf; + const char *__s = __fmt; + const char *const __limit = __d + __bufsize - 1; // Leave space for NUL. + + while (__s[0] != '\0' && __d < __limit) + { + if (__s[0] == '%') + switch (__s[1]) + { + default: // Stray '%'. Just print it. + break; + case '%': // '%%' + __s += 1; + break; + case 's': // '%s'. + { + const char *__v = va_arg(__ap, const char *); + + while (__v[0] != '\0' && __d < __limit) + *__d++ = *__v++; + + if (__v[0] != '\0') + // Not enough space for __fmt expansion. + __throw_insufficient_space(__buf, __d); + + __s += 2; // Step over %s. + continue; + } + break; + case 'z': + if (__s[2] == 'u') // '%zu' -- expand next size_t arg. + { + const int __len = __concat_size_t(__d, __limit - __d, + va_arg(__ap, size_t)); + if (__len > 0) + __d += __len; + else + // Not enough space for __fmt expansion. + __throw_insufficient_space(__buf, __d); + + __s += 3; // Step over %zu + continue; + } + // Stray '%zX'. Just print it. + break; + } + *__d++ = *__s++; + } + + if (__s[0] != '\0') + // Not enough space for __fmt expansion. + __throw_insufficient_space(__buf, __d); + + *__d = '\0'; + return __d - __buf; + } + +} // __gnu_cxx diff --git a/libstdc++-v3/testsuite/20_util/exchange/1.cc b/libstdc++-v3/testsuite/20_util/exchange/1.cc index d16d9e9642e..2157b69e7e9 100644 --- a/libstdc++-v3/testsuite/20_util/exchange/1.cc +++ b/libstdc++-v3/testsuite/20_util/exchange/1.cc @@ -55,6 +55,10 @@ test02() VERIFY( old.value == 1 ); } +int f(int) { return 0; } + +double f(double) { return 0; } + // Deduce type of overloaded function void test03() @@ -62,8 +66,6 @@ test03() bool test __attribute__((unused)) = true; int (*fp)(int); - int f(int); - double f(double); std::exchange(fp, &f); VERIFY( fp != nullptr ); } diff --git a/libstdc++-v3/testsuite/20_util/function/58569.cc b/libstdc++-v3/testsuite/20_util/function/58569.cc new file mode 100644 index 00000000000..f1e67bc5ab9 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/function/58569.cc @@ -0,0 +1,29 @@ +// { dg-options "-std=gnu++11" } +// { dg-do compile } +// Copyright (C) 2013 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/>. + +// libstdc++/58569 + +#include <functional> + +struct foo { + std::function<foo (int)> x; + std::function<foo ()> y; +}; + +foo a; diff --git a/libstdc++-v3/testsuite/20_util/function/cons/57465.cc b/libstdc++-v3/testsuite/20_util/function/cons/57465.cc new file mode 100644 index 00000000000..44413fbd6ef --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/function/cons/57465.cc @@ -0,0 +1,31 @@ +// Copyright (C) 2013 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/>. + +// libstdc++/57465 + +// { dg-options "-std=gnu++11" } + +#include <functional> +#include <testsuite_hooks.h> + +int main() +{ + using F = void(); + F* f = nullptr; + std::function<F> x(f); + VERIFY( !x ); +} diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/cons/43820_neg.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/43820_neg.cc index b6d1009d884..fd2a677e0c7 100644 --- a/libstdc++-v3/testsuite/20_util/shared_ptr/cons/43820_neg.cc +++ b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/43820_neg.cc @@ -32,7 +32,7 @@ void test01() { X* px = 0; std::shared_ptr<X> p1(px); // { dg-error "here" } - // { dg-error "incomplete" "" { target *-*-* } 807 } + // { dg-error "incomplete" "" { target *-*-* } 778 } std::shared_ptr<X> p9(ap()); // { dg-error "here" } // { dg-error "incomplete" "" { target *-*-* } 307 } diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/cons/58659.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/58659.cc new file mode 100644 index 00000000000..9315796b240 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/58659.cc @@ -0,0 +1,68 @@ +// { dg-options "-std=gnu++11" } + +// Copyright (C) 2013 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 <memory> +#include <testsuite_hooks.h> + +struct X { }; + +using spcd = std::_Sp_counted_deleter<X*, std::default_delete<X>, +std::allocator<void>, std::__default_lock_policy>; + +namespace std +{ + template<> + struct allocator<spcd> + { + using value_type = spcd; + + allocator() = default; + + template<typename U> + allocator(const allocator<U>&) { } + + value_type* allocate(size_t n) + { + if (n != 1) + throw bad_alloc(); + allocated = true; + return static_cast<value_type*>((void*)(storage)); + } + + void deallocate(value_type* p, size_t n) + { + VERIFY(n == 1 && p == (void*)storage && allocated); + allocated = false; + } + + static char storage[sizeof(spcd)]; + static bool allocated; + }; + + char allocator<spcd>::storage[]; + bool allocator<spcd>::allocated = false; +} + +int main() +{ + std::shared_ptr<X> s( std::unique_ptr<X>(new X) ); + VERIFY( std::allocator<spcd>::allocated ); + s.reset(); + VERIFY( !std::allocator<spcd>::allocated ); +} diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/creation/58594.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/creation/58594.cc new file mode 100644 index 00000000000..d1e3a7c5ddc --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/shared_ptr/creation/58594.cc @@ -0,0 +1,27 @@ +// { dg-options "-std=gnu++11" } +// { dg-do compile } + +// Copyright (C) 2013 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 <memory> + +// libstdc++/58594 +void test01() +{ + std::make_shared<const int>(); +} diff --git a/libstdc++-v3/testsuite/23_containers/array/tuple_interface/get_debug_neg.cc b/libstdc++-v3/testsuite/23_containers/array/tuple_interface/get_debug_neg.cc index 353577f6bbc..6667629e149 100644 --- a/libstdc++-v3/testsuite/23_containers/array/tuple_interface/get_debug_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/array/tuple_interface/get_debug_neg.cc @@ -28,6 +28,6 @@ int n1 = std::get<1>(a); int n2 = std::get<1>(std::move(a)); int n3 = std::get<1>(ca); -// { dg-error "static assertion failed" "" { target *-*-* } 266 } -// { dg-error "static assertion failed" "" { target *-*-* } 275 } -// { dg-error "static assertion failed" "" { target *-*-* } 283 } +// { dg-error "static assertion failed" "" { target *-*-* } 271 } +// { dg-error "static assertion failed" "" { target *-*-* } 280 } +// { dg-error "static assertion failed" "" { target *-*-* } 288 } diff --git a/libstdc++-v3/testsuite/23_containers/array/tuple_interface/get_neg.cc b/libstdc++-v3/testsuite/23_containers/array/tuple_interface/get_neg.cc index d465cd296b9..ca6f9f84e82 100644 --- a/libstdc++-v3/testsuite/23_containers/array/tuple_interface/get_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/array/tuple_interface/get_neg.cc @@ -28,6 +28,6 @@ int n1 = std::get<1>(a); int n2 = std::get<1>(std::move(a)); int n3 = std::get<1>(ca); -// { dg-error "static assertion failed" "" { target *-*-* } 270 } -// { dg-error "static assertion failed" "" { target *-*-* } 279 } -// { dg-error "static assertion failed" "" { target *-*-* } 287 } +// { dg-error "static assertion failed" "" { target *-*-* } 274 } +// { dg-error "static assertion failed" "" { target *-*-* } 283 } +// { dg-error "static assertion failed" "" { target *-*-* } 291 } diff --git a/libstdc++-v3/testsuite/23_containers/array/tuple_interface/tuple_element_debug_neg.cc b/libstdc++-v3/testsuite/23_containers/array/tuple_interface/tuple_element_debug_neg.cc index 76ea230b14e..a8e0624ee6e 100644 --- a/libstdc++-v3/testsuite/23_containers/array/tuple_interface/tuple_element_debug_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/array/tuple_interface/tuple_element_debug_neg.cc @@ -23,4 +23,4 @@ typedef std::tuple_element<1, std::array<int, 1>>::type type; -// { dg-error "static assertion failed" "" { target *-*-* } 300 } +// { dg-error "static assertion failed" "" { target *-*-* } 305 } diff --git a/libstdc++-v3/testsuite/23_containers/array/tuple_interface/tuple_element_neg.cc b/libstdc++-v3/testsuite/23_containers/array/tuple_interface/tuple_element_neg.cc index 3a52607deb6..0648bc1176e 100644 --- a/libstdc++-v3/testsuite/23_containers/array/tuple_interface/tuple_element_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/array/tuple_interface/tuple_element_neg.cc @@ -23,4 +23,4 @@ typedef std::tuple_element<1, std::array<int, 1>>::type type; -// { dg-error "static assertion failed" "" { target *-*-* } 316 } +// { dg-error "static assertion failed" "" { target *-*-* } 320 } 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 a0bdcdb53f8..e5917b81f60 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 *-*-* } 1755 } +// { dg-error "no matching" "" { target *-*-* } 1758 } #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 86d7016e616..fd83c0e1493 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 *-*-* } 1688 } +// { dg-error "no matching" "" { target *-*-* } 1691 } #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 84be8ebda5e..4dc6e8dec73 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 *-*-* } 1688 } +// { dg-error "no matching" "" { target *-*-* } 1691 } #include <deque> #include <utility> 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 26e5c290013..dbbfbaa5c6d 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 *-*-* } 1839 } +// { dg-error "no matching" "" { target *-*-* } 1842 } #include <deque> @@ -32,4 +32,3 @@ void f() std::deque<A> d; d.insert(d.begin(), 10, 1); } - diff --git a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/assign_neg.cc b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/assign_neg.cc index 388e57182cc..b8a6621b339 100644 --- a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/assign_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/assign_neg.cc @@ -18,7 +18,7 @@ // <http://www.gnu.org/licenses/>. // { dg-do compile } -// { dg-error "no matching" "" { target *-*-* } 1302 } +// { dg-error "no matching" "" { target *-*-* } 1305 } #include <vector> diff --git a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc index 68cfab064f8..ec3aa5a62e8 100644 --- a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc @@ -18,7 +18,7 @@ // <http://www.gnu.org/licenses/>. // { dg-do compile } -// { dg-error "no matching" "" { target *-*-* } 1228 } +// { dg-error "no matching" "" { target *-*-* } 1231 } #include <vector> diff --git a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc index 35c03286a26..5c7d436ad34 100644 --- a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc @@ -18,7 +18,7 @@ // <http://www.gnu.org/licenses/>. // { dg-do compile } -// { dg-error "no matching" "" { target *-*-* } 1228 } +// { dg-error "no matching" "" { target *-*-* } 1231 } #include <vector> #include <utility> diff --git a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/insert_neg.cc b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/insert_neg.cc index 6ab70388b83..2daaf527197 100644 --- a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/insert_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/insert_neg.cc @@ -18,7 +18,7 @@ // <http://www.gnu.org/licenses/>. // { dg-do compile } -// { dg-error "no matching" "" { target *-*-* } 1343 } +// { dg-error "no matching" "" { target *-*-* } 1346 } #include <vector> diff --git a/libstdc++-v3/testsuite/25_algorithms/adjacent_find/vectorbool.cc b/libstdc++-v3/testsuite/25_algorithms/adjacent_find/vectorbool.cc new file mode 100644 index 00000000000..c5278bbe974 --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/adjacent_find/vectorbool.cc @@ -0,0 +1,44 @@ +// Copyright (C) 2013 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/>. + +// 25.1.5 [lib.alg.adjacent_find] + +#include <vector> +#include <algorithm> +#include <testsuite_hooks.h> + +void +test01() +{ + bool test __attribute__((unused)) = true; + + std::vector<bool> v; + v.push_back(true); + v.push_back(false); + v.push_back(true); + v.push_back(false); + v.push_back(false); + + VERIFY( std::adjacent_find(v.begin(), v.end()) == v.begin() + 3 ); + VERIFY( std::adjacent_find(v.begin(), v.end() - 1) == v.end() - 1 ); +} + +int +main() +{ + test01(); +} diff --git a/libstdc++-v3/testsuite/25_algorithms/find/vectorbool.cc b/libstdc++-v3/testsuite/25_algorithms/find/vectorbool.cc new file mode 100644 index 00000000000..13de9300c10 --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/find/vectorbool.cc @@ -0,0 +1,39 @@ +// Copyright (C) 2013 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/>. + +// 25.1.2 find + +#include <algorithm> +#include <vector> +#include <testsuite_hooks.h> + +void +test1() +{ + std::vector<bool> v; + v.push_back(false); + v.push_back(false); + v.push_back(true); + v.push_back(false); + VERIFY( std::find(v.begin(), v.end(), true) == v.begin() + 2 ); +} + +int +main() +{ + test1(); +} diff --git a/libstdc++-v3/testsuite/25_algorithms/find_end/vectorbool.cc b/libstdc++-v3/testsuite/25_algorithms/find_end/vectorbool.cc new file mode 100644 index 00000000000..eabaa4c572c --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/find_end/vectorbool.cc @@ -0,0 +1,50 @@ +// Copyright (C) 2013 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/>. + +// 25.1.3 [lib.alg.find.end] + +#include <algorithm> +#include <vector> +#include <testsuite_hooks.h> + +void +test1() +{ + std::vector<bool> v1; + v1.push_back(false); + v1.push_back(false); + v1.push_back(false); + v1.push_back(true); + v1.push_back(true); + v1.push_back(false); + v1.push_back(true); + v1.push_back(true); + v1.push_back(false); + + std::vector<bool> v2; + v2.push_back(true); + v2.push_back(true); + + VERIFY( std::find_end(v1.begin(), v1.end(), v2.begin(), v2.end()) + == v1.begin() + 6 ); +} + +int +main() +{ + test1(); +} diff --git a/libstdc++-v3/testsuite/25_algorithms/find_first_of/vectorbool.cc b/libstdc++-v3/testsuite/25_algorithms/find_first_of/vectorbool.cc new file mode 100644 index 00000000000..d43a391c843 --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/find_first_of/vectorbool.cc @@ -0,0 +1,50 @@ +// Copyright (C) 2013 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/>. + +// 25.1.4 [lib.alg.find.first.of] + +#include <algorithm> +#include <vector> +#include <testsuite_hooks.h> + +void +test1() +{ + std::vector<bool> v1; + v1.push_back(false); + v1.push_back(false); + v1.push_back(true); + v1.push_back(false); + v1.push_back(true); + v1.push_back(true); + v1.push_back(false); + v1.push_back(true); + v1.push_back(true); + + std::vector<bool> v2; + v2.push_back(true); + v2.push_back(false); + + VERIFY( std::find_first_of(v1.begin(), v1.end(), v2.begin(), v2.end()) + == v1.begin() ); +} + +int +main() +{ + test1(); +} diff --git a/libstdc++-v3/testsuite/25_algorithms/find_if/vectorbool.cc b/libstdc++-v3/testsuite/25_algorithms/find_if/vectorbool.cc new file mode 100644 index 00000000000..13de9300c10 --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/find_if/vectorbool.cc @@ -0,0 +1,39 @@ +// Copyright (C) 2013 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/>. + +// 25.1.2 find + +#include <algorithm> +#include <vector> +#include <testsuite_hooks.h> + +void +test1() +{ + std::vector<bool> v; + v.push_back(false); + v.push_back(false); + v.push_back(true); + v.push_back(false); + VERIFY( std::find(v.begin(), v.end(), true) == v.begin() + 2 ); +} + +int +main() +{ + test1(); +} diff --git a/libstdc++-v3/testsuite/25_algorithms/find_if_not/vectorbool.cc b/libstdc++-v3/testsuite/25_algorithms/find_if_not/vectorbool.cc new file mode 100644 index 00000000000..f97a7e24256 --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/find_if_not/vectorbool.cc @@ -0,0 +1,40 @@ +// { dg-options "-std=gnu++0x" } + +// Copyright (C) 2013 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 <algorithm> +#include <vector> +#include <testsuite_hooks.h> + +void +test1() +{ + std::vector<bool> v; + v.push_back(false); + v.push_back(false); + v.push_back(true); + v.push_back(false); + VERIFY( std::find_if_not(v.begin(), v.end(), [](bool val){ return !val; }) + == v.begin() + 2 ); +} + +int +main() +{ + test1(); +} diff --git a/libstdc++-v3/testsuite/25_algorithms/heap/vectorbool.cc b/libstdc++-v3/testsuite/25_algorithms/heap/vectorbool.cc new file mode 100644 index 00000000000..7f2bc61e1a0 --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/heap/vectorbool.cc @@ -0,0 +1,146 @@ +// Copyright (C) 2013 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/>. + +// 25.3.6 Heap operations [lib.alg.heap.operations] + +#include <iterator> +#include <vector> +#include <algorithm> +#include <testsuite_hooks.h> + +const bool A[] = { true, true, false, true, false, false, true, false }; +const int B[] = { false, false, false, false, true, true, true, true }; +const int C[] = { true, true, true, true, false, false, false, false }; +const int N = sizeof(A) / sizeof(bool); + +// This functor has the equivalent functionality of std::greater<>, +// but there is no dependency on <functional> and it also tracks the +// number of invocations since creation. +class Gt +{ +public: + static int count() { return _S_count; } + static void reset() { _S_count = 0; } + + bool + operator()(bool x, bool y) const + { + ++_S_count; + return x > y; + } + +private: + static int _S_count; +}; + +int Gt::_S_count = 0; + +// Exercise all of the heap functions for operator<. The intermediate +// results between push_heap and pop_heap and make_heap and sort_heap +// are not checked (they could be). +void +test01() +{ + bool test __attribute__((unused)) = true; + + // sort array s1 using push_heap/pop_heap + std::vector<bool> s1; + std::copy(A, A + N, std::back_inserter(s1)); + VERIFY( std::equal(s1.begin(), s1.begin() + N, A) ); + + for (int i = 2; i <= N; ++i) + std::push_heap(s1.begin(), s1.begin() + i); + + for (int i = N; i >= 2; --i) + std::pop_heap(s1.begin(), s1.begin() + i); + + VERIFY( std::equal(s1.begin(), s1.begin() + N, B) ); + + // sort array s2 using make_heap/sort_heap + std::vector<bool> s2; + std::copy(A, A + N, std::back_inserter(s2)); + VERIFY( std::equal(s2.begin(), s2.begin() + N, A) ); + + std::make_heap(s2.begin(), s2.begin() + N); + std::sort_heap(s2.begin(), s2.begin() + N); + VERIFY( std::equal(s2.begin(), s2.begin() + N, B) ); +} + +// Perform same tests as above but with the comparison predicate +// versions, and add complexity constraint checks. +void +test02() +{ + bool test __attribute__((unused)) = true; + + Gt gt; + +#ifndef _GLIBCXX_DEBUG + //const int logN = static_cast<int>(std::log(static_cast<double>(N)) + 0.5); + const int logN = 3; +#endif + + std::vector<bool> s1; + std::copy(A, A + N, std::back_inserter(s1)); + VERIFY(std::equal(s1.begin(), s1.begin() + N, A)); + + for (int i = 2; i <= N; ++i) + { + std::push_heap(s1.begin(), s1.begin() + i, gt); +#ifndef _GLIBCXX_DEBUG + VERIFY(gt.count() <= logN); +#endif + gt.reset(); + } + + for (int i = N; i >= 2; --i) + { + std::pop_heap(s1.begin(), s1.begin() + i, gt); +#ifndef _GLIBCXX_DEBUG + VERIFY(gt.count() <= 2 * logN); +#endif + gt.reset(); + } + + VERIFY(std::equal(s1.begin(), s1.begin() + N, C)); + + // sort array s2 using make_heap/sort_heap + std::vector<bool> s2; + std::copy(A, A + N, std::back_inserter(s2)); + VERIFY(std::equal(s2.begin(), s2.begin() + N, A)); + + std::make_heap(s2.begin(), s2.begin() + N, gt); +#ifndef _GLIBCXX_DEBUG + VERIFY(gt.count() <= 3 * N); +#endif + gt.reset(); + + std::sort_heap(s2.begin(), s2.begin() + N, gt); +#ifndef _GLIBCXX_DEBUG + VERIFY(gt.count() <= N * logN); +#endif + + VERIFY(std::equal(s2.begin(), s2.begin() + N, C)); +} + +int +main() +{ + test01(); + test02(); + return 0; +} diff --git a/libstdc++-v3/testsuite/25_algorithms/is_permutation/vectorbool.cc b/libstdc++-v3/testsuite/25_algorithms/is_permutation/vectorbool.cc new file mode 100644 index 00000000000..be5b4ff531f --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/is_permutation/vectorbool.cc @@ -0,0 +1,50 @@ +// { dg-options "-std=gnu++1y" } + +// Copyright (C) 2013 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/>. + +// 25.2.12 [alg.is_permutation] Is permutation + +#include <vector> +#include <algorithm> +#include <testsuite_hooks.h> + +void test01() +{ + bool test __attribute__((unused)) = true; + + std::vector<bool> v1 = { true, false, true, false, true }; + std::vector<bool> v2 = { false, true, false, true, true }; + VERIFY( std::is_permutation(v1.begin(), v1.end(), v2.begin()) ); + VERIFY( !std::is_permutation(v1.begin() + 1, v1.end(), v2.begin() + 1) ); +} + +void test02() +{ + bool test __attribute__((unused)) = true; + + std::vector<bool> v1 = { true, false, true, false, true }; + std::vector<bool> v2 = { false, true, false, true, true }; + VERIFY( std::is_permutation(v1.begin(), v1.end(), v2.begin(), v2.end()) ); + VERIFY( !std::is_permutation(v1.begin(), v1.end() - 1, v2.begin(), v2.end()) ); +} + +int main() +{ + test01(); + test02(); +} diff --git a/libstdc++-v3/testsuite/25_algorithms/nth_element/58800.cc b/libstdc++-v3/testsuite/25_algorithms/nth_element/58800.cc new file mode 100644 index 00000000000..108c0e5abd1 --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/nth_element/58800.cc @@ -0,0 +1,52 @@ +// Copyright (C) 2013 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/>. + +// 25.3.2 [lib.alg.nth.element] + +// { dg-options "-std=gnu++11" } + +#include <algorithm> +#include <testsuite_hooks.h> +#include <testsuite_iterators.h> + +using __gnu_test::test_container; +using __gnu_test::random_access_iterator_wrapper; + +typedef test_container<int, random_access_iterator_wrapper> Container; + +void test01() +{ + std::vector<int> v = { + 207089, + 202585, + 180067, + 157549, + 211592, + 216096, + 207089 + }; + + Container con(v.data(), v.data() + 7); + + std::nth_element(con.begin(), con.begin() + 3, con.end()); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/26_numerics/valarray/subset_assignment.cc b/libstdc++-v3/testsuite/26_numerics/valarray/subset_assignment.cc index 6b598c461c7..ed339fd08b0 100644 --- a/libstdc++-v3/testsuite/26_numerics/valarray/subset_assignment.cc +++ b/libstdc++-v3/testsuite/26_numerics/valarray/subset_assignment.cc @@ -75,4 +75,4 @@ int main() VERIFY(check_array(val_g, ans4)); return 0; -}; +} diff --git a/libstdc++-v3/testsuite/27_io/ios_base/types/fmtflags/bitmask_operators.cc b/libstdc++-v3/testsuite/27_io/ios_base/types/fmtflags/bitmask_operators.cc index 3fd96493f2f..74c3f99490f 100644 --- a/libstdc++-v3/testsuite/27_io/ios_base/types/fmtflags/bitmask_operators.cc +++ b/libstdc++-v3/testsuite/27_io/ios_base/types/fmtflags/bitmask_operators.cc @@ -26,4 +26,4 @@ int main() { __gnu_test::bitmask_operators<std::ios_base::fmtflags>(); -}; +} diff --git a/libstdc++-v3/testsuite/27_io/ios_base/types/iostate/bitmask_operators.cc b/libstdc++-v3/testsuite/27_io/ios_base/types/iostate/bitmask_operators.cc index 3931db429e9..acfa45a8f62 100644 --- a/libstdc++-v3/testsuite/27_io/ios_base/types/iostate/bitmask_operators.cc +++ b/libstdc++-v3/testsuite/27_io/ios_base/types/iostate/bitmask_operators.cc @@ -26,4 +26,4 @@ int main() { __gnu_test::bitmask_operators<std::ios_base::iostate>(); -}; +} diff --git a/libstdc++-v3/testsuite/27_io/ios_base/types/openmode/bitmask_operators.cc b/libstdc++-v3/testsuite/27_io/ios_base/types/openmode/bitmask_operators.cc index cdb9b1b4055..c2e40bc06b5 100644 --- a/libstdc++-v3/testsuite/27_io/ios_base/types/openmode/bitmask_operators.cc +++ b/libstdc++-v3/testsuite/27_io/ios_base/types/openmode/bitmask_operators.cc @@ -26,4 +26,4 @@ int main() { __gnu_test::bitmask_operators<std::ios_base::openmode>(); -}; +} diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/awk/cstring_01.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/awk/cstring_01.cc index d4edf123e97..e2bde2216df 100644 --- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/awk/cstring_01.cc +++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/awk/cstring_01.cc @@ -25,7 +25,9 @@ #include <regex> #include <testsuite_hooks.h> +#include <testsuite_regex.h> +using namespace __gnu_test; using namespace std; void @@ -34,12 +36,12 @@ test01() bool test __attribute__((unused)) = true; regex("\\[", regex_constants::awk); - VERIFY(regex_match("\"", regex("[\\\"]", regex_constants::awk))); - VERIFY(regex_match("/", regex("/", regex_constants::awk))); - VERIFY(regex_match("\a", regex("\\a", regex_constants::awk))); - VERIFY(regex_match("\"", regex("\\\"", regex_constants::awk))); - VERIFY(regex_match("5", regex("\\65", regex_constants::awk))); - VERIFY(regex_match("53", regex("\\0653", regex_constants::awk))); + VERIFY(regex_match_debug("\"", regex("[\\\"]", regex_constants::awk))); + VERIFY(regex_match_debug("/", regex("/", regex_constants::awk))); + VERIFY(regex_match_debug("\a", regex("\\a", regex_constants::awk))); + VERIFY(regex_match_debug("\"", regex("\\\"", regex_constants::awk))); + VERIFY(regex_match_debug("5", regex("\\65", regex_constants::awk))); + VERIFY(regex_match_debug("53", regex("\\0653", regex_constants::awk))); } int diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/basic/empty_range.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/basic/empty_range.cc index eb22569f337..dd0dac4392f 100644 --- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/basic/empty_range.cc +++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/basic/empty_range.cc @@ -25,7 +25,9 @@ #include <regex> #include <testsuite_hooks.h> +#include <testsuite_regex.h> +using namespace __gnu_test; using namespace std; void @@ -45,8 +47,8 @@ test01() } FAIL("[]"); FAIL("[^]"); - VERIFY(regex_match("]", regex("[]]", regex_constants::basic))); - VERIFY(!regex_match("]", regex("[^]]", regex_constants::basic))); + VERIFY(regex_match_debug ("]", regex("[]]", regex_constants::basic))); + VERIFY(!regex_match_debug ("]", regex("[^]]", regex_constants::basic))); } int diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/basic/string_01.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/basic/string_01.cc index 668309d8cbf..34cfa557f01 100644 --- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/basic/string_01.cc +++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/basic/string_01.cc @@ -25,6 +25,10 @@ #include <regex> #include <testsuite_hooks.h> +#include <testsuite_regex.h> + +using namespace __gnu_test; +using namespace std; void test01() @@ -35,7 +39,7 @@ test01() std::string target("aaba"); std::smatch m; - VERIFY( std::regex_match(target, m, re) ); + VERIFY( regex_match_debug(target, m, re) ); VERIFY( m.size() == re.mark_count()+1 ); VERIFY( m.empty() == false ); diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/basic/string_range_00_03.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/basic/string_range_00_03.cc index 18783866f5e..36f032d7024 100644 --- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/basic/string_range_00_03.cc +++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/basic/string_range_00_03.cc @@ -25,6 +25,10 @@ #include <regex> #include <testsuite_hooks.h> +#include <testsuite_regex.h> + +using namespace __gnu_test; +using namespace std; void test01() @@ -35,7 +39,7 @@ test01() std::string target("aa"); std::smatch m; - VERIFY( std::regex_match(target, m, re) ); + VERIFY( regex_match_debug(target, m, re) ); VERIFY( m.size() == re.mark_count()+1 ); VERIFY( m.empty() == false ); diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/basic/string_range_01_03.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/basic/string_range_01_03.cc index 93826a78fb3..812e3efa4d3 100644 --- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/basic/string_range_01_03.cc +++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/basic/string_range_01_03.cc @@ -25,6 +25,10 @@ #include <regex> #include <testsuite_hooks.h> +#include <testsuite_regex.h> + +using namespace __gnu_test; +using namespace std; void test01() @@ -35,7 +39,7 @@ test01() std::string target("aa"); std::smatch m; - VERIFY( std::regex_match(target, m, re) ); + VERIFY( regex_match_debug(target, m, re) ); VERIFY( m.size() == re.mark_count()+1 ); VERIFY( m.empty() == false ); diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/basic/string_range_02_03.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/basic/string_range_02_03.cc index 91bc101392b..0924ed0014b 100644 --- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/basic/string_range_02_03.cc +++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/basic/string_range_02_03.cc @@ -25,6 +25,10 @@ #include <regex> #include <testsuite_hooks.h> +#include <testsuite_regex.h> + +using namespace __gnu_test; +using namespace std; void test01() @@ -35,7 +39,7 @@ test01() std::string target("aa"); std::smatch m; - VERIFY( std::regex_match(target, m, re) ); + VERIFY( regex_match_debug(target, m, re) ); VERIFY( m.size() == re.mark_count()+1 ); VERIFY( m.empty() == false ); diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/53622.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/53622.cc index aee1dbe15dc..5a762ab6eb4 100644 --- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/53622.cc +++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/53622.cc @@ -21,10 +21,13 @@ // <http://www.gnu.org/licenses/>. // 28.11.2 regex_match -// Tests Extended grouping against a std::string target. #include <regex> #include <testsuite_hooks.h> +#include <testsuite_regex.h> + +using namespace __gnu_test; +using namespace std; // libstdc++/53622 void @@ -33,11 +36,11 @@ test01() bool test __attribute__((unused)) = true; { - std::regex re("zxcv/(one.*)abc", std::regex::extended); + std::regex re("zxcv/(one.*)abc", std::regex::ECMAScript); std::string target("zxcv/onetwoabc"); std::smatch m; - VERIFY( std::regex_match(target, m, re) ); + VERIFY( regex_match_debug(target, m, re) ); VERIFY( m.size() == 2 ); VERIFY( m[0].matched == true ); VERIFY( std::string(m[0].first, m[0].second) == "zxcv/onetwoabc" ); @@ -46,11 +49,11 @@ test01() } { - std::regex re("zxcv/(one.*)abc()\\2", std::regex::extended); + std::regex re("zxcv/(one.*)abc()\\2", std::regex::ECMAScript); std::string target("zxcv/onetwoabc"); std::smatch m; - VERIFY( std::regex_match(target, m, re) ); + VERIFY( regex_match_debug(target, m, re) ); VERIFY( m.size() == 3 ); VERIFY( m[0].matched == true ); VERIFY( std::string(m[0].first, m[0].second) == "zxcv/onetwoabc" ); diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/57173.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/57173.cc index cb3a54f4d88..dc177e54274 100644 --- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/57173.cc +++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/57173.cc @@ -20,11 +20,14 @@ // with this library; see the file COPYING3. If not see // <http://www.gnu.org/licenses/>. -// 28.11.3 regex_search -// Tests Extended against a std::string target. +// 28.11.2 regex_match #include <regex> #include <testsuite_hooks.h> +#include <testsuite_regex.h> + +using namespace __gnu_test; +using namespace std; #include <iostream> // libstdc++/57173 @@ -34,20 +37,20 @@ test01() bool test __attribute__((unused)) = true; { - std::regex re("/asdf(/.*)", std::regex::extended); + std::regex re("/asdf(/.*)", std::regex::ECMAScript); std::string target("/asdf/qwerty"); std::smatch m; - VERIFY( std::regex_match(target, m, re) ); + VERIFY( regex_match_debug(target, m, re) ); VERIFY( m.size() == 2 ); VERIFY( std::string(m[1].first, m[1].second) == "/qwerty"); } { - std::regex re("/asdf(/.*)()\\2", std::regex::extended); + std::regex re("/asdf(/.*)()\\2", std::regex::ECMAScript); std::string target("/asdf/qwerty"); std::smatch m; - VERIFY( std::regex_match(target, m, re) ); + VERIFY( regex_match_debug(target, m, re) ); VERIFY( m.size() == 3 ); VERIFY( std::string(m[1].first, m[1].second) == "/qwerty"); } diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/58576.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/58576.cc new file mode 100644 index 00000000000..f745ef34e37 --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/58576.cc @@ -0,0 +1,100 @@ +// { dg-options "-std=gnu++11" } + +// +// 2013-10-01 Tim Shen <timshen91@gmail.com> +// +// Copyright (C) 2013 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/>. + +// 28.11.2 regex_match + +#include <regex> +#include <testsuite_hooks.h> +#include <testsuite_regex.h> + +using namespace __gnu_test; +using namespace std; + +// libstdc++/58576 +void +test01() +{ + bool test __attribute__((unused)) = true; + + string domain_name = "valid.hostname.org"; + /** + * based on http://stackoverflow.com/questions/1418423/the-hostname-regex + */ + regex fqdn_regex + ( + "^" + "(?=.{1,255}$)" + "[[:alnum:]]" + "(" + "(([[:alnum:]]|-)" + "{0,61})" + "[[:alnum:]]" + ")?" + "(" + "\\." + "[[:alnum:]]" + "(" + "(([[:alnum:]]|-)" + "{0,61})" + "[[:alnum:]]" + ")?" + ")*" + "\\.?" + "$" + ); + + smatch m; + const char* sol[] = + { + "valid.hostname.org", + "alid", + "ali", + "i", + ".org", + "rg", + "r", + "r", + }; + try + { + VERIFY(regex_match_debug( domain_name, m, fqdn_regex )); + VERIFY(m.size() == sizeof(sol) / sizeof(*sol)); + for (size_t i = 0; i < m.size(); i++) { + string s(m[i].first, m[i].second); + VERIFY(s == sol[i]); + } + } + catch ( const regex_error& ex ) + { + if ( ex.code() == regex_constants::error_brack ) + { + throw; + } + } +} + +int +main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/anymatcher.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/anymatcher.cc index 6e6095b8f24..866ff7fead8 100644 --- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/anymatcher.cc +++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/anymatcher.cc @@ -25,7 +25,9 @@ #include <regex> #include <testsuite_hooks.h> +#include <testsuite_regex.h> +using namespace __gnu_test; using namespace std; void @@ -37,7 +39,7 @@ test01() {\ regex re(res);\ string st(s);\ - VERIFY(!regex_match(st, re));\ + VERIFY(!regex_match_debug(st, re));\ } TEST(".", "\0"); TEST(".", "\n"); diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/backref.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/backref.cc index 321ce35a038..05a57725d04 100644 --- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/backref.cc +++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/backref.cc @@ -25,7 +25,9 @@ #include <regex> #include <testsuite_hooks.h> +#include <testsuite_regex.h> +using namespace __gnu_test; using namespace std; void diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/empty_range.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/empty_range.cc index 3c48d3521a5..9f09c7463e8 100644 --- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/empty_range.cc +++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/empty_range.cc @@ -25,7 +25,9 @@ #include <regex> #include <testsuite_hooks.h> +#include <testsuite_regex.h> +using namespace __gnu_test; using namespace std; void @@ -33,10 +35,10 @@ test01() { bool test __attribute__((unused)) = true; - VERIFY(!regex_match("x", regex("[]"))); - VERIFY(regex_match("x", regex("[^]"))); - VERIFY(!regex_match("]", regex("[]]"))); - VERIFY(!regex_match("]", regex("[^]]"))); + VERIFY(!regex_match_debug("x", regex("[]"))); + VERIFY(regex_match_debug("x", regex("[^]"))); + VERIFY(!regex_match_debug("]", regex("[]]"))); + VERIFY(!regex_match_debug("]", regex("[^]]"))); } int diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/emptygroup.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/emptygroup.cc index 1dc8f63f789..77fd43c0acb 100644 --- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/emptygroup.cc +++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/emptygroup.cc @@ -25,7 +25,9 @@ #include <regex> #include <testsuite_hooks.h> +#include <testsuite_regex.h> +using namespace __gnu_test; using namespace std; void @@ -37,7 +39,7 @@ test01() regex re("()*\\1"); cmatch m; const char s[] = ""; - VERIFY( regex_match(s, m, re) ); + VERIFY( regex_match_debug(s, m, re) ); VERIFY( m.size() == 2 ); VERIFY( m[0].matched ); VERIFY( m[1].matched ); @@ -46,7 +48,7 @@ test01() regex re("()*"); cmatch m; const char s[] = ""; - VERIFY( regex_match(s, m, re) ); + VERIFY( regex_match_debug(s, m, re) ); } } diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/hex.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/hex.cc index a73b742a5e4..b1030615ec3 100644 --- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/hex.cc +++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/hex.cc @@ -25,7 +25,9 @@ #include <regex> #include <testsuite_hooks.h> +#include <testsuite_regex.h> +using namespace __gnu_test; using namespace std; void @@ -33,7 +35,7 @@ test01() { bool test __attribute__((unused)) = true; - VERIFY(regex_match(":", regex("\\x3a"))); + VERIFY(regex_match_debug(":", regex("\\x3a"))); try { regex("\\u400x"); diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/quoted_char.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/quoted_char.cc index b54f5619a24..118c4722677 100644 --- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/quoted_char.cc +++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/quoted_char.cc @@ -25,7 +25,9 @@ #include <regex> #include <testsuite_hooks.h> +#include <testsuite_regex.h> +using namespace __gnu_test; using namespace std; void @@ -33,15 +35,15 @@ test01() { bool test __attribute__((unused)) = true; - VERIFY(regex_match("01", regex("\\d*"))); - VERIFY(regex_match("asdfjkl", regex("\\D*"))); - VERIFY(!regex_match("asdfjkl0", regex("\\D*"))); - VERIFY(regex_match("\r\t\v\f ", regex("\\s*"))); - VERIFY(regex_match("asdfjkl", regex("\\S*"))); - VERIFY(!regex_match("asdfjkl\r", regex("\\S*"))); - VERIFY(regex_match("_az", regex("\\w*"))); - VERIFY(regex_match("!@#$%", regex("\\W*"))); - VERIFY(!regex_match("_01234", regex("\\W*"))); + VERIFY(regex_match_debug("01", regex("\\d*"))); + VERIFY(regex_match_debug("asdfjkl", regex("\\D*"))); + VERIFY(!regex_match_debug("asdfjkl0", regex("\\D*"))); + VERIFY(regex_match_debug("\r\t\v\f ", regex("\\s*"))); + VERIFY(regex_match_debug("asdfjkl", regex("\\S*"))); + VERIFY(!regex_match_debug("asdfjkl\r", regex("\\S*"))); + VERIFY(regex_match_debug("_az", regex("\\w*"))); + VERIFY(regex_match_debug("!@#$%", regex("\\W*"))); + VERIFY(!regex_match_debug("_01234", regex("\\W*"))); } int diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/wchar_t/anymatcher.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/wchar_t/anymatcher.cc index c574908d6a9..323a2ff4ed6 100644 --- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/wchar_t/anymatcher.cc +++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/wchar_t/anymatcher.cc @@ -25,7 +25,9 @@ #include <regex> #include <testsuite_hooks.h> +#include <testsuite_regex.h> +using namespace __gnu_test; using namespace std; void @@ -37,7 +39,7 @@ test01() {\ wregex re(res);\ wstring st(s);\ - VERIFY(!regex_match(st, re));\ + VERIFY(!regex_match_debug(st, re));\ } TESTL(L".", L"\u2028"); TESTL(L".", L"\u2029"); diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/wchar_t/cjk_match.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/wchar_t/cjk_match.cc new file mode 100644 index 00000000000..15929ddc532 --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/wchar_t/cjk_match.cc @@ -0,0 +1,50 @@ +// { dg-options "-std=gnu++11" } + +// +// 2013-10-18 Tim Shen <timshen91@gmail.com> +// +// Copyright (C) 2013 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/>. + +// 28.11.2 regex_match +// Tests CJK support. + +#include <regex> +#include <testsuite_hooks.h> +#include <testsuite_regex.h> + +using namespace __gnu_test; +using namespace std; + +void +test01() +{ + bool test __attribute__((unused)) = true; + + const wchar_t * s = L"\u4f60\u597d\u002c\u0020\u4e16\u002b\u754c"; + + wregex re(s); + VERIFY(regex_match_debug(L"\u4f60\u597d\u002c\u0020\u4e16\u4e16\u4e16\u754c", + re)); +} + +int +main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/wchar_t/hex.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/wchar_t/hex.cc index f9561be70e2..876a7df1e2e 100644 --- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/wchar_t/hex.cc +++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/wchar_t/hex.cc @@ -25,7 +25,9 @@ #include <regex> #include <testsuite_hooks.h> +#include <testsuite_regex.h> +using namespace __gnu_test; using namespace std; void @@ -33,7 +35,7 @@ test01() { bool test __attribute__((unused)) = true; - VERIFY(regex_match(L"\u1234", wregex(L"\\u1234"))); + VERIFY(regex_match_debug(L"\u1234", wregex(L"\\u1234"))); } int diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/cstring_bracket_01.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/cstring_bracket_01.cc index 3a4ff31f104..c5f066bec81 100644 --- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/cstring_bracket_01.cc +++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/cstring_bracket_01.cc @@ -25,6 +25,10 @@ #include <regex> #include <testsuite_hooks.h> +#include <testsuite_regex.h> + +using namespace __gnu_test; +using namespace std; void test01() @@ -33,28 +37,33 @@ test01() { std::regex re("pre/[za-x]", std::regex::extended); - VERIFY( std::regex_match("pre/z", re) ); - VERIFY( std::regex_match("pre/a", re) ); - VERIFY( !std::regex_match("pre/y", re) ); + VERIFY( regex_match_debug("pre/z", re) ); + VERIFY( regex_match_debug("pre/a", re) ); + VERIFY( !regex_match_debug("pre/y", re) ); } { std::regex re("pre/[[:uPPer:]]", std::regex::extended); - VERIFY( std::regex_match("pre/Z", re) ); - VERIFY( !std::regex_match("pre/_", re) ); - VERIFY( !std::regex_match("pre/a", re) ); - VERIFY( !std::regex_match("pre/0", re) ); + VERIFY( regex_match_debug("pre/Z", re) ); + VERIFY( !regex_match_debug("pre/_", re) ); + VERIFY( !regex_match_debug("pre/a", re) ); + VERIFY( !regex_match_debug("pre/0", re) ); } { std::regex re("pre/[[:lOWer:]]", std::regex::extended | std::regex::icase); - VERIFY( std::regex_match("pre/Z", re) ); - VERIFY( std::regex_match("pre/a", re) ); + VERIFY( regex_match_debug("pre/Z", re) ); + VERIFY( regex_match_debug("pre/a", re) ); } { std::regex re("pre/[[:w:][.tilde.]]", std::regex::extended); - VERIFY( std::regex_match("pre/~", re) ); - VERIFY( std::regex_match("pre/_", re) ); - VERIFY( std::regex_match("pre/a", re) ); - VERIFY( std::regex_match("pre/0", re) ); + VERIFY( regex_match_debug("pre/~", re) ); + VERIFY( regex_match_debug("pre/_", re) ); + VERIFY( regex_match_debug("pre/a", re) ); + VERIFY( regex_match_debug("pre/0", re) ); + } + { + std::regex re("pre/[[=a=]]", std::regex::extended); + VERIFY( regex_match_debug("pre/a", re) ); + VERIFY( regex_match_debug("pre/A", re) ); } } diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/cstring_plus.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/cstring_plus.cc index 375f34b8064..32bc24f9982 100644 --- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/cstring_plus.cc +++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/cstring_plus.cc @@ -25,6 +25,10 @@ #include <regex> #include <testsuite_hooks.h> +#include <testsuite_regex.h> + +using namespace __gnu_test; +using namespace std; void test01() @@ -35,7 +39,7 @@ test01() const char target[] = "aa"; std::cmatch m; - VERIFY( std::regex_match(target, m, re) ); + VERIFY( regex_match_debug(target, m, re) ); VERIFY( re.mark_count() == 1 ); VERIFY( m.size() == re.mark_count()+1 ); @@ -53,9 +57,9 @@ test01() VERIFY( m[1].second == target+sizeof(target)-1 ); VERIFY( m[1].matched == true ); - VERIFY(!std::regex_match("", std::regex("a+", std::regex::extended))); - VERIFY(std::regex_match("a", std::regex("a+", std::regex::extended))); - VERIFY(std::regex_match("aa", std::regex("a+", std::regex::extended))); + VERIFY(!regex_match_debug("", std::regex("a+", std::regex::extended))); + VERIFY(regex_match_debug("a", std::regex("a+", std::regex::extended))); + VERIFY(regex_match_debug("aa", std::regex("a+", std::regex::extended))); } diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/cstring_questionmark.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/cstring_questionmark.cc index 79b52a88c4f..90e9eafae60 100644 --- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/cstring_questionmark.cc +++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/cstring_questionmark.cc @@ -25,6 +25,10 @@ #include <regex> #include <testsuite_hooks.h> +#include <testsuite_regex.h> + +using namespace __gnu_test; +using namespace std; void test01() @@ -35,7 +39,7 @@ test01() char target[] = "a"; std::cmatch m; - VERIFY( std::regex_match(target, m, re) ); + VERIFY( regex_match_debug(target, m, re) ); VERIFY( re.mark_count() == 1 ); VERIFY( m.size() == re.mark_count()+1 ); @@ -53,9 +57,9 @@ test01() VERIFY( m[1].second == target+sizeof(target)-1 ); VERIFY( m[1].matched == true ); - VERIFY(std::regex_match("", std::regex("a?", std::regex::extended))); - VERIFY(std::regex_match("a", std::regex("a?", std::regex::extended))); - VERIFY(!std::regex_match("aa", std::regex("a?", std::regex::extended))); + VERIFY(regex_match_debug("", std::regex("a?", std::regex::extended))); + VERIFY(regex_match_debug("a", std::regex("a?", std::regex::extended))); + VERIFY(!regex_match_debug("aa", std::regex("a?", std::regex::extended))); } diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/cstring_range.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/cstring_range.cc index 62f825a0fb9..f9f7b6af1fd 100644 --- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/cstring_range.cc +++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/cstring_range.cc @@ -25,7 +25,9 @@ #include <regex> #include <testsuite_hooks.h> +#include <testsuite_regex.h> +using namespace __gnu_test; using namespace std; void @@ -35,29 +37,29 @@ test01() regex re; re.assign("(ab){3}", std::regex::extended); - VERIFY(!regex_match("abab", re)); - VERIFY(regex_match("ababab", re)); - VERIFY(!regex_match("abababab", re)); + VERIFY(!regex_match_debug("abab", re)); + VERIFY(regex_match_debug("ababab", re)); + VERIFY(!regex_match_debug("abababab", re)); re.assign("(ab){3,}", std::regex::extended); - VERIFY(!regex_match("abab", re)); - VERIFY(regex_match("ababab", re)); - VERIFY(regex_match("abababab", re)); - VERIFY(regex_match("ababababab", re)); + VERIFY(!regex_match_debug("abab", re)); + VERIFY(regex_match_debug("ababab", re)); + VERIFY(regex_match_debug("abababab", re)); + VERIFY(regex_match_debug("ababababab", re)); re.assign("(ab){0,3}", std::regex::extended); - VERIFY(regex_match("", re)); - VERIFY(regex_match("ab", re)); - VERIFY(regex_match("abab", re)); - VERIFY(regex_match("ababab", re)); - VERIFY(!regex_match("abababab", re)); + VERIFY(regex_match_debug("", re)); + VERIFY(regex_match_debug("ab", re)); + VERIFY(regex_match_debug("abab", re)); + VERIFY(regex_match_debug("ababab", re)); + VERIFY(!regex_match_debug("abababab", re)); re.assign("(a|b){0,2}", std::regex::extended); - VERIFY(regex_match("", re)); - VERIFY(regex_match("a", re)); - VERIFY(regex_match("b", re)); - VERIFY(regex_match("aa", re)); - VERIFY(regex_match("ab", re)); - VERIFY(regex_match("ba", re)); - VERIFY(regex_match("bb", re)); - VERIFY(!regex_match("aaa", re)); + VERIFY(regex_match_debug("", re)); + VERIFY(regex_match_debug("a", re)); + VERIFY(regex_match_debug("b", re)); + VERIFY(regex_match_debug("aa", re)); + VERIFY(regex_match_debug("ab", re)); + VERIFY(regex_match_debug("ba", re)); + VERIFY(regex_match_debug("bb", re)); + VERIFY(!regex_match_debug("aaa", re)); } int diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/string_any.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/string_any.cc index 57628f13215..cd870396781 100644 --- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/string_any.cc +++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/string_any.cc @@ -25,6 +25,10 @@ #include <regex> #include <testsuite_hooks.h> +#include <testsuite_regex.h> + +using namespace __gnu_test; +using namespace std; void test01() @@ -35,7 +39,7 @@ test01() std::string target("aaba"); std::smatch m; - VERIFY( std::regex_match(target, m, re) ); + VERIFY( regex_match_debug(target, m, re) ); VERIFY( m.size() == re.mark_count()+1 ); VERIFY( m.empty() == false ); diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/string_dispatch_01.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/string_dispatch_01.cc index cb502eadfb4..50141f0037d 100644 --- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/string_dispatch_01.cc +++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/string_dispatch_01.cc @@ -38,9 +38,12 @@ template<typename _Bi_iter, typename _Alloc, regex_constants::match_flag_type __flags = regex_constants::match_default) { + using namespace __detail; + auto& __res = (vector<sub_match<_Bi_iter>, _Alloc>&)(__m); VERIFY( (dynamic_cast - <__detail::_DFSExecutor<_Bi_iter, _Alloc, _Ch_type, _Rx_traits>*> - (&*__detail::__get_executor(__s, __e, __m, __re, __flags)) + <_DFSExecutor<_Bi_iter, _Alloc, _Ch_type, _Rx_traits>*> + (&*__get_executor<_Bi_iter, _Alloc, _Ch_type, _Rx_traits, + _RegexExecutorPolicy::_S_auto>(__s, __e, __res, __re, __flags)) != nullptr) ); } diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/string_range_00_03.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/string_range_00_03.cc index e10dba81ffa..e483b0abb9d 100644 --- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/string_range_00_03.cc +++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/string_range_00_03.cc @@ -25,6 +25,9 @@ #include <regex> #include <testsuite_hooks.h> +#include <testsuite_regex.h> + +using namespace __gnu_test; void test01() @@ -35,7 +38,7 @@ test01() std::string target("aa"); std::smatch m; - VERIFY( std::regex_match(target, m, re) ); + VERIFY( regex_match_debug(target, m, re) ); VERIFY( m.size() == re.mark_count()+1 ); VERIFY( m.empty() == false ); diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/string_range_01_03.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/string_range_01_03.cc index e715290c242..3879fc418aa 100644 --- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/string_range_01_03.cc +++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/string_range_01_03.cc @@ -25,6 +25,10 @@ #include <regex> #include <testsuite_hooks.h> +#include <testsuite_regex.h> + +using namespace __gnu_test; +using namespace std; void test01() @@ -35,7 +39,7 @@ test01() std::string target("aa"); std::smatch m; - VERIFY( std::regex_match(target, m, re) ); + VERIFY( regex_match_debug(target, m, re) ); VERIFY( m.size() == re.mark_count()+1 ); VERIFY( m.empty() == false ); diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/string_range_02_03.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/string_range_02_03.cc index 62793b4a199..c2ebdf8b143 100644 --- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/string_range_02_03.cc +++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/string_range_02_03.cc @@ -25,6 +25,10 @@ #include <regex> #include <testsuite_hooks.h> +#include <testsuite_regex.h> + +using namespace __gnu_test; +using namespace std; void test01() @@ -35,7 +39,7 @@ test01() std::string target("aa"); std::smatch m; - VERIFY( std::regex_match(target, m, re) ); + VERIFY( regex_match_debug(target, m, re) ); VERIFY( m.size() == re.mark_count()+1 ); VERIFY( m.empty() == false ); diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/wstring_locale.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/wstring_locale.cc index 6ab48ca6baf..ba0ecd5b4c4 100644 --- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/wstring_locale.cc +++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/wstring_locale.cc @@ -26,6 +26,10 @@ #include <regex> #include <testsuite_hooks.h> +#include <testsuite_regex.h> + +using namespace __gnu_test; +using namespace std; void test01() @@ -37,7 +41,7 @@ test01() re2.imbue(std::locale("de_DE.UTF-8")); re2.assign(L"[[:upper:]]*", std::regex::extended); std::wsmatch m2; - VERIFY(std::regex_match(str2, m2, re2)); + VERIFY(regex_match_debug(str2, m2, re2)); } int diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_replace/char/basic_replace.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_replace/char/basic_replace.cc new file mode 100644 index 00000000000..ca3f16f7d23 --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_replace/char/basic_replace.cc @@ -0,0 +1,51 @@ +// { dg-options "-std=gnu++11" } + +// +// 2013-09-24 Tim Shen <timshen91@gmail.com> +// +// Copyright (C) 2013 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/>. + +// 28.11.4 regex_replace +// Tests ECMAScript regex_replace. + +#include <regex> +#include <testsuite_hooks.h> + +using namespace std; + +void +test01() +{ + bool test __attribute__((unused)) = true; + + VERIFY(regex_replace(string("This is a string"), regex("\\b\\w*\\b"), "|$0|") + == "|This||| |is||| |a||| |string|||"); + VERIFY(regex_replace(string("This is a string"), regex("\\b\\w*\\b"), "|$0|", + regex_constants::format_no_copy) + == "|This||||is||||a||||string|||"); + VERIFY(regex_replace(string("This is a string"), regex("\\b\\w*\\b"), "|$0|", + regex_constants::format_first_only) + == "|This| is a string"); +} + +int +main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_search/basic/string_01.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_search/basic/string_01.cc index ee487f19836..fed8e7dd17f 100644 --- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_search/basic/string_01.cc +++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_search/basic/string_01.cc @@ -25,6 +25,10 @@ #include <regex> #include <testsuite_hooks.h> +#include <testsuite_regex.h> + +using namespace __gnu_test; +using namespace std; void test01() @@ -35,7 +39,7 @@ test01() std::string target("xxasdfyy"); std::smatch m; - VERIFY( std::regex_search(target, m, re) ); + VERIFY( regex_search_debug(target, m, re) ); VERIFY( m.size() == re.mark_count()+1 ); VERIFY( m.empty() == false ); diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_search/ecma/assertion.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_search/ecma/assertion.cc index 3064b3b26e4..f7bce8023d3 100644 --- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_search/ecma/assertion.cc +++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_search/ecma/assertion.cc @@ -25,7 +25,9 @@ #include <regex> #include <testsuite_hooks.h> +#include <testsuite_regex.h> +using namespace __gnu_test; using namespace std; void @@ -33,21 +35,21 @@ test01() { bool test __attribute__((unused)) = true; - VERIFY(!regex_search("2123456", regex("^1234"))); - VERIFY(regex_search("123456", regex("^1234"))); - VERIFY(regex_search("123456", regex("(5|^)1234"))); - VERIFY(regex_search("5123456", regex("(5|^)1234"))); - VERIFY(!regex_search("1234562", regex("3456$"))); - VERIFY(regex_search("123456", regex("3456$"))); - VERIFY(!regex_search("123456", regex("(?=1234)56"))); - VERIFY(regex_search("123456", regex("(?=1234)123456"))); - VERIFY(regex_search("123456", regex("(?!1234)56"))); - VERIFY(!regex_search("123456", regex("(?!1234)123456"))); + VERIFY(!regex_search_debug("2123456", regex("^1234"))); + VERIFY(regex_search_debug("123456", regex("^1234"))); + VERIFY(regex_search_debug("123456", regex("(5|^)1234"))); + VERIFY(regex_search_debug("5123456", regex("(5|^)1234"))); + VERIFY(!regex_search_debug("1234562", regex("3456$"))); + VERIFY(regex_search_debug("123456", regex("3456$"))); + VERIFY(!regex_search_debug("123456", regex("(?=1234)56"))); + VERIFY(regex_search_debug("123456", regex("(?=1234)123456"))); + VERIFY(regex_search_debug("123456", regex("(?!1234)56"))); + VERIFY(!regex_search_debug("123456", regex("(?!1234)123456"))); - VERIFY(regex_search("a-", regex("a\\b-"))); - VERIFY(!regex_search("ab", regex("a\\bb"))); - VERIFY(!regex_search("a-", regex("a\\B-"))); - VERIFY(regex_search("ab", regex("a\\Bb"))); + VERIFY(regex_search_debug("a-", regex("a\\b-"))); + VERIFY(!regex_search_debug("ab", regex("a\\bb"))); + VERIFY(!regex_search_debug("a-", regex("a\\B-"))); + VERIFY(regex_search_debug("ab", regex("a\\Bb"))); string s("This is a regular expression"); string sol[] = diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_search/ecma/flags.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_search/ecma/flags.cc index 4be406cb072..490ab1c9159 100644 --- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_search/ecma/flags.cc +++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_search/ecma/flags.cc @@ -25,7 +25,9 @@ #include <regex> #include <testsuite_hooks.h> +#include <testsuite_regex.h> +using namespace __gnu_test; using namespace std; void @@ -35,32 +37,34 @@ test01() cmatch m; regex re("((as)(df))", regex_constants::ECMAScript | regex_constants::nosubs); - VERIFY(regex_search("asdf", m, re)); + VERIFY(regex_search_debug("asdf", m, re)); VERIFY(m.size() == 1); VERIFY(m[0].matched && string(m[0].first, m[0].second) == "asdf"); - VERIFY( regex_search("a", regex("^a"))); - VERIFY(!regex_search("a", regex("^a"), regex_constants::match_not_bol)); - VERIFY( regex_search("a", regex("a$"))); - VERIFY(!regex_search("a", regex("a$"), regex_constants::match_not_eol)); - VERIFY( regex_search("a", regex("\\ba"))); - VERIFY(!regex_search("a", regex("\\ba"), regex_constants::match_not_bow)); - VERIFY( regex_search("a", regex("a\\b"))); - VERIFY(!regex_search("a", regex("a\\b"), regex_constants::match_not_eow)); - VERIFY( regex_search("", regex(""))); - VERIFY(!regex_search("", regex(""), regex_constants::match_not_null)); - VERIFY( regex_search("", regex("^$"))); - VERIFY(!regex_search("", regex("^$"), regex_constants::match_not_null)); - VERIFY( regex_search("aaa", m, regex("a*?"), - regex_constants::match_not_null)); + VERIFY( regex_search_debug("a", regex("^a"))); + VERIFY(!regex_search_debug("a", regex("^a"), regex_constants::match_not_bol)); + VERIFY( regex_search_debug("a", regex("a$"))); + VERIFY(!regex_search_debug("a", regex("a$"), regex_constants::match_not_eol)); + VERIFY( regex_search_debug("a", regex("\\ba"))); + VERIFY(!regex_search_debug("a", regex("\\ba"), + regex_constants::match_not_bow)); + VERIFY( regex_search_debug("a", regex("a\\b"))); + VERIFY(!regex_search_debug("a", regex("a\\b"), + regex_constants::match_not_eow)); + VERIFY( regex_search_debug("", regex(""))); + VERIFY(!regex_search_debug("", regex(""), regex_constants::match_not_null)); + VERIFY( regex_search_debug("", regex("^$"))); + VERIFY(!regex_search_debug("", regex("^$"), regex_constants::match_not_null)); + VERIFY( regex_search_debug("aaa", m, regex("a*?"), + regex_constants::match_not_null)); VERIFY(m[0].matched && string(m[0].first, m[0].second) == "a"); - VERIFY( regex_search("asdf", regex("sdf"))); - VERIFY(!regex_search("asdf", regex("sdf"), - regex_constants::match_continuous)); - VERIFY( regex_search(" a"+1, regex("\\ba"), - regex_constants::match_prev_avail)); - VERIFY( regex_search("ba"+1, regex("\\Ba"), - regex_constants::match_prev_avail)); + VERIFY( regex_search_debug("asdf", regex("sdf"))); + VERIFY(!regex_search_debug("asdf", regex("sdf"), + regex_constants::match_continuous)); + VERIFY( regex_search_debug(" a"+1, regex("\\ba"), + regex_constants::match_prev_avail)); + VERIFY( regex_search_debug("ba"+1, regex("\\Ba"), + regex_constants::match_prev_avail)); } int diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_search/ecma/greedy.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_search/ecma/greedy.cc index ad37ec8649a..107ced0edc8 100644 --- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_search/ecma/greedy.cc +++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_search/ecma/greedy.cc @@ -25,7 +25,9 @@ #include <regex> #include <testsuite_hooks.h> +#include <testsuite_regex.h> +using namespace __gnu_test; using namespace std; void @@ -35,30 +37,30 @@ test01() cmatch m; #define TEST(i, s) VERIFY(m[i].matched && string(m[i].first, m[i].second) == s) - VERIFY(regex_search("aaaa", m, regex("a*"))); + VERIFY(regex_search_debug("aaaa", m, regex("a*"))); TEST(0, "aaaa"); - VERIFY(regex_search("aaaa", m, regex("a*?"))); + VERIFY(regex_search_debug("aaaa", m, regex("a*?"))); TEST(0, ""); - VERIFY(regex_search("aaaa", m, regex("a+"))); + VERIFY(regex_search_debug("aaaa", m, regex("a+"))); TEST(0, "aaaa"); - VERIFY(regex_search("aaaa", m, regex("a+?"))); + VERIFY(regex_search_debug("aaaa", m, regex("a+?"))); TEST(0, "a"); - VERIFY(regex_search("a", m, regex("a?"))); + VERIFY(regex_search_debug("a", m, regex("a?"))); TEST(0, "a"); - VERIFY(regex_search("a", m, regex("a??"))); + VERIFY(regex_search_debug("a", m, regex("a??"))); TEST(0, ""); - VERIFY(regex_search("", m, regex("a??"))); + VERIFY(regex_search_debug("", m, regex("a??"))); TEST(0, ""); - VERIFY(regex_search("aaaa", m, regex("(a+)(a+)"))); + VERIFY(regex_search_debug("aaaa", m, regex("(a+)(a+)"))); TEST(1, "aaa"); TEST(2, "a"); - VERIFY(regex_search("aaaa", m, regex("(a+?)(a+)"))); + VERIFY(regex_search_debug("aaaa", m, regex("(a+?)(a+)"))); TEST(1, "a"); TEST(2, "aaa"); - VERIFY(regex_search("aaaa", m, regex("(a+?)(a+)"))); + VERIFY(regex_search_debug("aaaa", m, regex("(a+?)(a+)"))); TEST(1, "a"); TEST(2, "aaa"); - VERIFY(regex_search("aaaa", m, regex("(a+?)(a+?)"))); + VERIFY(regex_search_debug("aaaa", m, regex("(a+?)(a+?)"))); TEST(1, "a"); TEST(2, "a"); } diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_search/ecma/string_01.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_search/ecma/string_01.cc index ec25875fdee..c07e7efa7d4 100644 --- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_search/ecma/string_01.cc +++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_search/ecma/string_01.cc @@ -25,13 +25,17 @@ #include <regex> #include <testsuite_hooks.h> +#include <testsuite_regex.h> + +using namespace __gnu_test; +using namespace std; void test01() { bool test __attribute__((unused)) = true; - VERIFY(std::regex_search("", std::regex(""))); + VERIFY(regex_search_debug("", std::regex(""))); } int diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/assign/char/cstring.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/assign/char/cstring.cc index 1b6c5327c4d..7340e7e45eb 100644 --- a/libstdc++-v3/testsuite/28_regex/basic_regex/assign/char/cstring.cc +++ b/libstdc++-v3/testsuite/28_regex/basic_regex/assign/char/cstring.cc @@ -41,4 +41,4 @@ main() { test01(); return 0; -}; +} diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/assign/char/cstring_op.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/assign/char/cstring_op.cc index e7dfe8d3302..a28e95e8f83 100644 --- a/libstdc++-v3/testsuite/28_regex/basic_regex/assign/char/cstring_op.cc +++ b/libstdc++-v3/testsuite/28_regex/basic_regex/assign/char/cstring_op.cc @@ -40,4 +40,4 @@ main() { test01(); return 0; -}; +} diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/assign/char/moveable.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/assign/char/moveable.cc index 18b3d5ef607..0897a0c28fc 100644 --- a/libstdc++-v3/testsuite/28_regex/basic_regex/assign/char/moveable.cc +++ b/libstdc++-v3/testsuite/28_regex/basic_regex/assign/char/moveable.cc @@ -30,16 +30,16 @@ void test01() { bool test __attribute__((unused)) = true; - std::regex src_re("aaba"); + std::regex src_re("aaba"); const unsigned mark_count = src_re.mark_count(); - const std::regex::flag_type flags = src_re.flags(); + const std::regex::flag_type flags = src_re.flags(); - std::regex target_re; + std::regex target_re; target_re.assign(std::move(src_re)); - VERIFY( target_re.flags() == flags ); - VERIFY( target_re.mark_count() == mark_count ); + VERIFY( target_re.flags() == flags ); + VERIFY( target_re.mark_count() == mark_count ); } int @@ -47,4 +47,4 @@ main() { test01(); return 0; -}; +} diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/assign/char/pstring.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/assign/char/pstring.cc index f5c6ff2a1ab..63f93c2dd3b 100644 --- a/libstdc++-v3/testsuite/28_regex/basic_regex/assign/char/pstring.cc +++ b/libstdc++-v3/testsuite/28_regex/basic_regex/assign/char/pstring.cc @@ -40,4 +40,4 @@ main() { test01(); return 0; -}; +} diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/assign/char/range.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/assign/char/range.cc index f871ff1111b..c08ac06d560 100644 --- a/libstdc++-v3/testsuite/28_regex/basic_regex/assign/char/range.cc +++ b/libstdc++-v3/testsuite/28_regex/basic_regex/assign/char/range.cc @@ -40,4 +40,4 @@ main() { test01(); return 0; -}; +} diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/assign/char/string.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/assign/char/string.cc index 2f75c7b6254..ed3fcdf7327 100644 --- a/libstdc++-v3/testsuite/28_regex/basic_regex/assign/char/string.cc +++ b/libstdc++-v3/testsuite/28_regex/basic_regex/assign/char/string.cc @@ -41,4 +41,4 @@ main() { test01(); return 0; -}; +} diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/assign/char/string_op.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/assign/char/string_op.cc index 752cf485363..a975761201f 100644 --- a/libstdc++-v3/testsuite/28_regex/basic_regex/assign/char/string_op.cc +++ b/libstdc++-v3/testsuite/28_regex/basic_regex/assign/char/string_op.cc @@ -41,4 +41,4 @@ main() { test01(); return 0; -}; +} diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/assign/wchar_t/cstring.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/assign/wchar_t/cstring.cc index 00db1f33499..8ce2b3bd111 100644 --- a/libstdc++-v3/testsuite/28_regex/basic_regex/assign/wchar_t/cstring.cc +++ b/libstdc++-v3/testsuite/28_regex/basic_regex/assign/wchar_t/cstring.cc @@ -41,4 +41,4 @@ main() { test01(); return 0; -}; +} diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/assign/wchar_t/cstring_op.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/assign/wchar_t/cstring_op.cc index 3da1a10fb4a..415cbb6b884 100644 --- a/libstdc++-v3/testsuite/28_regex/basic_regex/assign/wchar_t/cstring_op.cc +++ b/libstdc++-v3/testsuite/28_regex/basic_regex/assign/wchar_t/cstring_op.cc @@ -41,4 +41,4 @@ main() { test01(); return 0; -}; +} diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/assign/wchar_t/pstring.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/assign/wchar_t/pstring.cc index 4664166d2f5..aaf69c6456d 100644 --- a/libstdc++-v3/testsuite/28_regex/basic_regex/assign/wchar_t/pstring.cc +++ b/libstdc++-v3/testsuite/28_regex/basic_regex/assign/wchar_t/pstring.cc @@ -40,4 +40,4 @@ main() { test01(); return 0; -}; +} diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/assign/wchar_t/range.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/assign/wchar_t/range.cc index 8f65898427b..f52e675ab56 100644 --- a/libstdc++-v3/testsuite/28_regex/basic_regex/assign/wchar_t/range.cc +++ b/libstdc++-v3/testsuite/28_regex/basic_regex/assign/wchar_t/range.cc @@ -41,4 +41,4 @@ main() { test01(); return 0; -}; +} diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/assign/wchar_t/string.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/assign/wchar_t/string.cc index d3c0f2daf31..1a9801ff7af 100644 --- a/libstdc++-v3/testsuite/28_regex/basic_regex/assign/wchar_t/string.cc +++ b/libstdc++-v3/testsuite/28_regex/basic_regex/assign/wchar_t/string.cc @@ -42,4 +42,4 @@ main() { test01(); return 0; -}; +} diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/assign/wchar_t/string_op.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/assign/wchar_t/string_op.cc index c3e88b3f594..38645660acd 100644 --- a/libstdc++-v3/testsuite/28_regex/basic_regex/assign/wchar_t/string_op.cc +++ b/libstdc++-v3/testsuite/28_regex/basic_regex/assign/wchar_t/string_op.cc @@ -42,4 +42,4 @@ main() { test01(); return 0; -}; +} diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/47724.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/47724.cc index cf25dd44a9c..12ab1bbc9ab 100644 --- a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/47724.cc +++ b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/47724.cc @@ -31,4 +31,4 @@ main() { test01(); return 0; -}; +} diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/basic/pstring_char.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/basic/pstring_char.cc index 255f5bf5170..db5ae80b53a 100644 --- a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/basic/pstring_char.cc +++ b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/basic/pstring_char.cc @@ -39,4 +39,4 @@ main() { test01(); return 0; -}; +} diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/basic/pstring_wchar_t.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/basic/pstring_wchar_t.cc index 7cf48068914..c0cc841b94f 100644 --- a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/basic/pstring_wchar_t.cc +++ b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/basic/pstring_wchar_t.cc @@ -41,4 +41,4 @@ main() { test01(); return 0; -}; +} diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/basic/raw_string.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/basic/raw_string.cc index 68fd56af760..d005dc040eb 100644 --- a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/basic/raw_string.cc +++ b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/basic/raw_string.cc @@ -1,5 +1,4 @@ -// { dg-options "-std=c++0x" } -// { dg-do run { xfail *-*-* } } +// { dg-options "-std=gnu++11" } // 2012-08-20 Benjamin Kosnik <bkoz@redhat.com> // diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/char/cstring.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/char/cstring.cc index a081ecbcf42..cda2ad2da44 100644 --- a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/char/cstring.cc +++ b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/char/cstring.cc @@ -39,4 +39,4 @@ main() { test01(); return 0; -}; +} diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/char/default.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/char/default.cc index aa8d70c57db..ed31f38e55e 100644 --- a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/char/default.cc +++ b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/char/default.cc @@ -44,4 +44,4 @@ main() { test01(); return 0; -}; +} diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/char/range.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/char/range.cc index b26151e41d1..63d32bc3a02 100644 --- a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/char/range.cc +++ b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/char/range.cc @@ -39,4 +39,4 @@ main() { test01(); return 0; -}; +} diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/copy_char.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/copy_char.cc index c51bfa0c95a..228c7fd8941 100644 --- a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/copy_char.cc +++ b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/copy_char.cc @@ -42,4 +42,4 @@ main() { test01(); return 0; -}; +} diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/move_char.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/move_char.cc index 3234f565be1..1311987e92f 100644 --- a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/move_char.cc +++ b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/move_char.cc @@ -46,4 +46,4 @@ main() { test01(); return 0; -}; +} diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/string_char.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/string_char.cc index 50d64dbb6e5..88411e579f6 100644 --- a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/string_char.cc +++ b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/string_char.cc @@ -51,4 +51,4 @@ main() test01(); test02(); return 0; -}; +} diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/string_wchar_t.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/string_wchar_t.cc index ffc9ba93c4d..c0d3b23fd95 100644 --- a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/string_wchar_t.cc +++ b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/string_wchar_t.cc @@ -53,4 +53,4 @@ main() test01(); test02(); return 0; -}; +} diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/wchar_t/cstring.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/wchar_t/cstring.cc index a8f1879aab5..ad79c097b64 100644 --- a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/wchar_t/cstring.cc +++ b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/wchar_t/cstring.cc @@ -40,4 +40,4 @@ main() { test01(); return 0; -}; +} diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/wchar_t/default.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/wchar_t/default.cc index 6b99b1d9beb..c2e3cc56a39 100644 --- a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/wchar_t/default.cc +++ b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/wchar_t/default.cc @@ -45,4 +45,4 @@ main() { test01(); return 0; -}; +} diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/wchar_t/range.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/wchar_t/range.cc index cf8217a9a6f..a0a680c823e 100644 --- a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/wchar_t/range.cc +++ b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/wchar_t/range.cc @@ -40,4 +40,4 @@ main() { test01(); return 0; -}; +} diff --git a/libstdc++-v3/testsuite/28_regex/match_results/format.cc b/libstdc++-v3/testsuite/28_regex/match_results/format.cc new file mode 100644 index 00000000000..659ffdcb13b --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/match_results/format.cc @@ -0,0 +1,53 @@ +// { dg-options "-std=gnu++11" } + +// +// 2013-09-24 Tim Shen <timshen91@gmail.com> +// +// Copyright (C) 2013 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/>. + +// 28.10.5 formatting +// Tests ECMAScript format() + +#include <regex> +#include <testsuite_hooks.h> +#include <testsuite_regex.h> + +using namespace std; +using namespace __gnu_test; + +void +test01() +{ + bool test __attribute__((unused)) = true; + + cmatch m; + VERIFY(regex_search_debug("*** this is a string !!!", m, + regex("(\\w+) (\\w+) (\\w+) (\\w+)"))); + VERIFY(m.format("$&|$`|$3|$4|$2|$1|$'$$$") + == "this is a string|*** |a|string|is|this| !!!$$"); + VERIFY(m.format("&|\\3|\\4|\\2|\\1|\\", + regex_constants::format_sed) + == "this is a string|a|string|is|this|\\"); +} + +int +main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/28_regex/traits/char/ctor.cc b/libstdc++-v3/testsuite/28_regex/traits/char/ctor.cc index b41e59ac5ff..e3ee30cdfa6 100644 --- a/libstdc++-v3/testsuite/28_regex/traits/char/ctor.cc +++ b/libstdc++-v3/testsuite/28_regex/traits/char/ctor.cc @@ -47,4 +47,4 @@ main() { test01(); return 0; -}; +} diff --git a/libstdc++-v3/testsuite/28_regex/traits/char/lookup_collatename.cc b/libstdc++-v3/testsuite/28_regex/traits/char/lookup_collatename.cc index 7e0b259e0b7..dba0fc357e5 100644 --- a/libstdc++-v3/testsuite/28_regex/traits/char/lookup_collatename.cc +++ b/libstdc++-v3/testsuite/28_regex/traits/char/lookup_collatename.cc @@ -35,12 +35,9 @@ test01() typedef char CharT; typedef std::regex_traits<CharT> traits; - char name[] = "ll"; - traits t; - - traits::string_type sname = t.lookup_collatename(name, name+sizeof(name)-1); - - VERIFY( !sname.empty() ); + traits t; + CharT name[] = "tilde"; + VERIFY(t.lookup_collatename(name, name+sizeof(name)-1) == "~"); } int main() diff --git a/libstdc++-v3/testsuite/28_regex/traits/char/translate_nocase.cc b/libstdc++-v3/testsuite/28_regex/traits/char/translate_nocase.cc index c805aa91e68..02e2eaefe44 100644 --- a/libstdc++-v3/testsuite/28_regex/traits/char/translate_nocase.cc +++ b/libstdc++-v3/testsuite/28_regex/traits/char/translate_nocase.cc @@ -43,4 +43,4 @@ main() { test01(); return 0; -}; +} diff --git a/libstdc++-v3/testsuite/28_regex/traits/char/value.cc b/libstdc++-v3/testsuite/28_regex/traits/char/value.cc index e68dac64e03..de0b2694121 100644 --- a/libstdc++-v3/testsuite/28_regex/traits/char/value.cc +++ b/libstdc++-v3/testsuite/28_regex/traits/char/value.cc @@ -46,4 +46,4 @@ main() { test01(); return 0; -}; +} diff --git a/libstdc++-v3/testsuite/28_regex/traits/wchar_t/ctor.cc b/libstdc++-v3/testsuite/28_regex/traits/wchar_t/ctor.cc index f2d487eb6a9..54931d01b83 100644 --- a/libstdc++-v3/testsuite/28_regex/traits/wchar_t/ctor.cc +++ b/libstdc++-v3/testsuite/28_regex/traits/wchar_t/ctor.cc @@ -46,4 +46,4 @@ main() { test01(); return 0; -}; +} diff --git a/libstdc++-v3/testsuite/28_regex/traits/wchar_t/lookup_collatename.cc b/libstdc++-v3/testsuite/28_regex/traits/wchar_t/lookup_collatename.cc index 197bb9b4a78..3d20cfaf9a0 100644 --- a/libstdc++-v3/testsuite/28_regex/traits/wchar_t/lookup_collatename.cc +++ b/libstdc++-v3/testsuite/28_regex/traits/wchar_t/lookup_collatename.cc @@ -33,13 +33,9 @@ test01() typedef wchar_t CharT; typedef std::regex_traits<CharT> traits; - wchar_t name[] = L"ll"; - traits t; - - traits::string_type sname = - t.lookup_collatename(name, name+sizeof(name)/sizeof(*name)-1); - - VERIFY( !sname.empty() ); + traits t; + CharT name[] = L"tilde"; + VERIFY(t.lookup_collatename(name, name+sizeof(name)/sizeof(*name)-1) == L"~"); } int main() diff --git a/libstdc++-v3/testsuite/28_regex/traits/wchar_t/translate_nocase.cc b/libstdc++-v3/testsuite/28_regex/traits/wchar_t/translate_nocase.cc index 2793f8c3af7..5aa11d33978 100644 --- a/libstdc++-v3/testsuite/28_regex/traits/wchar_t/translate_nocase.cc +++ b/libstdc++-v3/testsuite/28_regex/traits/wchar_t/translate_nocase.cc @@ -43,4 +43,4 @@ main() { test01(); return 0; -}; +} diff --git a/libstdc++-v3/testsuite/28_regex/traits/wchar_t/value.cc b/libstdc++-v3/testsuite/28_regex/traits/wchar_t/value.cc index 6d5885cc627..2ad3354d6f0 100644 --- a/libstdc++-v3/testsuite/28_regex/traits/wchar_t/value.cc +++ b/libstdc++-v3/testsuite/28_regex/traits/wchar_t/value.cc @@ -46,4 +46,4 @@ main() { test01(); return 0; -}; +} diff --git a/libstdc++-v3/testsuite/29_atomics/atomic/cons/49445.cc b/libstdc++-v3/testsuite/29_atomics/atomic/cons/49445.cc index 793b58d9549..e45e777dc7b 100644 --- a/libstdc++-v3/testsuite/29_atomics/atomic/cons/49445.cc +++ b/libstdc++-v3/testsuite/29_atomics/atomic/cons/49445.cc @@ -1,3 +1,4 @@ +// { dg-require-atomic-builtins "" } // { dg-options "-std=gnu++0x" } // Copyright (C) 2012-2013 Free Software Foundation, Inc. diff --git a/libstdc++-v3/testsuite/29_atomics/atomic_integral/operators/bitwise.cc b/libstdc++-v3/testsuite/29_atomics/atomic_integral/operators/bitwise.cc index 0c2ad78528d..052afc305ce 100644 --- a/libstdc++-v3/testsuite/29_atomics/atomic_integral/operators/bitwise.cc +++ b/libstdc++-v3/testsuite/29_atomics/atomic_integral/operators/bitwise.cc @@ -26,4 +26,4 @@ int main() __gnu_test::has_bitwise_operators test; using __gnu_test::atomic_integrals_no_bool; __gnu_cxx::typelist::apply_generator(test, atomic_integrals_no_bool::type()); -}; +} diff --git a/libstdc++-v3/testsuite/29_atomics/atomic_integral/operators/decrement.cc b/libstdc++-v3/testsuite/29_atomics/atomic_integral/operators/decrement.cc index 512478aa64c..891a37b0db8 100644 --- a/libstdc++-v3/testsuite/29_atomics/atomic_integral/operators/decrement.cc +++ b/libstdc++-v3/testsuite/29_atomics/atomic_integral/operators/decrement.cc @@ -26,4 +26,4 @@ int main() __gnu_test::has_decrement_operators test; using __gnu_test::atomic_integrals_no_bool; __gnu_cxx::typelist::apply_generator(test, atomic_integrals_no_bool::type()); -}; +} diff --git a/libstdc++-v3/testsuite/29_atomics/atomic_integral/operators/increment.cc b/libstdc++-v3/testsuite/29_atomics/atomic_integral/operators/increment.cc index 5979cfa7273..7d269a9f29d 100644 --- a/libstdc++-v3/testsuite/29_atomics/atomic_integral/operators/increment.cc +++ b/libstdc++-v3/testsuite/29_atomics/atomic_integral/operators/increment.cc @@ -26,4 +26,4 @@ int main() __gnu_test::has_increment_operators test; using __gnu_test::atomic_integrals_no_bool; __gnu_cxx::typelist::apply_generator(test, atomic_integrals_no_bool::type()); -}; +} diff --git a/libstdc++-v3/testsuite/performance/25_algorithms/sort.cc b/libstdc++-v3/testsuite/performance/25_algorithms/sort.cc new file mode 100644 index 00000000000..07062ab8b3f --- /dev/null +++ b/libstdc++-v3/testsuite/performance/25_algorithms/sort.cc @@ -0,0 +1,65 @@ +// Copyright (C) 2013 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 <vector> +#include <algorithm> +#include <testsuite_performance.h> + +int main() +{ + using namespace __gnu_test; + + time_counter time; + resource_counter resource; + + const int max_size = 10000000; + + std::vector<int> v(max_size); + + for (int i = 0; i < max_size; ++i) + v[i] = -i; + + start_counters(time, resource); + std::sort(v.begin(), v.end()); + stop_counters(time, resource); + + report_performance(__FILE__, "reverse", time, resource); + clear_counters(time, resource); + + for (int i = 0; i < max_size; ++i) + v[i] = i; + + start_counters(time, resource); + std::sort(v.begin(), v.end()); + stop_counters(time, resource); + + report_performance(__FILE__, "forwards", time, resource); + clear_counters(time, resource); + + // a simple psuedo-random series which does not rely on rand() and friends + v[0] = 0; + for (int i = 1; i < max_size; ++i) + v[i] = (v[i-1] + 110211473) * 745988807; + + start_counters(time, resource); + std::sort(v.begin(), v.end()); + stop_counters(time, resource); + + report_performance(__FILE__, "random", time, resource); + + return 0; +} diff --git a/libstdc++-v3/testsuite/performance/25_algorithms/sort_heap.cc b/libstdc++-v3/testsuite/performance/25_algorithms/sort_heap.cc new file mode 100644 index 00000000000..63cb2248033 --- /dev/null +++ b/libstdc++-v3/testsuite/performance/25_algorithms/sort_heap.cc @@ -0,0 +1,73 @@ +// Copyright (C) 2013 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 <vector> +#include <algorithm> +#include <testsuite_performance.h> + +int main() +{ + using namespace __gnu_test; + + time_counter time; + resource_counter resource; + + const int max_size = 10000000; + + std::vector<int> v(max_size); + + for (int i = 0; i < max_size; ++i) + v[i] = -i; + + start_counters(time, resource); + std::make_heap(v.begin(), v.end()); + stop_counters(time, resource); + + report_performance(__FILE__, "make_heap_reverse", time, resource); + clear_counters(time, resource); + + for (int i = 0; i < max_size; ++i) + v[i] = i; + + start_counters(time, resource); + std::make_heap(v.begin(), v.end()); + stop_counters(time, resource); + + report_performance(__FILE__, "make_heap_forwards", time, resource); + clear_counters(time, resource); + + // a simple psuedo-random series which does not rely on rand() and friends + v[0] = 0; + for (int i = 1; i < max_size; ++i) + v[i] = (v[i-1] + 110211473) * 745988807; + + start_counters(time, resource); + std::make_heap(v.begin(), v.end()); + stop_counters(time, resource); + + report_performance(__FILE__, "make_heap_random", time, resource); + + + start_counters(time, resource); + std::sort_heap(v.begin(), v.end()); + stop_counters(time, resource); + + report_performance(__FILE__, "sort_heap", time, resource); + clear_counters(time, resource); + + return 0; +} diff --git a/libstdc++-v3/testsuite/performance/25_algorithms/stable_sort.cc b/libstdc++-v3/testsuite/performance/25_algorithms/stable_sort.cc new file mode 100644 index 00000000000..6440eb35f8f --- /dev/null +++ b/libstdc++-v3/testsuite/performance/25_algorithms/stable_sort.cc @@ -0,0 +1,65 @@ +// Copyright (C) 2013 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 <vector> +#include <algorithm> +#include <testsuite_performance.h> + +int main() +{ + using namespace __gnu_test; + + time_counter time; + resource_counter resource; + + const int max_size = 10000000; + + std::vector<int> v(max_size); + + for (int i = 0; i < max_size; ++i) + v[i] = -i; + + start_counters(time, resource); + std::stable_sort(v.begin(), v.end()); + stop_counters(time, resource); + + report_performance(__FILE__, "reverse", time, resource); + clear_counters(time, resource); + + for (int i = 0; i < max_size; ++i) + v[i] = i; + + start_counters(time, resource); + std::stable_sort(v.begin(), v.end()); + stop_counters(time, resource); + + report_performance(__FILE__, "forwards", time, resource); + clear_counters(time, resource); + + // a simple psuedo-random series which does not rely on rand() and friends + v[0] = 0; + for (int i = 1; i < max_size; ++i) + v[i] = (v[i-1] + 110211473) * 745988807; + + start_counters(time, resource); + std::stable_sort(v.begin(), v.end()); + stop_counters(time, resource); + + report_performance(__FILE__, "random", time, resource); + + return 0; +} diff --git a/libstdc++-v3/testsuite/performance/27_io/ifstream_extract_int.cc b/libstdc++-v3/testsuite/performance/27_io/ifstream_extract_int.cc index d22586663ce..4548e44b2ca 100644 --- a/libstdc++-v3/testsuite/performance/27_io/ifstream_extract_int.cc +++ b/libstdc++-v3/testsuite/performance/27_io/ifstream_extract_int.cc @@ -45,4 +45,4 @@ int main() unlink("tmp_perf_int.txt"); return 0; -}; +} diff --git a/libstdc++-v3/testsuite/performance/27_io/ofstream_insert_int.cc b/libstdc++-v3/testsuite/performance/27_io/ofstream_insert_int.cc index 6bd90105a8b..48dcba2bccf 100644 --- a/libstdc++-v3/testsuite/performance/27_io/ofstream_insert_int.cc +++ b/libstdc++-v3/testsuite/performance/27_io/ofstream_insert_int.cc @@ -38,4 +38,4 @@ int main() unlink("tmp_perf_int.txt"); return 0; -}; +} diff --git a/libstdc++-v3/testsuite/performance/28_regex/split.cc b/libstdc++-v3/testsuite/performance/28_regex/split.cc new file mode 100644 index 00000000000..5b972e43696 --- /dev/null +++ b/libstdc++-v3/testsuite/performance/28_regex/split.cc @@ -0,0 +1,115 @@ +// Copyright (C) 2013 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/>. + +// 2013-10-08 Tim Shen <timshen91@gmail.com> + +#include <testsuite_performance.h> +#include <regex> + +using namespace __gnu_test; +using namespace std; + +void split(string s) +{ + regex re("\\s+"); + for (auto it = sregex_token_iterator(s.begin(), s.end(), re, -1); + it != sregex_token_iterator(); + ++it) + { + } +} + +int main() +{ + string source = "\ +// Copyright (C) 2013 Free Software Foundation, Inc.\n\ +//\n\ +// This file is part of the GNU ISO C++ Library. This library is free\n\ +// software; you can redistribute it and/or modify it under the\n\ +// terms of the GNU General Public License as published by the\n\ +// Free Software Foundation; either version 3, or (at your option)\n\ +// any later version.\n\ +\n\ +// This library is distributed in the hope that it will be useful,\n\ +// but WITHOUT ANY WARRANTY; without even the implied warranty of\n\ +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n\ +// GNU General Public License for more details.\n\ +\n\ +// You should have received a copy of the GNU General Public License along\n\ +// with this library; see the file COPYING3. If not see\n\ +// <http://www.gnu.org/licenses/>.\n\ +\n\ +// 2013-10-08 Tim Shen <timshen91@gmail.com>\n\ +\n\ +#include <testsuite_performance.h>\n\ +#include <regex>\n\ +\n\ +using namespace __gnu_test;\n\ +using namespace std;\n\ +\n\ +void split(string s)\n\ +{\n\ + regex re(\"\\s+\");\n\ + for (auto it = sregex_token_iterator(s.begin(), s.end(), re, -1);\n\ + it != sregex_token_iterator();\n\ + ++it)\n\ + {\n\ + }\n\ +}\n\ +\n\ +int main()\n\ +{\n\ + string source = \"\";\n\ + time_counter time;\n\ + resource_counter resource;\n\ +\n\ + source = source + source;\n\ + source = source + source;\n\ + source = source + source;\n\ + source = source + source;\n\ + source = source + source;\n\ + source = source + source;\n\ + source = source + source;\n\ + source = source + source;\n\ +\n\ + start_counters(time, resource);\n\ + split(source);\n\ + stop_counters(time, resource);\n\ + report_performance(__FILE__, \"\", time, resource);\n\ +\n\ + return 0;\n\ +}\n"; + + time_counter time; + resource_counter resource; + + source = source + source; + source = source + source; + source = source + source; + source = source + source; + source = source + source; + source = source + source; + source = source + source; + source = source + source; + + start_counters(time, resource); + split(source); + stop_counters(time, resource); + report_performance(__FILE__, "", time, resource); + + return 0; +} diff --git a/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/assign/char/cstring.cc b/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/assign/char/cstring.cc index d7589410b8f..7a8ac85544a 100644 --- a/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/assign/char/cstring.cc +++ b/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/assign/char/cstring.cc @@ -39,4 +39,4 @@ main() { test01(); return 0; -}; +} diff --git a/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/assign/char/cstring_op.cc b/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/assign/char/cstring_op.cc index a8631ba5bda..d9a52199bf1 100644 --- a/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/assign/char/cstring_op.cc +++ b/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/assign/char/cstring_op.cc @@ -39,4 +39,4 @@ main() { test01(); return 0; -}; +} diff --git a/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/assign/char/pstring.cc b/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/assign/char/pstring.cc index 1c76bac6f92..d917e45b5b5 100644 --- a/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/assign/char/pstring.cc +++ b/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/assign/char/pstring.cc @@ -39,4 +39,4 @@ main() { test01(); return 0; -}; +} diff --git a/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/assign/char/range.cc b/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/assign/char/range.cc index c18030848c0..5e7483342b3 100644 --- a/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/assign/char/range.cc +++ b/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/assign/char/range.cc @@ -39,4 +39,4 @@ main() { test01(); return 0; -}; +} diff --git a/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/assign/char/string.cc b/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/assign/char/string.cc index 481051a29af..9bb386aafbe 100644 --- a/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/assign/char/string.cc +++ b/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/assign/char/string.cc @@ -40,4 +40,4 @@ main() { test01(); return 0; -}; +} diff --git a/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/assign/char/string_op.cc b/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/assign/char/string_op.cc index 89f5f71065b..59f84595559 100644 --- a/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/assign/char/string_op.cc +++ b/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/assign/char/string_op.cc @@ -40,4 +40,4 @@ main() { test01(); return 0; -}; +} diff --git a/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/assign/wchar_t/cstring.cc b/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/assign/wchar_t/cstring.cc index c77864ab3bf..f2a914b1974 100644 --- a/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/assign/wchar_t/cstring.cc +++ b/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/assign/wchar_t/cstring.cc @@ -39,4 +39,4 @@ main() { test01(); return 0; -}; +} diff --git a/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/assign/wchar_t/cstring_op.cc b/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/assign/wchar_t/cstring_op.cc index d5a8067418f..d70a0e1c5d0 100644 --- a/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/assign/wchar_t/cstring_op.cc +++ b/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/assign/wchar_t/cstring_op.cc @@ -39,4 +39,4 @@ main() { test01(); return 0; -}; +} diff --git a/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/assign/wchar_t/pstring.cc b/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/assign/wchar_t/pstring.cc index fb7ff3bd141..b65ccdba297 100644 --- a/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/assign/wchar_t/pstring.cc +++ b/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/assign/wchar_t/pstring.cc @@ -39,4 +39,4 @@ main() { test01(); return 0; -}; +} diff --git a/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/assign/wchar_t/range.cc b/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/assign/wchar_t/range.cc index 94763f4b1a2..317217ac990 100644 --- a/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/assign/wchar_t/range.cc +++ b/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/assign/wchar_t/range.cc @@ -39,4 +39,4 @@ main() { test01(); return 0; -}; +} diff --git a/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/assign/wchar_t/string.cc b/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/assign/wchar_t/string.cc index 36312e4dca7..fe7852165d3 100644 --- a/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/assign/wchar_t/string.cc +++ b/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/assign/wchar_t/string.cc @@ -40,4 +40,4 @@ main() { test01(); return 0; -}; +} diff --git a/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/assign/wchar_t/string_op.cc b/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/assign/wchar_t/string_op.cc index 2d79962ea67..27b9583610b 100644 --- a/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/assign/wchar_t/string_op.cc +++ b/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/assign/wchar_t/string_op.cc @@ -40,4 +40,4 @@ main() { test01(); return 0; -}; +} diff --git a/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/ctors/char/cstring.cc b/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/ctors/char/cstring.cc index c6c4760951b..adf8ec10003 100644 --- a/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/ctors/char/cstring.cc +++ b/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/ctors/char/cstring.cc @@ -38,4 +38,4 @@ main() { test01(); return 0; -}; +} diff --git a/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/ctors/char/default.cc b/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/ctors/char/default.cc index 4d8300c9daa..71103a84898 100644 --- a/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/ctors/char/default.cc +++ b/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/ctors/char/default.cc @@ -43,4 +43,4 @@ main() { test01(); return 0; -}; +} diff --git a/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/ctors/char/pstring.cc b/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/ctors/char/pstring.cc index fa86082d32b..c37f8250fa7 100644 --- a/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/ctors/char/pstring.cc +++ b/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/ctors/char/pstring.cc @@ -38,4 +38,4 @@ main() { test01(); return 0; -}; +} diff --git a/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/ctors/char/range.cc b/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/ctors/char/range.cc index 6d5f1b0942c..a41869d80bd 100644 --- a/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/ctors/char/range.cc +++ b/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/ctors/char/range.cc @@ -38,4 +38,4 @@ main() { test01(); return 0; -}; +} diff --git a/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/ctors/char/string.cc b/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/ctors/char/string.cc index c367d100778..1e8ab0f4ff9 100644 --- a/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/ctors/char/string.cc +++ b/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/ctors/char/string.cc @@ -50,4 +50,4 @@ main() test01(); test02(); return 0; -}; +} diff --git a/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/ctors/wchar_t/cstring.cc b/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/ctors/wchar_t/cstring.cc index 595ccaf17d6..bd7ffa27f9a 100644 --- a/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/ctors/wchar_t/cstring.cc +++ b/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/ctors/wchar_t/cstring.cc @@ -38,4 +38,4 @@ main() { test01(); return 0; -}; +} diff --git a/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/ctors/wchar_t/default.cc b/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/ctors/wchar_t/default.cc index 32a2a8fdc46..816ac2b160b 100644 --- a/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/ctors/wchar_t/default.cc +++ b/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/ctors/wchar_t/default.cc @@ -43,4 +43,4 @@ main() { test01(); return 0; -}; +} diff --git a/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/ctors/wchar_t/pstring.cc b/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/ctors/wchar_t/pstring.cc index 9742c9b5b56..31072ef435b 100644 --- a/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/ctors/wchar_t/pstring.cc +++ b/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/ctors/wchar_t/pstring.cc @@ -38,4 +38,4 @@ main() { test01(); return 0; -}; +} diff --git a/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/ctors/wchar_t/range.cc b/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/ctors/wchar_t/range.cc index f0c5ee2b13f..ccd16f2b608 100644 --- a/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/ctors/wchar_t/range.cc +++ b/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/ctors/wchar_t/range.cc @@ -38,4 +38,4 @@ main() { test01(); return 0; -}; +} diff --git a/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/ctors/wchar_t/string.cc b/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/ctors/wchar_t/string.cc index a67fddc9769..6064686d2d9 100644 --- a/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/ctors/wchar_t/string.cc +++ b/libstdc++-v3/testsuite/tr1/7_regular_expressions/basic_regex/ctors/wchar_t/string.cc @@ -50,4 +50,4 @@ main() test01(); test02(); return 0; -}; +} diff --git a/libstdc++-v3/testsuite/tr1/7_regular_expressions/match_results/ctors/char/default.cc b/libstdc++-v3/testsuite/tr1/7_regular_expressions/match_results/ctors/char/default.cc index 614845a196d..799c8cbef7a 100644 --- a/libstdc++-v3/testsuite/tr1/7_regular_expressions/match_results/ctors/char/default.cc +++ b/libstdc++-v3/testsuite/tr1/7_regular_expressions/match_results/ctors/char/default.cc @@ -54,4 +54,4 @@ main() { test01(); return 0; -}; +} diff --git a/libstdc++-v3/testsuite/tr1/7_regular_expressions/regex_traits/char/ctor.cc b/libstdc++-v3/testsuite/tr1/7_regular_expressions/regex_traits/char/ctor.cc index cca58b4888f..6ec7583e6e2 100644 --- a/libstdc++-v3/testsuite/tr1/7_regular_expressions/regex_traits/char/ctor.cc +++ b/libstdc++-v3/testsuite/tr1/7_regular_expressions/regex_traits/char/ctor.cc @@ -45,4 +45,4 @@ main() { test01(); return 0; -}; +} diff --git a/libstdc++-v3/testsuite/tr1/7_regular_expressions/regex_traits/char/translate_nocase.cc b/libstdc++-v3/testsuite/tr1/7_regular_expressions/regex_traits/char/translate_nocase.cc index 4a941ef3d04..4df0e507f64 100644 --- a/libstdc++-v3/testsuite/tr1/7_regular_expressions/regex_traits/char/translate_nocase.cc +++ b/libstdc++-v3/testsuite/tr1/7_regular_expressions/regex_traits/char/translate_nocase.cc @@ -38,4 +38,4 @@ main() { test01(); return 0; -}; +} diff --git a/libstdc++-v3/testsuite/tr1/7_regular_expressions/regex_traits/char/value.cc b/libstdc++-v3/testsuite/tr1/7_regular_expressions/regex_traits/char/value.cc index 0db6e5b583d..c317c3fe82e 100644 --- a/libstdc++-v3/testsuite/tr1/7_regular_expressions/regex_traits/char/value.cc +++ b/libstdc++-v3/testsuite/tr1/7_regular_expressions/regex_traits/char/value.cc @@ -45,4 +45,4 @@ main() { test01(); return 0; -}; +} diff --git a/libstdc++-v3/testsuite/tr1/7_regular_expressions/regex_traits/wchar_t/ctor.cc b/libstdc++-v3/testsuite/tr1/7_regular_expressions/regex_traits/wchar_t/ctor.cc index 5c869a8aedd..4f468b57aed 100644 --- a/libstdc++-v3/testsuite/tr1/7_regular_expressions/regex_traits/wchar_t/ctor.cc +++ b/libstdc++-v3/testsuite/tr1/7_regular_expressions/regex_traits/wchar_t/ctor.cc @@ -45,4 +45,4 @@ main() { test01(); return 0; -}; +} diff --git a/libstdc++-v3/testsuite/tr1/7_regular_expressions/regex_traits/wchar_t/translate_nocase.cc b/libstdc++-v3/testsuite/tr1/7_regular_expressions/regex_traits/wchar_t/translate_nocase.cc index 168999b4411..83b4ee2f802 100644 --- a/libstdc++-v3/testsuite/tr1/7_regular_expressions/regex_traits/wchar_t/translate_nocase.cc +++ b/libstdc++-v3/testsuite/tr1/7_regular_expressions/regex_traits/wchar_t/translate_nocase.cc @@ -38,4 +38,4 @@ main() { test01(); return 0; -}; +} diff --git a/libstdc++-v3/testsuite/tr1/7_regular_expressions/regex_traits/wchar_t/value.cc b/libstdc++-v3/testsuite/tr1/7_regular_expressions/regex_traits/wchar_t/value.cc index 0db6e5b583d..c317c3fe82e 100644 --- a/libstdc++-v3/testsuite/tr1/7_regular_expressions/regex_traits/wchar_t/value.cc +++ b/libstdc++-v3/testsuite/tr1/7_regular_expressions/regex_traits/wchar_t/value.cc @@ -45,4 +45,4 @@ main() { test01(); return 0; -}; +} diff --git a/libstdc++-v3/testsuite/tr2/dynamic_bitset/pr58729.cc b/libstdc++-v3/testsuite/tr2/dynamic_bitset/pr58729.cc new file mode 100644 index 00000000000..7607e3f2c76 --- /dev/null +++ b/libstdc++-v3/testsuite/tr2/dynamic_bitset/pr58729.cc @@ -0,0 +1,64 @@ +// { dg-options "-std=gnu++11" } + +// 2013-10-15 Edward M. Smith-Rowland <3dw4rd@verizon.net> +// +// Copyright (C) 2013 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/>. + +// libstdc++/58729 + +#include <tr2/dynamic_bitset> +#include <testsuite_hooks.h> + +void +test01() +{ + std::tr2::dynamic_bitset<> pdb2{}; + + pdb2.resize(10, true); + VERIFY (pdb2 == std::tr2::dynamic_bitset<>{"1111111111"}); + + pdb2.resize(15); + VERIFY (pdb2 == std::tr2::dynamic_bitset<>{"000001111111111"}); + + pdb2.flip(); + VERIFY (pdb2 == std::tr2::dynamic_bitset<>{"111110000000000"}); + + VERIFY (pdb2.size() == 15); + VERIFY (pdb2.count() == 5); + + pdb2.resize(20, false); + VERIFY (pdb2 == std::tr2::dynamic_bitset<>{"00000111110000000000"}); + + pdb2.resize(25, true); + VERIFY (pdb2 == std::tr2::dynamic_bitset<>{"1111100000111110000000000"}); + + pdb2.resize(75, true); + VERIFY (pdb2 == std::tr2::dynamic_bitset<>{"1111111111111111111111111" + "1111111111111111111111111" + "1111100000111110000000000"}); + + VERIFY (pdb2.size() == 75); + VERIFY (pdb2.count() == 60); +} + +int +main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/util/exception/safety.h b/libstdc++-v3/testsuite/util/exception/safety.h index 5ba9b13ce37..ca311797bad 100644 --- a/libstdc++-v3/testsuite/util/exception/safety.h +++ b/libstdc++-v3/testsuite/util/exception/safety.h @@ -47,22 +47,12 @@ namespace __gnu_test 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", (unsigned long)random); - __s += buf; - __s += " on range ["; - __builtin_sprintf(buf, "%lu", (unsigned long)distribution.min()); - __s += buf; - __s += ", "; - __builtin_sprintf(buf, "%lu", (unsigned long)distribution.max()); - __s += buf; - __s += "]\n"; - std::__throw_out_of_range(__s.c_str()); - } + std::__throw_out_of_range_fmt(__N("setup_base::generate\n" + "random number generated is: %zu " + "out of range [%zu, %zu]\n"), + (size_t)random, + (size_t)distribution.min(), + (size_t)distribution.max()); return random; } diff --git a/libstdc++-v3/testsuite/util/testsuite_regex.h b/libstdc++-v3/testsuite/util/testsuite_regex.h index ebd72a67258..bc0f3d5bfd9 100644 --- a/libstdc++-v3/testsuite/util/testsuite_regex.h +++ b/libstdc++-v3/testsuite/util/testsuite_regex.h @@ -31,9 +31,12 @@ namespace __gnu_test // Test on a compilation of simple expressions, throw regex_error on error. typedef std::regex regex_type; typedef regex_type::flag_type flag_type; + typedef std::regex_constants::match_flag_type match_flag_type; typedef std::regex_constants::error_type error_type; typedef std::size_t size_type; typedef std::string string_type; + using std::basic_regex; + using std::match_results; // Utilities struct regex_expected_fail { }; @@ -126,5 +129,177 @@ namespace __gnu_test } } + // regex_match_debug behaves like regex_match, but will run *two* executors + // (if there's no back-reference) and check if their results agree. If not, + // an exception throws. One can use them just in the way of using regex_match. + template<typename _Bi_iter, typename _Alloc, + typename _Ch_type, typename _Rx_traits> + bool + regex_match_debug(_Bi_iter __s, + _Bi_iter __e, + match_results<_Bi_iter, _Alloc>& __m, + const basic_regex<_Ch_type, _Rx_traits>& __re, + match_flag_type __flags + = std::regex_constants::match_default) + { + using namespace std::__detail; + auto __res1 = __regex_algo_impl<_Bi_iter, _Alloc, _Ch_type, _Rx_traits, + _RegexExecutorPolicy::_S_auto, true> + (__s, __e, __m, __re, __flags); + match_results<_Bi_iter, _Alloc> __mm; + auto __res2 = __regex_algo_impl<_Bi_iter, _Alloc, _Ch_type, _Rx_traits, + _RegexExecutorPolicy::_S_alternate, true> + (__s, __e, __mm, __re, __flags); + if (__res1 == __res2 && __m == __mm) + return __res1; + throw(std::exception()); + } + + // No match_results version + template<typename _Bi_iter, typename _Ch_type, typename _Rx_traits> + inline bool + regex_match_debug(_Bi_iter __first, + _Bi_iter __last, + const basic_regex<_Ch_type, _Rx_traits>& __re, + match_flag_type __flags + = std::regex_constants::match_default) + { + match_results<_Bi_iter> __what; + return regex_match_debug(__first, __last, __what, __re, __flags); + } + + // C-string version + template<typename _Ch_type, typename _Alloc, typename _Rx_traits> + inline bool + regex_match_debug(const _Ch_type* __s, + match_results<const _Ch_type*, _Alloc>& __m, + const basic_regex<_Ch_type, _Rx_traits>& __re, + match_flag_type __f + = std::regex_constants::match_default) + { return regex_match_debug(__s, __s + _Rx_traits::length(__s), + __m, __re, __f); } + + // C-string version without match_results + template<typename _Ch_type, class _Rx_traits> + inline bool + regex_match_debug(const _Ch_type* __s, + const basic_regex<_Ch_type, _Rx_traits>& __re, + match_flag_type __f + = std::regex_constants::match_default) + { return regex_match_debug(__s, __s + _Rx_traits::length(__s), + __re, __f); } + + // std::basic_string version + template<typename _Ch_traits, typename _Ch_alloc, + typename _Alloc, typename _Ch_type, typename _Rx_traits> + inline bool + regex_match_debug(const std::basic_string<_Ch_type, _Ch_traits, + _Ch_alloc>& __s, + match_results<typename std::basic_string<_Ch_type, + _Ch_traits, _Ch_alloc>::const_iterator, + _Alloc>& __m, + const basic_regex<_Ch_type, _Rx_traits>& __re, + match_flag_type __flags + = std::regex_constants::match_default) + { return regex_match_debug(__s.begin(), __s.end(), + __m, __re, __flags); } + + // std::basic_string version without match_results + template<typename _Ch_traits, typename _Str_allocator, + typename _Ch_type, typename _Rx_traits> + inline bool + regex_match_debug(const std::basic_string<_Ch_type, _Ch_traits, + _Str_allocator>& __s, + const basic_regex<_Ch_type, _Rx_traits>& __re, + match_flag_type __flags + = std::regex_constants::match_default) + { return regex_match_debug(__s.begin(), __s.end(), __re, __flags); } + + // regex_match_debug behaves like regex_match, but will run *two* executors + // (if there's no back-reference) and check if their results agree. If not, + // an exception throws. One can use them just in the way of using regex_match. + template<typename _Bi_iter, typename _Alloc, + typename _Ch_type, typename _Rx_traits> + bool + regex_search_debug(_Bi_iter __s, + _Bi_iter __e, + match_results<_Bi_iter, _Alloc>& __m, + const basic_regex<_Ch_type, _Rx_traits>& __re, + match_flag_type __flags + = std::regex_constants::match_default) + { + using namespace std::__detail; + auto __res1 = __regex_algo_impl<_Bi_iter, _Alloc, _Ch_type, _Rx_traits, + _RegexExecutorPolicy::_S_auto, false> + (__s, __e, __m, __re, __flags); + match_results<_Bi_iter, _Alloc> __mm; + auto __res2 = __regex_algo_impl<_Bi_iter, _Alloc, _Ch_type, _Rx_traits, + _RegexExecutorPolicy::_S_alternate, false> + (__s, __e, __mm, __re, __flags); + if (__res1 == __res2 && __m == __mm) + return __res1; + throw(std::exception()); // Let test fail. Give it a name. + } + + // No match_results version + template<typename _Bi_iter, typename _Ch_type, typename _Rx_traits> + inline bool + regex_search_debug(_Bi_iter __first, + _Bi_iter __last, + const basic_regex<_Ch_type, _Rx_traits>& __re, + match_flag_type __flags + = std::regex_constants::match_default) + { + match_results<_Bi_iter> __what; + return regex_search_debug(__first, __last, __what, __re, __flags); + } + + // C-string version + template<typename _Ch_type, class _Alloc, class _Rx_traits> + inline bool + regex_search_debug(const _Ch_type* __s, + match_results<const _Ch_type*, _Alloc>& __m, + const basic_regex<_Ch_type, _Rx_traits>& __e, + match_flag_type __f + = std::regex_constants::match_default) + { return regex_search_debug(__s, __s + _Rx_traits::length(__s), + __m, __e, __f); } + + // C-string version without match_results + template<typename _Ch_type, typename _Rx_traits> + inline bool + regex_search_debug(const _Ch_type* __s, + const basic_regex<_Ch_type, _Rx_traits>& __e, + match_flag_type __f + = std::regex_constants::match_default) + { return regex_search_debug(__s, __s + _Rx_traits::length(__s), + __e, __f); } + + // std::basic_string version + template<typename _Ch_traits, typename _Ch_alloc, + typename _Alloc, typename _Ch_type, + typename _Rx_traits> + inline bool + regex_search_debug(const std::basic_string<_Ch_type, _Ch_traits, + _Ch_alloc>& __s, + match_results<typename std::basic_string<_Ch_type, + _Ch_traits, _Ch_alloc>::const_iterator, _Alloc>& + __m, + const basic_regex<_Ch_type, _Rx_traits>& __e, + match_flag_type __f + = std::regex_constants::match_default) + { return regex_search_debug(__s.begin(), __s.end(), __m, __e, __f); } + + // std::basic_string version without match_results + template<typename _Ch_traits, typename _String_allocator, + typename _Ch_type, typename _Rx_traits> + inline bool + regex_search_debug(const std::basic_string<_Ch_type, _Ch_traits, + _String_allocator>& __s, + const basic_regex<_Ch_type, _Rx_traits>& __e, + match_flag_type __f + = std::regex_constants::match_default) + { return regex_search_debug(__s.begin(), __s.end(), __e, __f); } + } // namespace __gnu_test #endif |