williamr@4: /* williamr@4: * williamr@4: * Copyright (c) 1994 williamr@4: * Hewlett-Packard Company williamr@4: * williamr@4: * Copyright (c) 1996,1997 williamr@4: * Silicon Graphics Computer Systems, Inc. williamr@4: * williamr@4: * Copyright (c) 1997 williamr@4: * Moscow Center for SPARC Technology williamr@4: * williamr@4: * Copyright (c) 1999 williamr@4: * Boris Fomitchev williamr@4: * williamr@4: * This material is provided "as is", with absolutely no warranty expressed williamr@4: * or implied. Any use is at your own risk. williamr@4: * williamr@4: * Permission to use or copy this software for any purpose is hereby granted williamr@4: * without fee, provided the above notices are retained on all copies. williamr@4: * Permission to modify the code and to distribute modified code is granted, williamr@4: * provided the above notices are retained, and a notice that the code was williamr@4: * modified is included with the above copyright notice. williamr@4: * williamr@4: */ williamr@4: williamr@4: #ifndef _STLP_ALGO_C williamr@4: #define _STLP_ALGO_C williamr@4: williamr@4: #if !defined (_STLP_INTERNAL_ALGO_H) williamr@4: # include williamr@4: #endif williamr@4: williamr@4: #ifndef _STLP_INTERNAL_TEMPBUF_H williamr@4: # include williamr@4: #endif williamr@4: williamr@4: _STLP_BEGIN_NAMESPACE williamr@4: williamr@4: _STLP_MOVE_TO_PRIV_NAMESPACE williamr@4: williamr@4: template williamr@4: void __merge_without_buffer(_BidirectionalIter __first, williamr@4: _BidirectionalIter __middle, williamr@4: _BidirectionalIter __last, williamr@4: _Distance __len1, _Distance __len2, williamr@4: _Compare __comp); williamr@4: williamr@4: williamr@4: template williamr@4: _BidirectionalIter3 __merge_backward(_BidirectionalIter1 __first1, williamr@4: _BidirectionalIter1 __last1, williamr@4: _BidirectionalIter2 __first2, williamr@4: _BidirectionalIter2 __last2, williamr@4: _BidirectionalIter3 __result, williamr@4: _Compare __comp); williamr@4: williamr@4: template williamr@4: #if !(defined (__SUNPRO_CC) && (__SUNPRO_CC < 0x420 )) williamr@4: inline williamr@4: #endif williamr@4: const _Tp& __median(const _Tp& __a, const _Tp& __b, const _Tp& __c) { williamr@4: if (__a < __b) williamr@4: if (__b < __c) williamr@4: return __b; williamr@4: else if (__a < __c) williamr@4: return __c; williamr@4: else williamr@4: return __a; williamr@4: else if (__a < __c) williamr@4: return __a; williamr@4: else if (__b < __c) williamr@4: return __c; williamr@4: else williamr@4: return __b; williamr@4: } williamr@4: williamr@4: template williamr@4: #if !(defined (__SUNPRO_CC) && (__SUNPRO_CC < 0x420 )) williamr@4: inline williamr@4: #endif williamr@4: const _Tp& williamr@4: __median(const _Tp& __a, const _Tp& __b, const _Tp& __c, _Compare __comp) { williamr@4: if (__comp(__a, __b)) { williamr@4: _STLP_VERBOSE_ASSERT(!__comp(__b, __a), _StlMsg_INVALID_STRICT_WEAK_PREDICATE) williamr@4: if (__comp(__b, __c)) { williamr@4: _STLP_VERBOSE_ASSERT(!__comp(__c, __b), _StlMsg_INVALID_STRICT_WEAK_PREDICATE) williamr@4: return __b; williamr@4: } williamr@4: else if (__comp(__a, __c)) { williamr@4: _STLP_VERBOSE_ASSERT(!__comp(__c, __a), _StlMsg_INVALID_STRICT_WEAK_PREDICATE) williamr@4: return __c; williamr@4: } williamr@4: else williamr@4: return __a; williamr@4: } williamr@4: else if (__comp(__a, __c)) { williamr@4: _STLP_VERBOSE_ASSERT(!__comp(__c, __a), _StlMsg_INVALID_STRICT_WEAK_PREDICATE) williamr@4: return __a; williamr@4: } williamr@4: else if (__comp(__b, __c)) { williamr@4: _STLP_VERBOSE_ASSERT(!__comp(__c, __b), _StlMsg_INVALID_STRICT_WEAK_PREDICATE) williamr@4: return __c; williamr@4: } williamr@4: else williamr@4: return __b; williamr@4: } williamr@4: williamr@4: _STLP_MOVE_TO_STD_NAMESPACE williamr@4: williamr@4: template williamr@4: _ForwardIter1 search(_ForwardIter1 __first1, _ForwardIter1 __last1, williamr@4: _ForwardIter2 __first2, _ForwardIter2 __last2) { williamr@4: _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first1, __last1)) williamr@4: _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first2, __last2)) williamr@4: // Test for empty ranges williamr@4: if (__first1 == __last1 || __first2 == __last2) williamr@4: return __first1; williamr@4: williamr@4: // Test for a pattern of length 1. williamr@4: _ForwardIter2 __tmp(__first2); williamr@4: ++__tmp; williamr@4: if (__tmp == __last2) williamr@4: return find(__first1, __last1, *__first2); williamr@4: williamr@4: // General case. williamr@4: _ForwardIter2 __p1 = __first2; williamr@4: ++__p1; williamr@4: williamr@4: _ForwardIter1 __current;// = __first1; williamr@4: williamr@4: while (__first1 != __last1) { williamr@4: __first1 = find(__first1, __last1, *__first2); williamr@4: if (__first1 == __last1) williamr@4: return __last1; williamr@4: williamr@4: _ForwardIter2 __p = __p1; williamr@4: __current = __first1; williamr@4: if (++__current == __last1) williamr@4: return __last1; williamr@4: williamr@4: while (*__current == *__p) { williamr@4: if (++__p == __last2) williamr@4: return __first1; williamr@4: if (++__current == __last1) williamr@4: return __last1; williamr@4: } williamr@4: williamr@4: ++__first1; williamr@4: } williamr@4: return __first1; williamr@4: } williamr@4: williamr@4: _STLP_MOVE_TO_PRIV_NAMESPACE williamr@4: williamr@4: template williamr@4: _RandomAccessIter __search_n(_RandomAccessIter __first, _RandomAccessIter __last, williamr@4: _Integer __count, const _Tp& __val, _BinaryPred __pred, williamr@4: _Distance*, const random_access_iterator_tag &) williamr@4: { williamr@4: _Distance __tailSize = __last - __first; williamr@4: const _Distance __pattSize = __count; williamr@4: const _Distance __skipOffset = __pattSize - 1; williamr@4: _RandomAccessIter __backTrack; williamr@4: _Distance __remainder, __prevRemainder; williamr@4: williamr@4: for ( _RandomAccessIter __lookAhead = __first + __skipOffset; __tailSize >= __pattSize; __lookAhead += __pattSize ) { // the main loop... williamr@4: //__lookAhead here is always pointing to the last element of next possible match. williamr@4: __tailSize -= __pattSize; williamr@4: williamr@4: while ( !__pred(*__lookAhead, __val) ) { // the skip loop... williamr@4: if (__tailSize < __pattSize) williamr@4: return __last; williamr@4: williamr@4: __lookAhead += __pattSize; williamr@4: __tailSize -= __pattSize; williamr@4: } williamr@4: williamr@4: if ( __skipOffset == 0 ) { williamr@4: return (__lookAhead - __skipOffset); //Success williamr@4: } williamr@4: williamr@4: __remainder = __skipOffset; williamr@4: williamr@4: for (__backTrack = __lookAhead; __pred(*--__backTrack, __val); ) { williamr@4: if (--__remainder == 0) williamr@4: return (__lookAhead - __skipOffset); //Success williamr@4: } williamr@4: williamr@4: if (__remainder > __tailSize) williamr@4: return __last; //failure williamr@4: williamr@4: __lookAhead += __remainder; williamr@4: __tailSize -= __remainder; williamr@4: williamr@4: while ( __pred(*__lookAhead, __val) ) { williamr@4: __prevRemainder = __remainder; williamr@4: __backTrack = __lookAhead; williamr@4: williamr@4: do { williamr@4: if (--__remainder == 0) williamr@4: return (__lookAhead - __skipOffset); //Success williamr@4: } while (__pred(*--__backTrack, __val)); williamr@4: williamr@4: //adjust remainder for next comparison williamr@4: __remainder += __pattSize - __prevRemainder; williamr@4: williamr@4: if (__remainder > __tailSize) williamr@4: return __last; //failure williamr@4: williamr@4: __lookAhead += __remainder; williamr@4: __tailSize -= __remainder; williamr@4: } williamr@4: williamr@4: //__lookAhead here is always pointing to the element of the last mismatch. williamr@4: } williamr@4: williamr@4: return __last; //failure williamr@4: } williamr@4: williamr@4: template williamr@4: _ForwardIter __search_n(_ForwardIter __first, _ForwardIter __last, williamr@4: _Integer __count, const _Tp& __val, _BinaryPred __pred, williamr@4: _Distance*, const forward_iterator_tag &) { williamr@4: for (; (__first != __last) && !__pred(*__first, __val); ++__first) {} williamr@4: while (__first != __last) { williamr@4: _Integer __n = __count - 1; williamr@4: _ForwardIter __i = __first; williamr@4: ++__i; williamr@4: while (__i != __last && __n != 0 && __pred(*__i, __val)) { williamr@4: ++__i; williamr@4: --__n; williamr@4: } williamr@4: if (__n == 0) williamr@4: return __first; williamr@4: else if (__i != __last) williamr@4: for (__first = ++__i; (__first != __last) && !__pred(*__first, __val); ++__first) {} williamr@4: else williamr@4: break; williamr@4: } williamr@4: return __last; williamr@4: } williamr@4: williamr@4: _STLP_MOVE_TO_STD_NAMESPACE williamr@4: williamr@4: // search_n. Search for __count consecutive copies of __val. williamr@4: template williamr@4: _ForwardIter search_n(_ForwardIter __first, _ForwardIter __last, williamr@4: _Integer __count, const _Tp& __val) { williamr@4: _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first, __last)) williamr@4: if (__count <= 0) williamr@4: return __first; williamr@4: if (__count == 1) williamr@4: //We use find when __count == 1 to use potential find overload. williamr@4: return find(__first, __last, __val); williamr@4: return _STLP_PRIV __search_n(__first, __last, __count, __val, equal_to<_Tp>(), williamr@4: _STLP_DISTANCE_TYPE(__first, _ForwardIter), williamr@4: _STLP_ITERATOR_CATEGORY(__first, _ForwardIter)); williamr@4: } williamr@4: williamr@4: template williamr@4: _ForwardIter search_n(_ForwardIter __first, _ForwardIter __last, williamr@4: _Integer __count, const _Tp& __val, williamr@4: _BinaryPred __binary_pred) { williamr@4: _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first, __last)) williamr@4: if (__count <= 0) williamr@4: return __first; williamr@4: return _STLP_PRIV __search_n(__first, __last, __count, __val, __binary_pred, williamr@4: _STLP_DISTANCE_TYPE(__first, _ForwardIter), williamr@4: _STLP_ITERATOR_CATEGORY(__first, _ForwardIter)); williamr@4: } williamr@4: williamr@4: template williamr@4: _ForwardIter1 williamr@4: find_end(_ForwardIter1 __first1, _ForwardIter1 __last1, williamr@4: _ForwardIter2 __first2, _ForwardIter2 __last2) { williamr@4: _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first1, __last1)) williamr@4: _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first2, __last2)) williamr@4: return _STLP_PRIV __find_end(__first1, __last1, __first2, __last2, williamr@4: #if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION) williamr@4: _STLP_ITERATOR_CATEGORY(__first1, _ForwardIter1), williamr@4: _STLP_ITERATOR_CATEGORY(__first2, _ForwardIter2), williamr@4: #else williamr@4: forward_iterator_tag(), williamr@4: forward_iterator_tag(), williamr@4: #endif williamr@4: _STLP_PRIV __equal_to(_STLP_VALUE_TYPE(__first1, _ForwardIter1)) williamr@4: ); williamr@4: } williamr@4: williamr@4: // unique and unique_copy williamr@4: _STLP_MOVE_TO_PRIV_NAMESPACE williamr@4: williamr@4: template williamr@4: _STLP_INLINE_LOOP _OutputIterator williamr@4: __unique_copy(_InputIterator __first, _InputIterator __last, williamr@4: _OutputIterator __result, williamr@4: _BinaryPredicate __binary_pred, _Tp*) { williamr@4: _Tp __val = *__first; williamr@4: *__result = __val; williamr@4: while (++__first != __last) williamr@4: if (!__binary_pred(__val, *__first)) { williamr@4: __val = *__first; williamr@4: *++__result = __val; williamr@4: } williamr@4: return ++__result; williamr@4: } williamr@4: williamr@4: template williamr@4: inline _OutputIter williamr@4: __unique_copy(_InputIter __first, _InputIter __last,_OutputIter __result, williamr@4: _BinaryPredicate __binary_pred, const output_iterator_tag &) { williamr@4: return __unique_copy(__first, __last, __result, __binary_pred, _STLP_VALUE_TYPE(__first, _InputIter)); williamr@4: } williamr@4: williamr@4: template williamr@4: _STLP_INLINE_LOOP _ForwardIter williamr@4: __unique_copy(_InputIter __first, _InputIter __last, _ForwardIter __result, williamr@4: _BinaryPredicate __binary_pred, const forward_iterator_tag &) { williamr@4: *__result = *__first; williamr@4: while (++__first != __last) williamr@4: if (!__binary_pred(*__result, *__first)) *++__result = *__first; williamr@4: return ++__result; williamr@4: } williamr@4: williamr@4: #if defined (_STLP_NONTEMPL_BASE_MATCH_BUG) williamr@4: template williamr@4: inline _BidirectionalIterator williamr@4: __unique_copy(_InputIterator __first, _InputIterator __last, williamr@4: _BidirectionalIterator __result, _BinaryPredicate __binary_pred, williamr@4: const bidirectional_iterator_tag &) { williamr@4: return __unique_copy(__first, __last, __result, __binary_pred, forward_iterator_tag()); williamr@4: } williamr@4: williamr@4: template williamr@4: inline _RandomAccessIterator williamr@4: __unique_copy(_InputIterator __first, _InputIterator __last, williamr@4: _RandomAccessIterator __result, _BinaryPredicate __binary_pred, williamr@4: const random_access_iterator_tag &) { williamr@4: return __unique_copy(__first, __last, __result, __binary_pred, forward_iterator_tag()); williamr@4: } williamr@4: #endif /* _STLP_NONTEMPL_BASE_MATCH_BUG */ williamr@4: williamr@4: _STLP_MOVE_TO_STD_NAMESPACE williamr@4: williamr@4: template williamr@4: _OutputIter williamr@4: unique_copy(_InputIter __first, _InputIter __last, _OutputIter __result) { williamr@4: _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first, __last)) williamr@4: if (__first == __last) return __result; williamr@4: return _STLP_PRIV __unique_copy(__first, __last, __result, williamr@4: _STLP_PRIV __equal_to(_STLP_VALUE_TYPE(__first, _InputIter)), williamr@4: _STLP_ITERATOR_CATEGORY(__result, _OutputIter)); williamr@4: } williamr@4: williamr@4: template williamr@4: _OutputIter williamr@4: unique_copy(_InputIter __first, _InputIter __last,_OutputIter __result, williamr@4: _BinaryPredicate __binary_pred) { williamr@4: _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first, __last)) williamr@4: if (__first == __last) return __result; williamr@4: return _STLP_PRIV __unique_copy(__first, __last, __result, __binary_pred, williamr@4: _STLP_ITERATOR_CATEGORY(__result, _OutputIter)); williamr@4: } williamr@4: williamr@4: // rotate and rotate_copy, and their auxiliary functions williamr@4: _STLP_MOVE_TO_PRIV_NAMESPACE williamr@4: williamr@4: template williamr@4: _ForwardIter __rotate_aux(_ForwardIter __first, williamr@4: _ForwardIter __middle, williamr@4: _ForwardIter __last, williamr@4: _Distance*, williamr@4: const forward_iterator_tag &) { williamr@4: if (__first == __middle) williamr@4: return __last; williamr@4: if (__last == __middle) williamr@4: return __first; williamr@4: williamr@4: _ForwardIter __first2 = __middle; williamr@4: do { williamr@4: swap(*__first++, *__first2++); williamr@4: if (__first == __middle) williamr@4: __middle = __first2; williamr@4: } while (__first2 != __last); williamr@4: williamr@4: _ForwardIter __new_middle = __first; williamr@4: williamr@4: __first2 = __middle; williamr@4: williamr@4: while (__first2 != __last) { williamr@4: swap (*__first++, *__first2++); williamr@4: if (__first == __middle) williamr@4: __middle = __first2; williamr@4: else if (__first2 == __last) williamr@4: __first2 = __middle; williamr@4: } williamr@4: williamr@4: return __new_middle; williamr@4: } williamr@4: williamr@4: template williamr@4: _BidirectionalIter __rotate_aux(_BidirectionalIter __first, williamr@4: _BidirectionalIter __middle, williamr@4: _BidirectionalIter __last, williamr@4: _Distance*, williamr@4: const bidirectional_iterator_tag &) { williamr@4: if (__first == __middle) williamr@4: return __last; williamr@4: if (__last == __middle) williamr@4: return __first; williamr@4: williamr@4: __reverse(__first, __middle, bidirectional_iterator_tag()); williamr@4: __reverse(__middle, __last, bidirectional_iterator_tag()); williamr@4: williamr@4: while (__first != __middle && __middle != __last) williamr@4: swap (*__first++, *--__last); williamr@4: williamr@4: if (__first == __middle) { williamr@4: __reverse(__middle, __last, bidirectional_iterator_tag()); williamr@4: return __last; williamr@4: } williamr@4: else { williamr@4: __reverse(__first, __middle, bidirectional_iterator_tag()); williamr@4: return __first; williamr@4: } williamr@4: } williamr@4: williamr@4: template williamr@4: _RandomAccessIter __rotate_aux(_RandomAccessIter __first, williamr@4: _RandomAccessIter __middle, williamr@4: _RandomAccessIter __last, williamr@4: _Distance *, _Tp *) { williamr@4: williamr@4: _Distance __n = __last - __first; williamr@4: _Distance __k = __middle - __first; williamr@4: _Distance __l = __n - __k; williamr@4: _RandomAccessIter __result = __first + (__last - __middle); williamr@4: williamr@4: if (__k == 0) /* __first == middle */ williamr@4: return __last; williamr@4: williamr@4: if (__k == __l) { williamr@4: swap_ranges(__first, __middle, __middle); williamr@4: return __result; williamr@4: } williamr@4: williamr@4: _Distance __d = __gcd(__n, __k); williamr@4: williamr@4: for (_Distance __i = 0; __i < __d; __i++) { williamr@4: _Tp __tmp = *__first; williamr@4: _RandomAccessIter __p = __first; williamr@4: williamr@4: if (__k < __l) { williamr@4: for (_Distance __j = 0; __j < __l/__d; __j++) { williamr@4: if (__p > __first + __l) { williamr@4: *__p = *(__p - __l); williamr@4: __p -= __l; williamr@4: } williamr@4: williamr@4: *__p = *(__p + __k); williamr@4: __p += __k; williamr@4: } williamr@4: } williamr@4: williamr@4: else { williamr@4: for (_Distance __j = 0; __j < __k/__d - 1; __j ++) { williamr@4: if (__p < __last - __k) { williamr@4: *__p = *(__p + __k); williamr@4: __p += __k; williamr@4: } williamr@4: williamr@4: *__p = * (__p - __l); williamr@4: __p -= __l; williamr@4: } williamr@4: } williamr@4: williamr@4: *__p = __tmp; williamr@4: ++__first; williamr@4: } williamr@4: williamr@4: return __result; williamr@4: } williamr@4: williamr@4: template williamr@4: inline _RandomAccessIter williamr@4: __rotate_aux(_RandomAccessIter __first, _RandomAccessIter __middle, _RandomAccessIter __last, williamr@4: _Distance * __dis, const random_access_iterator_tag &) { williamr@4: return __rotate_aux(__first, __middle, __last, williamr@4: __dis, _STLP_VALUE_TYPE(__first, _RandomAccessIter)); williamr@4: } williamr@4: williamr@4: template williamr@4: _ForwardIter williamr@4: __rotate(_ForwardIter __first, _ForwardIter __middle, _ForwardIter __last) { williamr@4: _STLP_DEBUG_CHECK(__check_range(__first, __middle)) williamr@4: _STLP_DEBUG_CHECK(__check_range(__middle, __last)) williamr@4: return __rotate_aux(__first, __middle, __last, williamr@4: _STLP_DISTANCE_TYPE(__first, _ForwardIter), williamr@4: _STLP_ITERATOR_CATEGORY(__first, _ForwardIter)); williamr@4: } williamr@4: williamr@4: _STLP_MOVE_TO_STD_NAMESPACE williamr@4: williamr@4: template williamr@4: void rotate(_ForwardIter __first, _ForwardIter __middle, _ForwardIter __last) { williamr@4: _STLP_PRIV __rotate(__first, __middle, __last); williamr@4: } williamr@4: williamr@4: // Return a random number in the range [0, __n). This function encapsulates williamr@4: // whether we're using rand (part of the standard C library) or lrand48 williamr@4: // (not standard, but a much better choice whenever it's available). williamr@4: _STLP_MOVE_TO_PRIV_NAMESPACE williamr@4: williamr@4: template williamr@4: inline _Distance __random_number(_Distance __n) { williamr@4: #ifdef _STLP_NO_DRAND48 williamr@4: return rand() % __n; williamr@4: #else williamr@4: return lrand48() % __n; williamr@4: #endif williamr@4: } williamr@4: williamr@4: _STLP_MOVE_TO_STD_NAMESPACE williamr@4: williamr@4: template williamr@4: void random_shuffle(_RandomAccessIter __first, williamr@4: _RandomAccessIter __last) { williamr@4: _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first, __last)) williamr@4: if (__first == __last) return; williamr@4: for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i) williamr@4: iter_swap(__i, __first + _STLP_PRIV __random_number((__i - __first) + 1)); williamr@4: } williamr@4: williamr@4: template williamr@4: void random_shuffle(_RandomAccessIter __first, _RandomAccessIter __last, williamr@4: _RandomNumberGenerator &__rand) { williamr@4: _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first, __last)) williamr@4: if (__first == __last) return; williamr@4: for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i) williamr@4: iter_swap(__i, __first + __rand((__i - __first) + 1)); williamr@4: } williamr@4: williamr@4: #if !defined (_STLP_NO_EXTENSIONS) williamr@4: // random_sample and random_sample_n (extensions, not part of the standard). williamr@4: template williamr@4: _OutputIter random_sample_n(_ForwardIter __first, _ForwardIter __last, williamr@4: _OutputIter __out_ite, const _Distance __n) { williamr@4: _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first, __last)) williamr@4: _Distance __remaining = distance(__first, __last); williamr@4: _Distance __m = (min) (__n, __remaining); williamr@4: williamr@4: while (__m > 0) { williamr@4: if (_STLP_PRIV __random_number(__remaining) < __m) { williamr@4: *__out_ite = *__first; williamr@4: ++__out_ite; williamr@4: --__m; williamr@4: } williamr@4: williamr@4: --__remaining; williamr@4: ++__first; williamr@4: } williamr@4: return __out_ite; williamr@4: } williamr@4: williamr@4: williamr@4: template williamr@4: _OutputIter random_sample_n(_ForwardIter __first, _ForwardIter __last, williamr@4: _OutputIter __out_ite, const _Distance __n, williamr@4: _RandomNumberGenerator& __rand) { williamr@4: _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first, __last)) williamr@4: _Distance __remaining = distance(__first, __last); williamr@4: _Distance __m = (min) (__n, __remaining); williamr@4: williamr@4: while (__m > 0) { williamr@4: if (__rand(__remaining) < __m) { williamr@4: *__out_ite = *__first; williamr@4: ++__out_ite; williamr@4: --__m; williamr@4: } williamr@4: williamr@4: --__remaining; williamr@4: ++__first; williamr@4: } williamr@4: return __out_ite; williamr@4: } williamr@4: williamr@4: _STLP_MOVE_TO_PRIV_NAMESPACE williamr@4: williamr@4: template williamr@4: _RandomAccessIter __random_sample(_InputIter __first, _InputIter __last, williamr@4: _RandomAccessIter __out_ite, williamr@4: const _Distance __n) { williamr@4: _Distance __m = 0; williamr@4: _Distance __t = __n; williamr@4: for ( ; __first != __last && __m < __n; ++__m, ++__first) williamr@4: __out_ite[__m] = *__first; williamr@4: williamr@4: while (__first != __last) { williamr@4: ++__t; williamr@4: _Distance __M = __random_number(__t); williamr@4: if (__M < __n) williamr@4: __out_ite[__M] = *__first; williamr@4: ++__first; williamr@4: } williamr@4: williamr@4: return __out_ite + __m; williamr@4: } williamr@4: williamr@4: template williamr@4: _RandomAccessIter __random_sample(_InputIter __first, _InputIter __last, williamr@4: _RandomAccessIter __out_ite, williamr@4: _RandomNumberGenerator& __rand, williamr@4: const _Distance __n) { williamr@4: _Distance __m = 0; williamr@4: _Distance __t = __n; williamr@4: for ( ; __first != __last && __m < __n; ++__m, ++__first) williamr@4: __out_ite[__m] = *__first; williamr@4: williamr@4: while (__first != __last) { williamr@4: ++__t; williamr@4: _Distance __M = __rand(__t); williamr@4: if (__M < __n) williamr@4: __out_ite[__M] = *__first; williamr@4: ++__first; williamr@4: } williamr@4: williamr@4: return __out_ite + __m; williamr@4: } williamr@4: williamr@4: _STLP_MOVE_TO_STD_NAMESPACE williamr@4: williamr@4: template williamr@4: _RandomAccessIter williamr@4: random_sample(_InputIter __first, _InputIter __last, williamr@4: _RandomAccessIter __out_first, _RandomAccessIter __out_last) { williamr@4: _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first, __last)) williamr@4: _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__out_first, __out_last)) williamr@4: return _STLP_PRIV __random_sample(__first, __last, williamr@4: __out_first, __out_last - __out_first); williamr@4: } williamr@4: williamr@4: template williamr@4: _RandomAccessIter williamr@4: random_sample(_InputIter __first, _InputIter __last, williamr@4: _RandomAccessIter __out_first, _RandomAccessIter __out_last, williamr@4: _RandomNumberGenerator& __rand) { williamr@4: _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first, __last)) williamr@4: _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__out_first, __out_last)) williamr@4: return _STLP_PRIV __random_sample(__first, __last, williamr@4: __out_first, __rand, williamr@4: __out_last - __out_first); williamr@4: } williamr@4: williamr@4: #endif /* _STLP_NO_EXTENSIONS */ williamr@4: williamr@4: // partition, stable_partition, and their auxiliary functions williamr@4: _STLP_MOVE_TO_PRIV_NAMESPACE williamr@4: williamr@4: template williamr@4: _STLP_INLINE_LOOP _ForwardIter __partition(_ForwardIter __first, williamr@4: _ForwardIter __last, williamr@4: _Predicate __pred, williamr@4: const forward_iterator_tag &) { williamr@4: if (__first == __last) return __first; williamr@4: williamr@4: while (__pred(*__first)) williamr@4: if (++__first == __last) return __first; williamr@4: williamr@4: _ForwardIter __next = __first; williamr@4: williamr@4: while (++__next != __last) { williamr@4: if (__pred(*__next)) { williamr@4: swap(*__first, *__next); williamr@4: ++__first; williamr@4: } williamr@4: } williamr@4: return __first; williamr@4: } williamr@4: williamr@4: template williamr@4: _STLP_INLINE_LOOP _BidirectionalIter __partition(_BidirectionalIter __first, williamr@4: _BidirectionalIter __last, williamr@4: _Predicate __pred, williamr@4: const bidirectional_iterator_tag &) { williamr@4: for (;;) { williamr@4: for (;;) { williamr@4: if (__first == __last) williamr@4: return __first; williamr@4: else if (__pred(*__first)) williamr@4: ++__first; williamr@4: else williamr@4: break; williamr@4: } williamr@4: --__last; williamr@4: for (;;) { williamr@4: if (__first == __last) williamr@4: return __first; williamr@4: else if (!__pred(*__last)) williamr@4: --__last; williamr@4: else williamr@4: break; williamr@4: } williamr@4: iter_swap(__first, __last); williamr@4: ++__first; williamr@4: } williamr@4: } williamr@4: williamr@4: #if defined (_STLP_NONTEMPL_BASE_MATCH_BUG) williamr@4: template williamr@4: inline williamr@4: _BidirectionalIter __partition(_BidirectionalIter __first, williamr@4: _BidirectionalIter __last, williamr@4: _Predicate __pred, williamr@4: const random_access_iterator_tag &) { williamr@4: return __partition(__first, __last, __pred, bidirectional_iterator_tag()); williamr@4: } williamr@4: #endif williamr@4: williamr@4: _STLP_MOVE_TO_STD_NAMESPACE williamr@4: williamr@4: template williamr@4: _ForwardIter partition(_ForwardIter __first, _ForwardIter __last, _Predicate __pred) { williamr@4: _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first, __last)) williamr@4: return _STLP_PRIV __partition(__first, __last, __pred, _STLP_ITERATOR_CATEGORY(__first, _ForwardIter)); williamr@4: } williamr@4: williamr@4: williamr@4: /* __pred_of_first: false if we know that __pred(*__first) is false, williamr@4: * true when we don't know the result of __pred(*__first). williamr@4: * __not_pred_of_before_last: true if we know that __pred(*--__last) is true, williamr@4: * false when we don't know the result of __pred(*--__last). williamr@4: */ williamr@4: _STLP_MOVE_TO_PRIV_NAMESPACE williamr@4: williamr@4: template williamr@4: _ForwardIter __inplace_stable_partition(_ForwardIter __first, williamr@4: _ForwardIter __last, williamr@4: _Predicate __pred, _Distance __len, williamr@4: bool __pred_of_first, bool __pred_of_before_last) { williamr@4: if (__len == 1) williamr@4: return (__pred_of_first && (__pred_of_before_last || __pred(*__first))) ? __last : __first; williamr@4: _ForwardIter __middle = __first; williamr@4: _Distance __half_len = __len / 2; williamr@4: advance(__middle, __half_len); williamr@4: return __rotate(__inplace_stable_partition(__first, __middle, __pred, __half_len, __pred_of_first, false), williamr@4: __middle, williamr@4: __inplace_stable_partition(__middle, __last, __pred, __len - __half_len, true, __pred_of_before_last)); williamr@4: } williamr@4: williamr@4: template williamr@4: _ForwardIter __stable_partition_adaptive(_ForwardIter __first, williamr@4: _ForwardIter __last, williamr@4: _Predicate __pred, _Distance __len, williamr@4: _Pointer __buffer, _Distance __buffer_size, williamr@4: bool __pred_of_first, bool __pred_of_before_last) { williamr@4: if (__len <= __buffer_size) { williamr@4: _ForwardIter __result1 = __first; williamr@4: _Pointer __result2 = __buffer; williamr@4: if ((__first != __last) && (!__pred_of_first || __pred(*__first))) { williamr@4: *__result2 = *__first; williamr@4: ++__result2; ++__first; --__len; williamr@4: } williamr@4: for (; __first != __last ; ++__first, --__len) { williamr@4: if (((__len == 1) && (__pred_of_before_last || __pred(*__first))) || williamr@4: ((__len != 1) && __pred(*__first))){ williamr@4: *__result1 = *__first; williamr@4: ++__result1; williamr@4: } williamr@4: else { williamr@4: *__result2 = *__first; williamr@4: ++__result2; williamr@4: } williamr@4: } williamr@4: copy(__buffer, __result2, __result1); williamr@4: return __result1; williamr@4: } williamr@4: else { williamr@4: _ForwardIter __middle = __first; williamr@4: _Distance __half_len = __len / 2; williamr@4: advance(__middle, __half_len); williamr@4: return __rotate(__stable_partition_adaptive( williamr@4: __first, __middle, __pred, williamr@4: __half_len, __buffer, __buffer_size, williamr@4: __pred_of_first, false), williamr@4: __middle, williamr@4: __stable_partition_adaptive( williamr@4: __middle, __last, __pred, williamr@4: __len - __half_len, __buffer, __buffer_size, williamr@4: true, __pred_of_before_last)); williamr@4: } williamr@4: } williamr@4: williamr@4: template williamr@4: inline _ForwardIter williamr@4: __stable_partition_aux_aux(_ForwardIter __first, _ForwardIter __last, williamr@4: _Predicate __pred, _Tp*, _Distance*, bool __pred_of_before_last = false) { williamr@4: _Temporary_buffer<_ForwardIter, _Tp> __buf(__first, __last); williamr@4: _STLP_MPWFIX_TRY //*TY 06/01/2000 - they forget to call dtor for _Temporary_buffer if no try/catch block is present williamr@4: return (__buf.size() > 0) ? williamr@4: __stable_partition_adaptive(__first, __last, __pred, williamr@4: _Distance(__buf.requested_size()), williamr@4: __buf.begin(), __buf.size(), williamr@4: false, __pred_of_before_last) : williamr@4: __inplace_stable_partition(__first, __last, __pred, williamr@4: _Distance(__buf.requested_size()), williamr@4: false, __pred_of_before_last); williamr@4: _STLP_MPWFIX_CATCH //*TY 06/01/2000 - they forget to call dtor for _Temporary_buffer if no try/catch block is present williamr@4: } williamr@4: williamr@4: template williamr@4: _ForwardIter williamr@4: __stable_partition_aux(_ForwardIter __first, _ForwardIter __last, _Predicate __pred, williamr@4: const forward_iterator_tag &) { williamr@4: return __stable_partition_aux_aux(__first, __last, __pred, williamr@4: _STLP_VALUE_TYPE(__first, _ForwardIter), williamr@4: _STLP_DISTANCE_TYPE(__first, _ForwardIter)); williamr@4: } williamr@4: williamr@4: template williamr@4: _BidirectIter williamr@4: __stable_partition_aux(_BidirectIter __first, _BidirectIter __last, _Predicate __pred, williamr@4: const bidirectional_iterator_tag &) { williamr@4: for (--__last;;) { williamr@4: if (__first == __last) williamr@4: return __first; williamr@4: else if (!__pred(*__last)) williamr@4: --__last; williamr@4: else williamr@4: break; williamr@4: } williamr@4: ++__last; williamr@4: //Here we know that __pred(*--__last) is true williamr@4: return __stable_partition_aux_aux(__first, __last, __pred, williamr@4: _STLP_VALUE_TYPE(__first, _BidirectIter), williamr@4: _STLP_DISTANCE_TYPE(__first, _BidirectIter), true); williamr@4: } williamr@4: williamr@4: #if defined (_STLP_NONTEMPL_BASE_MATCH_BUG) williamr@4: template williamr@4: _BidirectIter williamr@4: __stable_partition_aux(_BidirectIter __first, _BidirectIter __last, _Predicate __pred, williamr@4: const random_access_iterator_tag &) { williamr@4: return __stable_partition_aux(__first, __last, __pred, bidirectional_iterator_tag()); williamr@4: } williamr@4: #endif williamr@4: williamr@4: _STLP_MOVE_TO_STD_NAMESPACE williamr@4: williamr@4: template williamr@4: _ForwardIter williamr@4: stable_partition(_ForwardIter __first, _ForwardIter __last, _Predicate __pred) { williamr@4: _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first, __last)) williamr@4: for (;;) { williamr@4: if (__first == __last) williamr@4: return __first; williamr@4: else if (__pred(*__first)) williamr@4: ++__first; williamr@4: else williamr@4: break; williamr@4: } williamr@4: return _STLP_PRIV __stable_partition_aux(__first, __last, __pred, williamr@4: _STLP_ITERATOR_CATEGORY(__first, _ForwardIter)); williamr@4: } williamr@4: williamr@4: _STLP_MOVE_TO_PRIV_NAMESPACE williamr@4: williamr@4: template williamr@4: _RandomAccessIter __unguarded_partition(_RandomAccessIter __first, williamr@4: _RandomAccessIter __last, williamr@4: _Tp __pivot, _Compare __comp) { williamr@4: for (;;) { williamr@4: while (__comp(*__first, __pivot)) { williamr@4: _STLP_VERBOSE_ASSERT(!__comp(__pivot, *__first), _StlMsg_INVALID_STRICT_WEAK_PREDICATE) williamr@4: ++__first; williamr@4: } williamr@4: --__last; williamr@4: while (__comp(__pivot, *__last)) { williamr@4: _STLP_VERBOSE_ASSERT(!__comp(*__last, __pivot), _StlMsg_INVALID_STRICT_WEAK_PREDICATE) williamr@4: --__last; williamr@4: } williamr@4: if (!(__first < __last)) williamr@4: return __first; williamr@4: iter_swap(__first, __last); williamr@4: ++__first; williamr@4: } williamr@4: } williamr@4: williamr@4: // sort() and its auxiliary functions. williamr@4: #define __stl_threshold 16 williamr@4: williamr@4: template williamr@4: void __unguarded_linear_insert(_RandomAccessIter __last, _Tp __val, williamr@4: _Compare __comp) { williamr@4: _RandomAccessIter __next = __last; williamr@4: --__next; williamr@4: while (__comp(__val, *__next)) { williamr@4: _STLP_VERBOSE_ASSERT(!__comp(*__next, __val), _StlMsg_INVALID_STRICT_WEAK_PREDICATE) williamr@4: *__last = *__next; williamr@4: __last = __next; williamr@4: --__next; williamr@4: } williamr@4: *__last = __val; williamr@4: } williamr@4: williamr@4: template williamr@4: inline void __linear_insert(_RandomAccessIter __first, williamr@4: _RandomAccessIter __last, _Tp __val, _Compare __comp) { williamr@4: //*TY 12/26/1998 - added __val as a paramter williamr@4: // _Tp __val = *__last; //*TY 12/26/1998 - __val supplied by caller williamr@4: if (__comp(__val, *__first)) { williamr@4: _STLP_VERBOSE_ASSERT(!__comp(*__first, __val), _StlMsg_INVALID_STRICT_WEAK_PREDICATE) williamr@4: copy_backward(__first, __last, __last + 1); williamr@4: *__first = __val; williamr@4: } williamr@4: else williamr@4: __unguarded_linear_insert(__last, __val, __comp); williamr@4: } williamr@4: williamr@4: template williamr@4: void __insertion_sort(_RandomAccessIter __first, williamr@4: _RandomAccessIter __last, williamr@4: _Tp *, _Compare __comp) { williamr@4: if (__first == __last) return; williamr@4: for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i) williamr@4: __linear_insert<_RandomAccessIter, _Tp, _Compare>(__first, __i, *__i, __comp); //*TY 12/26/1998 - supply *__i as __val williamr@4: } williamr@4: williamr@4: template williamr@4: void __unguarded_insertion_sort_aux(_RandomAccessIter __first, williamr@4: _RandomAccessIter __last, williamr@4: _Tp*, _Compare __comp) { williamr@4: for (_RandomAccessIter __i = __first; __i != __last; ++__i) williamr@4: __unguarded_linear_insert<_RandomAccessIter, _Tp, _Compare>(__i, *__i, __comp); williamr@4: } williamr@4: williamr@4: template williamr@4: inline void __unguarded_insertion_sort(_RandomAccessIter __first, williamr@4: _RandomAccessIter __last, williamr@4: _Compare __comp) { williamr@4: __unguarded_insertion_sort_aux(__first, __last, _STLP_VALUE_TYPE(__first, _RandomAccessIter), __comp); williamr@4: } williamr@4: williamr@4: template williamr@4: void __final_insertion_sort(_RandomAccessIter __first, williamr@4: _RandomAccessIter __last, _Compare __comp) { williamr@4: if (__last - __first > __stl_threshold) { williamr@4: __insertion_sort(__first, __first + __stl_threshold, _STLP_VALUE_TYPE(__first,_RandomAccessIter), __comp); williamr@4: __unguarded_insertion_sort(__first + __stl_threshold, __last, __comp); williamr@4: } williamr@4: else williamr@4: __insertion_sort(__first, __last, _STLP_VALUE_TYPE(__first,_RandomAccessIter), __comp); williamr@4: } williamr@4: williamr@4: template williamr@4: void __introsort_loop(_RandomAccessIter __first, williamr@4: _RandomAccessIter __last, _Tp*, williamr@4: _Size __depth_limit, _Compare __comp) { williamr@4: while (__last - __first > __stl_threshold) { williamr@4: if (__depth_limit == 0) { williamr@4: partial_sort(__first, __last, __last, __comp); williamr@4: return; williamr@4: } williamr@4: --__depth_limit; williamr@4: _RandomAccessIter __cut = williamr@4: __unguarded_partition(__first, __last, williamr@4: _Tp(__median(*__first, williamr@4: *(__first + (__last - __first)/2), williamr@4: *(__last - 1), __comp)), williamr@4: __comp); williamr@4: __introsort_loop(__cut, __last, (_Tp*) 0, __depth_limit, __comp); williamr@4: __last = __cut; williamr@4: } williamr@4: } williamr@4: williamr@4: _STLP_MOVE_TO_STD_NAMESPACE williamr@4: williamr@4: template williamr@4: void sort(_RandomAccessIter __first, _RandomAccessIter __last) { williamr@4: _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first, __last)) williamr@4: if (__first != __last) { williamr@4: _STLP_PRIV __introsort_loop(__first, __last, williamr@4: _STLP_VALUE_TYPE(__first, _RandomAccessIter), williamr@4: _STLP_PRIV __lg(__last - __first) * 2, williamr@4: _STLP_PRIV __less(_STLP_VALUE_TYPE(__first, _RandomAccessIter))); williamr@4: _STLP_PRIV __final_insertion_sort(__first, __last, williamr@4: _STLP_PRIV __less(_STLP_VALUE_TYPE(__first, _RandomAccessIter))); williamr@4: } williamr@4: } williamr@4: williamr@4: template williamr@4: void sort(_RandomAccessIter __first, _RandomAccessIter __last, _Compare __comp) { williamr@4: _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first, __last)) williamr@4: if (__first != __last) { williamr@4: _STLP_PRIV __introsort_loop(__first, __last, williamr@4: _STLP_VALUE_TYPE(__first, _RandomAccessIter), williamr@4: _STLP_PRIV __lg(__last - __first) * 2, __comp); williamr@4: _STLP_PRIV __final_insertion_sort(__first, __last, __comp); williamr@4: } williamr@4: } williamr@4: williamr@4: // stable_sort() and its auxiliary functions. williamr@4: _STLP_MOVE_TO_PRIV_NAMESPACE williamr@4: williamr@4: template williamr@4: void __inplace_stable_sort(_RandomAccessIter __first, williamr@4: _RandomAccessIter __last, _Compare __comp) { williamr@4: if (__last - __first < 15) { williamr@4: __insertion_sort(__first, __last, _STLP_VALUE_TYPE(__first,_RandomAccessIter), __comp); williamr@4: return; williamr@4: } williamr@4: _RandomAccessIter __middle = __first + (__last - __first) / 2; williamr@4: __inplace_stable_sort(__first, __middle, __comp); williamr@4: __inplace_stable_sort(__middle, __last, __comp); williamr@4: __merge_without_buffer(__first, __middle, __last, williamr@4: __middle - __first, williamr@4: __last - __middle, williamr@4: __comp); williamr@4: } williamr@4: williamr@4: template williamr@4: void __merge_sort_loop(_RandomAccessIter1 __first, williamr@4: _RandomAccessIter1 __last, williamr@4: _RandomAccessIter2 __result, _Distance __step_size, williamr@4: _Compare __comp) { williamr@4: _Distance __two_step = 2 * __step_size; williamr@4: williamr@4: while (__last - __first >= __two_step) { williamr@4: __result = merge(__first, __first + __step_size, williamr@4: __first + __step_size, __first + __two_step, williamr@4: __result, williamr@4: __comp); williamr@4: __first += __two_step; williamr@4: } williamr@4: __step_size = (min) (_Distance(__last - __first), __step_size); williamr@4: williamr@4: merge(__first, __first + __step_size, williamr@4: __first + __step_size, __last, williamr@4: __result, williamr@4: __comp); williamr@4: } williamr@4: williamr@4: const int __stl_chunk_size = 7; williamr@4: williamr@4: template williamr@4: void __chunk_insertion_sort(_RandomAccessIter __first, williamr@4: _RandomAccessIter __last, williamr@4: _Distance __chunk_size, _Compare __comp) { williamr@4: while (__last - __first >= __chunk_size) { williamr@4: __insertion_sort(__first, __first + __chunk_size, williamr@4: _STLP_VALUE_TYPE(__first,_RandomAccessIter), __comp); williamr@4: __first += __chunk_size; williamr@4: } williamr@4: __insertion_sort(__first, __last, _STLP_VALUE_TYPE(__first,_RandomAccessIter), __comp); williamr@4: } williamr@4: williamr@4: template williamr@4: void __merge_sort_with_buffer(_RandomAccessIter __first, williamr@4: _RandomAccessIter __last, _Pointer __buffer, williamr@4: _Distance*, _Compare __comp) { williamr@4: _Distance __len = __last - __first; williamr@4: _Pointer __buffer_last = __buffer + __len; williamr@4: williamr@4: _Distance __step_size = __stl_chunk_size; williamr@4: __chunk_insertion_sort(__first, __last, __step_size, __comp); williamr@4: williamr@4: while (__step_size < __len) { williamr@4: __merge_sort_loop(__first, __last, __buffer, __step_size, __comp); williamr@4: __step_size *= 2; williamr@4: __merge_sort_loop(__buffer, __buffer_last, __first, __step_size, __comp); williamr@4: __step_size *= 2; williamr@4: } williamr@4: } williamr@4: williamr@4: template williamr@4: _BidirectionalIter1 __rotate_adaptive(_BidirectionalIter1 __first, williamr@4: _BidirectionalIter1 __middle, williamr@4: _BidirectionalIter1 __last, williamr@4: _Distance __len1, _Distance __len2, williamr@4: _BidirectionalIter2 __buffer, williamr@4: _Distance __buffer_size) { williamr@4: if (__len1 > __len2 && __len2 <= __buffer_size) { williamr@4: _BidirectionalIter2 __buffer_end = copy(__middle, __last, __buffer); williamr@4: copy_backward(__first, __middle, __last); williamr@4: return copy(__buffer, __buffer_end, __first); williamr@4: } williamr@4: else if (__len1 <= __buffer_size) { williamr@4: _BidirectionalIter2 __buffer_end = copy(__first, __middle, __buffer); williamr@4: copy(__middle, __last, __first); williamr@4: return copy_backward(__buffer, __buffer_end, __last); williamr@4: } williamr@4: else williamr@4: return __rotate(__first, __middle, __last); williamr@4: } williamr@4: williamr@4: template williamr@4: void __merge_adaptive(_BidirectionalIter __first, williamr@4: _BidirectionalIter __middle, williamr@4: _BidirectionalIter __last, williamr@4: _Distance __len1, _Distance __len2, williamr@4: _Pointer __buffer, _Distance __buffer_size, williamr@4: _Compare __comp) { williamr@4: if (__len1 <= __len2 && __len1 <= __buffer_size) { williamr@4: _Pointer __buffer_end = copy(__first, __middle, __buffer); williamr@4: merge(__buffer, __buffer_end, __middle, __last, __first, __comp); williamr@4: } williamr@4: else if (__len2 <= __buffer_size) { williamr@4: _Pointer __buffer_end = copy(__middle, __last, __buffer); williamr@4: __merge_backward(__first, __middle, __buffer, __buffer_end, __last, williamr@4: __comp); williamr@4: } williamr@4: else { williamr@4: _BidirectionalIter __first_cut = __first; williamr@4: _BidirectionalIter __second_cut = __middle; williamr@4: _Distance __len11 = 0; williamr@4: _Distance __len22 = 0; williamr@4: if (__len1 > __len2) { williamr@4: __len11 = __len1 / 2; williamr@4: advance(__first_cut, __len11); williamr@4: __second_cut = lower_bound(__middle, __last, *__first_cut, __comp); williamr@4: __len22 += distance(__middle, __second_cut); williamr@4: } williamr@4: else { williamr@4: __len22 = __len2 / 2; williamr@4: advance(__second_cut, __len22); williamr@4: __first_cut = upper_bound(__first, __middle, *__second_cut, __comp); williamr@4: __len11 += distance(__first, __first_cut); williamr@4: } williamr@4: _BidirectionalIter __new_middle = williamr@4: __rotate_adaptive(__first_cut, __middle, __second_cut, __len1 - __len11, williamr@4: __len22, __buffer, __buffer_size); williamr@4: __merge_adaptive(__first, __first_cut, __new_middle, __len11, williamr@4: __len22, __buffer, __buffer_size, __comp); williamr@4: __merge_adaptive(__new_middle, __second_cut, __last, __len1 - __len11, williamr@4: __len2 - __len22, __buffer, __buffer_size, __comp); williamr@4: } williamr@4: } williamr@4: williamr@4: template williamr@4: void __stable_sort_adaptive(_RandomAccessIter __first, williamr@4: _RandomAccessIter __last, _Pointer __buffer, williamr@4: _Distance __buffer_size, _Compare __comp) { williamr@4: _Distance __len = (__last - __first + 1) / 2; williamr@4: _RandomAccessIter __middle = __first + __len; williamr@4: if (__len > __buffer_size) { williamr@4: __stable_sort_adaptive(__first, __middle, __buffer, __buffer_size, williamr@4: __comp); williamr@4: __stable_sort_adaptive(__middle, __last, __buffer, __buffer_size, williamr@4: __comp); williamr@4: } williamr@4: else { williamr@4: __merge_sort_with_buffer(__first, __middle, __buffer, (_Distance*)0, williamr@4: __comp); williamr@4: __merge_sort_with_buffer(__middle, __last, __buffer, (_Distance*)0, williamr@4: __comp); williamr@4: } williamr@4: __merge_adaptive(__first, __middle, __last, _Distance(__middle - __first), williamr@4: _Distance(__last - __middle), __buffer, __buffer_size, williamr@4: __comp); williamr@4: } williamr@4: williamr@4: template williamr@4: void __stable_sort_aux(_RandomAccessIter __first, williamr@4: _RandomAccessIter __last, _Tp*, _Distance*, williamr@4: _Compare __comp) { williamr@4: _Temporary_buffer<_RandomAccessIter, _Tp> buf(__first, __last); williamr@4: if (buf.begin() == 0) williamr@4: __inplace_stable_sort(__first, __last, __comp); williamr@4: else williamr@4: __stable_sort_adaptive(__first, __last, buf.begin(), williamr@4: _Distance(buf.size()), williamr@4: __comp); williamr@4: } williamr@4: williamr@4: _STLP_MOVE_TO_STD_NAMESPACE williamr@4: williamr@4: template williamr@4: void stable_sort(_RandomAccessIter __first, williamr@4: _RandomAccessIter __last) { williamr@4: _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first, __last)) williamr@4: _STLP_PRIV __stable_sort_aux(__first, __last, williamr@4: _STLP_VALUE_TYPE(__first, _RandomAccessIter), williamr@4: _STLP_DISTANCE_TYPE(__first, _RandomAccessIter), williamr@4: _STLP_PRIV __less(_STLP_VALUE_TYPE(__first, _RandomAccessIter))); williamr@4: } williamr@4: williamr@4: template williamr@4: void stable_sort(_RandomAccessIter __first, williamr@4: _RandomAccessIter __last, _Compare __comp) { williamr@4: _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first, __last)) williamr@4: _STLP_PRIV __stable_sort_aux(__first, __last, williamr@4: _STLP_VALUE_TYPE(__first, _RandomAccessIter), williamr@4: _STLP_DISTANCE_TYPE(__first, _RandomAccessIter), williamr@4: __comp); williamr@4: } williamr@4: williamr@4: // partial_sort, partial_sort_copy, and auxiliary functions. williamr@4: _STLP_MOVE_TO_PRIV_NAMESPACE williamr@4: williamr@4: template williamr@4: void __partial_sort(_RandomAccessIter __first, _RandomAccessIter __middle, williamr@4: _RandomAccessIter __last, _Tp*, _Compare __comp) { williamr@4: make_heap(__first, __middle, __comp); williamr@4: for (_RandomAccessIter __i = __middle; __i < __last; ++__i) { williamr@4: if (__comp(*__i, *__first)) { williamr@4: _STLP_VERBOSE_ASSERT(!__comp(*__first, *__i), _StlMsg_INVALID_STRICT_WEAK_PREDICATE) williamr@4: __pop_heap(__first, __middle, __i, _Tp(*__i), __comp, williamr@4: _STLP_DISTANCE_TYPE(__first, _RandomAccessIter)); williamr@4: } williamr@4: } williamr@4: sort_heap(__first, __middle, __comp); williamr@4: } williamr@4: williamr@4: _STLP_MOVE_TO_STD_NAMESPACE williamr@4: williamr@4: template williamr@4: void partial_sort(_RandomAccessIter __first,_RandomAccessIter __middle, williamr@4: _RandomAccessIter __last) { williamr@4: _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first, __middle)) williamr@4: _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__middle, __last)) williamr@4: _STLP_PRIV __partial_sort(__first, __middle, __last, _STLP_VALUE_TYPE(__first, _RandomAccessIter), williamr@4: _STLP_PRIV __less(_STLP_VALUE_TYPE(__first, _RandomAccessIter))); williamr@4: } williamr@4: williamr@4: template williamr@4: void partial_sort(_RandomAccessIter __first,_RandomAccessIter __middle, williamr@4: _RandomAccessIter __last, _Compare __comp) { williamr@4: _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first, __middle)) williamr@4: _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__middle, __last)) williamr@4: _STLP_PRIV __partial_sort(__first, __middle, __last, _STLP_VALUE_TYPE(__first, _RandomAccessIter), __comp); williamr@4: } williamr@4: williamr@4: _STLP_MOVE_TO_PRIV_NAMESPACE williamr@4: williamr@4: template williamr@4: _RandomAccessIter __partial_sort_copy(_InputIter __first, williamr@4: _InputIter __last, williamr@4: _RandomAccessIter __result_first, williamr@4: _RandomAccessIter __result_last, williamr@4: _Compare __comp, _Distance*, _Tp*) { williamr@4: if (__result_first == __result_last) return __result_last; williamr@4: _RandomAccessIter __result_real_last = __result_first; williamr@4: while(__first != __last && __result_real_last != __result_last) { williamr@4: *__result_real_last = *__first; williamr@4: ++__result_real_last; williamr@4: ++__first; williamr@4: } williamr@4: make_heap(__result_first, __result_real_last, __comp); williamr@4: while (__first != __last) { williamr@4: if (__comp(*__first, *__result_first)) { williamr@4: _STLP_VERBOSE_ASSERT(!__comp(*__result_first, *__first), _StlMsg_INVALID_STRICT_WEAK_PREDICATE) williamr@4: __adjust_heap(__result_first, _Distance(0), williamr@4: _Distance(__result_real_last - __result_first), williamr@4: _Tp(*__first), williamr@4: __comp); williamr@4: } williamr@4: ++__first; williamr@4: } williamr@4: sort_heap(__result_first, __result_real_last, __comp); williamr@4: return __result_real_last; williamr@4: } williamr@4: williamr@4: _STLP_MOVE_TO_STD_NAMESPACE williamr@4: williamr@4: template williamr@4: _RandomAccessIter williamr@4: partial_sort_copy(_InputIter __first, _InputIter __last, williamr@4: _RandomAccessIter __result_first, _RandomAccessIter __result_last) { williamr@4: _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first, __last)) williamr@4: _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__result_first, __result_last)) williamr@4: return _STLP_PRIV __partial_sort_copy(__first, __last, __result_first, __result_last, williamr@4: _STLP_PRIV __less(_STLP_VALUE_TYPE(__first, _InputIter)), williamr@4: _STLP_DISTANCE_TYPE(__result_first, _RandomAccessIter), williamr@4: _STLP_VALUE_TYPE(__first, _InputIter)); williamr@4: } williamr@4: williamr@4: template williamr@4: _RandomAccessIter williamr@4: partial_sort_copy(_InputIter __first, _InputIter __last, williamr@4: _RandomAccessIter __result_first, williamr@4: _RandomAccessIter __result_last, _Compare __comp) { williamr@4: _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first, __last)) williamr@4: _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__result_first, __result_last)) williamr@4: return _STLP_PRIV __partial_sort_copy(__first, __last, __result_first, __result_last, williamr@4: __comp, williamr@4: _STLP_DISTANCE_TYPE(__result_first, _RandomAccessIter), williamr@4: _STLP_VALUE_TYPE(__first, _InputIter)); williamr@4: } williamr@4: williamr@4: // nth_element() and its auxiliary functions. williamr@4: _STLP_MOVE_TO_PRIV_NAMESPACE williamr@4: williamr@4: template williamr@4: void __nth_element(_RandomAccessIter __first, _RandomAccessIter __nth, williamr@4: _RandomAccessIter __last, _Tp*, _Compare __comp) { williamr@4: while (__last - __first > 3) { williamr@4: _RandomAccessIter __cut = williamr@4: __unguarded_partition(__first, __last, williamr@4: _Tp(__median(*__first, williamr@4: *(__first + (__last - __first)/2), williamr@4: *(__last - 1), williamr@4: __comp)), williamr@4: __comp); williamr@4: if (__cut <= __nth) williamr@4: __first = __cut; williamr@4: else williamr@4: __last = __cut; williamr@4: } williamr@4: __insertion_sort(__first, __last, _STLP_VALUE_TYPE(__first,_RandomAccessIter), __comp); williamr@4: } williamr@4: williamr@4: _STLP_MOVE_TO_STD_NAMESPACE williamr@4: williamr@4: template williamr@4: void nth_element(_RandomAccessIter __first, _RandomAccessIter __nth, williamr@4: _RandomAccessIter __last) { williamr@4: _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first, __nth)) williamr@4: _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__nth, __last)) williamr@4: _STLP_PRIV __nth_element(__first, __nth, __last, _STLP_VALUE_TYPE(__first, _RandomAccessIter), williamr@4: _STLP_PRIV __less(_STLP_VALUE_TYPE(__first, _RandomAccessIter))); williamr@4: } williamr@4: williamr@4: template williamr@4: void nth_element(_RandomAccessIter __first, _RandomAccessIter __nth, williamr@4: _RandomAccessIter __last, _Compare __comp) { williamr@4: _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first, __nth)) williamr@4: _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__nth, __last)) williamr@4: _STLP_PRIV __nth_element(__first, __nth, __last, _STLP_VALUE_TYPE(__first, _RandomAccessIter), __comp); williamr@4: } williamr@4: williamr@4: // Binary search (lower_bound, upper_bound, equal_range, binary_search). williamr@4: _STLP_MOVE_TO_PRIV_NAMESPACE williamr@4: williamr@4: template williamr@4: _ForwardIter __upper_bound(_ForwardIter __first, _ForwardIter __last, const _Tp& __val, williamr@4: _Compare1 __comp1, _Compare2 __comp2, _Distance*) { williamr@4: _Distance __len = distance(__first, __last); williamr@4: _Distance __half; williamr@4: williamr@4: while (__len > 0) { williamr@4: __half = __len >> 1; williamr@4: _ForwardIter __middle = __first; williamr@4: advance(__middle, __half); williamr@4: if (__comp2(__val, *__middle)) { williamr@4: _STLP_VERBOSE_ASSERT(!__comp1(*__middle, __val), _StlMsg_INVALID_STRICT_WEAK_PREDICATE) williamr@4: __len = __half; williamr@4: } williamr@4: else { williamr@4: __first = __middle; williamr@4: ++__first; williamr@4: __len = __len - __half - 1; williamr@4: } williamr@4: } williamr@4: return __first; williamr@4: } williamr@4: williamr@4: template williamr@4: pair<_ForwardIter, _ForwardIter> williamr@4: __equal_range(_ForwardIter __first, _ForwardIter __last, const _Tp& __val, williamr@4: _Compare1 __comp1, _Compare2 __comp2, _Distance* __dist) { williamr@4: _Distance __len = distance(__first, __last); williamr@4: _Distance __half; williamr@4: williamr@4: while (__len > 0) { williamr@4: __half = __len >> 1; williamr@4: _ForwardIter __middle = __first; williamr@4: advance(__middle, __half); williamr@4: if (__comp1(*__middle, __val)) { williamr@4: _STLP_VERBOSE_ASSERT(!__comp2(__val, *__middle), _StlMsg_INVALID_STRICT_WEAK_PREDICATE) williamr@4: __first = __middle; williamr@4: ++__first; williamr@4: __len = __len - __half - 1; williamr@4: } williamr@4: else if (__comp2(__val, *__middle)) { williamr@4: _STLP_VERBOSE_ASSERT(!__comp1(*__middle, __val), _StlMsg_INVALID_STRICT_WEAK_PREDICATE) williamr@4: __len = __half; williamr@4: } williamr@4: else { williamr@4: _ForwardIter __left = __lower_bound(__first, __middle, __val, __comp1, __comp2, __dist); williamr@4: //Small optim: If lower_bound haven't found an equivalent value williamr@4: //there is no need to call upper_bound. williamr@4: if (__comp1(*__left, __val)) { williamr@4: _STLP_VERBOSE_ASSERT(!__comp2(__val, *__left), _StlMsg_INVALID_STRICT_WEAK_PREDICATE) williamr@4: return pair<_ForwardIter, _ForwardIter>(__left, __left); williamr@4: } williamr@4: advance(__first, __len); williamr@4: _ForwardIter __right = __upper_bound(++__middle, __first, __val, __comp1, __comp2, __dist); williamr@4: return pair<_ForwardIter, _ForwardIter>(__left, __right); williamr@4: } williamr@4: } williamr@4: return pair<_ForwardIter, _ForwardIter>(__first, __first); williamr@4: } williamr@4: williamr@4: _STLP_MOVE_TO_STD_NAMESPACE williamr@4: williamr@4: template williamr@4: _OutputIter merge(_InputIter1 __first1, _InputIter1 __last1, williamr@4: _InputIter2 __first2, _InputIter2 __last2, williamr@4: _OutputIter __result) { williamr@4: _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first1, __last1)) williamr@4: _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first2, __last2)) williamr@4: while (__first1 != __last1 && __first2 != __last2) { williamr@4: if (*__first2 < *__first1) { williamr@4: *__result = *__first2; williamr@4: ++__first2; williamr@4: } williamr@4: else { williamr@4: *__result = *__first1; williamr@4: ++__first1; williamr@4: } williamr@4: ++__result; williamr@4: } williamr@4: return copy(__first2, __last2, copy(__first1, __last1, __result)); williamr@4: } williamr@4: williamr@4: template williamr@4: _OutputIter merge(_InputIter1 __first1, _InputIter1 __last1, williamr@4: _InputIter2 __first2, _InputIter2 __last2, williamr@4: _OutputIter __result, _Compare __comp) { williamr@4: _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first1, __last1)) williamr@4: _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first2, __last2)) williamr@4: while (__first1 != __last1 && __first2 != __last2) { williamr@4: if (__comp(*__first2, *__first1)) { williamr@4: _STLP_VERBOSE_ASSERT(!__comp(*__first1, *__first2), _StlMsg_INVALID_STRICT_WEAK_PREDICATE) williamr@4: *__result = *__first2; williamr@4: ++__first2; williamr@4: } williamr@4: else { williamr@4: *__result = *__first1; williamr@4: ++__first1; williamr@4: } williamr@4: ++__result; williamr@4: } williamr@4: return copy(__first2, __last2, copy(__first1, __last1, __result)); williamr@4: } williamr@4: williamr@4: _STLP_MOVE_TO_PRIV_NAMESPACE williamr@4: williamr@4: template williamr@4: void __merge_without_buffer(_BidirectionalIter __first, williamr@4: _BidirectionalIter __middle, williamr@4: _BidirectionalIter __last, williamr@4: _Distance __len1, _Distance __len2, williamr@4: _Compare __comp) { williamr@4: if (__len1 == 0 || __len2 == 0) williamr@4: return; williamr@4: if (__len1 + __len2 == 2) { williamr@4: if (__comp(*__middle, *__first)) { williamr@4: _STLP_VERBOSE_ASSERT(!__comp(*__first, *__middle), _StlMsg_INVALID_STRICT_WEAK_PREDICATE) williamr@4: iter_swap(__first, __middle); williamr@4: } williamr@4: return; williamr@4: } williamr@4: _BidirectionalIter __first_cut = __first; williamr@4: _BidirectionalIter __second_cut = __middle; williamr@4: _Distance __len11 = 0; williamr@4: _Distance __len22 = 0; williamr@4: if (__len1 > __len2) { williamr@4: __len11 = __len1 / 2; williamr@4: advance(__first_cut, __len11); williamr@4: __second_cut = lower_bound(__middle, __last, *__first_cut, __comp); williamr@4: __len22 += distance(__middle, __second_cut); williamr@4: } williamr@4: else { williamr@4: __len22 = __len2 / 2; williamr@4: advance(__second_cut, __len22); williamr@4: __first_cut = upper_bound(__first, __middle, *__second_cut, __comp); williamr@4: __len11 +=distance(__first, __first_cut); williamr@4: } williamr@4: _BidirectionalIter __new_middle williamr@4: = __rotate(__first_cut, __middle, __second_cut); williamr@4: __merge_without_buffer(__first, __first_cut, __new_middle, __len11, __len22, williamr@4: __comp); williamr@4: __merge_without_buffer(__new_middle, __second_cut, __last, __len1 - __len11, williamr@4: __len2 - __len22, __comp); williamr@4: } williamr@4: williamr@4: template williamr@4: _BidirectionalIter3 __merge_backward(_BidirectionalIter1 __first1, williamr@4: _BidirectionalIter1 __last1, williamr@4: _BidirectionalIter2 __first2, williamr@4: _BidirectionalIter2 __last2, williamr@4: _BidirectionalIter3 __result, williamr@4: _Compare __comp) { williamr@4: if (__first1 == __last1) williamr@4: return copy_backward(__first2, __last2, __result); williamr@4: if (__first2 == __last2) williamr@4: return copy_backward(__first1, __last1, __result); williamr@4: --__last1; williamr@4: --__last2; williamr@4: for (;;) { williamr@4: if (__comp(*__last2, *__last1)) { williamr@4: _STLP_VERBOSE_ASSERT(!__comp(*__last1, *__last2), _StlMsg_INVALID_STRICT_WEAK_PREDICATE) williamr@4: *--__result = *__last1; williamr@4: if (__first1 == __last1) williamr@4: return copy_backward(__first2, ++__last2, __result); williamr@4: --__last1; williamr@4: } williamr@4: else { williamr@4: *--__result = *__last2; williamr@4: if (__first2 == __last2) williamr@4: return copy_backward(__first1, ++__last1, __result); williamr@4: --__last2; williamr@4: } williamr@4: } williamr@4: } williamr@4: williamr@4: template williamr@4: inline void __inplace_merge_aux(_BidirectionalIter __first, williamr@4: _BidirectionalIter __middle, williamr@4: _BidirectionalIter __last, _Tp*, _Distance*, williamr@4: _Compare __comp) { williamr@4: _Distance __len1 = distance(__first, __middle); williamr@4: _Distance __len2 = distance(__middle, __last); williamr@4: williamr@4: _Temporary_buffer<_BidirectionalIter, _Tp> __buf(__first, __last); williamr@4: if (__buf.begin() == 0) williamr@4: __merge_without_buffer(__first, __middle, __last, __len1, __len2, __comp); williamr@4: else williamr@4: __merge_adaptive(__first, __middle, __last, __len1, __len2, williamr@4: __buf.begin(), _Distance(__buf.size()), williamr@4: __comp); williamr@4: } williamr@4: williamr@4: _STLP_MOVE_TO_STD_NAMESPACE williamr@4: williamr@4: template williamr@4: void inplace_merge(_BidirectionalIter __first, williamr@4: _BidirectionalIter __middle, williamr@4: _BidirectionalIter __last) { williamr@4: _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first, __middle)) williamr@4: _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__middle, __last)) williamr@4: if (__first == __middle || __middle == __last) williamr@4: return; williamr@4: _STLP_PRIV __inplace_merge_aux(__first, __middle, __last, williamr@4: _STLP_VALUE_TYPE(__first, _BidirectionalIter), _STLP_DISTANCE_TYPE(__first, _BidirectionalIter), williamr@4: _STLP_PRIV __less(_STLP_VALUE_TYPE(__first, _BidirectionalIter))); williamr@4: } williamr@4: williamr@4: template williamr@4: void inplace_merge(_BidirectionalIter __first, williamr@4: _BidirectionalIter __middle, williamr@4: _BidirectionalIter __last, _Compare __comp) { williamr@4: _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first, __middle)) williamr@4: _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__middle, __last)) williamr@4: if (__first == __middle || __middle == __last) williamr@4: return; williamr@4: _STLP_PRIV __inplace_merge_aux(__first, __middle, __last, williamr@4: _STLP_VALUE_TYPE(__first, _BidirectionalIter), _STLP_DISTANCE_TYPE(__first, _BidirectionalIter), williamr@4: __comp); williamr@4: } williamr@4: williamr@4: _STLP_MOVE_TO_PRIV_NAMESPACE williamr@4: williamr@4: template williamr@4: bool __includes(_InputIter1 __first1, _InputIter1 __last1, williamr@4: _InputIter2 __first2, _InputIter2 __last2, _Compare __comp) { williamr@4: _STLP_DEBUG_CHECK(__check_range(__first1, __last1)) williamr@4: _STLP_DEBUG_CHECK(__check_range(__first2, __last2)) williamr@4: while (__first1 != __last1 && __first2 != __last2) williamr@4: if (__comp(*__first2, *__first1)) { williamr@4: _STLP_VERBOSE_ASSERT(!__comp(*__first1, *__first2), _StlMsg_INVALID_STRICT_WEAK_PREDICATE) williamr@4: return false; williamr@4: } williamr@4: else if (__comp(*__first1, *__first2)) williamr@4: ++__first1; williamr@4: else williamr@4: ++__first1, ++__first2; williamr@4: williamr@4: return __first2 == __last2; williamr@4: } williamr@4: williamr@4: _STLP_MOVE_TO_STD_NAMESPACE williamr@4: williamr@4: template williamr@4: bool includes(_InputIter1 __first1, _InputIter1 __last1, williamr@4: _InputIter2 __first2, _InputIter2 __last2, _Compare __comp) { williamr@4: return _STLP_PRIV __includes(__first1, __last1, __first2, __last2, __comp); williamr@4: } williamr@4: williamr@4: template williamr@4: bool includes(_InputIter1 __first1, _InputIter1 __last1, williamr@4: _InputIter2 __first2, _InputIter2 __last2) { williamr@4: return _STLP_PRIV __includes(__first1, __last1, __first2, __last2, williamr@4: _STLP_PRIV __less(_STLP_VALUE_TYPE(__first1, _InputIter1))); williamr@4: } williamr@4: williamr@4: _STLP_MOVE_TO_PRIV_NAMESPACE williamr@4: williamr@4: template williamr@4: _OutputIter __set_union(_InputIter1 __first1, _InputIter1 __last1, williamr@4: _InputIter2 __first2, _InputIter2 __last2, williamr@4: _OutputIter __result, _Compare __comp) { williamr@4: _STLP_DEBUG_CHECK(__check_range(__first1, __last1)) williamr@4: _STLP_DEBUG_CHECK(__check_range(__first2, __last2)) williamr@4: while (__first1 != __last1 && __first2 != __last2) { williamr@4: if (__comp(*__first1, *__first2)) { williamr@4: _STLP_VERBOSE_ASSERT(!__comp(*__first2, *__first1), _StlMsg_INVALID_STRICT_WEAK_PREDICATE) williamr@4: *__result = *__first1; williamr@4: ++__first1; williamr@4: } williamr@4: else if (__comp(*__first2, *__first1)) { williamr@4: _STLP_VERBOSE_ASSERT(!__comp(*__first1, *__first2), _StlMsg_INVALID_STRICT_WEAK_PREDICATE) williamr@4: *__result = *__first2; williamr@4: ++__first2; williamr@4: } williamr@4: else { williamr@4: *__result = *__first1; williamr@4: ++__first1; williamr@4: ++__first2; williamr@4: } williamr@4: ++__result; williamr@4: } williamr@4: return copy(__first2, __last2, copy(__first1, __last1, __result)); williamr@4: } williamr@4: williamr@4: _STLP_MOVE_TO_STD_NAMESPACE williamr@4: williamr@4: template williamr@4: _OutputIter set_union(_InputIter1 __first1, _InputIter1 __last1, williamr@4: _InputIter2 __first2, _InputIter2 __last2, williamr@4: _OutputIter __result) { williamr@4: return _STLP_PRIV __set_union(__first1, __last1, __first2, __last2, __result, williamr@4: _STLP_PRIV __less(_STLP_VALUE_TYPE(__first1, _InputIter1))); williamr@4: } williamr@4: williamr@4: template williamr@4: _OutputIter set_union(_InputIter1 __first1, _InputIter1 __last1, williamr@4: _InputIter2 __first2, _InputIter2 __last2, williamr@4: _OutputIter __result, _Compare __comp) { williamr@4: return _STLP_PRIV __set_union(__first1, __last1, __first2, __last2, __result, __comp); williamr@4: } williamr@4: williamr@4: _STLP_MOVE_TO_PRIV_NAMESPACE williamr@4: williamr@4: template williamr@4: _OutputIter __set_intersection(_InputIter1 __first1, _InputIter1 __last1, williamr@4: _InputIter2 __first2, _InputIter2 __last2, williamr@4: _OutputIter __result, _Compare __comp) { williamr@4: _STLP_DEBUG_CHECK(__check_range(__first1, __last1)) williamr@4: _STLP_DEBUG_CHECK(__check_range(__first2, __last2)) williamr@4: while (__first1 != __last1 && __first2 != __last2) williamr@4: if (__comp(*__first1, *__first2)) { williamr@4: _STLP_VERBOSE_ASSERT(!__comp(*__first2, *__first1), _StlMsg_INVALID_STRICT_WEAK_PREDICATE) williamr@4: ++__first1; williamr@4: } williamr@4: else if (__comp(*__first2, *__first1)) williamr@4: ++__first2; williamr@4: else { williamr@4: *__result = *__first1; williamr@4: ++__first1; williamr@4: ++__first2; williamr@4: ++__result; williamr@4: } williamr@4: return __result; williamr@4: } williamr@4: williamr@4: _STLP_MOVE_TO_STD_NAMESPACE williamr@4: williamr@4: template williamr@4: _OutputIter set_intersection(_InputIter1 __first1, _InputIter1 __last1, williamr@4: _InputIter2 __first2, _InputIter2 __last2, williamr@4: _OutputIter __result) { williamr@4: return _STLP_PRIV __set_intersection(__first1, __last1, __first2, __last2, __result, williamr@4: _STLP_PRIV __less(_STLP_VALUE_TYPE(__first1, _InputIter1))); williamr@4: } williamr@4: williamr@4: template williamr@4: _OutputIter set_intersection(_InputIter1 __first1, _InputIter1 __last1, williamr@4: _InputIter2 __first2, _InputIter2 __last2, williamr@4: _OutputIter __result, _Compare __comp) { williamr@4: return _STLP_PRIV __set_intersection(__first1, __last1, __first2, __last2, __result, __comp); williamr@4: } williamr@4: williamr@4: _STLP_MOVE_TO_PRIV_NAMESPACE williamr@4: williamr@4: template williamr@4: _OutputIter __set_difference(_InputIter1 __first1, _InputIter1 __last1, williamr@4: _InputIter2 __first2, _InputIter2 __last2, williamr@4: _OutputIter __result, _Compare __comp) { williamr@4: _STLP_DEBUG_CHECK(__check_range(__first1, __last1)) williamr@4: _STLP_DEBUG_CHECK(__check_range(__first2, __last2)) williamr@4: while (__first1 != __last1 && __first2 != __last2) williamr@4: if (__comp(*__first1, *__first2)) { williamr@4: _STLP_VERBOSE_ASSERT(!__comp(*__first2, *__first1), _StlMsg_INVALID_STRICT_WEAK_PREDICATE) williamr@4: *__result = *__first1; williamr@4: ++__first1; williamr@4: ++__result; williamr@4: } williamr@4: else if (__comp(*__first2, *__first1)) williamr@4: ++__first2; williamr@4: else { williamr@4: ++__first1; williamr@4: ++__first2; williamr@4: } williamr@4: return copy(__first1, __last1, __result); williamr@4: } williamr@4: williamr@4: _STLP_MOVE_TO_STD_NAMESPACE williamr@4: williamr@4: template williamr@4: _OutputIter set_difference(_InputIter1 __first1, _InputIter1 __last1, williamr@4: _InputIter2 __first2, _InputIter2 __last2, williamr@4: _OutputIter __result) { williamr@4: return _STLP_PRIV __set_difference(__first1, __last1, __first2, __last2, __result, williamr@4: _STLP_PRIV __less(_STLP_VALUE_TYPE(__first1, _InputIter1))); williamr@4: } williamr@4: williamr@4: template williamr@4: _OutputIter set_difference(_InputIter1 __first1, _InputIter1 __last1, williamr@4: _InputIter2 __first2, _InputIter2 __last2, williamr@4: _OutputIter __result, _Compare __comp) { williamr@4: return _STLP_PRIV __set_difference(__first1, __last1, __first2, __last2, __result, __comp); williamr@4: } williamr@4: williamr@4: _STLP_MOVE_TO_PRIV_NAMESPACE williamr@4: williamr@4: template williamr@4: _OutputIter williamr@4: __set_symmetric_difference(_InputIter1 __first1, _InputIter1 __last1, williamr@4: _InputIter2 __first2, _InputIter2 __last2, williamr@4: _OutputIter __result, _Compare __comp) { williamr@4: _STLP_DEBUG_CHECK(__check_range(__first1, __last1)) williamr@4: _STLP_DEBUG_CHECK(__check_range(__first2, __last2)) williamr@4: while (__first1 != __last1 && __first2 != __last2) { williamr@4: if (__comp(*__first1, *__first2)) { williamr@4: _STLP_VERBOSE_ASSERT(!__comp(*__first2, *__first1), _StlMsg_INVALID_STRICT_WEAK_PREDICATE) williamr@4: *__result = *__first1; williamr@4: ++__first1; williamr@4: ++__result; williamr@4: } williamr@4: else if (__comp(*__first2, *__first1)) { williamr@4: *__result = *__first2; williamr@4: ++__first2; williamr@4: ++__result; williamr@4: } williamr@4: else { williamr@4: ++__first1; williamr@4: ++__first2; williamr@4: } williamr@4: } williamr@4: return copy(__first2, __last2, copy(__first1, __last1, __result)); williamr@4: } williamr@4: williamr@4: _STLP_MOVE_TO_STD_NAMESPACE williamr@4: williamr@4: template williamr@4: _OutputIter williamr@4: set_symmetric_difference(_InputIter1 __first1, _InputIter1 __last1, williamr@4: _InputIter2 __first2, _InputIter2 __last2, williamr@4: _OutputIter __result) { williamr@4: return _STLP_PRIV __set_symmetric_difference(__first1, __last1, __first2, __last2, __result, williamr@4: _STLP_PRIV __less(_STLP_VALUE_TYPE(__first1, _InputIter1))); williamr@4: } williamr@4: williamr@4: template williamr@4: _OutputIter williamr@4: set_symmetric_difference(_InputIter1 __first1, _InputIter1 __last1, williamr@4: _InputIter2 __first2, _InputIter2 __last2, williamr@4: _OutputIter __result, williamr@4: _Compare __comp) { williamr@4: return _STLP_PRIV __set_symmetric_difference(__first1, __last1, __first2, __last2, __result, __comp); williamr@4: } williamr@4: williamr@4: // min_element and max_element, with and without an explicitly supplied williamr@4: // comparison function. williamr@4: williamr@4: template williamr@4: _ForwardIter max_element(_ForwardIter __first, _ForwardIter __last) { williamr@4: _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first, __last)) williamr@4: if (__first == __last) return __first; williamr@4: _ForwardIter __result = __first; williamr@4: while (++__first != __last) williamr@4: if (*__result < *__first) williamr@4: __result = __first; williamr@4: return __result; williamr@4: } williamr@4: williamr@4: template williamr@4: _ForwardIter max_element(_ForwardIter __first, _ForwardIter __last, williamr@4: _Compare __comp) { williamr@4: _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first, __last)) williamr@4: if (__first == __last) return __first; williamr@4: _ForwardIter __result = __first; williamr@4: while (++__first != __last) { williamr@4: if (__comp(*__result, *__first)) { williamr@4: _STLP_VERBOSE_ASSERT(!__comp(*__first, *__result), _StlMsg_INVALID_STRICT_WEAK_PREDICATE) williamr@4: __result = __first; williamr@4: } williamr@4: } williamr@4: return __result; williamr@4: } williamr@4: williamr@4: template williamr@4: _ForwardIter min_element(_ForwardIter __first, _ForwardIter __last) { williamr@4: _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first, __last)) williamr@4: if (__first == __last) return __first; williamr@4: _ForwardIter __result = __first; williamr@4: while (++__first != __last) williamr@4: if (*__first < *__result) williamr@4: __result = __first; williamr@4: return __result; williamr@4: } williamr@4: williamr@4: template williamr@4: _ForwardIter min_element(_ForwardIter __first, _ForwardIter __last, williamr@4: _Compare __comp) { williamr@4: _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first, __last)) williamr@4: if (__first == __last) return __first; williamr@4: _ForwardIter __result = __first; williamr@4: while (++__first != __last) { williamr@4: if (__comp(*__first, *__result)) { williamr@4: _STLP_VERBOSE_ASSERT(!__comp(*__result, *__first), _StlMsg_INVALID_STRICT_WEAK_PREDICATE) williamr@4: __result = __first; williamr@4: } williamr@4: } williamr@4: return __result; williamr@4: } williamr@4: williamr@4: // next_permutation and prev_permutation, with and without an explicitly williamr@4: // supplied comparison function. williamr@4: _STLP_MOVE_TO_PRIV_NAMESPACE williamr@4: williamr@4: template williamr@4: bool __next_permutation(_BidirectionalIter __first, _BidirectionalIter __last, williamr@4: _Compare __comp) { williamr@4: _STLP_DEBUG_CHECK(__check_range(__first, __last)) williamr@4: if (__first == __last) williamr@4: return false; williamr@4: _BidirectionalIter __i = __first; williamr@4: ++__i; williamr@4: if (__i == __last) williamr@4: return false; williamr@4: __i = __last; williamr@4: --__i; williamr@4: williamr@4: for(;;) { williamr@4: _BidirectionalIter __ii = __i; williamr@4: --__i; williamr@4: if (__comp(*__i, *__ii)) { williamr@4: _STLP_VERBOSE_ASSERT(!__comp(*__ii, *__i), _StlMsg_INVALID_STRICT_WEAK_PREDICATE) williamr@4: _BidirectionalIter __j = __last; williamr@4: while (!__comp(*__i, *--__j)) {} williamr@4: iter_swap(__i, __j); williamr@4: reverse(__ii, __last); williamr@4: return true; williamr@4: } williamr@4: if (__i == __first) { williamr@4: reverse(__first, __last); williamr@4: return false; williamr@4: } williamr@4: } williamr@4: #if defined (_STLP_NEED_UNREACHABLE_RETURN) williamr@4: return false; williamr@4: #endif williamr@4: } williamr@4: williamr@4: _STLP_MOVE_TO_STD_NAMESPACE williamr@4: williamr@4: template williamr@4: bool next_permutation(_BidirectionalIter __first, _BidirectionalIter __last) { williamr@4: _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first, __last)) williamr@4: return _STLP_PRIV __next_permutation(__first, __last, williamr@4: _STLP_PRIV __less(_STLP_VALUE_TYPE(__first, _BidirectionalIter))); williamr@4: } williamr@4: williamr@4: template williamr@4: bool next_permutation(_BidirectionalIter __first, _BidirectionalIter __last, williamr@4: _Compare __comp) { williamr@4: _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first, __last)) williamr@4: return _STLP_PRIV __next_permutation(__first, __last, __comp); williamr@4: } williamr@4: williamr@4: _STLP_MOVE_TO_PRIV_NAMESPACE williamr@4: williamr@4: template williamr@4: bool __prev_permutation(_BidirectionalIter __first, _BidirectionalIter __last, williamr@4: _Compare __comp) { williamr@4: if (__first == __last) williamr@4: return false; williamr@4: _BidirectionalIter __i = __first; williamr@4: ++__i; williamr@4: if (__i == __last) williamr@4: return false; williamr@4: __i = __last; williamr@4: --__i; williamr@4: williamr@4: for(;;) { williamr@4: _BidirectionalIter __ii = __i; williamr@4: --__i; williamr@4: if (__comp(*__ii, *__i)) { williamr@4: _STLP_VERBOSE_ASSERT(!__comp(*__i, *__ii), _StlMsg_INVALID_STRICT_WEAK_PREDICATE) williamr@4: _BidirectionalIter __j = __last; williamr@4: while (!__comp(*--__j, *__i)) {} williamr@4: iter_swap(__i, __j); williamr@4: reverse(__ii, __last); williamr@4: return true; williamr@4: } williamr@4: if (__i == __first) { williamr@4: reverse(__first, __last); williamr@4: return false; williamr@4: } williamr@4: } williamr@4: #if defined (_STLP_NEED_UNREACHABLE_RETURN) williamr@4: return false; williamr@4: #endif williamr@4: } williamr@4: williamr@4: _STLP_MOVE_TO_STD_NAMESPACE williamr@4: williamr@4: template williamr@4: bool prev_permutation(_BidirectionalIter __first, _BidirectionalIter __last) { williamr@4: _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first, __last)) williamr@4: return _STLP_PRIV __prev_permutation(__first, __last, williamr@4: _STLP_PRIV __less(_STLP_VALUE_TYPE(__first, _BidirectionalIter))); williamr@4: } williamr@4: williamr@4: template williamr@4: bool prev_permutation(_BidirectionalIter __first, _BidirectionalIter __last, williamr@4: _Compare __comp) { williamr@4: _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first, __last)) williamr@4: return _STLP_PRIV __prev_permutation(__first, __last, __comp); williamr@4: } williamr@4: williamr@4: #if !defined (_STLP_NO_EXTENSIONS) williamr@4: williamr@4: // is_heap, a predicate testing whether or not a range is williamr@4: // a heap. This function is an extension, not part of the C++ williamr@4: // standard. williamr@4: _STLP_MOVE_TO_PRIV_NAMESPACE williamr@4: williamr@4: template williamr@4: bool __is_heap(_RandomAccessIter __first, _StrictWeakOrdering __comp, williamr@4: _Distance __n) { williamr@4: _Distance __parent = 0; williamr@4: for (_Distance __child = 1; __child < __n; ++__child) { williamr@4: if (__comp(__first[__parent], __first[__child])) { williamr@4: _STLP_VERBOSE_ASSERT(!__comp(__first[__child], __first[__parent]), _StlMsg_INVALID_STRICT_WEAK_PREDICATE) williamr@4: return false; williamr@4: } williamr@4: if ((__child & 1) == 0) williamr@4: ++__parent; williamr@4: } williamr@4: return true; williamr@4: } williamr@4: williamr@4: _STLP_MOVE_TO_STD_NAMESPACE williamr@4: williamr@4: template williamr@4: bool is_heap(_RandomAccessIter __first, _RandomAccessIter __last) { williamr@4: _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first, __last)) williamr@4: return _STLP_PRIV __is_heap(__first, _STLP_PRIV __less(_STLP_VALUE_TYPE(__first, _RandomAccessIter)), __last - __first); williamr@4: } williamr@4: williamr@4: template williamr@4: bool is_heap(_RandomAccessIter __first, _RandomAccessIter __last, williamr@4: _StrictWeakOrdering __comp) { williamr@4: _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first, __last)) williamr@4: return _STLP_PRIV __is_heap(__first, __comp, __last - __first); williamr@4: } williamr@4: williamr@4: williamr@4: _STLP_MOVE_TO_PRIV_NAMESPACE williamr@4: williamr@4: template williamr@4: bool __is_sorted(_ForwardIter __first, _ForwardIter __last, williamr@4: _StrictWeakOrdering __comp) { williamr@4: _STLP_DEBUG_CHECK(__check_range(__first, __last)) williamr@4: if (__first == __last) williamr@4: return true; williamr@4: williamr@4: _ForwardIter __next = __first; williamr@4: for (++__next; __next != __last; __first = __next, ++__next) { williamr@4: if (__comp(*__next, *__first)) { williamr@4: _STLP_VERBOSE_ASSERT(!__comp(*__first, *__next), _StlMsg_INVALID_STRICT_WEAK_PREDICATE) williamr@4: return false; williamr@4: } williamr@4: } williamr@4: williamr@4: return true; williamr@4: } williamr@4: williamr@4: _STLP_MOVE_TO_STD_NAMESPACE williamr@4: #endif /* _STLP_NO_EXTENSIONS */ williamr@4: williamr@4: _STLP_END_NAMESPACE williamr@4: williamr@4: #undef __stl_threshold williamr@4: williamr@4: #endif /* _STLP_ALGO_C */ williamr@4: // Local Variables: williamr@4: // mode:C++ williamr@4: // End: