diff options
author | François Dumont <fdumont@gcc.gnu.org> | 2013-09-27 21:17:36 +0000 |
---|---|---|
committer | François Dumont <fdumont@gcc.gnu.org> | 2013-09-27 21:17:36 +0000 |
commit | ea89b2482f97aa55e4d3fa4c57e0a6b2cdb69f64 (patch) | |
tree | 982dee36a36ef4c06c3ecd1d32e305fef700f0c9 /libstdc++-v3/include | |
parent | 522d4efcd3bda29e0557756bbe7346cbf8a375f0 (diff) | |
download | gcc-ea89b2482f97aa55e4d3fa4c57e0a6b2cdb69f64.zip gcc-ea89b2482f97aa55e4d3fa4c57e0a6b2cdb69f64.tar.gz gcc-ea89b2482f97aa55e4d3fa4c57e0a6b2cdb69f64.tar.bz2 |
predefined_ops.h: New.
2013-09-27 François Dumont <fdumont@gcc.gnu.org>
* include/bits/predefined_ops.h: New.
* include/bits/stl_heap.h: Include <bits/predefined_ops.h>.
(__is_heap_until, __push_heap, __adjust_heap, __pop_heap): Remove
algo duplication.
(__is_heap): Adapt.
(__make_heap): New.
(make_heap): Adapt to use latter.
(__sort_heap): New.
(sort_heap): Adapt to use latter.
* include/bits/algobase.h: Include <bits/predefined_ops.h>.
(__lexicographical_compare_impl): New.
(__lexicographical_compare<false>::__lc): Adapt to use latter.
(lexicographical_compare): Likewise.
(__lower_bound): New.
(lower_bound): Adapt to use latter.
(equal): Use _GLIBCXX_STD_A::equal in N3671 overloads.
(__mismatch): New.
(mismatch): Use latter.
* include/bits/algo.h: Include <bits/predefined_ops.h>. Remove
<functional> include.
(__move_median_first, __find, __find_if, __find_if_not): Remove
algo duplication.
(__find_end): Likewise.
(__search_n): Rename into ...
(__search_n_aux): ... this.
(__search_n): Renew, use latter.
(search_n): Use latter.
(__search): New.
(search): Use latter.
(__find_end): Likewise.
(__remove_copy_if): New.
(remove_copy): Use latter.
(__adjacent_find): New.
(adjacent_find): Use latter.
(__unique): New.
(unique): Use latter.
(__unique_copy): Remove algo duplication.
(__stable_partition): New.
(stable_partition): Use latter.
(__heap_select): Remove algo duplication, use __make_heap.
(__partial_sort): New, use latter.
(partial_sort): Use latter.
(__partial_sort_copy): New.
(partial_sort_copy): Use latter.
(__unguarded_linear_insert, __insertion_sort): Remove algo
duplication.
(__unguarded_insertion_sort, __final_insertion_sort): Likewise.
(__unguarded_partition, __unguarded_partition_pivot): Likewise.
(__partial_sort): New.
(partial_sort): Use latter.
(__sort): New.
(sort): Use latter.
(lower_bound): Use __lower_bound.
(__upper_bound): New.
(upper_bound): Use latter.
(__equal_range): New.
(equal_range): Use latter.
(__move_merge_adaptive, __move_merge_adaptive_backward): Remove
algo duplication.
(__merge_adaptive, __merge_without_buffer): Likewise.
(__inplace_merge): New.
(inplace_merge): Use latter.
(__move_merge, __merge_sort_loop, __chunk_insertion_sort): Remove
algo duplication.
(__merge_sort_with_buffer, __stable_sort_adaptive): Likewise.
(__inplace_stable_sort): Likewise.
(__include): New.
(includes): Use latter.
(__next_permutation): New.
(next_permutation): Use latter.
(__prev_permutation): New.
(prev_permutation): Use latter.
(__replace_copy_if): New.
(replace_copy): Use latter.
(__is_sorted_until): New.
(is_sorted_unitl): Use latter.
(__minmax_element): New.
(minmax_element): Use latter.
(__is_permutation): New.
(is_permutation): Use latter.
(__adjacent_find): New.
(adjacent_find): Use latter.
(__count_if): New.
(count): Use latter.
(count_if): Likewise.
(__merge): New.
(merge): Use latter.
(__stable_sort): New.
(stable_sort): Use latter.
(__set_union): New.
(set_union): Use latter.
(__set_intersection): New.
(set_intersection): Use latter.
(__set_difference): New.
(set_difference): Use latter.
(__set_symmetric_difference): New.
(set_symmetric_difference): Use latter.
(__min_element): New.
(min_element): Use latter.
(__max_element): New.
(max_element): Use latter.
* include/Makefile.am: Add predefined_ops.h.
* include/Makefile.in: Regenerate.
* include/parallel/algobase.h (equal, mismatch): Add overloads
from N3671.
* testsuite/25_algorithms/is_permutation/vectorbool.cc: New.
* testsuite/25_algorithms/adjacent_find/vectorbool.cc: Likewise.
* testsuite/25_algorithms/find/vectorbool.cc: Likewise.
* testsuite/25_algorithms/find_if/vectorbool.cc: Likewise.
* testsuite/25_algorithms/find_first_of/vectorbool.cc: Likewise.
* testsuite/25_algorithms/heap/vectorbool.cc: Likewise.
* testsuite/25_algorithms/find_end/vectorbool.cc: Likewise.
* testsuite/25_algorithms/find_if_not/vectorbool.cc: Likewise.
From-SVN: r202992
Diffstat (limited to 'libstdc++-v3/include')
-rw-r--r-- | libstdc++-v3/include/Makefile.am | 1 | ||||
-rw-r--r-- | libstdc++-v3/include/Makefile.in | 1 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/predefined_ops.h | 304 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/stl_algo.h | 3013 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/stl_algobase.h | 174 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/stl_heap.h | 232 | ||||
-rw-r--r-- | libstdc++-v3/include/parallel/algobase.h | 35 |
7 files changed, 1563 insertions, 2197 deletions
diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am index 3be6e575..1a4fd6f 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 cd0b467..87a9f1b 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 0000000..30870b7 --- /dev/null +++ b/libstdc++-v3/include/bits/predefined_ops.h @@ -0,0 +1,304 @@ +// Default predicates for internal use -*- C++ -*- + +// Copyright (C) 2013 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file predefined_ops.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _GLIBCXX_PREDEFINED_OPS_H +#define _GLIBCXX_PREDEFINED_OPS_H 1 + +namespace __gnu_cxx +{ +namespace __ops +{ + struct _Iter_less_iter + { + template<typename _Iterator1, typename _Iterator2> + bool + operator()(_Iterator1 __it1, _Iterator2 __it2) const + { return *__it1 < *__it2; } + }; + + inline _Iter_less_iter + __iter_less_iter() + { return _Iter_less_iter(); } + + struct _Iter_less_val + { + template<typename _Iterator, typename _Value> + bool + operator()(_Iterator __it, _Value& __val) const + { return *__it < __val; } + }; + + inline _Iter_less_val + __iter_less_val() + { return _Iter_less_val(); } + + inline _Iter_less_val + __iter_comp_val(_Iter_less_iter) + { return _Iter_less_val(); } + + struct _Val_less_iter + { + template<typename _Value, typename _Iterator> + bool + operator()(_Value& __val, _Iterator __it) const + { return __val < *__it; } + }; + + inline _Val_less_iter + __val_less_iter() + { return _Val_less_iter(); } + + inline _Val_less_iter + __val_comp_iter(_Iter_less_iter) + { return _Val_less_iter(); } + + struct _Iter_equal_to_iter + { + template<typename _Iterator1, typename _Iterator2> + bool + operator()(_Iterator1 __it1, _Iterator2 __it2) const + { return *__it1 == *__it2; } + }; + + inline _Iter_equal_to_iter + __iter_equal_to_iter() + { return _Iter_equal_to_iter(); } + + struct _Iter_equal_to_val + { + template<typename _Iterator, typename _Value> + bool + operator()(_Iterator __it, _Value& __val) const + { return *__it == __val; } + }; + + inline _Iter_equal_to_val + __iter_equal_to_val() + { return _Iter_equal_to_val(); } + + inline _Iter_equal_to_val + __iter_comp_val(_Iter_equal_to_iter) + { return _Iter_equal_to_val(); } + + template<typename _Compare> + struct _Iter_comp_iter + { + _Compare _M_comp; + + _Iter_comp_iter(_Compare __comp) + : _M_comp(__comp) + { } + + template<typename _Iterator1, typename _Iterator2> + bool + operator()(_Iterator1 __it1, _Iterator2 __it2) + { return bool(_M_comp(*__it1, *__it2)); } + }; + + template<typename _Compare> + inline _Iter_comp_iter<_Compare> + __iter_comp_iter(_Compare __comp) + { return _Iter_comp_iter<_Compare>(__comp); } + + template<typename _Compare> + struct _Iter_comp_val + { + _Compare _M_comp; + + _Iter_comp_val(_Compare __comp) + : _M_comp(__comp) + { } + + template<typename _Iterator, typename _Value> + bool + operator()(_Iterator __it, _Value& __val) + { return bool(_M_comp(*__it, __val)); } + }; + + template<typename _Compare> + inline _Iter_comp_val<_Compare> + __iter_comp_val(_Compare __comp) + { return _Iter_comp_val<_Compare>(__comp); } + + template<typename _Compare> + inline _Iter_comp_val<_Compare> + __iter_comp_val(_Iter_comp_iter<_Compare> __comp) + { return _Iter_comp_val<_Compare>(__comp._M_comp); } + + template<typename _Compare> + struct _Val_comp_iter + { + _Compare _M_comp; + + _Val_comp_iter(_Compare __comp) + : _M_comp(__comp) + { } + + template<typename _Value, typename _Iterator> + bool + operator()(_Value& __val, _Iterator __it) + { return bool(_M_comp(__val, *__it)); } + }; + + template<typename _Compare> + inline _Val_comp_iter<_Compare> + __val_comp_iter(_Compare __comp) + { return _Val_comp_iter<_Compare>(__comp); } + + template<typename _Compare> + inline _Val_comp_iter<_Compare> + __val_comp_iter(_Iter_comp_iter<_Compare> __comp) + { return _Val_comp_iter<_Compare>(__comp._M_comp); } + + template<typename _Value> + struct _Iter_equals_val + { + _Value& _M_value; + + _Iter_equals_val(_Value& __value) + : _M_value(__value) + { } + + template<typename _Iterator> + bool + operator()(_Iterator __it) + { return *__it == _M_value; } + }; + + template<typename _Value> + inline _Iter_equals_val<_Value> + __iter_equals_val(_Value& __val) + { return _Iter_equals_val<_Value>(__val); } + + template<typename _Iterator1> + struct _Iter_equals_iter + { + typename std::iterator_traits<_Iterator1>::reference _M_ref; + + _Iter_equals_iter(_Iterator1 __it1) + : _M_ref(*__it1) + { } + + template<typename _Iterator2> + bool + operator()(_Iterator2 __it2) + { return *__it2 == _M_ref; } + }; + + template<typename _Iterator> + inline _Iter_equals_iter<_Iterator> + __iter_comp_iter(_Iter_equal_to_iter, _Iterator __it) + { return _Iter_equals_iter<_Iterator>(__it); } + + template<typename _Predicate> + struct _Iter_pred + { + _Predicate _M_pred; + + _Iter_pred(_Predicate __pred) + : _M_pred(__pred) + { } + + template<typename _Iterator> + bool + operator()(_Iterator __it) + { return bool(_M_pred(*__it)); } + }; + + template<typename _Predicate> + inline _Iter_pred<_Predicate> + __pred_iter(_Predicate __pred) + { return _Iter_pred<_Predicate>(__pred); } + + template<typename _Compare, typename _Value> + struct _Iter_comp_to_val + { + _Compare _M_comp; + _Value& _M_value; + + _Iter_comp_to_val(_Compare __comp, _Value& __value) + : _M_comp(__comp), _M_value(__value) + { } + + template<typename _Iterator> + bool + operator()(_Iterator __it) + { return bool(_M_comp(*__it, _M_value)); } + }; + + template<typename _Compare, typename _Value> + _Iter_comp_to_val<_Compare, _Value> + __iter_comp_val(_Compare __comp, _Value &__val) + { return _Iter_comp_to_val<_Compare, _Value>(__comp, __val); } + + template<typename _Compare, typename _Iterator1> + struct _Iter_comp_to_iter + { + _Compare _M_comp; + typename std::iterator_traits<_Iterator1>::reference _M_ref; + + _Iter_comp_to_iter(_Compare __comp, _Iterator1 __it1) + : _M_comp(__comp), _M_ref(*__it1) + { } + + template<typename _Iterator2> + bool + operator()(_Iterator2 __it2) + { return bool(_M_comp(*__it2, _M_ref)); } + }; + + template<typename _Compare, typename _Iterator> + inline _Iter_comp_to_iter<_Compare, _Iterator> + __iter_comp_iter(_Iter_comp_iter<_Compare> __comp, _Iterator __it) + { return _Iter_comp_to_iter<_Compare, _Iterator>(__comp._M_comp, __it); } + + template<typename _Predicate> + struct _Iter_negate + { + _Predicate _M_pred; + + _Iter_negate(_Predicate __pred) + : _M_pred(__pred) + { } + + template<typename _Iterator> + bool + operator()(_Iterator __it) + { return !bool(_M_pred(*__it)); } + }; + + template<typename _Predicate> + inline _Iter_negate<_Predicate> + __negate(_Iter_pred<_Predicate> __pred) + { return _Iter_negate<_Predicate>(__pred._M_pred); } + +} // namespace __ops +} // namespace __gnu_cxx + +#endif diff --git a/libstdc++-v3/include/bits/stl_algo.h b/libstdc++-v3/include/bits/stl_algo.h index b06211e..36f03a4 100644 --- a/libstdc++-v3/include/bits/stl_algo.h +++ b/libstdc++-v3/include/bits/stl_algo.h @@ -60,10 +60,10 @@ #include <bits/algorithmfwd.h> #include <bits/stl_heap.h> #include <bits/stl_tempbuf.h> // for _Temporary_buffer +#include <bits/predefined_ops.h> #if __cplusplus >= 201103L #include <random> // for std::uniform_int_distribution -#include <functional> // for std::bind #endif // See concept_check.h for the __glibcxx_*_requires macros. @@ -72,129 +72,39 @@ namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION - /// Swaps the median value of *__a, *__b and *__c to *__a - template<typename _Iterator> - void - __move_median_first(_Iterator __a, _Iterator __b, _Iterator __c) - { - // concept requirements - __glibcxx_function_requires(_LessThanComparableConcept< - typename iterator_traits<_Iterator>::value_type>) - - if (*__a < *__b) - { - if (*__b < *__c) - std::iter_swap(__a, __b); - else if (*__a < *__c) - std::iter_swap(__a, __c); - } - else if (*__a < *__c) - return; - else if (*__b < *__c) - std::iter_swap(__a, __c); - else - std::iter_swap(__a, __b); - } - /// Swaps the median value of *__a, *__b and *__c under __comp to *__a template<typename _Iterator, typename _Compare> 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<typename _InputIterator, typename _Tp> - inline _InputIterator - __find(_InputIterator __first, _InputIterator __last, - const _Tp& __val, input_iterator_tag) - { - while (__first != __last && !(*__first == __val)) - ++__first; - return __first; - } - - /// This is an overload used by find_if() for the Input Iterator case. + /// This is an overload used by find algos for the Input Iterator case. template<typename _InputIterator, typename _Predicate> inline _InputIterator __find_if(_InputIterator __first, _InputIterator __last, _Predicate __pred, input_iterator_tag) { - while (__first != __last && !bool(__pred(*__first))) + while (__first != __last && !__pred(__first)) ++__first; return __first; } - /// This is an overload used by find() for the RAI case. - template<typename _RandomAccessIterator, typename _Tp> - _RandomAccessIterator - __find(_RandomAccessIterator __first, _RandomAccessIterator __last, - const _Tp& __val, random_access_iterator_tag) - { - typename iterator_traits<_RandomAccessIterator>::difference_type - __trip_count = (__last - __first) >> 2; - - for (; __trip_count > 0; --__trip_count) - { - if (*__first == __val) - return __first; - ++__first; - - if (*__first == __val) - return __first; - ++__first; - - if (*__first == __val) - return __first; - ++__first; - - if (*__first == __val) - return __first; - ++__first; - } - - switch (__last - __first) - { - case 3: - if (*__first == __val) - return __first; - ++__first; - case 2: - if (*__first == __val) - return __first; - ++__first; - case 1: - if (*__first == __val) - return __first; - ++__first; - case 0: - default: - return __last; - } - } - - /// This is an overload used by find_if() for the RAI case. + /// This is an overload used by find algos for the RAI case. template<typename _RandomAccessIterator, typename _Predicate> _RandomAccessIterator __find_if(_RandomAccessIterator __first, _RandomAccessIterator __last, @@ -205,19 +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<typename _InputIterator, typename _Predicate> - inline _InputIterator - __find_if_not(_InputIterator __first, _InputIterator __last, - _Predicate __pred, input_iterator_tag) + template<typename _Iterator, typename _Predicate> + inline _Iterator + __find_if(_Iterator __first, _Iterator __last, _Predicate __pred) { - while (__first != __last && bool(__pred(*__first))) - ++__first; - return __first; - } - - /// This is an overload used by find_if_not() for the RAI case. - template<typename _RandomAccessIterator, typename _Predicate> - _RandomAccessIterator - __find_if_not(_RandomAccessIterator __first, _RandomAccessIterator __last, - _Predicate __pred, random_access_iterator_tag) - { - 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<typename _ForwardIterator, typename _Integer, typename _Tp> - _ForwardIterator - __search_n(_ForwardIterator __first, _ForwardIterator __last, - _Integer __count, const _Tp& __val, - std::forward_iterator_tag) + template<typename _ForwardIterator1, typename _ForwardIterator2, + typename _BinaryPredicate> + _ForwardIterator1 + __search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2, + _BinaryPredicate __predicate) { - __first = _GLIBCXX_STD_A::find(__first, __last, __val); - while (__first != __last) - { - typename iterator_traits<_ForwardIterator>::difference_type - __n = __count; - _ForwardIterator __i = __first; - ++__i; - while (__i != __last && __n != 1 && *__i == __val) - { - ++__i; - --__n; - } - if (__n == 1) - return __first; - if (__i == __last) - return __last; - __first = _GLIBCXX_STD_A::find(++__i, __last, __val); - } - return __last; - } + // Test for empty ranges + if (__first1 == __last1 || __first2 == __last2) + return __first1; - /** - * This is an uglified - * search_n(_ForwardIterator, _ForwardIterator, _Integer, const _Tp&) - * overloaded for random access iterators. - */ - template<typename _RandomAccessIter, typename _Integer, typename _Tp> - _RandomAccessIter - __search_n(_RandomAccessIter __first, _RandomAccessIter __last, - _Integer __count, const _Tp& __val, - std::random_access_iterator_tag) - { - - typedef typename std::iterator_traits<_RandomAccessIter>::difference_type - _DistanceType; + // Test for a pattern of length 1. + _ForwardIterator2 __p1(__first2); + if (++__p1 == __last2) + return std::__find_if(__first1, __last1, + __gnu_cxx::__ops::__iter_comp_iter(__predicate, __first2)); - _DistanceType __tailSize = __last - __first; - _DistanceType __remainder = __count; + // General case. + _ForwardIterator2 __p; + _ForwardIterator1 __current = __first1; - while (__remainder <= __tailSize) // the main loop... + for (;;) { - __first += __remainder; - __tailSize -= __remainder; - // __first here is always pointing to one past the last element of - // next possible match. - _RandomAccessIter __backTrack = __first; - while (*--__backTrack == __val) + __first1 = + std::__find_if(__first1, __last1, + __gnu_cxx::__ops::__iter_comp_iter(__predicate, __first2)); + + if (__first1 == __last1) + return __last1; + + __p = __p1; + __current = __first1; + if (++__current == __last1) + return __last1; + + while (__predicate(__current, __p)) { - if (--__remainder == 0) - return (__first - __count); // Success + if (++__p == __last2) + return __first1; + if (++__current == __last1) + return __last1; } - __remainder = __count + 1 - (__first - __backTrack); + ++__first1; } - return __last; // Failure + return __first1; } // search_n /** - * This is an uglified - * search_n(_ForwardIterator, _ForwardIterator, _Integer, const _Tp&, - * _BinaryPredicate) - * overloaded for forward iterators. + * This is an helper function for search_n overloaded for forward iterators. */ - template<typename _ForwardIterator, typename _Integer, typename _Tp, - typename _BinaryPredicate> + template<typename _ForwardIterator, typename _Integer, + typename _UnaryPredicate> _ForwardIterator - __search_n(_ForwardIterator __first, _ForwardIterator __last, - _Integer __count, const _Tp& __val, - _BinaryPredicate __binary_pred, std::forward_iterator_tag) + __search_n_aux(_ForwardIterator __first, _ForwardIterator __last, + _Integer __count, _UnaryPredicate __unary_pred, + std::forward_iterator_tag) { - while (__first != __last && !bool(__binary_pred(*__first, __val))) - ++__first; - + __first = std::__find_if(__first, __last, __unary_pred); while (__first != __last) { typename iterator_traits<_ForwardIterator>::difference_type __n = __count; _ForwardIterator __i = __first; ++__i; - while (__i != __last && __n != 1 && bool(__binary_pred(*__i, __val))) + while (__i != __last && __n != 1 && __unary_pred(__i)) { ++__i; --__n; @@ -437,28 +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<typename _RandomAccessIter, typename _Integer, typename _Tp, - typename _BinaryPredicate> + template<typename _RandomAccessIter, typename _Integer, + typename _UnaryPredicate> _RandomAccessIter - __search_n(_RandomAccessIter __first, _RandomAccessIter __last, - _Integer __count, const _Tp& __val, - _BinaryPredicate __binary_pred, std::random_access_iterator_tag) + __search_n_aux(_RandomAccessIter __first, _RandomAccessIter __last, + _Integer __count, _UnaryPredicate __unary_pred, + std::random_access_iterator_tag) { - typedef typename std::iterator_traits<_RandomAccessIter>::difference_type _DistanceType; @@ -472,7 +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<typename _ForwardIterator1, typename _ForwardIterator2> - _ForwardIterator1 - __find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator2 __last2, - forward_iterator_tag, forward_iterator_tag) + template<typename _ForwardIterator, typename _Integer, + typename _UnaryPredicate> + _ForwardIterator + __search_n(_ForwardIterator __first, _ForwardIterator __last, + _Integer __count, + _UnaryPredicate __unary_pred) { - if (__first2 == __last2) - return __last1; - else - { - _ForwardIterator1 __result = __last1; - while (1) - { - _ForwardIterator1 __new_result - = _GLIBCXX_STD_A::search(__first1, __last1, __first2, __last2); - if (__new_result == __last1) - return __result; - else - { - __result = __new_result; - __first1 = __new_result; - ++__first1; - } - } - } + if (__count <= 0) + return __first; + + if (__count == 1) + return std::__find_if(__first, __last, __unary_pred); + + return std::__search_n_aux(__first, __last, __count, __unary_pred, + std::__iterator_category(__first)); } + // find_end for forward iterators. template<typename _ForwardIterator1, typename _ForwardIterator2, typename _BinaryPredicate> _ForwardIterator1 @@ -520,61 +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<typename _BidirectionalIterator1, typename _BidirectionalIterator2> - _BidirectionalIterator1 - __find_end(_BidirectionalIterator1 __first1, - _BidirectionalIterator1 __last1, - _BidirectionalIterator2 __first2, - _BidirectionalIterator2 __last2, - bidirectional_iterator_tag, bidirectional_iterator_tag) - { - // concept requirements - __glibcxx_function_requires(_BidirectionalIteratorConcept< - _BidirectionalIterator1>) - __glibcxx_function_requires(_BidirectionalIteratorConcept< - _BidirectionalIterator2>) - - typedef reverse_iterator<_BidirectionalIterator1> _RevIterator1; - typedef reverse_iterator<_BidirectionalIterator2> _RevIterator2; - - _RevIterator1 __rlast1(__first1); - _RevIterator2 __rlast2(__first2); - _RevIterator1 __rresult = _GLIBCXX_STD_A::search(_RevIterator1(__last1), - __rlast1, - _RevIterator2(__last2), - __rlast2); - - if (__rresult == __rlast1) - return __last1; - else - { - _BidirectionalIterator1 __result = __rresult.base(); - std::advance(__result, -std::distance(__first2, __last2)); - return __result; - } - } - template<typename _BidirectionalIterator1, typename _BidirectionalIterator2, typename _BinaryPredicate> _BidirectionalIterator1 @@ -596,9 +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,6 +631,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } #endif + template<typename _InputIterator, typename _OutputIterator, + typename _Predicate> + _OutputIterator + __remove_copy_if(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, _Predicate __pred) + { + for (; __first != __last; ++__first) + if (!__pred(__first)) + { + *__result = *__first; + ++__result; + } + return __result; + } /** * @brief Copy a sequence, removing elements of a given value. @@ -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<typename _InputIterator, typename _Size, typename _OutputIterator> _OutputIterator __copy_n(_InputIterator __first, _Size __n, @@ -1063,6 +850,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } #endif + template<typename _ForwardIterator, typename _Predicate> + _ForwardIterator + __remove_if(_ForwardIterator __first, _ForwardIterator __last, + _Predicate __pred) + { + __first = std::__find_if(__first, __last, __pred); + if (__first == __last) + return __first; + _ForwardIterator __result = __first; + ++__first; + for (; __first != __last; ++__first) + if (!__pred(__first)) + { + *__result = _GLIBCXX_MOVE(*__first); + ++__result; + } + return __result; + } + /** * @brief Remove elements from a sequence. * @ingroup mutating_algorithms @@ -1081,7 +887,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * are still present, but their value is unspecified. */ template<typename _ForwardIterator, typename _Tp> - _ForwardIterator + inline _ForwardIterator remove(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { @@ -1092,18 +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<typename _ForwardIterator, typename _Predicate> - _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<typename _ForwardIterator, typename _BinaryPredicate> + _ForwardIterator + __adjacent_find(_ForwardIterator __first, _ForwardIterator __last, + _BinaryPredicate __binary_pred) + { + if (__first == __last) + return __last; + _ForwardIterator __next = __first; + while (++__next != __last) + { + if (__binary_pred(__first, __next)) + return __first; + __first = __next; + } + return __last; + } + + template<typename _ForwardIterator, typename _BinaryPredicate> + _ForwardIterator + __unique(_ForwardIterator __first, _ForwardIterator __last, + _BinaryPredicate __binary_pred) + { + // Skip the beginning, if already unique. + __first = std::__adjacent_find(__first, __last, __binary_pred); + if (__first == __last) + return __last; + + // Do the real copy work. + _ForwardIterator __dest = __first; ++__first; - for(; __first != __last; ++__first) - if(!bool(__pred(*__first))) - { - *__result = _GLIBCXX_MOVE(*__first); - ++__result; - } - return __result; + while (++__first != __last) + if (!__binary_pred(__dest, __first)) + *++__dest = _GLIBCXX_MOVE(*__first); + return ++__dest; } /** @@ -1164,7 +986,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * are still present, but their value is unspecified. */ template<typename _ForwardIterator> - _ForwardIterator + inline _ForwardIterator unique(_ForwardIterator __first, _ForwardIterator __last) { // concept requirements @@ -1174,18 +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<typename _ForwardIterator, typename _BinaryPredicate> - _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<typename _ForwardIterator, typename _OutputIterator> - _OutputIterator - __unique_copy(_ForwardIterator __first, _ForwardIterator __last, - _OutputIterator __result, - forward_iterator_tag, output_iterator_tag) - { - // concept requirements -- taken care of in dispatching function - _ForwardIterator __next = __first; - *__result = *__first; - while (++__next != __last) - if (!(*__first == *__next)) - { - __first = __next; - *++__result = *__first; - } - return ++__result; - } - - /** - * This is an uglified unique_copy(_InputIterator, _InputIterator, - * _OutputIterator) - * overloaded for input iterators and output iterator as result. - */ - template<typename _InputIterator, typename _OutputIterator> - _OutputIterator - __unique_copy(_InputIterator __first, _InputIterator __last, - _OutputIterator __result, - input_iterator_tag, output_iterator_tag) - { - // concept requirements -- taken care of in dispatching function - typename iterator_traits<_InputIterator>::value_type __value = *__first; - *__result = __value; - while (++__first != __last) - if (!(__value == *__first)) - { - __value = *__first; - *++__result = __value; - } - return ++__result; - } - - /** - * This is an uglified unique_copy(_InputIterator, _InputIterator, - * _OutputIterator) - * overloaded for input iterators and forward iterator as result. - */ - template<typename _InputIterator, typename _ForwardIterator> - _ForwardIterator - __unique_copy(_InputIterator __first, _InputIterator __last, - _ForwardIterator __result, - input_iterator_tag, forward_iterator_tag) - { - // concept requirements -- taken care of in dispatching function - *__result = *__first; - while (++__first != __last) - if (!(*__result == *__first)) - *++__result = *__first; - return ++__result; + return std::__unique(__first, __last, + __gnu_cxx::__ops::__iter_comp_iter(__binary_pred)); } /** @@ -1316,7 +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<typename _ForwardIterator, typename _Pointer, typename _Predicate, typename _Distance> @@ -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<typename _ForwardIterator, typename _Predicate> + _ForwardIterator + __stable_partition(_ForwardIterator __first, _ForwardIterator __last, + _Predicate __pred) + { + __first = std::__find_if_not(__first, __last, __pred); + + if (__first == __last) + return __first; + + typedef typename iterator_traits<_ForwardIterator>::value_type + _ValueType; + typedef typename iterator_traits<_ForwardIterator>::difference_type + _DistanceType; + + _Temporary_buffer<_ForwardIterator, _ValueType> __buf(__first, __last); + if (__buf.size() > 0) + return + std::__stable_partition_adaptive(__first, __last, __pred, + _DistanceType(__buf.requested_size()), + __buf.begin(), + _DistanceType(__buf.size())); + else + return + std::__inplace_stable_partition(__first, __pred, + _DistanceType(__buf.requested_size())); + } + /** * @brief Move elements for which a predicate is true to the beginning * of a sequence, preserving relative ordering. @@ -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<typename _RandomAccessIterator> - void - __heap_select(_RandomAccessIterator __first, - _RandomAccessIterator __middle, - _RandomAccessIterator __last) - { - std::make_heap(__first, __middle); - for (_RandomAccessIterator __i = __middle; __i < __last; ++__i) - if (*__i < *__first) - std::__pop_heap(__first, __middle, __i); + return std::__stable_partition(__first, __last, + __gnu_cxx::__ops::__pred_iter(__pred)); } /// This is a helper function for the sort routines. @@ -1937,14 +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<typename _InputIterator, typename _RandomAccessIterator, + typename _Compare> + _RandomAccessIterator + __partial_sort_copy(_InputIterator __first, _InputIterator __last, + _RandomAccessIterator __result_first, + _RandomAccessIterator __result_last, + _Compare __comp) + { + typedef typename iterator_traits<_InputIterator>::value_type + _InputValueType; + typedef iterator_traits<_RandomAccessIterator> _RItTraits; + typedef typename _RItTraits::difference_type _DistanceType; + + if (__result_first == __result_last) + return __result_last; + _RandomAccessIterator __result_real_last = __result_first; + while (__first != __last && __result_real_last != __result_last) + { + *__result_real_last = *__first; + ++__result_real_last; + ++__first; + } + + std::__make_heap(__result_first, __result_real_last, __comp); + while (__first != __last) + { + if (__comp(__first, __result_first)) + std::__adjust_heap(__result_first, _DistanceType(0), + _DistanceType(__result_real_last + - __result_first), + _InputValueType(*__first), __comp); + ++__first; + } + std::__sort_heap(__result_first, __result_real_last, __comp); + return __result_real_last; + } + /** * @brief Copy the smallest elements of a sequence. * @ingroup sorting_algorithms @@ -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<typename _InputIterator, typename _RandomAccessIterator, typename _Compare> + template<typename _InputIterator, typename _RandomAccessIterator, + typename _Compare> _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<typename _RandomAccessIterator> - void - __unguarded_linear_insert(_RandomAccessIterator __last) - { - typename iterator_traits<_RandomAccessIterator>::value_type - __val = _GLIBCXX_MOVE(*__last); - _RandomAccessIterator __next = __last; - --__next; - while (__val < *__next) - { - *__last = _GLIBCXX_MOVE(*__next); - __last = __next; - --__next; - } - *__last = _GLIBCXX_MOVE(__val); + return std::__partial_sort_copy(__first, __last, + __result_first, __result_last, + __gnu_cxx::__ops::__iter_comp_iter(__comp)); } /// This is a helper function for the sort routine. @@ -2108,7 +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; @@ -2118,29 +1833,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } /// This is a helper function for the sort routine. - template<typename _RandomAccessIterator> - void - __insertion_sort(_RandomAccessIterator __first, - _RandomAccessIterator __last) - { - if (__first == __last) - return; - - for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i) - { - if (*__i < *__first) - { - typename iterator_traits<_RandomAccessIterator>::value_type - __val = _GLIBCXX_MOVE(*__i); - _GLIBCXX_MOVE_BACKWARD3(__first, __i, __i + 1); - *__first = _GLIBCXX_MOVE(__val); - } - else - std::__unguarded_linear_insert(__i); - } - } - - /// This is a helper function for the sort routine. template<typename _RandomAccessIterator, typename _Compare> void __insertion_sort(_RandomAccessIterator __first, @@ -2150,7 +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<typename _RandomAccessIterator> - inline void - __unguarded_insertion_sort(_RandomAccessIterator __first, - _RandomAccessIterator __last) - { - typedef typename iterator_traits<_RandomAccessIterator>::value_type - _ValueType; - - for (_RandomAccessIterator __i = __first; __i != __last; ++__i) - std::__unguarded_linear_insert(__i); - } - - /// This is a helper function for the sort routine. template<typename _RandomAccessIterator, typename _Compare> inline void __unguarded_insertion_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { - typedef typename iterator_traits<_RandomAccessIterator>::value_type - _ValueType; - for (_RandomAccessIterator __i = __first; __i != __last; ++__i) - std::__unguarded_linear_insert(__i, __comp); + std::__unguarded_linear_insert(__i, + __gnu_cxx::__ops::__val_comp_iter(__comp)); } /** @@ -2195,21 +1873,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION enum { _S_threshold = 16 }; /// This is a helper function for the sort routine. - template<typename _RandomAccessIterator> - void - __final_insertion_sort(_RandomAccessIterator __first, - _RandomAccessIterator __last) - { - if (__last - __first > int(_S_threshold)) - { - std::__insertion_sort(__first, __first + int(_S_threshold)); - std::__unguarded_insertion_sort(__first + int(_S_threshold), __last); - } - else - std::__insertion_sort(__first, __last); - } - - /// This is a helper function for the sort routine. template<typename _RandomAccessIterator, typename _Compare> void __final_insertion_sort(_RandomAccessIterator __first, @@ -2226,38 +1889,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } /// This is a helper function... - template<typename _RandomAccessIterator, typename _Tp> - _RandomAccessIterator - __unguarded_partition(_RandomAccessIterator __first, - _RandomAccessIterator __last, const _Tp& __pivot) - { - while (true) - { - while (*__first < __pivot) - ++__first; - --__last; - while (__pivot < *__last) - --__last; - if (!(__first < __last)) - return __first; - std::iter_swap(__first, __last); - ++__first; - } - } - - /// This is a helper function... - template<typename _RandomAccessIterator, typename _Tp, typename _Compare> + template<typename _RandomAccessIterator, typename _Compare> _RandomAccessIterator __unguarded_partition(_RandomAccessIterator __first, _RandomAccessIterator __last, - const _Tp& __pivot, _Compare __comp) + _RandomAccessIterator __pivot, _Compare __comp) { while (true) { - while (__comp(*__first, __pivot)) + while (__comp(__first, __pivot)) ++__first; --__last; - while (__comp(__pivot, *__last)) + while (__comp(__pivot, __last)) --__last; if (!(__first < __last)) return __first; @@ -2267,18 +1910,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } /// This is a helper function... - template<typename _RandomAccessIterator> - inline _RandomAccessIterator - __unguarded_partition_pivot(_RandomAccessIterator __first, - _RandomAccessIterator __last) - { - _RandomAccessIterator __mid = __first + (__last - __first) / 2; - std::__move_median_first(__first, __mid, (__last - 1)); - return std::__unguarded_partition(__first + 1, __last, *__first); - } - - - /// This is a helper function... template<typename _RandomAccessIterator, typename _Compare> inline _RandomAccessIterator __unguarded_partition_pivot(_RandomAccessIterator __first, @@ -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<typename _RandomAccessIterator, typename _Size> - void - __introsort_loop(_RandomAccessIterator __first, - _RandomAccessIterator __last, - _Size __depth_limit) + template<typename _RandomAccessIterator, typename _Compare> + inline void + __partial_sort(_RandomAccessIterator __first, + _RandomAccessIterator __middle, + _RandomAccessIterator __last, + _Compare __comp) { - while (__last - __first > int(_S_threshold)) - { - if (__depth_limit == 0) - { - _GLIBCXX_STD_A::partial_sort(__first, __last, __last); - return; - } - --__depth_limit; - _RandomAccessIterator __cut = - std::__unguarded_partition_pivot(__first, __last); - std::__introsort_loop(__cut, __last, __depth_limit); - __last = __cut; - } + std::__heap_select(__first, __middle, __last, __comp); + std::__sort_heap(__first, __middle, __comp); } /// This is a helper function for the sort routine. @@ -2322,7 +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<typename _RandomAccessIterator, typename _Size> - void - __introselect(_RandomAccessIterator __first, _RandomAccessIterator __nth, - _RandomAccessIterator __last, _Size __depth_limit) + template<typename _RandomAccessIterator, typename _Compare> + inline void + __sort(_RandomAccessIterator __first, _RandomAccessIterator __last, + _Compare __comp) { - typedef typename iterator_traits<_RandomAccessIterator>::value_type - _ValueType; - - while (__last - __first > 3) + if (__first != __last) { - if (__depth_limit == 0) - { - std::__heap_select(__first, __nth + 1, __last); - - // Place the nth largest element in its final position. - std::iter_swap(__first, __nth); - return; - } - --__depth_limit; - _RandomAccessIterator __cut = - std::__unguarded_partition_pivot(__first, __last); - if (__cut <= __nth) - __first = __cut; - else - __last = __cut; + std::__introsort_loop(__first, __last, + std::__lg(__last - __first) * 2, + __comp); + std::__final_insertion_sort(__first, __last, __comp); } - std::__insertion_sort(__first, __last); } template<typename _RandomAccessIterator, typename _Size, typename _Compare> @@ -2370,9 +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<typename _ForwardIterator, typename _Tp, typename _Compare> + _ForwardIterator + __upper_bound(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __val, _Compare __comp) + { + typedef typename iterator_traits<_ForwardIterator>::difference_type + _DistanceType; + _DistanceType __len = std::distance(__first, __last); while (__len > 0) @@ -2437,14 +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<typename _ForwardIterator, typename _Tp, + typename _CompareItTp, typename _CompareTpIt> + pair<_ForwardIterator, _ForwardIterator> + __equal_range(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __val, + _CompareItTp __comp_it_val, _CompareTpIt __comp_val_it) + { + typedef typename iterator_traits<_ForwardIterator>::difference_type + _DistanceType; + _DistanceType __len = std::distance(__first, __last); while (__len > 0) @@ -2533,16 +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,7 +2303,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __glibcxx_requires_partitioned_upper_pred(__first, __last, __val, __comp); - _ForwardIterator __i = std::lower_bound(__first, __last, __val, __comp); + _ForwardIterator __i + = std::__lower_bound(__first, __last, __val, + __gnu_cxx::__ops::__iter_comp_val(__comp)); return __i != __last && !bool(__comp(__val, *__i)); } @@ -2743,32 +2313,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /// This is a helper function for the __merge_adaptive routines. template<typename _InputIterator1, typename _InputIterator2, - typename _OutputIterator> - void - __move_merge_adaptive(_InputIterator1 __first1, _InputIterator1 __last1, - _InputIterator2 __first2, _InputIterator2 __last2, - _OutputIterator __result) - { - while (__first1 != __last1 && __first2 != __last2) - { - if (*__first2 < *__first1) - { - *__result = _GLIBCXX_MOVE(*__first2); - ++__first2; - } - else - { - *__result = _GLIBCXX_MOVE(*__first1); - ++__first1; - } - ++__result; - } - if (__first1 != __last1) - _GLIBCXX_MOVE3(__first1, __last1, __result); - } - - /// This is a helper function for the __merge_adaptive routines. - template<typename _InputIterator1, typename _InputIterator2, typename _OutputIterator, typename _Compare> void __move_merge_adaptive(_InputIterator1 __first1, _InputIterator1 __last1, @@ -2777,7 +2321,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { while (__first1 != __last1 && __first2 != __last2) { - if (__comp(*__first2, *__first1)) + if (__comp(__first2, __first1)) { *__result = _GLIBCXX_MOVE(*__first2); ++__first2; @@ -2795,48 +2339,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /// This is a helper function for the __merge_adaptive routines. template<typename _BidirectionalIterator1, typename _BidirectionalIterator2, - typename _BidirectionalIterator3> - void - __move_merge_adaptive_backward(_BidirectionalIterator1 __first1, - _BidirectionalIterator1 __last1, - _BidirectionalIterator2 __first2, - _BidirectionalIterator2 __last2, - _BidirectionalIterator3 __result) - { - if (__first1 == __last1) - { - _GLIBCXX_MOVE_BACKWARD3(__first2, __last2, __result); - return; - } - else if (__first2 == __last2) - return; - - --__last1; - --__last2; - while (true) - { - if (*__last2 < *__last1) - { - *--__result = _GLIBCXX_MOVE(*__last1); - if (__first1 == __last1) - { - _GLIBCXX_MOVE_BACKWARD3(__first2, ++__last2, __result); - return; - } - --__last1; - } - else - { - *--__result = _GLIBCXX_MOVE(*__last2); - if (__first2 == __last2) - return; - --__last2; - } - } - } - - /// This is a helper function for the __merge_adaptive routines. - template<typename _BidirectionalIterator1, typename _BidirectionalIterator2, typename _BidirectionalIterator3, typename _Compare> void __move_merge_adaptive_backward(_BidirectionalIterator1 __first1, @@ -2858,7 +2360,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION --__last2; while (true) { - if (__comp(*__last2, *__last1)) + if (__comp(__last2, __last1)) { *--__result = _GLIBCXX_MOVE(*__last1); if (__first1 == __last1) @@ -2921,62 +2423,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } /// This is a helper function for the merge routines. - template<typename _BidirectionalIterator, typename _Distance, - typename _Pointer> - void - __merge_adaptive(_BidirectionalIterator __first, - _BidirectionalIterator __middle, - _BidirectionalIterator __last, - _Distance __len1, _Distance __len2, - _Pointer __buffer, _Distance __buffer_size) - { - if (__len1 <= __len2 && __len1 <= __buffer_size) - { - _Pointer __buffer_end = _GLIBCXX_MOVE3(__first, __middle, __buffer); - std::__move_merge_adaptive(__buffer, __buffer_end, __middle, __last, - __first); - } - else if (__len2 <= __buffer_size) - { - _Pointer __buffer_end = _GLIBCXX_MOVE3(__middle, __last, __buffer); - std::__move_merge_adaptive_backward(__first, __middle, __buffer, - __buffer_end, __last); - } - else - { - _BidirectionalIterator __first_cut = __first; - _BidirectionalIterator __second_cut = __middle; - _Distance __len11 = 0; - _Distance __len22 = 0; - if (__len1 > __len2) - { - __len11 = __len1 / 2; - std::advance(__first_cut, __len11); - __second_cut = std::lower_bound(__middle, __last, - *__first_cut); - __len22 = std::distance(__middle, __second_cut); - } - else - { - __len22 = __len2 / 2; - std::advance(__second_cut, __len22); - __first_cut = std::upper_bound(__first, __middle, - *__second_cut); - __len11 = std::distance(__first, __first_cut); - } - _BidirectionalIterator __new_middle = - std::__rotate_adaptive(__first_cut, __middle, __second_cut, - __len1 - __len11, __len22, __buffer, - __buffer_size); - std::__merge_adaptive(__first, __first_cut, __new_middle, __len11, - __len22, __buffer, __buffer_size); - std::__merge_adaptive(__new_middle, __second_cut, __last, - __len1 - __len11, - __len2 - __len22, __buffer, __buffer_size); - } - } - - /// This is a helper function for the merge routines. template<typename _BidirectionalIterator, typename _Distance, typename _Pointer, typename _Compare> void @@ -3009,22 +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, @@ -3035,49 +2483,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } /// This is a helper function for the merge routines. - template<typename _BidirectionalIterator, typename _Distance> - void - __merge_without_buffer(_BidirectionalIterator __first, - _BidirectionalIterator __middle, - _BidirectionalIterator __last, - _Distance __len1, _Distance __len2) - { - if (__len1 == 0 || __len2 == 0) - return; - if (__len1 + __len2 == 2) - { - if (*__middle < *__first) - std::iter_swap(__first, __middle); - return; - } - _BidirectionalIterator __first_cut = __first; - _BidirectionalIterator __second_cut = __middle; - _Distance __len11 = 0; - _Distance __len22 = 0; - if (__len1 > __len2) - { - __len11 = __len1 / 2; - std::advance(__first_cut, __len11); - __second_cut = std::lower_bound(__middle, __last, *__first_cut); - __len22 = std::distance(__middle, __second_cut); - } - else - { - __len22 = __len2 / 2; - std::advance(__second_cut, __len22); - __first_cut = std::upper_bound(__first, __middle, *__second_cut); - __len11 = std::distance(__first, __first_cut); - } - std::rotate(__first_cut, __middle, __second_cut); - _BidirectionalIterator __new_middle = __first_cut; - std::advance(__new_middle, std::distance(__middle, __second_cut)); - std::__merge_without_buffer(__first, __first_cut, __new_middle, - __len11, __len22); - std::__merge_without_buffer(__new_middle, __second_cut, __last, - __len1 - __len11, __len2 - __len22); - } - - /// This is a helper function for the merge routines. template<typename _BidirectionalIterator, typename _Distance, typename _Compare> void @@ -3091,7 +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<typename _BidirectionalIterator, typename _Compare> + void + __inplace_merge(_BidirectionalIterator __first, + _BidirectionalIterator __middle, + _BidirectionalIterator __last, + _Compare __comp) + { + typedef typename iterator_traits<_BidirectionalIterator>::value_type + _ValueType; + typedef typename iterator_traits<_BidirectionalIterator>::difference_type + _DistanceType; + + if (__first == __middle || __middle == __last) + return; + + const _DistanceType __len1 = std::distance(__first, __middle); + const _DistanceType __len2 = std::distance(__middle, __last); + + typedef _Temporary_buffer<_BidirectionalIterator, _ValueType> _TmpBuf; + _TmpBuf __buf(__first, __last); + + if (__buf.begin() == 0) + std::__merge_without_buffer + (__first, __middle, __last, __len1, __len2, __comp); + else + std::__merge_adaptive + (__first, __middle, __last, __len1, __len2, __buf.begin(), + _DistanceType(__buf.size()), __comp); + } + /** * @brief Merges two sorted ranges in place. * @ingroup sorting_algorithms @@ -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<typename _InputIterator1, typename _InputIterator2, - typename _OutputIterator> - _OutputIterator - __move_merge(_InputIterator1 __first1, _InputIterator1 __last1, - _InputIterator2 __first2, _InputIterator2 __last2, - _OutputIterator __result) - { - while (__first1 != __last1 && __first2 != __last2) - { - if (*__first2 < *__first1) - { - *__result = _GLIBCXX_MOVE(*__first2); - ++__first2; - } - else - { - *__result = _GLIBCXX_MOVE(*__first1); - ++__first1; - } - ++__result; - } - return _GLIBCXX_MOVE3(__first2, __last2, - _GLIBCXX_MOVE3(__first1, __last1, - __result)); - } - - /// This is a helper function for the __merge_sort_loop routines. - template<typename _InputIterator1, typename _InputIterator2, - typename _OutputIterator, typename _Compare> + template<typename _InputIterator, typename _OutputIterator, + typename _Compare> _OutputIterator - __move_merge(_InputIterator1 __first1, _InputIterator1 __last1, - _InputIterator2 __first2, _InputIterator2 __last2, + __move_merge(_InputIterator __first1, _InputIterator __last1, + _InputIterator __first2, _InputIterator __last2, _OutputIterator __result, _Compare __comp) { while (__first1 != __last1 && __first2 != __last2) { - if (__comp(*__first2, *__first1)) + if (__comp(__first2, __first1)) { *__result = _GLIBCXX_MOVE(*__first2); ++__first2; @@ -3290,29 +2668,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } template<typename _RandomAccessIterator1, typename _RandomAccessIterator2, - typename _Distance> - void - __merge_sort_loop(_RandomAccessIterator1 __first, - _RandomAccessIterator1 __last, - _RandomAccessIterator2 __result, - _Distance __step_size) - { - const _Distance __two_step = 2 * __step_size; - - while (__last - __first >= __two_step) - { - __result = std::__move_merge(__first, __first + __step_size, - __first + __step_size, - __first + __two_step, __result); - __first += __two_step; - } - - __step_size = std::min(_Distance(__last - __first), __step_size); - std::__move_merge(__first, __first + __step_size, - __first + __step_size, __last, __result); - } - - template<typename _RandomAccessIterator1, typename _RandomAccessIterator2, typename _Distance, typename _Compare> void __merge_sort_loop(_RandomAccessIterator1 __first, @@ -3332,24 +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<typename _RandomAccessIterator, typename _Distance> - void - __chunk_insertion_sort(_RandomAccessIterator __first, - _RandomAccessIterator __last, - _Distance __chunk_size) - { - while (__last - __first >= __chunk_size) - { - std::__insertion_sort(__first, __first + __chunk_size); - __first += __chunk_size; - } - std::__insertion_sort(__first, __last); - } - template<typename _RandomAccessIterator, typename _Distance, typename _Compare> void @@ -3367,30 +2708,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION enum { _S_chunk_size = 7 }; - template<typename _RandomAccessIterator, typename _Pointer> - void - __merge_sort_with_buffer(_RandomAccessIterator __first, - _RandomAccessIterator __last, - _Pointer __buffer) - { - typedef typename iterator_traits<_RandomAccessIterator>::difference_type - _Distance; - - const _Distance __len = __last - __first; - const _Pointer __buffer_last = __buffer + __len; - - _Distance __step_size = _S_chunk_size; - std::__chunk_insertion_sort(__first, __last, __step_size); - - while (__step_size < __len) - { - std::__merge_sort_loop(__first, __last, __buffer, __step_size); - __step_size *= 2; - std::__merge_sort_loop(__buffer, __buffer_last, __first, __step_size); - __step_size *= 2; - } - } - template<typename _RandomAccessIterator, typename _Pointer, typename _Compare> void __merge_sort_with_buffer(_RandomAccessIterator __first, @@ -3418,33 +2735,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } template<typename _RandomAccessIterator, typename _Pointer, - typename _Distance> - void - __stable_sort_adaptive(_RandomAccessIterator __first, - _RandomAccessIterator __last, - _Pointer __buffer, _Distance __buffer_size) - { - const _Distance __len = (__last - __first + 1) / 2; - const _RandomAccessIterator __middle = __first + __len; - if (__len > __buffer_size) - { - std::__stable_sort_adaptive(__first, __middle, - __buffer, __buffer_size); - std::__stable_sort_adaptive(__middle, __last, - __buffer, __buffer_size); - } - else - { - std::__merge_sort_with_buffer(__first, __middle, __buffer); - std::__merge_sort_with_buffer(__middle, __last, __buffer); - } - std::__merge_adaptive(__first, __middle, __last, - _Distance(__middle - __first), - _Distance(__last - __middle), - __buffer, __buffer_size); - } - - template<typename _RandomAccessIterator, typename _Pointer, typename _Distance, typename _Compare> void __stable_sort_adaptive(_RandomAccessIterator __first, @@ -3474,25 +2764,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } /// This is a helper function for the stable sorting routines. - template<typename _RandomAccessIterator> - void - __inplace_stable_sort(_RandomAccessIterator __first, - _RandomAccessIterator __last) - { - if (__last - __first < 15) - { - std::__insertion_sort(__first, __last); - return; - } - _RandomAccessIterator __middle = __first + (__last - __first) / 2; - std::__inplace_stable_sort(__first, __middle); - std::__inplace_stable_sort(__middle, __last); - std::__merge_without_buffer(__first, __middle, __last, - __middle - __first, - __last - __middle); - } - - /// This is a helper function for the stable sorting routines. template<typename _RandomAccessIterator, typename _Compare> void __inplace_stable_sort(_RandomAccessIterator __first, @@ -3519,6 +2790,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // that their input ranges are sorted and the postcondition that their output // ranges are sorted. + template<typename _InputIterator1, typename _InputIterator2, + typename _Compare> + bool + __includes(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, + _Compare __comp) + { + while (__first1 != __last1 && __first2 != __last2) + if (__comp(__first2, __first1)) + return false; + else if (__comp(__first1, __first2)) + ++__first1; + else + ++__first1, ++__first2; + + return __first2 == __last2; + } + /** * @brief Determines whether all elements of a sequence exists in a range. * @param __first1 Start of search range. @@ -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<typename _BidirectionalIterator> + template<typename _BidirectionalIterator, typename _Compare> bool - next_permutation(_BidirectionalIterator __first, - _BidirectionalIterator __last) + __next_permutation(_BidirectionalIterator __first, + _BidirectionalIterator __last, _Compare __comp) { - // concept requirements - __glibcxx_function_requires(_BidirectionalIteratorConcept< - _BidirectionalIterator>) - __glibcxx_function_requires(_LessThanComparableConcept< - typename iterator_traits<_BidirectionalIterator>::value_type>) - __glibcxx_requires_valid_range(__first, __last); - if (__first == __last) return false; _BidirectionalIterator __i = __first; @@ -3667,24 +2919,54 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { _BidirectionalIterator __ii = __i; --__i; - if (*__i < *__ii) + if (__comp(__i, __ii)) { _BidirectionalIterator __j = __last; - while (!(*__i < *--__j)) + while (!__comp(__i, --__j)) {} std::iter_swap(__i, __j); - std::reverse(__ii, __last); + std::__reverse(__ii, __last, + std::__iterator_category(__first)); return true; } if (__i == __first) { - std::reverse(__first, __last); + std::__reverse(__first, __last, + std::__iterator_category(__first)); return false; } } } /** + * @brief Permute range into the next @e dictionary ordering. + * @ingroup sorting_algorithms + * @param __first Start of range. + * @param __last End of range. + * @return False if wrapped to first permutation, true otherwise. + * + * Treats all permutations of the range as a set of @e dictionary sorted + * sequences. Permutes the current sequence into the next one of this set. + * Returns true if there are more sequences to generate. If the sequence + * is the largest of the set, the smallest is generated and false returned. + */ + template<typename _BidirectionalIterator> + bool + next_permutation(_BidirectionalIterator __first, + _BidirectionalIterator __last) + { + // concept requirements + __glibcxx_function_requires(_BidirectionalIteratorConcept< + _BidirectionalIterator>) + __glibcxx_function_requires(_LessThanComparableConcept< + typename iterator_traits<_BidirectionalIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + return std::__next_permutation + (__first, __last, __gnu_cxx::__ops::__iter_less_iter()); + } + + /** * @brief Permute range into the next @e dictionary ordering using * comparison functor. * @ingroup sorting_algorithms @@ -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<typename _BidirectionalIterator, typename _Compare> + 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<typename _InputIterator, typename _OutputIterator, + typename _Predicate, typename _Tp> + _OutputIterator + __replace_copy_if(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, + _Predicate __pred, const _Tp& __new_value) + { + for (; __first != __last; ++__first, ++__result) + if (__pred(__first)) + *__result = __new_value; + else + *__result = *__first; + return __result; + } + /** * @brief Copy a sequence, replacing each element of one value with another * value. @@ -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 _InputIterator, typename _Predicate> + typename iterator_traits<_InputIterator>::difference_type + __count_if(_InputIterator __first, _InputIterator __last, _Predicate __pred) + { + typename iterator_traits<_InputIterator>::difference_type __n = 0; + for (; __first != __last; ++__first) + if (__pred(__first)) + ++__n; + return __n; } #if __cplusplus >= 201103L @@ -3960,6 +3221,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _Compare __comp) { return std::is_sorted_until(__first, __last, __comp) == __last; } + template<typename _ForwardIterator, typename _Compare> + _ForwardIterator + __is_sorted_until(_ForwardIterator __first, _ForwardIterator __last, + _Compare __comp) + { + if (__first == __last) + return __last; + + _ForwardIterator __next = __first; + for (++__next; __next != __last; __first = __next, ++__next) + if (__comp(__next, __first)) + return __next; + return __next; + } + /** * @brief Determines the end of a sorted sequence. * @ingroup sorting_algorithms @@ -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<const _Tp&, const _Tp&>(__a, __b); } - /** - * @brief Return a pair of iterators pointing to the minimum and maximum - * elements in a range. - * @ingroup sorting_algorithms - * @param __first Start of range. - * @param __last End of range. - * @return make_pair(m, M), where m is the first iterator i in - * [__first, __last) such that no other element in the range is - * smaller, and where M is the last iterator i in [__first, __last) - * such that no other element in the range is larger. - */ - template<typename _ForwardIterator> + template<typename _ForwardIterator, typename _Compare> pair<_ForwardIterator, _ForwardIterator> - minmax_element(_ForwardIterator __first, _ForwardIterator __last) + __minmax_element(_ForwardIterator __first, _ForwardIterator __last, + _Compare __comp) { - // concept requirements - __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) - __glibcxx_function_requires(_LessThanComparableConcept< - typename iterator_traits<_ForwardIterator>::value_type>) - __glibcxx_requires_valid_range(__first, __last); - _ForwardIterator __next = __first; if (__first == __last || ++__next == __last) return std::make_pair(__first, __first); _ForwardIterator __min, __max; - if (*__next < *__first) + if (__comp(__next, __first)) { __min = __next; __max = __first; @@ -4101,25 +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; } @@ -4136,6 +3384,31 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * @ingroup sorting_algorithms * @param __first Start of range. * @param __last End of range. + * @return make_pair(m, M), where m is the first iterator i in + * [__first, __last) such that no other element in the range is + * smaller, and where M is the last iterator i in [__first, __last) + * such that no other element in the range is larger. + */ + template<typename _ForwardIterator> + pair<_ForwardIterator, _ForwardIterator> + minmax_element(_ForwardIterator __first, _ForwardIterator __last) + { + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_LessThanComparableConcept< + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + return std::__minmax_element(__first, __last, + __gnu_cxx::__ops::__iter_less_iter()); + } + + /** + * @brief Return a pair of iterators pointing to the minimum and maximum + * elements in a range. + * @ingroup sorting_algorithms + * @param __first Start of range. + * @param __last End of range. * @param __comp Comparison functor. * @return make_pair(m, M), where m is the first iterator i in * [__first, __last) such that no other element in the range is @@ -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,27 +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<typename _ForwardIterator1, typename _ForwardIterator2> + template<typename _ForwardIterator1, typename _ForwardIterator2, + typename _BinaryPredicate> bool - is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2) + __is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _BinaryPredicate __pred) { // Efficiently compare identical prefixes: O(N) if sequences // have the same elements in the same order. for (; __first1 != __last1; ++__first1, ++__first2) - if (!(*__first1 == *__first2)) + if (!__pred(__first1, __first2)) break; if (__first1 == __last1) @@ -4279,12 +3491,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION std::advance(__last2, std::distance(__first1, __last1)); for (_ForwardIterator1 __scan = __first1; __scan != __last1; ++__scan) { - if (__scan != _GLIBCXX_STD_A::find(__first1, __scan, *__scan)) + if (__scan != std::__find_if(__first1, __scan, + __gnu_cxx::__ops::__iter_comp_iter(__pred, __scan))) continue; // We've seen this one before. - - auto __matches = std::count(__first2, __last2, *__scan); - if (0 == __matches - || std::count(__scan, __last1, *__scan) != __matches) + + auto __matches + = std::__count_if(__first2, __last2, + __gnu_cxx::__ops::__iter_comp_iter(__pred, __scan)); + if (0 == __matches || + std::__count_if(__scan, __last1, + __gnu_cxx::__ops::__iter_comp_iter(__pred, __scan)) + != __matches) return false; } return true; @@ -4297,6 +3514,35 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * @param __first1 Start of first range. * @param __last1 End of first range. * @param __first2 Start of second range. + * @return true if there exists a permutation of the elements in the range + * [__first2, __first2 + (__last1 - __first1)), beginning with + * ForwardIterator2 begin, such that equal(__first1, __last1, begin) + * returns true; otherwise, returns false. + */ + template<typename _ForwardIterator1, typename _ForwardIterator2> + bool + is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2) + { + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator1>) + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator2>) + __glibcxx_function_requires(_EqualOpConcept< + typename iterator_traits<_ForwardIterator1>::value_type, + typename iterator_traits<_ForwardIterator2>::value_type>) + __glibcxx_requires_valid_range(__first1, __last1); + + return std::__is_permutation(__first1, __last1, __first2, + __gnu_cxx::__ops::__iter_equal_to_iter()); + } + + /** + * @brief Checks whether a permutation of the second sequence is equal + * to the first sequence. + * @ingroup non_mutating_algorithms + * @param __first1 Start of first range. + * @param __last1 End of first range. + * @param __first2 Start of second range. * @param __pred A binary predicate. * @return true if there exists a permutation of the elements in * the range [__first2, __first2 + (__last1 - __first1)), @@ -4310,38 +3556,79 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _BinaryPredicate __pred) { + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator1>) + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator2>) + __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, + typename iterator_traits<_ForwardIterator1>::value_type, + typename iterator_traits<_ForwardIterator2>::value_type>) + __glibcxx_requires_valid_range(__first1, __last1); + + return std::__is_permutation(__first1, __last1, __first2, + __gnu_cxx::__ops::__iter_comp_iter(__pred)); + } + +#if __cplusplus > 201103L + template<typename _ForwardIterator1, typename _ForwardIterator2, + typename _BinaryPredicate> + bool + __is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2, + _BinaryPredicate __pred) + { + using _Cat1 + = typename iterator_traits<_ForwardIterator1>::iterator_category; + using _Cat2 + = typename iterator_traits<_ForwardIterator2>::iterator_category; + using _It1_is_RA = is_same<_Cat1, random_access_iterator_tag>; + using _It2_is_RA = is_same<_Cat2, random_access_iterator_tag>; + constexpr bool __ra_iters = _It1_is_RA() && _It2_is_RA(); + if (__ra_iters) + { + auto __d1 = std::distance(__first1, __last1); + auto __d2 = std::distance(__first2, __last2); + if (__d1 != __d2) + return false; + } + // Efficiently compare identical prefixes: O(N) if sequences // have the same elements in the same order. for (; __first1 != __last1; ++__first1, ++__first2) - if (!bool(__pred(*__first1, *__first2))) + if (!__pred(__first1, __first2)) break; - if (__first1 == __last1) - return true; + if (__ra_iters) + { + if (__first1 == __last1) + return true; + } + else + { + auto __d1 = std::distance(__first1, __last1); + auto __d2 = std::distance(__first2, __last2); + if (__d1 == 0 && __d2 == 0) + return true; + if (__d1 != __d2) + return false; + } - // Establish __last2 assuming equal ranges by iterating over the - // rest of the list. - _ForwardIterator2 __last2 = __first2; - std::advance(__last2, std::distance(__first1, __last1)); for (_ForwardIterator1 __scan = __first1; __scan != __last1; ++__scan) { - using std::placeholders::_1; - - if (__scan != _GLIBCXX_STD_A::find_if(__first1, __scan, - std::bind(__pred, _1, *__scan))) + if (__scan != std::__find_if(__first1, __scan, + __gnu_cxx::__ops::__iter_comp_iter(__pred, __scan))) continue; // We've seen this one before. - - auto __matches = std::count_if(__first2, __last2, - std::bind(__pred, _1, *__scan)); + + auto __matches = std::__count_if(__first2, __last2, + __gnu_cxx::__ops::__iter_comp_iter(__pred, __scan)); if (0 == __matches - || std::count_if(__scan, __last1, - std::bind(__pred, _1, *__scan)) != __matches) + || std::__count_if(__scan, __last1, + __gnu_cxx::__ops::__iter_comp_iter(__pred, __scan)) + != __matches) return false; } return true; } -#if __cplusplus > 201103L /** * @brief Checks whether a permutaion of the second sequence is equal * to the first sequence. @@ -4360,43 +3647,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2) { - using _Cat1 - = typename iterator_traits<_ForwardIterator1>::iterator_category; - using _Cat2 - = typename iterator_traits<_ForwardIterator2>::iterator_category; - using _It1_is_RA = is_same<_Cat1, random_access_iterator_tag>; - using _It2_is_RA = is_same<_Cat2, random_access_iterator_tag>; - if (_It1_is_RA() && _It2_is_RA()) - { - auto __d1 = std::distance(__first1, __last1); - auto __d2 = std::distance(__first2, __last2); - if (__d1 != __d2) - return false; - } - - // Efficiently compare identical prefixes: O(N) if sequences - // have the same elements in the same order. - for (; __first1 != __last1 && __first2 != __last2; ++__first1, ++__first2) - if (!(*__first1 == *__first2)) - break; - - if (__first1 == __last1 && __first2 == __last2) - return true; - - if (std::distance(__first1, __last1) != std::distance(__first2, __last2)) - return false; - - for (auto __scan = __first1; __scan != __last1; ++__scan) - { - if (__scan != _GLIBCXX_STD_A::find(__first1, __scan, *__scan)) - continue; // We've seen this one before. + __glibcxx_requires_valid_range(__first1, __last1); + __glibcxx_requires_valid_range(__first2, __last2); - auto __matches = std::count(__first2, __last2, *__scan); - if (0 == __matches - || std::count(__scan, __last1, *__scan) != __matches) - return false; - } - return true; + return + std::__is_permutation(__first1, __last1, __first2, __last2, + __gnu_cxx::__ops::__iter_equal_to_iter()); } /** @@ -4420,58 +3676,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __pred) { - using _Cat1 - = typename iterator_traits<_ForwardIterator1>::iterator_category; - using _Cat2 - = typename iterator_traits<_ForwardIterator2>::iterator_category; - using _It1_is_RA = is_same<_Cat1, random_access_iterator_tag>; - using _It2_is_RA = is_same<_Cat2, random_access_iterator_tag>; - constexpr bool __ra_iters = _It1_is_RA() && _It2_is_RA(); - if (__ra_iters) - { - auto __d1 = std::distance(__first1, __last1); - auto __d2 = std::distance(__first2, __last2); - if (__d1 != __d2) - return false; - } - - // Efficiently compare identical prefixes: O(N) if sequences - // have the same elements in the same order. - for (; __first1 != __last1; ++__first1, ++__first2) - if (!bool(__pred(*__first1, *__first2))) - break; - - if (__ra_iters) - { - if (__first1 == __last1) - return true; - } - else - { - auto __d1 = std::distance(__first1, __last1); - auto __d2 = std::distance(__first2, __last2); - if (__d1 == 0 && __d2 == 0) - return true; - if (__d1 != __d2) - return false; - } - - for (_ForwardIterator1 __scan = __first1; __scan != __last1; ++__scan) - { - using std::placeholders::_1; - - if (__scan != _GLIBCXX_STD_A::find_if(__first1, __scan, - std::bind(__pred, _1, *__scan))) - continue; // We've seen this one before. + __glibcxx_requires_valid_range(__first1, __last1); + __glibcxx_requires_valid_range(__first2, __last2); - auto __matches = std::count_if(__first2, __last2, - std::bind(__pred, _1, *__scan)); - if (0 == __matches - || std::count_if(__scan, __last1, - std::bind(__pred, _1, *__scan)) != __matches) - return false; - } - return true; + return std::__is_permutation(__first1, __last1, __first2, __last2, + __gnu_cxx::__ops::__iter_comp_iter(__pred)); } #endif @@ -4564,8 +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<typename _InputIterator1, typename _InputIterator2, + typename _OutputIterator, typename _Compare> + _OutputIterator + __merge(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, + _OutputIterator __result, _Compare __comp) + { + while (__first1 != __last1 && __first2 != __last2) { - std::__introsort_loop(__first, __last, - std::__lg(__last - __first) * 2, __comp); - std::__final_insertion_sort(__first, __last, __comp); + if (__comp(__first2, __first1)) + { + *__result = *__first2; + ++__first2; + } + else + { + *__result = *__first1; + ++__first1; + } + ++__result; } + return std::copy(__first2, __last2, + std::copy(__first1, __last1, __result)); } /** @@ -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()); } /** @@ -5709,41 +4804,43 @@ _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, - _ValueType2, _ValueType1>) + typename iterator_traits<_InputIterator2>::value_type, + typename iterator_traits<_InputIterator1>::value_type>) __glibcxx_requires_sorted_set_pred(__first1, __last1, __first2, __comp); __glibcxx_requires_sorted_set_pred(__first2, __last2, __first1, __comp); - while (__first1 != __last1 && __first2 != __last2) - { - if (__comp(*__first2, *__first1)) - { - *__result = *__first2; - ++__first2; - } - else - { - *__result = *__first1; - ++__first1; - } - ++__result; - } - return std::copy(__first2, __last2, std::copy(__first1, __last1, - __result)); + return _GLIBCXX_STD_A::__merge(__first1, __last1, + __first2, __last2, __result, + __gnu_cxx::__ops::__iter_comp_iter(__comp)); } + template<typename _RandomAccessIterator, typename _Compare> + inline void + __stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, + _Compare __comp) + { + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + typedef typename iterator_traits<_RandomAccessIterator>::difference_type + _DistanceType; + + typedef _Temporary_buffer<_RandomAccessIterator, _ValueType> _TmpBuf; + _TmpBuf __buf(__first, __last); + + if (__buf.begin() == 0) + std::__inplace_stable_sort(__first, __last, __comp); + else + std::__stable_sort_adaptive(__first, __last, __buf.begin(), + _DistanceType(__buf.size()), __comp); + } /** * @brief Sort the elements of a sequence, preserving the relative order @@ -5766,24 +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<typename _InputIterator1, typename _InputIterator2, + typename _OutputIterator, + typename _Compare> + _OutputIterator + __set_union(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, + _OutputIterator __result, _Compare __comp) + { + while (__first1 != __last1 && __first2 != __last2) + { + if (__comp(__first1, __first2)) + { + *__result = *__first1; + ++__first1; + } + else if (__comp(__first2, __first1)) + { + *__result = *__first2; + ++__first2; + } + else + { + *__result = *__first1; + ++__first1; + ++__first2; + } + ++__result; + } + return std::copy(__first2, __last2, + std::copy(__first1, __last1, __result)); + } /** * @brief Return the union of two sorted ranges. @@ -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<typename _InputIterator1, typename _InputIterator2, + typename _OutputIterator, + typename _Compare> + _OutputIterator + __set_intersection(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, + _OutputIterator __result, _Compare __comp) + { while (__first1 != __last1 && __first2 != __last2) - { - if (__comp(*__first1, *__first2)) - { - *__result = *__first1; - ++__first1; - } - else if (__comp(*__first2, *__first1)) - { - *__result = *__first2; - ++__first2; - } - else - { - *__result = *__first1; - ++__first1; - ++__first2; - } - ++__result; - } - return std::copy(__first2, __last2, std::copy(__first1, __last1, - __result)); + if (__comp(__first1, __first2)) + ++__first1; + else if (__comp(__first2, __first1)) + ++__first2; + else + { + *__result = *__first1; + ++__first1; + ++__first2; + ++__result; + } + return __result; } /** @@ -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<typename _InputIterator1, typename _InputIterator2, + typename _OutputIterator, + typename _Compare> + _OutputIterator + __set_difference(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, + _OutputIterator __result, _Compare __comp) + { while (__first1 != __last1 && __first2 != __last2) - if (__comp(*__first1, *__first2)) - ++__first1; - else if (__comp(*__first2, *__first1)) + if (__comp(__first1, __first2)) + { + *__result = *__first1; + ++__first1; + ++__result; + } + else if (__comp(__first2, __first1)) ++__first2; else { - *__result = *__first1; ++__first1; ++__first2; - ++__result; } - return __result; + return std::copy(__first1, __last1, __result); } /** @@ -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<typename _InputIterator1, typename _InputIterator2, + typename _OutputIterator, + typename _Compare> + _OutputIterator + __set_symmetric_difference(_InputIterator1 __first1, + _InputIterator1 __last1, + _InputIterator2 __first2, + _InputIterator2 __last2, + _OutputIterator __result, + _Compare __comp) + { while (__first1 != __last1 && __first2 != __last2) - if (__comp(*__first1, *__first2)) + if (__comp(__first1, __first2)) { *__result = *__first1; ++__first1; ++__result; } - else if (__comp(*__first2, *__first1)) - ++__first2; + else if (__comp(__first2, __first1)) + { + *__result = *__first2; + ++__first2; + ++__result; + } else { ++__first1; ++__first2; } - return std::copy(__first1, __last1, __result); + return std::copy(__first2, __last2, + std::copy(__first1, __last1, __result)); } /** @@ -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<typename _ForwardIterator, typename _Compare> + _ForwardIterator + __min_element(_ForwardIterator __first, _ForwardIterator __last, + _Compare __comp) + { + if (__first == __last) + return __first; + _ForwardIterator __result = __first; + while (++__first != __last) + if (__comp(__first, __result)) + __result = __first; + return __result; + } /** * @brief Return the minimum element in a range. @@ -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<typename _ForwardIterator, typename _Compare> + _ForwardIterator + __max_element(_ForwardIterator __first, _ForwardIterator __last, + _Compare __comp) + { + if (__first == __last) return __first; _ForwardIterator __result = __first; while (++__first != __last) - if (__comp(*__first, *__result)) + if (__comp(__result, __first)) __result = __first; return __result; } @@ -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 1c88935..fae8beb 100644 --- a/libstdc++-v3/include/bits/stl_algobase.h +++ b/libstdc++-v3/include/bits/stl_algobase.h @@ -68,6 +68,7 @@ #include <bits/concept_check.h> #include <debug/debug.h> #include <bits/move.h> // For std::swap and _GLIBCXX_MOVE +#include <bits/predefined_ops.h> namespace std _GLIBCXX_VISIBILITY(default) { @@ -862,6 +863,28 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return true; } }; + template<typename _II1, typename _II2, typename _Compare> + bool + __lexicographical_compare_impl(_II1 __first1, _II1 __last1, + _II2 __first2, _II2 __last2, + _Compare __comp) + { + typedef typename iterator_traits<_II1>::iterator_category _Category1; + typedef typename iterator_traits<_II2>::iterator_category _Category2; + typedef std::__lc_rai<_Category1, _Category2> __rai_type; + + __last1 = __rai_type::__newlast1(__first1, __last1, __first2, __last2); + for (; __first1 != __last1 && __rai_type::__cnd2(__first2, __last2); + ++__first1, ++__first2) + { + if (__comp(__first1, __first2)) + return true; + if (__comp(__first2, __first1)) + return false; + } + return __first1 == __last1 && __first2 != __last2; + } + template<bool _BoolType> struct __lexicographical_compare { @@ -875,21 +898,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __lexicographical_compare<_BoolType>:: __lc(_II1 __first1, _II1 __last1, _II2 __first2, _II2 __last2) { - typedef typename iterator_traits<_II1>::iterator_category _Category1; - typedef typename iterator_traits<_II2>::iterator_category _Category2; - typedef std::__lc_rai<_Category1, _Category2> __rai_type; - - __last1 = __rai_type::__newlast1(__first1, __last1, - __first2, __last2); - for (; __first1 != __last1 && __rai_type::__cnd2(__first2, __last2); - ++__first1, ++__first2) - { - if (*__first1 < *__first2) - return true; - if (*__first2 < *__first1) - return false; - } - return __first1 == __last1 && __first2 != __last2; + return std::__lexicographical_compare_impl( + __first1, __last1, __first2, __last2, + __gnu_cxx::__ops::__iter_less_iter()); } template<> @@ -926,34 +937,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __first2, __last2); } - /** - * @brief Finds the first position in which @a val could be inserted - * without changing the ordering. - * @param __first An iterator. - * @param __last Another iterator. - * @param __val The search term. - * @return An iterator pointing to the first element <em>not less - * than</em> @a val, or end() if every element is less than - * @a val. - * @ingroup binary_search_algorithms - */ - template<typename _ForwardIterator, typename _Tp> + template<typename _ForwardIterator, typename _Tp, typename _Compare> _ForwardIterator - lower_bound(_ForwardIterator __first, _ForwardIterator __last, - const _Tp& __val) + __lower_bound(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __val, _Compare __comp) { -#ifdef _GLIBCXX_CONCEPT_CHECKS - typedef typename iterator_traits<_ForwardIterator>::value_type - _ValueType; -#endif typedef typename iterator_traits<_ForwardIterator>::difference_type _DistanceType; - // concept requirements - __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) - __glibcxx_function_requires(_LessThanOpConcept<_ValueType, _Tp>) - __glibcxx_requires_partitioned_lower(__first, __last, __val); - _DistanceType __len = std::distance(__first, __last); while (__len > 0) @@ -961,7 +952,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _DistanceType __half = __len >> 1; _ForwardIterator __middle = __first; std::advance(__middle, __half); - if (*__middle < __val) + if (__comp(__middle, __val)) { __first = __middle; ++__first; @@ -973,6 +964,32 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return __first; } + /** + * @brief Finds the first position in which @a val could be inserted + * without changing the ordering. + * @param __first An iterator. + * @param __last Another iterator. + * @param __val The search term. + * @return An iterator pointing to the first element <em>not less + * than</em> @a val, or end() if every element is less than + * @a val. + * @ingroup binary_search_algorithms + */ + template<typename _ForwardIterator, typename _Tp> + _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<typename _InputIterator1, typename _InputIterator2, + typename _BinaryPredicate> + pair<_InputIterator1, _InputIterator2> + __mismatch(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _BinaryPredicate __binary_pred) + { + while (__first1 != __last1 && __binary_pred(__first1, __first2)) + { + ++__first1; + ++__first2; + } + return pair<_InputIterator1, _InputIterator2>(__first1, __first2); } /** @@ -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<typename _InputIterator1, typename _InputIterator2, + typename _BinaryPredicate> + pair<_InputIterator1, _InputIterator2> + __mismatch(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, + _BinaryPredicate __binary_pred) + { + while (__first1 != __last1 && __first2 != __last2 + && __binary_pred(__first1, __first2)) { ++__first1; ++__first2; @@ -1303,7 +1334,6 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO return pair<_InputIterator1, _InputIterator2>(__first1, __first2); } -#if __cplusplus > 201103L /** * @brief Finds the places in ranges which don't match. * @ingroup non_mutating_algorithms @@ -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 807a8cf..a0c51ff 100644 --- a/libstdc++-v3/include/bits/stl_heap.h +++ b/libstdc++-v3/include/bits/stl_heap.h @@ -57,6 +57,7 @@ #include <debug/debug.h> #include <bits/move.h> +#include <bits/predefined_ops.h> namespace std _GLIBCXX_VISIBILITY(default) { @@ -67,21 +68,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * @ingroup sorting_algorithms */ - template<typename _RandomAccessIterator, typename _Distance> - _Distance - __is_heap_until(_RandomAccessIterator __first, _Distance __n) - { - _Distance __parent = 0; - for (_Distance __child = 1; __child < __n; ++__child) - { - if (__first[__parent] < __first[__child]) - return __child; - if ((__child & 1) == 0) - ++__parent; - } - return __n; - } - template<typename _RandomAccessIterator, typename _Distance, typename _Compare> _Distance @@ -91,7 +77,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _Distance __parent = 0; for (_Distance __child = 1; __child < __n; ++__child) { - if (__comp(__first[__parent], __first[__child])) + if (__comp(__first + __parent, __first + __child)) return __child; if ((__child & 1) == 0) ++__parent; @@ -104,13 +90,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _RandomAccessIterator, typename _Distance> inline bool __is_heap(_RandomAccessIterator __first, _Distance __n) - { return std::__is_heap_until(__first, __n) == __n; } + { + return std::__is_heap_until(__first, __n, + __gnu_cxx::__ops::__iter_less_iter()) == __n; + } template<typename _RandomAccessIterator, typename _Compare, typename _Distance> inline bool __is_heap(_RandomAccessIterator __first, _Compare __comp, _Distance __n) - { return std::__is_heap_until(__first, __n, __comp) == __n; } + { + return std::__is_heap_until(__first, __n, + __gnu_cxx::__ops::__iter_comp_iter(__comp)) == __n; + } template<typename _RandomAccessIterator> inline bool @@ -126,13 +118,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // Heap-manipulation functions: push_heap, pop_heap, make_heap, sort_heap, // + is_heap and is_heap_until in C++0x. - template<typename _RandomAccessIterator, typename _Distance, typename _Tp> + template<typename _RandomAccessIterator, typename _Distance, typename _Tp, + typename _Compare> void __push_heap(_RandomAccessIterator __first, - _Distance __holeIndex, _Distance __topIndex, _Tp __value) + _Distance __holeIndex, _Distance __topIndex, _Tp __value, + _Compare __comp) { _Distance __parent = (__holeIndex - 1) / 2; - while (__holeIndex > __topIndex && *(__first + __parent) < __value) + while (__holeIndex > __topIndex && __comp(__first + __parent, __value)) { *(__first + __holeIndex) = _GLIBCXX_MOVE(*(__first + __parent)); __holeIndex = __parent; @@ -169,24 +163,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _ValueType __value = _GLIBCXX_MOVE(*(__last - 1)); std::__push_heap(__first, _DistanceType((__last - __first) - 1), - _DistanceType(0), _GLIBCXX_MOVE(__value)); - } - - template<typename _RandomAccessIterator, typename _Distance, typename _Tp, - typename _Compare> - void - __push_heap(_RandomAccessIterator __first, _Distance __holeIndex, - _Distance __topIndex, _Tp __value, _Compare __comp) - { - _Distance __parent = (__holeIndex - 1) / 2; - while (__holeIndex > __topIndex - && __comp(*(__first + __parent), __value)) - { - *(__first + __holeIndex) = _GLIBCXX_MOVE(*(__first + __parent)); - __holeIndex = __parent; - __parent = (__holeIndex - 1) / 2; - } - *(__first + __holeIndex) = _GLIBCXX_MOVE(__value); + _DistanceType(0), _GLIBCXX_MOVE(__value), + __gnu_cxx::__ops::__iter_less_val()); } /** @@ -219,20 +197,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _ValueType __value = _GLIBCXX_MOVE(*(__last - 1)); std::__push_heap(__first, _DistanceType((__last - __first) - 1), - _DistanceType(0), _GLIBCXX_MOVE(__value), __comp); + _DistanceType(0), _GLIBCXX_MOVE(__value), + __gnu_cxx::__ops::__iter_comp_val(__comp)); } - template<typename _RandomAccessIterator, typename _Distance, typename _Tp> + template<typename _RandomAccessIterator, typename _Distance, + typename _Tp, typename _Compare> void __adjust_heap(_RandomAccessIterator __first, _Distance __holeIndex, - _Distance __len, _Tp __value) + _Distance __len, _Tp __value, _Compare __comp) { const _Distance __topIndex = __holeIndex; _Distance __secondChild = __holeIndex; while (__secondChild < (__len - 1) / 2) { __secondChild = 2 * (__secondChild + 1); - if (*(__first + __secondChild) < *(__first + (__secondChild - 1))) + if (__comp(__first + __secondChild, + __first + (__secondChild - 1))) __secondChild--; *(__first + __holeIndex) = _GLIBCXX_MOVE(*(__first + __secondChild)); __holeIndex = __secondChild; @@ -244,14 +225,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION + (__secondChild - 1))); __holeIndex = __secondChild - 1; } - std::__push_heap(__first, __holeIndex, __topIndex, - _GLIBCXX_MOVE(__value)); + std::__push_heap(__first, __holeIndex, __topIndex, + _GLIBCXX_MOVE(__value), + __gnu_cxx::__ops::__iter_comp_val(__comp)); } - template<typename _RandomAccessIterator> + template<typename _RandomAccessIterator, typename _Compare> inline void __pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, - _RandomAccessIterator __result) + _RandomAccessIterator __result, _Compare __comp) { typedef typename iterator_traits<_RandomAccessIterator>::value_type _ValueType; @@ -262,7 +244,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION *__result = _GLIBCXX_MOVE(*__first); std::__adjust_heap(__first, _DistanceType(0), _DistanceType(__last - __first), - _GLIBCXX_MOVE(__value)); + _GLIBCXX_MOVE(__value), __comp); } /** @@ -294,55 +276,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION if (__last - __first > 1) { --__last; - std::__pop_heap(__first, __last, __last); + std::__pop_heap(__first, __last, __last, + __gnu_cxx::__ops::__iter_less_iter()); } } - template<typename _RandomAccessIterator, typename _Distance, - typename _Tp, typename _Compare> - void - __adjust_heap(_RandomAccessIterator __first, _Distance __holeIndex, - _Distance __len, _Tp __value, _Compare __comp) - { - const _Distance __topIndex = __holeIndex; - _Distance __secondChild = __holeIndex; - while (__secondChild < (__len - 1) / 2) - { - __secondChild = 2 * (__secondChild + 1); - if (__comp(*(__first + __secondChild), - *(__first + (__secondChild - 1)))) - __secondChild--; - *(__first + __holeIndex) = _GLIBCXX_MOVE(*(__first + __secondChild)); - __holeIndex = __secondChild; - } - if ((__len & 1) == 0 && __secondChild == (__len - 2) / 2) - { - __secondChild = 2 * (__secondChild + 1); - *(__first + __holeIndex) = _GLIBCXX_MOVE(*(__first - + (__secondChild - 1))); - __holeIndex = __secondChild - 1; - } - std::__push_heap(__first, __holeIndex, __topIndex, - _GLIBCXX_MOVE(__value), __comp); - } - - template<typename _RandomAccessIterator, typename _Compare> - inline void - __pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, - _RandomAccessIterator __result, _Compare __comp) - { - typedef typename iterator_traits<_RandomAccessIterator>::value_type - _ValueType; - typedef typename iterator_traits<_RandomAccessIterator>::difference_type - _DistanceType; - - _ValueType __value = _GLIBCXX_MOVE(*__result); - *__result = _GLIBCXX_MOVE(*__first); - std::__adjust_heap(__first, _DistanceType(0), - _DistanceType(__last - __first), - _GLIBCXX_MOVE(__value), __comp); - } - /** * @brief Pop an element off a heap using comparison functor. * @param __first Start of heap. @@ -369,33 +307,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION if (__last - __first > 1) { --__last; - std::__pop_heap(__first, __last, __last, __comp); + std::__pop_heap(__first, __last, __last, + __gnu_cxx::__ops::__iter_comp_iter(__comp)); } } - /** - * @brief Construct a heap over a range. - * @param __first Start of heap. - * @param __last End of heap. - * @ingroup heap_algorithms - * - * This operation makes the elements in [__first,__last) into a heap. - */ - template<typename _RandomAccessIterator> + template<typename _RandomAccessIterator, typename _Compare> void - make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) + __make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, + _Compare __comp) { typedef typename iterator_traits<_RandomAccessIterator>::value_type _ValueType; typedef typename iterator_traits<_RandomAccessIterator>::difference_type _DistanceType; - // concept requirements - __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< - _RandomAccessIterator>) - __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>) - __glibcxx_requires_valid_range(__first, __last); - if (__last - __first < 2) return; @@ -404,12 +330,36 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION while (true) { _ValueType __value = _GLIBCXX_MOVE(*(__first + __parent)); - std::__adjust_heap(__first, __parent, __len, _GLIBCXX_MOVE(__value)); + std::__adjust_heap(__first, __parent, __len, _GLIBCXX_MOVE(__value), + __comp); if (__parent == 0) return; __parent--; } } + + /** + * @brief Construct a heap over a range. + * @param __first Start of heap. + * @param __last End of heap. + * @ingroup heap_algorithms + * + * This operation makes the elements in [__first,__last) into a heap. + */ + template<typename _RandomAccessIterator> + inline void + make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) + { + // concept requirements + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_function_requires(_LessThanComparableConcept< + typename iterator_traits<_RandomAccessIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + std::__make_heap(__first, __last, + __gnu_cxx::__ops::__iter_less_iter()); + } /** * @brief Construct a heap over a range using comparison functor. @@ -422,33 +372,28 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * Comparisons are made using __comp. */ template<typename _RandomAccessIterator, typename _Compare> - void + inline void make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { - typedef typename iterator_traits<_RandomAccessIterator>::value_type - _ValueType; - typedef typename iterator_traits<_RandomAccessIterator>::difference_type - _DistanceType; - // concept requirements __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< _RandomAccessIterator>) __glibcxx_requires_valid_range(__first, __last); - if (__last - __first < 2) - return; + std::__make_heap(__first, __last, + __gnu_cxx::__ops::__iter_comp_iter(__comp)); + } - const _DistanceType __len = __last - __first; - _DistanceType __parent = (__len - 2) / 2; - while (true) + template<typename _RandomAccessIterator, typename _Compare> + void + __sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, + _Compare __comp) + { + while (__last - __first > 1) { - _ValueType __value = _GLIBCXX_MOVE(*(__first + __parent)); - std::__adjust_heap(__first, __parent, __len, _GLIBCXX_MOVE(__value), - __comp); - if (__parent == 0) - return; - __parent--; + --__last; + std::__pop_heap(__first, __last, __last, __comp); } } @@ -461,7 +406,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * This operation sorts the valid heap in the range [__first,__last). */ template<typename _RandomAccessIterator> - void + inline void sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) { // concept requirements @@ -472,11 +417,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __glibcxx_requires_valid_range(__first, __last); __glibcxx_requires_heap(__first, __last); - while (__last - __first > 1) - { - --__last; - std::__pop_heap(__first, __last, __last); - } + std::__sort_heap(__first, __last, + __gnu_cxx::__ops::__iter_less_iter()); } /** @@ -490,7 +432,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * Comparisons are made using __comp. */ template<typename _RandomAccessIterator, typename _Compare> - void + inline void sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { @@ -500,11 +442,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __glibcxx_requires_valid_range(__first, __last); __glibcxx_requires_heap_pred(__first, __last, __comp); - while (__last - __first > 1) - { - --__last; - std::__pop_heap(__first, __last, __last, __comp); - } + std::__sort_heap(__first, __last, + __gnu_cxx::__ops::__iter_comp_iter(__comp)); } #if __cplusplus >= 201103L @@ -529,8 +468,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typename iterator_traits<_RandomAccessIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); - return __first + std::__is_heap_until(__first, std::distance(__first, - __last)); + return __first + + std::__is_heap_until(__first, std::distance(__first, __last), + __gnu_cxx::__ops::__iter_less_iter()); } /** @@ -554,9 +494,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _RandomAccessIterator>) __glibcxx_requires_valid_range(__first, __last); - return __first + std::__is_heap_until(__first, std::distance(__first, - __last), - __comp); + return __first + + std::__is_heap_until(__first, std::distance(__first, __last), + __gnu_cxx::__ops::__iter_comp_iter(__comp)); } /** diff --git a/libstdc++-v3/include/parallel/algobase.h b/libstdc++-v3/include/parallel/algobase.h index e3737cc..d615065 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<typename _InputIterator1, typename _InputIterator2> + inline pair<_InputIterator1, _InputIterator2> + mismatch(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2) + { return _GLIBCXX_STD_A::mismatch(__first1, __last1, __first2, __last2); } + + template<typename _InputIterator1, typename _InputIterator2, + typename _BinaryPredicate> + 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<typename _IIter1, typename _IIter2> inline bool @@ -155,6 +174,22 @@ namespace __parallel == __end1; } +#if __cplusplus > 201103L + template<typename _II1, typename _II2> + inline bool + equal(_II1 __first1, _II1 __last1, _II2 __first2, _II2 __last2) + { return _GLIBCXX_STD_A::equal(__first1, __last1, __first2, __last2); } + + template<typename _IIter1, typename _IIter2, typename _BinaryPredicate> + 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<typename _IIter1, typename _IIter2> inline bool |