From: François Dumont Date: Fri, 27 Sep 2013 21:17:36 +0000 (+0000) Subject: predefined_ops.h: New. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=ea89b2482f97aa55e4d3fa4c57e0a6b2cdb69f64;p=gcc.git predefined_ops.h: New. 2013-09-27 François Dumont * include/bits/predefined_ops.h: New. * include/bits/stl_heap.h: Include . (__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 . (__lexicographical_compare_impl): New. (__lexicographical_compare::__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 . Remove 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. From-SVN: r202992 --- diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index fccf7083dcb..ead095e786a 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,4 +1,120 @@ -2013-08-07 Jonathan Wakely +2013-09-27 François Dumont + + * include/bits/predefined_ops.h: New. + * include/bits/stl_heap.h: Include . + (__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 . + (__lexicographical_compare_impl): New. + (__lexicographical_compare::__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 . Remove + 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 PR libstdc++/57465 * include/std/functional diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am index 3be6e5750d6..1a4fd6f9bc2 100644 --- a/libstdc++-v3/include/Makefile.am +++ b/libstdc++-v3/include/Makefile.am @@ -121,6 +121,7 @@ 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 \ diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in index cd0b467315f..87a9f1b80cf 100644 --- a/libstdc++-v3/include/Makefile.in +++ b/libstdc++-v3/include/Makefile.in @@ -388,6 +388,7 @@ 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 \ 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 +// . + +/** @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 + 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 + 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 + 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 + 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 + 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 + struct _Iter_comp_iter + { + _Compare _M_comp; + + _Iter_comp_iter(_Compare __comp) + : _M_comp(__comp) + { } + + template + bool + operator()(_Iterator1 __it1, _Iterator2 __it2) + { return bool(_M_comp(*__it1, *__it2)); } + }; + + template + inline _Iter_comp_iter<_Compare> + __iter_comp_iter(_Compare __comp) + { return _Iter_comp_iter<_Compare>(__comp); } + + template + struct _Iter_comp_val + { + _Compare _M_comp; + + _Iter_comp_val(_Compare __comp) + : _M_comp(__comp) + { } + + template + bool + operator()(_Iterator __it, _Value& __val) + { return bool(_M_comp(*__it, __val)); } + }; + + template + inline _Iter_comp_val<_Compare> + __iter_comp_val(_Compare __comp) + { return _Iter_comp_val<_Compare>(__comp); } + + template + inline _Iter_comp_val<_Compare> + __iter_comp_val(_Iter_comp_iter<_Compare> __comp) + { return _Iter_comp_val<_Compare>(__comp._M_comp); } + + template + struct _Val_comp_iter + { + _Compare _M_comp; + + _Val_comp_iter(_Compare __comp) + : _M_comp(__comp) + { } + + template + bool + operator()(_Value& __val, _Iterator __it) + { return bool(_M_comp(__val, *__it)); } + }; + + template + inline _Val_comp_iter<_Compare> + __val_comp_iter(_Compare __comp) + { return _Val_comp_iter<_Compare>(__comp); } + + template + inline _Val_comp_iter<_Compare> + __val_comp_iter(_Iter_comp_iter<_Compare> __comp) + { return _Val_comp_iter<_Compare>(__comp._M_comp); } + + template + struct _Iter_equals_val + { + _Value& _M_value; + + _Iter_equals_val(_Value& __value) + : _M_value(__value) + { } + + template + bool + operator()(_Iterator __it) + { return *__it == _M_value; } + }; + + template + inline _Iter_equals_val<_Value> + __iter_equals_val(_Value& __val) + { return _Iter_equals_val<_Value>(__val); } + + template + struct _Iter_equals_iter + { + typename std::iterator_traits<_Iterator1>::reference _M_ref; + + _Iter_equals_iter(_Iterator1 __it1) + : _M_ref(*__it1) + { } + + template + bool + operator()(_Iterator2 __it2) + { return *__it2 == _M_ref; } + }; + + template + inline _Iter_equals_iter<_Iterator> + __iter_comp_iter(_Iter_equal_to_iter, _Iterator __it) + { return _Iter_equals_iter<_Iterator>(__it); } + + template + struct _Iter_pred + { + _Predicate _M_pred; + + _Iter_pred(_Predicate __pred) + : _M_pred(__pred) + { } + + template + bool + operator()(_Iterator __it) + { return bool(_M_pred(*__it)); } + }; + + template + inline _Iter_pred<_Predicate> + __pred_iter(_Predicate __pred) + { return _Iter_pred<_Predicate>(__pred); } + + template + 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 + bool + operator()(_Iterator __it) + { return bool(_M_comp(*__it, _M_value)); } + }; + + template + _Iter_comp_to_val<_Compare, _Value> + __iter_comp_val(_Compare __comp, _Value &__val) + { return _Iter_comp_to_val<_Compare, _Value>(__comp, __val); } + + template + 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 + bool + operator()(_Iterator2 __it2) + { return bool(_M_comp(*__it2, _M_ref)); } + }; + + template + 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 + struct _Iter_negate + { + _Predicate _M_pred; + + _Iter_negate(_Predicate __pred) + : _M_pred(__pred) + { } + + template + bool + operator()(_Iterator __it) + { return !bool(_M_pred(*__it)); } + }; + + template + 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/stl_algo.h b/libstdc++-v3/include/bits/stl_algo.h index b06211e0100..36f03a40539 100644 --- a/libstdc++-v3/include/bits/stl_algo.h +++ b/libstdc++-v3/include/bits/stl_algo.h @@ -60,10 +60,10 @@ #include #include #include // for _Temporary_buffer +#include #if __cplusplus >= 201103L #include // for std::uniform_int_distribution -#include // for std::bind #endif // See concept_check.h for the __glibcxx_*_requires macros. @@ -72,129 +72,39 @@ namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION - /// Swaps the median value of *__a, *__b and *__c to *__a - template - 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 template void __move_median_first(_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)) + if (__comp(__b, __c)) std::iter_swap(__a, __b); - else if (__comp(*__a, *__c)) + else if (__comp(__a, __c)) std::iter_swap(__a, __c); } - else if (__comp(*__a, *__c)) + else if (__comp(__a, __c)) return; - else if (__comp(*__b, *__c)) + else if (__comp(__b, __c)) std::iter_swap(__a, __c); else std::iter_swap(__a, __b); } - // for_each - - /// This is an overload used by find() for the Input Iterator case. - template - 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 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 - _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 _RandomAccessIterator __find_if(_RandomAccessIterator __first, _RandomAccessIterator __last, @@ -205,19 +115,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 +135,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 +152,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } } - /// This is an overload used by find_if_not() for the Input Iterator case. - template - 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 - _RandomAccessIterator - __find_if_not(_RandomAccessIterator __first, _RandomAccessIterator __last, - _Predicate __pred, random_access_iterator_tag) + template + 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 +166,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 +179,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 +197,73 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // count_if // search - /** - * This is an uglified - * search_n(_ForwardIterator, _ForwardIterator, _Integer, const _Tp&) - * overloaded for forward iterators. - */ - template - _ForwardIterator - __search_n(_ForwardIterator __first, _ForwardIterator __last, - _Integer __count, const _Tp& __val, - std::forward_iterator_tag) + template + _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 - _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 + template _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 +272,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 + template _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 +301,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 +311,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return __last; // Failure } - // find_end for forward iterators. - template - _ForwardIterator1 - __find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator2 __last2, - forward_iterator_tag, forward_iterator_tag) + template + _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 _ForwardIterator1 @@ -520,61 +339,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 - _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 _BidirectionalIterator1 @@ -596,9 +378,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 +409,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 +434,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 +485,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 +561,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,12 +631,26 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } #endif - - /** - * @brief Copy a sequence, removing elements of a given value. - * @ingroup mutating_algorithms - * @param __first An input iterator. - * @param __last An input iterator. + template + _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. + * @ingroup mutating_algorithms + * @param __first An input iterator. + * @param __last An input iterator. * @param __result An output iterator. * @param __value The value to be removed. * @return An iterator designating the end of the resulting sequence. @@ -875,13 +673,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)); } /** @@ -913,13 +706,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 +749,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return __result; } - template _OutputIterator __copy_n(_InputIterator __first, _Size __n, @@ -1063,6 +850,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } #endif + template + _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 +887,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * are still present, but their value is unspecified. */ template - _ForwardIterator + inline _ForwardIterator remove(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { @@ -1092,18 +898,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 +920,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * are still present, but their value is unspecified. */ template - _ForwardIterator + inline _ForwardIterator remove_if(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) { @@ -1135,18 +931,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 + _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 + _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 +986,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * are still present, but their value is unspecified. */ template - _ForwardIterator + inline _ForwardIterator unique(_ForwardIterator __first, _ForwardIterator __last) { // concept requirements @@ -1174,18 +996,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 +1016,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * are still present, but their value is unspecified. */ template - _ForwardIterator + inline _ForwardIterator unique(_ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __binary_pred) { @@ -1216,83 +1028,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 - _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 - _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 - _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 +1053,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 +1080,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 +1110,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; } @@ -1800,10 +1539,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 @@ -1818,14 +1557,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 +1601,34 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } } + template + _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. @@ -1891,43 +1658,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 - 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 +1669,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 + _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 @@ -1986,27 +1755,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,7 +1780,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * @p __comp(*j,*i) is false. * The value returned is @p __result_first+N. */ - template + template _RandomAccessIterator partial_sort_copy(_InputIterator __first, _InputIterator __last, _RandomAccessIterator __result_first, @@ -2056,46 +1808,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 - 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 +1823,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; @@ -2117,29 +1832,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION *__last = _GLIBCXX_MOVE(__val); } - /// This is a helper function for the sort routine. - template - 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 void @@ -2150,7 +1842,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 +1850,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 - 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 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)); } /** @@ -2194,21 +1872,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION */ enum { _S_threshold = 16 }; - /// This is a helper function for the sort routine. - template - 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 void @@ -2226,38 +1889,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } /// This is a helper function... - template - _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 + template _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; @@ -2266,18 +1909,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } } - /// This is a helper function... - template - 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 inline _RandomAccessIterator @@ -2286,29 +1917,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { _RandomAccessIterator __mid = __first + (__last - __first) / 2; std::__move_median_first(__first, __mid, (__last - 1), __comp); - return std::__unguarded_partition(__first + 1, __last, *__first, __comp); + return std::__unguarded_partition(__first + 1, __last, __first, __comp); } - /// This is a helper function for the sort routine. - template - void - __introsort_loop(_RandomAccessIterator __first, - _RandomAccessIterator __last, - _Size __depth_limit) + template + 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 +1942,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 +1955,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // sort - template - void - __introselect(_RandomAccessIterator __first, _RandomAccessIterator __nth, - _RandomAccessIterator __last, _Size __depth_limit) + template + 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 @@ -2370,9 +1975,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) @@ -2420,8 +2022,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { 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 +2030,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 + _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 +2049,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; } @@ -2467,31 +2079,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { 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()); } /** @@ -2516,8 +2111,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { 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 +2119,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 + 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 +2140,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); } /** @@ -2569,42 +2185,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { 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()); } /** @@ -2631,8 +2222,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { 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 +2234,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 +2265,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,38 +2303,14 @@ _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)); } // merge - /// This is a helper function for the __merge_adaptive routines. - template - 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 @@ -2777,7 +2321,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { while (__first1 != __last1 && __first2 != __last2) { - if (__comp(*__first2, *__first1)) + if (__comp(__first2, __first1)) { *__result = _GLIBCXX_MOVE(*__first2); ++__first2; @@ -2793,48 +2337,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _GLIBCXX_MOVE3(__first1, __last1, __result); } - /// This is a helper function for the __merge_adaptive routines. - template - 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 @@ -2858,7 +2360,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION --__last2; while (true) { - if (__comp(*__last2, *__last1)) + if (__comp(__last2, __last1)) { *--__result = _GLIBCXX_MOVE(*__last1); if (__first1 == __last1) @@ -2920,62 +2422,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } } - /// This is a helper function for the merge routines. - template - 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 @@ -3009,22 +2455,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, @@ -3034,49 +2482,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } } - /// This is a helper function for the merge routines. - template - 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 @@ -3091,7 +2496,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 +2508,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 +2531,36 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __len1 - __len11, __len2 - __len22, __comp); } + template + 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 @@ -3148,31 +2585,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _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()); } /** @@ -3204,75 +2626,31 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _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 - _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 + template _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; @@ -3289,29 +2667,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __result)); } - template - 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 void @@ -3332,24 +2687,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 - 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 void @@ -3367,30 +2708,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION enum { _S_chunk_size = 7 }; - template - 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 void __merge_sort_with_buffer(_RandomAccessIterator __first, @@ -3418,78 +2735,32 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } template + typename _Distance, typename _Compare> void __stable_sort_adaptive(_RandomAccessIterator __first, _RandomAccessIterator __last, - _Pointer __buffer, _Distance __buffer_size) + _Pointer __buffer, _Distance __buffer_size, + _Compare __comp) { 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); + std::__stable_sort_adaptive(__first, __middle, __buffer, + __buffer_size, __comp); + std::__stable_sort_adaptive(__middle, __last, __buffer, + __buffer_size, __comp); } else { - std::__merge_sort_with_buffer(__first, __middle, __buffer); - std::__merge_sort_with_buffer(__middle, __last, __buffer); + std::__merge_sort_with_buffer(__first, __middle, __buffer, __comp); + std::__merge_sort_with_buffer(__middle, __last, __buffer, __comp); } std::__merge_adaptive(__first, __middle, __last, _Distance(__middle - __first), _Distance(__last - __middle), - __buffer, __buffer_size); - } - - template - void - __stable_sort_adaptive(_RandomAccessIterator __first, - _RandomAccessIterator __last, - _Pointer __buffer, _Distance __buffer_size, - _Compare __comp) - { - 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, __comp); - std::__stable_sort_adaptive(__middle, __last, __buffer, - __buffer_size, __comp); - } - else - { - std::__merge_sort_with_buffer(__first, __middle, __buffer, __comp); - std::__merge_sort_with_buffer(__middle, __last, __buffer, __comp); - } - std::__merge_adaptive(__first, __middle, __last, - _Distance(__middle - __first), - _Distance(__last - __middle), - __buffer, __buffer_size, - __comp); - } - - /// This is a helper function for the stable sorting routines. - template - 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); + __buffer, __buffer_size, + __comp); } /// This is a helper function for the stable sorting routines. @@ -3519,6 +2790,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // that their input ranges are sorted and the postcondition that their output // ranges are sorted. + template + 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. @@ -3542,28 +2831,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION 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()); } /** @@ -3594,30 +2875,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _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 +2901,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 + template 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,23 +2919,53 @@ _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 + 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. @@ -3712,6 +2994,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 + bool + __prev_permutation(_BidirectionalIterator __first, + _BidirectionalIterator __last, _Compare __comp) + { if (__first == __last) return false; _BidirectionalIterator __i = __first; @@ -3725,18 +3016,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; } } @@ -3767,34 +3060,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()); } /** @@ -3825,39 +3092,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 + _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. @@ -3886,12 +3142,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); } /** @@ -3924,12 +3177,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 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 +3221,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _Compare __comp) { return std::is_sorted_until(__first, __last, __comp) == __last; } + template + _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 @@ -3978,14 +3254,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()); } /** @@ -4009,14 +3279,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 +3319,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION : pair(__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 + template 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 +3349,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; } @@ -4130,6 +3378,31 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return std::make_pair(__min, __max); } + /** + * @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 + 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. @@ -4154,58 +3427,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,73 +3470,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 - bool - is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2) - { - // Efficiently compare identical prefixes: O(N) if sequences - // have the same elements in the same order. - for (; __first1 != __last1; ++__first1, ++__first2) - if (!(*__first1 == *__first2)) - break; - - if (__first1 == __last1) - return true; - - // 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) - { - if (__scan != _GLIBCXX_STD_A::find(__first1, __scan, *__scan)) - continue; // We've seen this one before. - - auto __matches = std::count(__first2, __last2, *__scan); - if (0 == __matches - || std::count(__scan, __last1, *__scan) != __matches) - return false; - } - return true; - } - - /** - * @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)), - * beginning with ForwardIterator2 begin, such that - * equal(__first1, __last1, __begin, __pred) returns true; - * otherwise, returns false. - */ template bool - is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _BinaryPredicate __pred) + __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 (!bool(__pred(*__first1, *__first2))) + if (!__pred(__first1, __first2)) break; if (__first1 == __last1) @@ -4325,78 +3491,49 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION 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)); - if (0 == __matches - || std::count_if(__scan, __last1, - std::bind(__pred, _1, *__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; } -#if __cplusplus > 201103L /** - * @brief Checks whether a permutaion of the second sequence is equal + * @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 __last2 End of first range. * @return true if there exists a permutation of the elements in the range - * [__first2, __last2), beginning with ForwardIterator2 begin, - * such that equal(__first1, __last1, begin) returns true; - * otherwise, returns false. + * [__first2, __first2 + (__last1 - __first1)), beginning with + * ForwardIterator2 begin, such that equal(__first1, __last1, begin) + * returns true; otherwise, returns false. */ template bool is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator2 __last2) + _ForwardIterator2 __first2) { - 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. + // 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); - 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, + __gnu_cxx::__ops::__iter_equal_to_iter()); } /** @@ -4406,19 +3543,38 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * @param __first1 Start of first range. * @param __last1 End of first range. * @param __first2 Start of second range. - * @param __last2 End of first range. * @param __pred A binary predicate. - * @return true if there exists a permutation of the elements in the range - * [__first2, __last2), beginning with ForwardIterator2 begin, - * such that equal(__first1, __last1, __begin, __pred) returns true; + * @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, __pred) returns true; * otherwise, returns false. */ template bool - is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator2 __last2, - _BinaryPredicate __pred) + 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 + bool + __is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2, + _BinaryPredicate __pred) { using _Cat1 = typename iterator_traits<_ForwardIterator1>::iterator_category; @@ -4438,7 +3594,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // 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 (__ra_iters) @@ -4458,21 +3614,74 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION 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; } + + /** + * @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. + * @param __last2 End of first range. + * @return true if there exists a permutation of the elements in the range + * [__first2, __last2), beginning with ForwardIterator2 begin, + * such that equal(__first1, __last1, begin) returns true; + * otherwise, returns false. + */ + template + bool + is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2) + { + __glibcxx_requires_valid_range(__first1, __last1); + __glibcxx_requires_valid_range(__first2, __last2); + + return + std::__is_permutation(__first1, __last1, __first2, __last2, + __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 __last2 End of first range. + * @param __pred A binary predicate. + * @return true if there exists a permutation of the elements in the range + * [__first2, __last2), beginning with ForwardIterator2 begin, + * such that equal(__first1, __last1, __begin, __pred) returns true; + * otherwise, returns false. + */ + template + bool + is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2, + _BinaryPredicate __pred) + { + __glibcxx_requires_valid_range(__first1, __last1); + __glibcxx_requires_valid_range(__first2, __last2); + + return std::__is_permutation(__first1, __last1, __first2, __last2, + __gnu_cxx::__ops::__iter_comp_iter(__pred)); + } #endif #ifdef _GLIBCXX_USE_C99_STDINT_TR1 @@ -4564,8 +3773,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 +3797,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)); } /** @@ -4689,16 +3899,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()); } /** @@ -4723,16 +3926,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)); } /** @@ -4751,13 +3947,11 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO // 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)); } /** @@ -4778,11 +3972,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)); } /** @@ -4825,40 +4017,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()); } /** @@ -4898,50 +4058,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 @@ -4965,15 +4085,11 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO // 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)); } @@ -5007,16 +4123,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 +4324,6 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO return __first; } - /** * @brief Copy a sequence, removing consecutive duplicate values. * @ingroup mutating_algorithms @@ -5254,6 +4361,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 +4400,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 +4498,6 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO } - /** * @brief Sort the smallest elements of a sequence. * @ingroup sorting_algorithms @@ -5413,18 +4520,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 +4558,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 +4591,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 +4603,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 +4629,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 +4642,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 +4664,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 +4694,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 + _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)); } /** @@ -5645,38 +4756,22 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO _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()); } /** @@ -5708,42 +4803,44 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO 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>) - __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, - _ValueType2>) - __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, - _ValueType2, _ValueType1>) - __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)); + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_InputIterator1>::value_type>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + 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::__merge(__first1, __last1, + __first2, __last2, __result, + __gnu_cxx::__ops::__iter_comp_iter(__comp)); } + template + 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 +4863,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 +4897,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 + _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. @@ -5857,45 +4966,25 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO _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()); } /** @@ -5924,47 +5013,48 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO _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 + _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; } /** @@ -5991,34 +5081,23 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO _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()); } /** @@ -6048,36 +5127,48 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO _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 + _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); } /** @@ -6106,36 +5197,23 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO _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()); } /** @@ -6167,38 +5245,56 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO _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 + _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)); } /** @@ -6225,43 +5321,25 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO _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()); } /** @@ -6292,47 +5370,40 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO _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 + _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. @@ -6351,13 +5422,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()); } /** @@ -6381,11 +5447,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 + _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; } @@ -6407,13 +5481,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()); } /** @@ -6437,12 +5506,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..fae8beb2171 100644 --- a/libstdc++-v3/include/bits/stl_algobase.h +++ b/libstdc++-v3/include/bits/stl_algobase.h @@ -68,6 +68,7 @@ #include #include #include // For std::swap and _GLIBCXX_MOVE +#include namespace std _GLIBCXX_VISIBILITY(default) { @@ -862,6 +863,28 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return true; } }; + template + 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 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 not less - * than @a val, or end() if every element is less than - * @a val. - * @ingroup binary_search_algorithms - */ - template + template _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 not less + * than @a val, or end() if every element is less than + * @a val. + * @ingroup binary_search_algorithms + */ + template + _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) @@ -1212,26 +1230,29 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO 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 + 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); } /** @@ -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()); } /** @@ -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 + 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 @@ -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()); } /** @@ -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_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 #include +#include namespace std _GLIBCXX_VISIBILITY(default) { @@ -67,21 +68,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * @ingroup sorting_algorithms */ - template - _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 _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 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 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 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 + template 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 - 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 + template 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 + template 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 - 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 - 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 + template 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 + 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 - 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 + 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 - 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 - 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/parallel/algobase.h b/libstdc++-v3/include/parallel/algobase.h index e3737cc8f70..d615065a555 100644 --- a/libstdc++-v3/include/parallel/algobase.h +++ b/libstdc++-v3/include/parallel/algobase.h @@ -122,6 +122,25 @@ namespace __parallel _IteratorCategory1(), _IteratorCategory2()); } +#if __cplusplus > 201103L + template + inline pair<_InputIterator1, _InputIterator2> + mismatch(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2) + { return _GLIBCXX_STD_A::mismatch(__first1, __last1, __first2, __last2); } + + template + inline pair<_InputIterator1, _InputIterator2> + mismatch(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, + _BinaryPredicate __binary_pred) + { + return _GLIBCXX_STD_A::mismatch(__first1, __last1, __first2, __last2, + __binary_pred); + } +#endif + // Sequential fallback template inline bool @@ -155,6 +174,22 @@ namespace __parallel == __end1; } +#if __cplusplus > 201103L + template + inline bool + equal(_II1 __first1, _II1 __last1, _II2 __first2, _II2 __last2) + { return _GLIBCXX_STD_A::equal(__first1, __last1, __first2, __last2); } + + template + inline bool + equal(_IIter1 __first1, _IIter1 __last1, + _IIter2 __first2, _IIter2 __last2, _BinaryPredicate __binary_pred) + { + return _GLIBCXX_STD_A::equal(__first1, __last1, __first2, __last2, + __binary_pred); + } +#endif + // Sequential fallback template inline bool 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 +// . + +// 25.1.5 [lib.alg.adjacent_find] + +#include +#include +#include + +void +test01() +{ + bool test __attribute__((unused)) = true; + + std::vector 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 +// . + +// 25.1.2 find + +#include +#include +#include + +void +test1() +{ + std::vector 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 +// . + +// 25.1.3 [lib.alg.find.end] + +#include +#include +#include + +void +test1() +{ + std::vector 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 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 +// . + +// 25.1.4 [lib.alg.find.first.of] + +#include +#include +#include + +void +test1() +{ + std::vector 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 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 +// . + +// 25.1.2 find + +#include +#include +#include + +void +test1() +{ + std::vector 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 +// . + +#include +#include +#include + +void +test1() +{ + std::vector 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 +// . + +// 25.3.6 Heap operations [lib.alg.heap.operations] + +#include +#include +#include +#include + +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 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 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 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(std::log(static_cast(N)) + 0.5); + const int logN = 3; +#endif + + std::vector 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 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 +// . + +// 25.2.12 [alg.is_permutation] Is permutation + +#include +#include +#include + +void test01() +{ + bool test __attribute__((unused)) = true; + + std::vector v1 = { true, false, true, false, true }; + std::vector 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 v1 = { true, false, true, false, true }; + std::vector 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(); +}