// -*- C++ -*- /*************************************************************************** * * algorithm - declarations and inline definitions of the Standard * Library algorithms * * $Id: algorithm 174568 2012-04-18 10:31:58Z tomcox01 $ * *************************************************************************** * * Copyright (c) 1994 * Hewlett-Packard Company * * Permission to use, copy, modify, distribute and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation. Hewlett-Packard Company makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. * *************************************************************************** * * Copyright (c) 1994-2001 Rogue Wave Software, Inc. All Rights Reserved. * * This computer software is owned by Rogue Wave Software, Inc. and is * protected by U.S. copyright laws and other laws and by international * treaties. This computer software is furnished by Rogue Wave Software, * Inc. pursuant to a written license agreement and may be used, copied, * transmitted, and stored only in accordance with the terms of such * license and with the inclusion of the above copyright notice. This * computer software or any other copies thereof may not be provided or * otherwise made available to any other person. * * U.S. Government Restricted Rights. This computer software is provided * with Restricted Rights. Use, duplication, or disclosure by the * Government is subject to restrictions as set forth in subparagraph (c) * (1) (ii) of The Rights in Technical Data and Computer Software clause * at DFARS 252.227-7013 or subparagraphs (c) (1) and (2) of the * Commercial Computer Software--Restricted Rights at 48 CFR 52.227-19, * as applicable. Manufacturer is Rogue Wave Software, Inc., 5500 * Flatiron Parkway, Boulder, Colorado 80301 USA. * **************************************************************************/ #ifndef _RWSTD_ALGORITHM_INCLUDED #define _RWSTD_ALGORITHM_INCLUDED #include #include #include #include #include #include _RWSTD_CSTDLIB #ifdef _INLINE_RECURSIVE # define _INLINE inline #else # define _INLINE #endif _RWSTD_NAMESPACE_BEGIN (std) // 25.1 - Non-modifying sequence operations [lib.alg.nonmodifying] // 25.1.1 - For Each [lib.alg.foreach] template inline _Function for_each (_InputIter __first, _InputIter __last, _Function __f) { _RWSTD_ASSERT_RANGE (__first, __last); for (;__first != __last; ++__first) __f (*__first); return __f; } // 25.1.2 - Find [lib.alg.find] template inline _InputIter find (_InputIter __first, _InputIter __last, const _TypeT& __value) { _RWSTD_ASSERT_RANGE (__first, __last); while (!(__first == __last) && !(*__first == __value)) ++__first; return __first; } template inline _InputIter find_if (_InputIter __first, _InputIter __last, _Predicate __pred) { _RWSTD_ASSERT_RANGE (__first, __last); while (__first != __last && !__pred (*__first)) ++__first; return __first; } // helpers to work around the lack of iterator_traits template _FwdIter1 __find_end (_FwdIter1, _FwdIter1, _FwdIter2, _FwdIter2, _Distance*); template _FwdIter1 __find_end (_FwdIter1, _FwdIter1, _FwdIter2, _FwdIter2, _BinaryPredicate, _Distance*); // 25.1.3 - Find End [lib.alg.find.end] template inline _FwdIter1 find_end (_FwdIter1 __first1, _FwdIter1 __last1, _FwdIter2 __first2, _FwdIter2 __last2) { _RWSTD_ASSERT_RANGE (__first1, __last1); _RWSTD_ASSERT_RANGE (__first2, __last2); return __find_end (__first1, __last1, __first2, __last2, _RWSTD_DIFFERENCE_TYPE (_FwdIter1)); } template _FwdIter1 find_end (_FwdIter1 __first1, _FwdIter1 __last1, _FwdIter2 __first2, _FwdIter2 __last2, _BinaryPredicate __pred) { _RWSTD_ASSERT_RANGE (__first1, __last1); _RWSTD_ASSERT_RANGE (__first2, __last2); return __find_end (__first1,__last1,__first2,__last2, __pred, _RWSTD_DIFFERENCE_TYPE (_FwdIter1)); } // 25.1.4 - Find First [lib.alg.find.first.of] template _FwdIter1 find_first_of (_FwdIter1, _FwdIter1, _FwdIter2, _FwdIter2); template _FwdIter1 find_first_of (_FwdIter1,_FwdIter1, _FwdIter2, _FwdIter2, _BinaryPred); // 25.1.5 - Adjacent Find [lib.alg.adjacent.find] template _FwdIter adjacent_find (_FwdIter, _FwdIter); template _FwdIter adjacent_find (_FwdIter, _FwdIter, _BinaryPredicate); #ifndef _RWSTD_NO_CLASS_PARTIAL_SPEC // 25.1.6 - Count [lib.alg.count] template inline _TYPENAME iterator_traits<_InputIter>::difference_type count (_InputIter __first, _InputIter __last, const _TypeT& __value) { _RWSTD_ASSERT_RANGE (__first, __last); _TYPENAME iterator_traits<_InputIter>::difference_type __n = 0; for (; __first != __last; ++__first) if (*__first == __value) ++__n; return __n; } template inline _TYPENAME iterator_traits<_InputIter>::difference_type count_if (_InputIter __first, _InputIter __last, _Predicate __pred) { _RWSTD_ASSERT_RANGE (__first, __last); _TYPENAME iterator_traits<_InputIter>::difference_type __n = 0; for (;__first != __last; ++__first) if (__pred (*__first)) ++__n; return __n; } #endif // _RWSTD_NO_CLASS_PARTIAL_SPEC // provided as a backward-compatibility extension (or as a workaround) #if !defined (_RWSTD_NO_EXT_VOID_COUNT) \ || defined (_RWSTD_NO_CLASS_PARTIAL_SPEC) template inline void count (_InputIter __first, _InputIter __last, const _TypeT& __value, _Size& __n) { _RWSTD_ASSERT_RANGE (__first, __last); for (;__first != __last;++__first) if (*__first == __value) ++__n; } template inline void count_if (_InputIter __first, _InputIter __last, _Predicate __pred, _Size& __n) { _RWSTD_ASSERT_RANGE (__first, __last); for (;__first != __last;++__first) if (__pred (*__first)) ++__n; } #endif // !_RWSTD_NO_EXT_VOID_COUNT || _RWSTD_NO_CLASS_PARTIAL_SPEC // 25.1.7 - Mismatch [lib.mismatch] // 25.1.8 - Equal [lib.alg.equal] // defined in // helpers to work around the lack of iterator_traits template _FwdIter1 __search (_FwdIter1, _FwdIter1, _FwdIter2, _FwdIter2, _Distance1*, _Distance2*); template _FwdIter1 __search (_FwdIter1, _FwdIter1, _FwdIter2, _FwdIter2, _BinaryPredicate, Distance1*, Distance2*); // 25.1.9 - Search [lib.alg.search] // 25.1.9, p1 template inline _FwdIter1 search (_FwdIter1 __first1, _FwdIter1 __last1, _FwdIter2 __first2, _FwdIter2 __last2) { return __search (__first1, __last1, __first2, __last2, _RWSTD_DIFFERENCE_TYPE (_FwdIter1), _RWSTD_DIFFERENCE_TYPE (_FwdIter2)); } template inline _FwdIter1 search (_FwdIter1 __first1,_FwdIter1 __last1, _FwdIter2 __first2,_FwdIter2 __last2, _BinaryPredicate __pred) { return __search (__first1, __last1, __first2, __last2, __pred, _RWSTD_DIFFERENCE_TYPE (_FwdIter1), _RWSTD_DIFFERENCE_TYPE (_FwdIter2)); } // helper to work around the lack of iterator_traits template _FwdIter __search_n (_FwdIter, _FwdIter, _Distance*, _Size, const _TypeT&); template _FwdIter __search_n (_FwdIter, _FwdIter, _Distance*, _Size, const _TypeT&, _BinaryPredicate); // 25.1.9, p4 template inline _FwdIter search_n (_FwdIter __first, _FwdIter __last, _Size __count, const _TypeT& __value) { if (__count) return __search_n (__first, __last, _RWSTD_DIFFERENCE_TYPE (_FwdIter), __count, __value); return __first; } template inline _FwdIter search_n (_FwdIter __first, _FwdIter __last, _Size __count, const _TypeT& __value, _BinaryPredicate __pred) { if (__count) return __search_n (__first, __last, _RWSTD_DIFFERENCE_TYPE (_FwdIter), __count,__value, __pred); return __first; } // 25.2 - Mutating sequence operations [lib.alg.modifying,operations] // 25.2.1 - Copy [lib.alg.copy] // 25.2.2, p1 swap // defined in // 25.2.2, p3 template _FwdIter2 swap_ranges (_FwdIter1, _FwdIter1, _FwdIter2); // 25.2.3 - Transform [lib.alg.transform] template _OutputIter transform (_InputIter, _InputIter, _OutputIter, _UnaryOperation); template _OutputIter transform (_InputIter1, _InputIter1, _InputIter2, _OutputIter, _BinaryOperation); // 25.2.4 - Replace [lib.alg.replace] template void replace (_FwdIter, _FwdIter, const _TypeT&, const _TypeT&); template void replace_if (_FwdIter, _FwdIter, _Predicate, const _TypeT&); template _OutputIter replace_copy (_InputIter, _InputIter, _OutputIter, const _TypeT&, const _TypeT&); template _OutputIter replace_copy_if (_Iter, _Iter, _OutputIter, _Predicate, const _TypeT&); // 25.2.5 - Fill [lib.alg.fill] // defined in // 25.2.6 - Generate [lib.alg.generate] template void generate (_FwdIter, _FwdIter, _Generator); template void generate_n (_OutputIter, _Size, _Generator); // 25.2.7 - Remove [lib.alg.remove] template _OutputIter remove_copy (_InputIter, _InputIter, _OutputIter, const _TypeT&); template _OutputIter remove_copy_if (_InputIter, _InputIter, _OutputIter, _Predicate); template inline _FwdIter remove (_FwdIter __first, _FwdIter __last, const _TypeT& __value) { __first = _STD::find (__first, __last, __value); _FwdIter __next = __first; return __first == __last ? __first : _STD::remove_copy (++__next, __last, __first, __value); } template inline _FwdIter remove_if (_FwdIter __first, _FwdIter __last, _Predicate __pred) { __first = _STD::find_if (__first, __last, __pred); _FwdIter __next = __first; return __first == __last ? __first : _STD::remove_copy_if (++__next, __last, __first, __pred); } template _FwdIter __unique_copy (_InputIter, _InputIter, _FwdIter, forward_iterator_tag); template inline _BidirIter __unique_copy (_InputIter __first, _InputIter __last, _BidirIter __res, bidirectional_iterator_tag) { return __unique_copy (__first, __last, __res, forward_iterator_tag ()); } template inline _RandomAccessIter __unique_copy (_InputIter __first, _InputIter __last, _RandomAccessIter __res, random_access_iterator_tag) { return __unique_copy (__first, __last, __res, forward_iterator_tag ()); } template _OutputIter __unique_copy (_InputIter, _InputIter, _OutputIter, _TypeT*); template inline _OutputIter __unique_copy (_InputIter __first, _InputIter __last, _OutputIter __res, output_iterator_tag) { return __unique_copy (__first, __last, __res, _RWSTD_VALUE_TYPE (_InputIter)); } template inline _OutputIter unique_copy (_InputIter __first, _InputIter __last, _OutputIter __res) { return __first == __last ? __res : __unique_copy (__first, __last, __res, _RWSTD_ITERATOR_CATEGORY (_OutputIter, __res)); } template _FwdIter __unique_copy (_InputIter, _InputIter, _FwdIter, _BinaryPredicate, forward_iterator_tag); template inline _BidirIter __unique_copy (_InputIter __first, _InputIter __last, _BidirIter __res, _BinaryPredicate __pred, bidirectional_iterator_tag) { return __unique_copy (__first, __last, __res, __pred, forward_iterator_tag ()); } template inline _RandomAccessIter __unique_copy (_InputIter __first, _InputIter __last, _RandomAccessIter __res, _BinaryPredicate __pred, random_access_iterator_tag) { return __unique_copy (__first, __last, __res, __pred, forward_iterator_tag ()); } template _OutputIter __unique_copy (_InputIter, _InputIter, _OutputIter, _BinaryPredicate, _TypeT*); template inline _OutputIter __unique_copy (_InputIter __first, _InputIter __last, _OutputIter __res, _BinaryPredicate __pred, output_iterator_tag) { return __unique_copy (__first, __last, __res, __pred, _RWSTD_VALUE_TYPE (_InputIter)); } template inline _OutputIter unique_copy (_InputIter __first, _InputIter __last, _OutputIter __res, _BinaryPredicate __pred) { return __first == __last ? __res : __unique_copy (__first, __last, __res, __pred, _RWSTD_ITERATOR_CATEGORY (_OutputIter, __res)); } template inline _FwdIter unique (_FwdIter __first, _FwdIter __last) { __first = _STD::adjacent_find (__first, __last); return _STD::unique_copy (__first, __last, __first); } template inline _FwdIter unique (_FwdIter __first, _FwdIter __last, _BinaryPredicate __pred) { __first = _STD::adjacent_find (__first, __last, __pred); return _STD::unique_copy (__first, __last, __first, __pred); } template void __reverse (_BidirIter, _BidirIter, bidirectional_iterator_tag); template void __reverse (_RandomAccessIter __first, _RandomAccessIter __last, random_access_iterator_tag); template inline void reverse (_BidirIter __first, _BidirIter __last) { __reverse (__first, __last, _RWSTD_ITERATOR_CATEGORY (_BidirIter, __first)); } template _OutputIter reverse_copy (_BidirIter, _BidirIter, _OutputIter); template void __rotate (_FwdIter, _FwdIter, _FwdIter, _Distance*, forward_iterator_tag); template inline void __rotate (_BidirIter __first, _BidirIter __middle, _BidirIter __last, _Distance*, bidirectional_iterator_tag) { _STD::reverse (__first, __middle); _STD::reverse (__middle, __last); _STD::reverse (__first, __last); } template _EuclideanRingElement __gcd (_EuclideanRingElement, _EuclideanRingElement); template void __rotate_cycle (_RandomAccessIter, _RandomAccessIter, _RandomAccessIter, _Distance, _TypeT*); template void __rotate (_RandomAccessIter, _RandomAccessIter, _RandomAccessIter, _Distance*, random_access_iterator_tag); template inline void rotate (_FwdIter __first, _FwdIter __middle, _FwdIter __last) { if (!(__first == __middle || __middle == __last)) __rotate (__first, __middle, __last, _RWSTD_DIFFERENCE_TYPE (_FwdIter), _RWSTD_ITERATOR_CATEGORY (_FwdIter, __first)); } template inline _OutputIter rotate_copy (_FwdIter __first, _FwdIter __middle, _FwdIter __last, _OutputIter __res) { if (__first == __last) return __res; _FwdIter __mod(__first); advance(__mod, distance(__first, __middle) % distance(__first, __last)); return _STD::copy(__first, __mod, _STD::copy(__mod, __last, __res)); } template void __random_shuffle (_RandomAccessIter, _RandomAccessIter, _Distance*); template inline void random_shuffle (_RandomAccessIter __first, _RandomAccessIter __last) { __random_shuffle (__first, __last, _RWSTD_DIFFERENCE_TYPE (_RandomAccessIter)); } template void random_shuffle (_RandomAccessIter, _RandomAccessIter, _RandomNumberGenerator&); template _BidirIter partition (_BidirIter, _BidirIter, _Predicate); template _BidirIter __inplace_stable_partition (_BidirIter, _BidirIter, _Predicate, _Distance); template _BidirIter __stable_partition_adaptive (_BidirIter, _BidirIter, _Predicate, _Distance, _Pointer, _Distance, _Distance&, _TypeT*); template _BidirIter __stable_partition (_BidirIter, _BidirIter, _Predicate, _TypeT*, _Distance*); template inline _BidirIter stable_partition (_BidirIter __first, _BidirIter __last, _Predicate __pred) { return __stable_partition (__first, __last, __pred, _RWSTD_VALUE_TYPE (_BidirIter), _RWSTD_DIFFERENCE_TYPE (_BidirIter)); } // 25.3.1 - Sorting [lib.alg.sort] template _RandomAccessIter __unguarded_partition (_RandomAccessIter, _RandomAccessIter, _TypeT, _Compare); template void __quick_sort_loop_aux (_RandomAccessIter, _RandomAccessIter, _TypeT*, _Compare); template inline void __quick_sort_loop (_RandomAccessIter __first, _RandomAccessIter __last, _Compare __comp) { __quick_sort_loop_aux (__first, __last, _RWSTD_VALUE_TYPE (_RandomAccessIter), __comp); } template void __unguarded_linear_insert (_RandomAccessIter, _TypeT, _Compare); template inline void __linear_insert (_RandomAccessIter __first, _RandomAccessIter __last, _TypeT*) { _TypeT __value = *__last; if (__value < *__first) { _STD::copy_backward (__first, __last, __last + 1); *__first = __value; } else __unguarded_linear_insert (__last, __value); } template inline void __linear_insert (_RandomAccessIter __first, _RandomAccessIter __last, _TypeT*, _Compare __comp) { _TypeT __value = *__last; if (__comp (__value, *__first)) { _STD::copy_backward (__first, __last, __last + 1); *__first = __value; } else __unguarded_linear_insert(__last, __value, __comp); } template void __insertion_sort (_RandomAccessIter, _RandomAccessIter, _Compare); template inline void __unguarded_insertion_sort (_RandomAccessIter __first, _RandomAccessIter __last, _Compare __comp) { _RWSTD_ASSERT_RANGE (__first, __last); for (_RandomAccessIter __i = __first; __i != __last; ++__i) __unguarded_linear_insert (__i, *__i, __comp); } template void __introsort_loop (_RandomAccessIter, _RandomAccessIter, _Distance, _Compare); template void __final_insertion_sort (_RandomAccessIter, _RandomAccessIter, _Compare); // 25.3.1.1 template inline void sort (_RandomAccessIter __first, _RandomAccessIter __last, _Compare __comp) { if (!(__first == __last)) { // introsort guarantees O(N * log(N)) in the worst case __introsort_loop (__first, __last, __last - __first, __comp); __final_insertion_sort (__first, __last, __comp); } } template inline void sort (_RandomAccessIter __first, _RandomAccessIter __last) { _STD::sort (__first, __last, _RWSTD_LESS (_RandomAccessIter)); } template void __merge_without_buffer (_BidirIter, _BidirIter, _BidirIter, _Distance, _Distance, _Compare); template _INLINE void __inplace_stable_sort (_RandomAccessIter __first, _RandomAccessIter __last, _Compare __comp) { if (__last - __first < 15) __insertion_sort (__first, __last, __comp); else { _RandomAccessIter __middle = __first + (__last - __first) / 2; __inplace_stable_sort (__first, __middle, __comp); __inplace_stable_sort (__middle, __last, __comp); __merge_without_buffer (__first, __middle, __last, __middle - __first, __last - __middle, __comp); } } template void __merge_sort_loop (_RandomAccessIter1, _RandomAccessIter1, _RandomAccessIter2, _Distance, _Compare); template void __chunk_insertion_sort (_RandomAccessIter, _RandomAccessIter, _Distance, _Compare); template void __merge_sort_with_buffer (_RandomAccessIter, _RandomAccessIter, _Pointer, _Distance*, _TypeT*, _Compare); template void __stable_sort_adaptive (_RandomAccessIter, _RandomAccessIter, _Pointer, _Distance, _TypeT*, _Compare); template inline void __stable_sort (_RandomAccessIter __first, _RandomAccessIter __last, _TypeT*, _Distance*, _Compare __comp) { // call an extension of get_temporary_buffer<>() in case partial class // specialization (and iterator_traits<>) isn't supported by compiler pair<_TypeT*, _Distance> __p = _STD::get_temporary_buffer (_Distance (__last - __first), (_TypeT*)0); if (__p.first == 0) __inplace_stable_sort (__first, __last, __comp); else { _Distance __len = min (_Distance (__p.second), _Distance (__last - __first)); _STD::copy (__first, __first + __len, raw_storage_iterator<_TypeT*, _TypeT>(__p.first)); __stable_sort_adaptive (__first, __last, __p.first, __p.second, (_TypeT*)0, __comp); _RW::__rw_destroy (__p.first, __p.first + __len); _STD::return_temporary_buffer (__p.first); } } // 25.3.1.2 template inline void stable_sort (_RandomAccessIter __first, _RandomAccessIter __last, _Compare __comp) { if (!(__first == __last)) __stable_sort (__first, __last, _RWSTD_VALUE_TYPE (_RandomAccessIter), _RWSTD_DIFFERENCE_TYPE (_RandomAccessIter), __comp); } template inline void stable_sort (_RandomAccessIter __first, _RandomAccessIter __last) { _STD::stable_sort (__first, __last, _RWSTD_LESS (_RandomAccessIter)); } // helper to work around the lack of iterator_traits template void __partial_sort (_RandomAccessIter, _RandomAccessIter, _RandomAccessIter, _TypeT*, _Compare); // 25.3.1.3 template inline void partial_sort (_RandomAccessIter __first, _RandomAccessIter __middle, _RandomAccessIter __last, _Compare __comp) { _RWSTD_ASSERT_RANGE (__first, __last); _RWSTD_ASSERT_RANGE (__first, __middle); if (!(__first == __middle)) __partial_sort (__first, __middle, __last, _RWSTD_VALUE_TYPE(_RandomAccessIter), __comp); } template inline void partial_sort (_RandomAccessIter __first, _RandomAccessIter __middle, _RandomAccessIter __last) { _STD::partial_sort (__first, __middle, __last, _RWSTD_LESS (_RandomAccessIter)); } // helper to work around the lack of iterator_traits template _RandomAccessIter __partial_sort_copy (_InputIter, _InputIter, _RandomAccessIter, _RandomAccessIter, _Compare, _Distance*, _TypeT*); // 25.3.1.4 template inline _RandomAccessIter partial_sort_copy (_InputIter __first, _InputIter __last, _RandomAccessIter __res_first, _RandomAccessIter __res_last, _Compare __comp) { return __first == __last ? __res_first : __partial_sort_copy (__first, __last, __res_first, __res_last, __comp, _RWSTD_DIFFERENCE_TYPE (_RandomAccessIter), _RWSTD_VALUE_TYPE (_RandomAccessIter)); } template inline _RandomAccessIter partial_sort_copy (_InputIter __first1, _InputIter __last1, _RandomAccessIter __first2, _RandomAccessIter __last2) { return _STD::partial_sort_copy (__first1, __last1, __first2, __last2, _RWSTD_LESS (_InputIter)); } template void __nth_element (_RandomAccessIter, _RandomAccessIter, _RandomAccessIter, _TypeT*, _Compare); // 25.3.2 - Nth element [lib.alg.nth.element] template inline void nth_element (_RandomAccessIter __first, _RandomAccessIter __nth, _RandomAccessIter __last, _Compare __comp) { if (!(__first == __last)) __nth_element (__first, __nth, __last, _RWSTD_VALUE_TYPE (_RandomAccessIter), __comp); } template inline void nth_element (_RandomAccessIter __first, _RandomAccessIter __nth, _RandomAccessIter __last) { _STD::nth_element (__first, __nth, __last, _RWSTD_LESS (_RandomAccessIter)); } // 25.3.3 - Binary search [lib.alg.binary.search] template _FwdIter __lower_bound (_FwdIter, _FwdIter, const _TypeT&, _Compare, _Distance*, forward_iterator_tag); template inline _FwdIter __lower_bound (_FwdIter __first, _FwdIter __last, const _TypeT& __value, _Compare __comp, _Distance*, bidirectional_iterator_tag) { return __lower_bound (__first, __last, __value, __comp, (_Distance*)0, forward_iterator_tag ()); } template _RandomAccessIter __lower_bound (_RandomAccessIter, _RandomAccessIter, const _TypeT&, _Compare, _Distance*, random_access_iterator_tag); // 25.3.3.1 template inline _FwdIter lower_bound (_FwdIter __first,_FwdIter __last, const _TypeT& __value, _Compare __comp) { return __lower_bound (__first, __last, __value, __comp, _RWSTD_DIFFERENCE_TYPE (_FwdIter), _RWSTD_ITERATOR_CATEGORY (_FwdIter, __first)); } template inline _FwdIter lower_bound (_FwdIter __first, _FwdIter __last, const _TypeT& __value) { return _STD::lower_bound (__first, __last, __value, _RWSTD_LESS (_FwdIter)); } template _FwdIter __upper_bound (_FwdIter, _FwdIter, const _TypeT&, _Compare, _Distance*, forward_iterator_tag); template inline _FwdIter __upper_bound (_FwdIter __first, _FwdIter __last, const _TypeT& __value, _Compare __comp, _Distance*, bidirectional_iterator_tag) { return __upper_bound (__first, __last, __value, __comp, (_Distance*)0, forward_iterator_tag ()); } template _RandomAccessIter __upper_bound (_RandomAccessIter, _RandomAccessIter, const _TypeT&, _Compare, _Distance*, random_access_iterator_tag); // 25.3.3.2 template inline _FwdIter upper_bound (_FwdIter __first,_FwdIter __last, const _TypeT& __value, _Compare __comp) { return __upper_bound (__first, __last, __value, __comp, _RWSTD_DIFFERENCE_TYPE (_FwdIter), _RWSTD_ITERATOR_CATEGORY (_FwdIter, __first)); } template inline _FwdIter upper_bound (_FwdIter __first, _FwdIter __last, const _TypeT& __value) { return _STD::upper_bound (__first, __last, __value, _RWSTD_LESS (_FwdIter)); } template pair<_FwdIter, _FwdIter> __equal_range (_FwdIter, _FwdIter, const _TypeT&, _Compare, _Distance*, forward_iterator_tag); template inline pair<_FwdIter, _FwdIter> __equal_range (_FwdIter __first, _FwdIter __last, const _TypeT& __value, _Compare __comp, _Distance*, bidirectional_iterator_tag) { return __equal_range (__first, __last, __value, __comp, (_Distance*)0, forward_iterator_tag()); } template pair<_RandomAccessIter, _RandomAccessIter> __equal_range (_RandomAccessIter, _RandomAccessIter, const _TypeT&, _Compare, _Distance*, random_access_iterator_tag); // 25.3.3.3 template inline pair<_FwdIter, _FwdIter> equal_range (_FwdIter __first, _FwdIter __last, const _TypeT& __value, _Compare __comp) { return __equal_range (__first, __last, __value, __comp, _RWSTD_DIFFERENCE_TYPE (_FwdIter), _RWSTD_ITERATOR_CATEGORY (_FwdIter, __first)); } template inline pair<_FwdIter, _FwdIter> equal_range (_FwdIter __first, _FwdIter __last, const _TypeT& __value) { return _STD::equal_range (__first, __last, __value, _RWSTD_LESS (_FwdIter)); } // 25.3.3.4 template inline bool binary_search (_FwdIter __first, _FwdIter __last, const _TypeT& __value, _Compare __comp) { _FwdIter __i = _STD::lower_bound (__first, __last, __value, __comp); return __i != __last && !__comp(__value, *__i); } template inline bool binary_search (_FwdIter __first, _FwdIter __last, const _TypeT& __value) { return _STD::binary_search (__first, __last, __value, _RWSTD_LESS (_FwdIter)); } // 25.3.4 - Merge [lib.alg.merge] template _OutputIter merge (_InputIter1 __first1, _InputIter1 __last1, _InputIter2 __first2, _InputIter2 __last2, _OutputIter __res, _Compare __comp); template _OutputIter merge (_InputIter1 __first1, _InputIter1 __last1, _InputIter2 __first2, _InputIter2 __last2, _OutputIter __res) { return _STD::merge (__first1, __last1, __first2, __last2, __res, _RWSTD_LESS (_InputIter1)); } template _BidirIter3 __merge_backward (_BidirIter1, _BidirIter1, _BidirIter2, _BidirIter2, _BidirIter3, _Compare); template void __merge_adaptive (_BidirIter, _BidirIter, _BidirIter, _Distance, _Distance, _Pointer, _Distance, _TypeT*, _Compare); template void __inplace_merge (_BidirIter, _BidirIter, _BidirIter, _Distance*, _TypeT*, _Compare); // 25.3.4, p6 template inline void inplace_merge (_BidirIter __first, _BidirIter __middle, _BidirIter __last, _Compare __comp) { if (!(__first == __middle || __middle == __last)) __inplace_merge (__first, __middle, __last, _RWSTD_DIFFERENCE_TYPE (_BidirIter), _RWSTD_VALUE_TYPE (_BidirIter), __comp); } // 25.3.4, p6 template inline void inplace_merge (_BidirIter __first, _BidirIter __middle, _BidirIter __last) { _STD::inplace_merge (__first, __middle, __last, _RWSTD_LESS (_BidirIter)); } // 25.3.5 - Set operations on sorted structures // 25.3.5.1 template bool includes (_InputIter1, _InputIter1, _InputIter2, _InputIter2, _Compare); template inline bool includes (_InputIter1 __first1, _InputIter1 __last1, _InputIter2 __first2, _InputIter2 __last2) { return _STD::includes (__first1, __last1, __first2, __last2, _RWSTD_LESS (_InputIter1)); } // 25.3.5.2 template _OutputIter set_union (_InputIter1, _InputIter1, _InputIter2, _InputIter2, _OutputIter, _Compare); template inline _OutputIter set_union (_InputIter1 __first1, _InputIter1 __last1, _InputIter2 __first2, _InputIter2 __last2, _OutputIter __res) { return _STD::set_union (__first1, __last1, __first2, __last2, __res, _RWSTD_LESS (_InputIter1)); } // 25.3.5.3 template _OutputIter set_intersection (_InputIter1, _InputIter1, _InputIter2, _InputIter2, _OutputIter, _Compare); template inline _OutputIter set_intersection (_InputIter1 __first1, _InputIter1 __last1, _InputIter2 __first2, _InputIter2 __last2, _OutputIter __res) { return _STD::set_intersection (__first1, __last1, __first2, __last2, __res, _RWSTD_LESS (_InputIter1)); } // 25.3.5.4 template _OutputIter set_difference (_InputIter1, _InputIter1, _InputIter2, _InputIter2, _OutputIter, _Compare); template inline _OutputIter set_difference (_InputIter1 __first1, _InputIter1 __last1, _InputIter2 __first2, _InputIter2 __last2, _OutputIter __res) { return _STD::set_difference (__first1, __last1, __first2, __last2, __res, _RWSTD_LESS (_InputIter1)); } // 25.3.5.5 template _OutputIter set_symmetric_difference (_InputIter1, _InputIter1, _InputIter2, _InputIter2, _OutputIter, _Compare); template inline _OutputIter set_symmetric_difference (_InputIter1 __first1, _InputIter1 __last1, _InputIter2 __first2, _InputIter2 __last2, _OutputIter __res) { return _STD::set_symmetric_difference (__first1, __last1, __first2, __last2, __res, _RWSTD_LESS (_InputIter1)); } // 25.3.6 - Heap operations // helper to work around the lack of iterator_traits template void __push_heap (_RandomAccessIter, _Distance, _Distance, _TypeT, _Compare); template inline void __push_heap (_RandomAccessIter __first, _RandomAccessIter __last, _Distance*, _Compare __comp) { __push_heap (__first, _Distance (__last - __first), _Distance (), *__last, __comp); } // 25.3.6.1 template inline void push_heap (_RandomAccessIter __first, _RandomAccessIter __last, _Compare __comp) { _RWSTD_ASSERT_RANGE (__first, __last); if (!(__first == __last)) __push_heap (__first, --__last, _RWSTD_DIFFERENCE_TYPE (_RandomAccessIter), __comp); } // 25.3.6.1 template inline void push_heap (_RandomAccessIter __first, _RandomAccessIter __last) { _STD::push_heap (__first, __last, _RWSTD_LESS (_RandomAccessIter)); } template void __adjust_heap (_RandomAccessIter, _Distance, _Distance, _TypeT, _Compare); // helper to work around the lack of iterator_traits template inline void __pop_heap (_RandomAccessIter __first, _RandomAccessIter __last, _RandomAccessIter __res, _TypeT __val, _Compare __cmp, _Distance*) { *__res = *__first; __adjust_heap (__first, _Distance (), _Distance (__last - __first), __val, __cmp); } // 25.3.6.2 template inline void pop_heap (_RandomAccessIter __first, _RandomAccessIter __last, _Compare __comp) { _RWSTD_ASSERT_RANGE (__first, __last); if (!(__first == __last)) { --__last; __pop_heap (__first, __last, __last, *__last, __comp, _RWSTD_DIFFERENCE_TYPE (_RandomAccessIter)); } } // 25.3.6.2 template inline void pop_heap (_RandomAccessIter __first, _RandomAccessIter __last) { _STD::pop_heap (__first, __last, _RWSTD_LESS (_RandomAccessIter)); } template void __make_heap (_RandomAccessIter, _RandomAccessIter, _Compare, _TypeT*, _Distance*); // 25.3.6.3 template inline void make_heap (_RandomAccessIter __first, _RandomAccessIter __last, _Compare __comp) { _RWSTD_ASSERT_RANGE (__first, __last); if (!(__last - __first < 2)) __make_heap (__first, __last, __comp, _RWSTD_VALUE_TYPE (_RandomAccessIter), _RWSTD_DIFFERENCE_TYPE (_RandomAccessIter)); } // 25.3.6.3 template inline void make_heap (_RandomAccessIter __first, _RandomAccessIter __last) { _STD::make_heap (__first, __last, _RWSTD_LESS (_RandomAccessIter)); } // 25.3.6.4 template inline void sort_heap (_RandomAccessIter __first, _RandomAccessIter __last, _Compare __comp) { _RWSTD_ASSERT_RANGE (__first, __last); for (; __last - __first > 1; --__last) _STD::pop_heap (__first, __last, __comp); } // 25.3.6.4 template inline void sort_heap (_RandomAccessIter __first, _RandomAccessIter __last) { _STD::sort_heap (__first, __last, _RWSTD_LESS (_RandomAccessIter)); } // 25.3.7 - Minimum and maximum // 25.3.7, p7 template _FwdIter min_element (_FwdIter, _FwdIter, _Compare); template inline _FwdIter min_element (_FwdIter __first, _FwdIter __last) { return _STD::min_element (__first, __last, _RWSTD_LESS (_FwdIter)); } // 25.3.7, p9 template _FwdIter max_element (_FwdIter, _FwdIter, _Compare); template inline _FwdIter max_element (_FwdIter __first, _FwdIter __last) { return _STD::max_element (__first, __last, _RWSTD_LESS (_FwdIter)); } // 25.3.9 - Permutation generators [lib.alg.permutation.generators] // 25.3.9, p1 template bool next_permutation (_BidirIter, _BidirIter, _Compare); template inline bool next_permutation (_BidirIter __first, _BidirIter __last) { return _STD::next_permutation (__first, __last, _RWSTD_LESS (_BidirIter)); } // 25.3.9, p3 template bool prev_permutation (_BidirIter, _BidirIter, _Compare); template inline bool prev_permutation (_BidirIter __first, _BidirIter __last) { return _STD::prev_permutation (__first, __last, _RWSTD_LESS (_BidirIter)); } // // Modifying sequence operations. // template inline _FwdIter2 swap_ranges (_FwdIter1 __first1, _FwdIter1 __last1, _FwdIter2 __first2) { _RWSTD_ASSERT_RANGE (__first1, __last1); for (; __first1 != __last1; ++__first1, ++__first2) _STD::iter_swap (__first1, __first2); return __first2; } template inline _OutputIter transform (_InputIter __first, _InputIter __last, _OutputIter __res, _UnaryOperation __unary_op) { _RWSTD_ASSERT_RANGE (__first, __last); for (; __first != __last; ++__res, ++__first) *__res = __unary_op (*__first); return __res; } template inline _OutputIter transform (_InputIter1 __first1, _InputIter1 __last1, _InputIter2 __first2, _OutputIter __res, _BinaryOperation __binary_op) { _RWSTD_ASSERT_RANGE (__first1, __last1); for (; __first1 != __last1; ++__res, ++__first1, ++__first2) *__res = __binary_op (*__first1, *__first2); return __res; } template inline void replace (_FwdIter __first, _FwdIter __last, const _TypeT& __old_value, const _TypeT& __new_value) { _RWSTD_ASSERT_RANGE (__first, __last); for (; __first != __last; ++__first) if (*__first == __old_value) *__first = __new_value; } template inline void replace_if (_FwdIter __first, _FwdIter __last, _Predicate __pred, const _TypeT& __new_value) { _RWSTD_ASSERT_RANGE (__first, __last); for (; __first != __last; ++__first) if (__pred(*__first)) *__first = __new_value; } template inline _OutputIter replace_copy (_InputIter __first, _InputIter __last, _OutputIter __res, const _TypeT& __old_value, const _TypeT& __new_value) { _RWSTD_ASSERT_RANGE (__first, __last); for (;__first != __last; ++__first, ++__res) *__res = *__first == __old_value ? __new_value : *__first; return __res; } template inline void generate (_FwdIter __first, _FwdIter __last, _Generator __gen) { _RWSTD_ASSERT_RANGE (__first, __last); for (; __first != __last; ++__first) *__first = __gen (); } template inline void generate_n (_OutputIter __first, _Size __n, _Generator __gen) { for (; __n > 0;--__n, ++__first) *__first = __gen (); } template inline void __reverse (_BidirIter __first, _BidirIter __last, bidirectional_iterator_tag) { // Complexity: exactly (last - first) / 2 calls to std::iter_swap<>() for (; __first != __last && __first != --__last; ++__first) _STD::iter_swap (__first, __last); } template inline void __reverse (_RandomAccessIter __first, _RandomAccessIter __last, random_access_iterator_tag) { // Complexity: exactly (last - first) / 2 calls to std::iter_swap<>() if (__first != __last) for (; __first < --__last; ++__first) _STD::iter_swap (__first, __last); } template inline _OutputIter reverse_copy (_BidirIter __first, _BidirIter __last, _OutputIter __res) { _RWSTD_ASSERT_RANGE (__first, __last); for (; __first != __last; ++__res) *__res = *--__last; return __res; } _RWSTD_NAMESPACE_END // std #undef _INLINE #ifdef _RWSTD_COMPILE_INSTANTIATE # include #endif #endif // _RWSTD_ALGORITHM_INCLUDED