#ifndef __ALGORITH_CC #define __ALGORITH_CC #pragma option push -b -a8 -pc -Vx- -Ve- -w-inl -w-aus -w-sig /*************************************************************************** * * algorithm.cc - Non-inline definitions for the Standard Library algorithms * *************************************************************************** * * 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-1999 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. * **************************************************************************/ #include #ifndef _RWSTD_NO_NAMESPACE namespace std { #endif // // Forward declare raw_storage_iterator // template class raw_storage_iterator; // // Non-modifying sequence operations. // template Function for_each (InputIterator first, InputIterator last, Function f) { while (first != last) f(*first++); return f; } template InputIterator find (InputIterator first, InputIterator last, const T& value) { while (first != last && *first != value) ++first; return first; } template InputIterator find_if (InputIterator first, InputIterator last, Predicate pred) { while (first != last && !pred(*first)) ++first; return first; } template ForwardIterator1 __find_end (ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, Distance*) { Distance d, d2; __initialize(d,Distance(0)); __initialize(d2,Distance(0)); distance(first2,last2,d); if (!d) return last1; distance(first1,last1,d2); ForwardIterator1 save = last1; while (d2 >= d) { if (equal(first2,last2,first1)) save = first1; __initialize(d2,Distance(0)); distance(++first1,last1,d2); } return save; } template ForwardIterator1 find_end (ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2) { return __find_end(first1,last1,first2,last2, __distance_type(first1)); } template ForwardIterator1 __find_end (ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred, Distance*) { Distance d, d2; __initialize(d,Distance(0)); __initialize(d2,Distance(0)); distance(first2,last2,d); if (!d) return last1; distance(first1,last1,d2); ForwardIterator1 save = last1; while (d2 >= d) { if (equal(first2,last2,first1,pred)) save = first1; __initialize(d2,Distance(0)); distance(++first1,last1,d2); } return save; } template ForwardIterator1 find_end (ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred) { return __find_end(first1,last1,first2,last2, pred,__distance_type(first1)); } template ForwardIterator1 find_first_of (ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2) { if (first2 == last2) return last1; ForwardIterator1 next = first1; while (next != last1) { if (find(first2,last2,*next) != last2) return next; next++; } return last1; } template ForwardIterator1 find_first_of (ForwardIterator1 first1,ForwardIterator1 last1, ForwardIterator2 first2,ForwardIterator2 last2, BinaryPredicate pred) { if (first2 == last2) return last1; for (ForwardIterator1 next = first1; next != last1; ++next) for (ForwardIterator2 iter = first2; iter != last2; ++iter) if (pred(*next, *iter)) return next; return last1; } template ForwardIterator adjacent_find (ForwardIterator first, ForwardIterator last) { if (first == last) return last; ForwardIterator next = first; while (++next != last) { if (*first == *next) return first; first = next; } return last; } template ForwardIterator adjacent_find (ForwardIterator first, ForwardIterator last, BinaryPredicate binary_pred) { if (first == last) return last; ForwardIterator next = first; while (++next != last) { if (binary_pred(*first, *next)) return first; first = next; } return last; } #ifndef _RWSTD_NO_CLASS_PARTIAL_SPEC template _TYPENAME iterator_traits::difference_type count (InputIterator first, InputIterator last, const T& value) { _TYPENAME iterator_traits::difference_type n = 0; while (first != last) if (*first++ == value) ++n; return n; } template _TYPENAME iterator_traits::difference_type count_if (InputIterator first, InputIterator last, Predicate pred) { _TYPENAME iterator_traits::difference_type n = 0; while (first != last) if (pred(*first++)) ++n; return n; } #endif /* _RWSTD_NO_CLASS_PARTIAL_SPEC */ #ifndef _RWSTD_NO_OLD_COUNT template void count (InputIterator first, InputIterator last, const T& value, Size& n) { while (first != last) if (*first++ == value) ++n; } template void count_if (InputIterator first, InputIterator last, Predicate pred, Size& n) { while (first != last) if (pred(*first++)) ++n; } #endif /* _RWSTD_NO_OLD_COUNT */ template pair mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2) { while (first1 != last1 && *first1 == *first2) { ++first1; ++first2; } pair tmp(first1, first2); return tmp; } template pair mismatch (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, BinaryPredicate binary_pred) { while (first1 != last1 && binary_pred(*first1, *first2)) { ++first1; ++first2; } pair tmp(first1, first2); return tmp; } template ForwardIterator1 __search (ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, Distance1*, Distance2*) { Distance1 d1; __initialize(d1, Distance1(0)); distance(first1, last1, d1); Distance2 d2; __initialize(d2, Distance2(0)); distance(first2, last2, d2); if (d1 < d2) return last1; ForwardIterator1 current1 = first1; ForwardIterator2 current2 = first2; while (current2 != last2) { if (*current1++ != *current2++) if (d1-- == d2) return last1; else { current1 = ++first1; current2 = first2; } } return (current2 == last2) ? first1 : last1; } template ForwardIterator1 __search (ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate binary_pred, Distance1*, Distance2*) { Distance1 d1; __initialize(d1, Distance1(0)); distance(first1, last1, d1); Distance2 d2; __initialize(d2, Distance2(0)); distance(first2, last2, d2); if (d1 < d2) return last1; ForwardIterator1 current1 = first1; ForwardIterator2 current2 = first2; while (current2 != last2) { if (!binary_pred(*current1++, *current2++)) if (d1-- == d2) return last1; else { current1 = ++first1; current2 = first2; } } return (current2 == last2) ? first1 : last1; } template ForwardIterator __search_n (ForwardIterator first, ForwardIterator last, Distance*, Size count, const T& value) { Distance d; __initialize(d, Distance(0)); distance(first, last, d); if (d < count || count <= 0) return last; Distance span = d - count; Size matches = 0; ForwardIterator current = first; while (current != last) { if (*current++ != value) { if (span < matches + 1) return last; span -= matches + 1; matches = 0; first = current; } else if (++matches == count) return first; } return last; } template ForwardIterator __search_n (ForwardIterator first, ForwardIterator last, Distance*, Size count, const T& value, BinaryPredicate pred) { Distance d; __initialize(d, Distance(0)); distance(first, last, d); if (d < count || count <= 0) return last; Distance span = d - count; Size matches = 0; ForwardIterator current = first; while (current != last) { if (!pred(*current++, value)) { if (span < matches + 1) return last; span -= matches + 1; matches = 0; first = current; } else if (++matches == count) return first; } return last; } // // Modifying sequence operations. // template OutputIterator copy (InputIterator first, InputIterator last, OutputIterator result) { while (first != last) *result++ = *first++; return result; } template BidirectionalIterator2 copy_backward (BidirectionalIterator1 first, BidirectionalIterator1 last, BidirectionalIterator2 result) { while (first != last) *--result = *--last; return result; } template ForwardIterator2 swap_ranges (ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2) { while (first1 != last1) iter_swap(first1++, first2++); return first2; } template OutputIterator transform (InputIterator first, InputIterator last, OutputIterator result, UnaryOperation op) { while (first != last) *result++ = op(*first++); return result; } template OutputIterator transform (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, OutputIterator result, BinaryOperation binary_op) { while (first1 != last1) *result++ = binary_op(*first1++, *first2++); return result; } template void replace (ForwardIterator first, ForwardIterator last, const T& old_value, const T& new_value) { while (first != last) { if (*first == old_value) *first = new_value; ++first; } } template void replace_if (ForwardIterator first, ForwardIterator last, Predicate pred, const T& new_value) { while (first != last) { if (pred(*first)) *first = new_value; ++first; } } template OutputIterator replace_copy (InputIterator first, InputIterator last, OutputIterator result, const T& old_value, const T& new_value) { while (first != last) { *result++ = *first == old_value ? new_value : *first; ++first; } return result; } template OutputIterator replace_copy_if (Iterator first, Iterator last, OutputIterator result, Predicate pred, const T& new_value) { while (first != last) { if(pred(*first)) *result++ = new_value; else *result++ = *first; ++first; } return result; } template #ifdef _RWSTD_FILL_NAME_CLASH void std_fill (ForwardIterator first, ForwardIterator last, const T& value) #else void fill (ForwardIterator first, ForwardIterator last, const T& value) #endif { while (first != last) *first++ = value; } template void fill_n (OutputIterator first, Size n, const T& value) { while (n-- > 0) *first++ = value; } template void generate (ForwardIterator first, ForwardIterator last, Generator gen) { while (first != last) *first++ = gen(); } template void generate_n (OutputIterator first, Size n, Generator gen) { while (n-- > 0) *first++ = gen(); } template OutputIterator remove_copy (InputIterator first, InputIterator last, OutputIterator result, const T& value) { while (first != last) { if (*first != value) *result++ = *first; ++first; } return result; } template OutputIterator remove_copy_if (InputIterator first, InputIterator last, OutputIterator result, Predicate pred) { while (first != last) { if (!pred(*first)) *result++ = *first; ++first; } return result; } template ForwardIterator __unique_copy (InputIterator first, InputIterator last, ForwardIterator result, forward_iterator_tag) { *result = *first; while (++first != last) if (*result != *first) *++result = *first; return ++result; } template OutputIterator __unique_copy (InputIterator first, InputIterator last, OutputIterator result, T*) { T value = *first; *result = value; while (++first != last) { if (value != *first) { value = *first; *++result = value; } } return ++result; } template ForwardIterator __unique_copy (InputIterator first, InputIterator last, ForwardIterator result, BinaryPredicate binary_pred, forward_iterator_tag) { *result = *first; while (++first != last) if (!binary_pred(*result, *first)) *++result = *first; return ++result; } template OutputIterator __unique_copy (InputIterator first, InputIterator last, OutputIterator result, BinaryPredicate binary_pred, T*) { T value = *first; *result = value; while (++first != last) { if (!binary_pred(value, *first)) { value = *first; *++result = value; } } return ++result; } template void __reverse (BidirectionalIterator first, BidirectionalIterator last, bidirectional_iterator_tag) { while (true) if (first == last || first == --last) return; else iter_swap(first++, last); } template void __reverse (RandomAccessIterator first, RandomAccessIterator last, random_access_iterator_tag) { while (first < last) iter_swap(first++, --last); } template OutputIterator reverse_copy (BidirectionalIterator first, BidirectionalIterator last, OutputIterator result) { while (first != last) *result++ = *--last; return result; } template void __rotate (ForwardIterator first, ForwardIterator middle, ForwardIterator last, Distance*, forward_iterator_tag) { for (ForwardIterator i = middle; ;) { iter_swap(first++, i++); if (first == middle) { if (i == last) return; middle = i; } else if (i == last) i = middle; } } template EuclideanRingElement __gcd (EuclideanRingElement m, EuclideanRingElement n) { while (n != 0) { EuclideanRingElement t = m % n; m = n; n = t; } return m; } template void __rotate_cycle (RandomAccessIterator first, RandomAccessIterator last, RandomAccessIterator initial, Distance shift, T*) { T value = *initial; RandomAccessIterator ptr1 = initial; RandomAccessIterator ptr2 = ptr1 + shift; while (ptr2 != initial) { *ptr1 = *ptr2; ptr1 = ptr2; if (last - ptr2 > shift) ptr2 += shift; else ptr2 = first + (shift - (last - ptr2)); } *ptr1 = value; } template void __rotate (RandomAccessIterator first, RandomAccessIterator middle, RandomAccessIterator last, Distance*, random_access_iterator_tag) { Distance n = __gcd(last - first, middle - first); while (n--) __rotate_cycle(first, last, first + n, middle - first, _RWSTD_VALUE_TYPE(first)); } #ifndef _RWSTD_NO_NAMESPACE } namespace __rwstd { #endif extern unsigned _RWSTDExport long __long_random (unsigned long); #ifndef _RWSTD_NO_NAMESPACE } namespace std { #endif template void __random_shuffle (RandomAccessIterator first, RandomAccessIterator last, Distance*) { if (!(first == last)) for (RandomAccessIterator i = first + 1; i != last; ++i) iter_swap(i, first + Distance(__RWSTD::__long_random((i - first) + 1))); } template void random_shuffle (RandomAccessIterator first, RandomAccessIterator last, RandomNumberGenerator& rand) { if (!(first == last)) for (RandomAccessIterator i = first + 1; i != last; ++i) iter_swap(i, first + rand((i - first) + 1)); } template BidirectionalIterator partition (BidirectionalIterator first, BidirectionalIterator last, Predicate pred) { while (true) { while (true) { if (first == last) return first; else if (pred(*first)) ++first; else break; } --last; while (true) { if (first == last) return first; else if (!pred(*last)) --last; else break; } iter_swap(first, last); ++first; } } template BidirectionalIterator __inplace_stable_partition (BidirectionalIterator first, BidirectionalIterator last, Predicate pred, Distance len) { if (len == 1) return pred(*first) ? last : first; BidirectionalIterator middle = first; advance(middle, len / 2); BidirectionalIterator first_cut = __inplace_stable_partition(first, middle, pred, len / 2); BidirectionalIterator second_cut = __inplace_stable_partition(middle, last, pred, len - len / 2); rotate(first_cut, middle, second_cut); __initialize(len, Distance(0)); distance(middle, second_cut, len); advance(first_cut, len); return first_cut; } template BidirectionalIterator __stable_partition_adaptive (BidirectionalIterator first, BidirectionalIterator last, Predicate pred, Distance len, Pointer buffer, Distance buffer_size, Distance& fill_pointer, T*) { if (len <= buffer_size) { len = 0; BidirectionalIterator result1 = first; Pointer result2 = buffer; while (first != last && len < fill_pointer) { if (pred(*first)) *result1++ = *first++; else { *result2++ = *first++; ++len; } } if (first != last) { raw_storage_iterator result3(result2); while (first != last) { if (pred(*first)) *result1++ = *first++; else { *result3++ = *first++; ++len; } } fill_pointer = len; } copy(buffer, buffer + len, result1); return result1; } BidirectionalIterator middle = first; advance(middle, len / 2); BidirectionalIterator first_cut = __stable_partition_adaptive (first, middle, pred, len / 2, buffer, buffer_size, fill_pointer, (T*)0); BidirectionalIterator second_cut = __stable_partition_adaptive (middle, last, pred, len-len/2, buffer, buffer_size, fill_pointer, (T*)0); rotate(first_cut, middle, second_cut); __initialize(len, Distance(0)); distance(middle, second_cut, len); advance(first_cut, len); return first_cut; } template BidirectionalIterator __stable_partition (BidirectionalIterator first, BidirectionalIterator last, Predicate pred, Distance len, pair p) { if (p.first == 0) return __inplace_stable_partition(first, last, pred, len); Distance fill_pointer = 0; BidirectionalIterator result = __stable_partition_adaptive(first, last, pred, len, p.first, p.second, fill_pointer, _RWSTD_VALUE_TYPE(first)); __RWSTD::__destroy(p.first, p.first + fill_pointer); return_temporary_buffer(p.first); return result; } // // Sorting and related operations. // template RandomAccessIterator __unguarded_partition (RandomAccessIterator first, RandomAccessIterator last, T pivot) { while (true) { while (*first < pivot) ++first; --last; while (pivot < *last) --last; if (!(first < last)) return first; iter_swap(first, last); ++first; } } template RandomAccessIterator __unguarded_partition (RandomAccessIterator first, RandomAccessIterator last, T pivot, Compare _RWSTD_COMP) { while (true) { while (_RWSTD_COMP(*first, pivot)) ++first; --last; while (_RWSTD_COMP(pivot, *last)) --last; if (!(first < last)) return first; iter_swap(first, last); ++first; } } const int __stl_threshold = 16; template void __quick_sort_loop_aux (RandomAccessIterator first, RandomAccessIterator last, T*) { while (last - first > __stl_threshold) { RandomAccessIterator cut = __unguarded_partition (first, last, T(__median(*first, *(first + (last - first)/2), *(last - 1)))); if (cut - first >= last - cut) { __quick_sort_loop(cut, last); last = cut; } else { __quick_sort_loop(first, cut); first = cut; } } } template void __quick_sort_loop_aux (RandomAccessIterator first, RandomAccessIterator last, T*, Compare _RWSTD_COMP) { while (last - first > __stl_threshold) { RandomAccessIterator cut = __unguarded_partition (first, last, T(__median(*first, *(first + (last - first)/2), *(last - 1), _RWSTD_COMP)), _RWSTD_COMP); if (cut - first >= last - cut) { __quick_sort_loop(cut, last, _RWSTD_COMP); last = cut; } else { __quick_sort_loop(first, cut, _RWSTD_COMP); first = cut; } } } template void __unguarded_linear_insert (RandomAccessIterator last, T value) { RandomAccessIterator next = last; --next; while (value < *next) { *last = *next; last = next--; } *last = value; } template void __unguarded_linear_insert (RandomAccessIterator last,T value,Compare _RWSTD_COMP) { RandomAccessIterator next = last; --next; while (_RWSTD_COMP(value , *next)) { *last = *next; last = next--; } *last = value; } template void __insertion_sort (RandomAccessIterator first, RandomAccessIterator last) { if (!(first == last)) for (RandomAccessIterator i = first + 1; i != last; ++i) __linear_insert(first, i, _RWSTD_VALUE_TYPE(first)); } template void __insertion_sort (RandomAccessIterator first, RandomAccessIterator last, Compare _RWSTD_COMP) { if (!(first == last)) for (RandomAccessIterator i = first + 1; i != last; ++i) __linear_insert(first, i, _RWSTD_VALUE_TYPE(first), _RWSTD_COMP); } template void __unguarded_insertion_sort_aux (RandomAccessIterator first, RandomAccessIterator last, T*) { for (RandomAccessIterator i = first; i != last; ++i) __unguarded_linear_insert(i, T(*i)); } template void __unguarded_insertion_sort_aux (RandomAccessIterator first, RandomAccessIterator last, T*, Compare _RWSTD_COMP) { for (RandomAccessIterator i = first; i != last; ++i) __unguarded_linear_insert(i, T(*i), _RWSTD_COMP); } template void __final_insertion_sort (RandomAccessIterator first, RandomAccessIterator last) { if (last - first > __stl_threshold) { __insertion_sort(first, first + __stl_threshold); __unguarded_insertion_sort(first + __stl_threshold, last); } else __insertion_sort(first, last); } template void __final_insertion_sort (RandomAccessIterator first, RandomAccessIterator last, Compare _RWSTD_COMP) { if (last - first > __stl_threshold) { __insertion_sort(first, first + __stl_threshold, _RWSTD_COMP); __unguarded_insertion_sort(first + __stl_threshold, last, _RWSTD_COMP); } else __insertion_sort(first, last, _RWSTD_COMP); } template void __merge_sort_loop (RandomAccessIterator1 first, RandomAccessIterator1 last, RandomAccessIterator2 result, Distance step_size) { Distance two_step = 2 * step_size; while (last - first >= two_step) { result = merge(first, first + step_size, first + step_size, first + two_step, result); first += two_step; } step_size = min(Distance(last - first), step_size); merge(first, first + step_size, first + step_size, last, result); } template void __merge_sort_loop (RandomAccessIterator1 first, RandomAccessIterator1 last, RandomAccessIterator2 result, Distance step_size, Compare _RWSTD_COMP) { Distance two_step = 2 * step_size; while (last - first >= two_step) { result = merge(first, first + step_size, first + step_size, first + two_step, result, _RWSTD_COMP); first += two_step; } step_size = min(Distance(last - first), step_size); merge(first, first + step_size, first + step_size, last, result, _RWSTD_COMP); } const int __stl_chunk_size = 7; template void __chunk_insertion_sort (RandomAccessIterator first, RandomAccessIterator last, Distance chunk_size) { while (last - first >= chunk_size) { __insertion_sort(first, first + chunk_size); first += chunk_size; } __insertion_sort(first, last); } template void __chunk_insertion_sort (RandomAccessIterator first, RandomAccessIterator last, Distance chunk_size, Compare _RWSTD_COMP) { while (last - first >= chunk_size) { __insertion_sort(first, first + chunk_size, _RWSTD_COMP); first += chunk_size; } __insertion_sort(first, last, _RWSTD_COMP); } template void __merge_sort_with_buffer (RandomAccessIterator first, RandomAccessIterator last, Pointer buffer, Distance*, T*) { Distance len = last - first; Pointer buffer_last = buffer + len; Distance step_size = __stl_chunk_size; __chunk_insertion_sort(first, last, step_size); while (step_size < len) { __merge_sort_loop(first, last, buffer, step_size); step_size *= 2; __merge_sort_loop(buffer, buffer_last, first, step_size); step_size *= 2; } } template void __merge_sort_with_buffer (RandomAccessIterator first, RandomAccessIterator last, Pointer buffer, Distance*, T*, Compare _RWSTD_COMP) { Distance len = last - first; Pointer buffer_last = buffer + len; Distance step_size = __stl_chunk_size; __chunk_insertion_sort(first, last, step_size, _RWSTD_COMP); while (step_size < len) { __merge_sort_loop(first, last, buffer, step_size, _RWSTD_COMP); step_size *= 2; __merge_sort_loop(buffer, buffer_last, first, step_size, _RWSTD_COMP); step_size *= 2; } } template void __stable_sort_adaptive (RandomAccessIterator first, RandomAccessIterator last, Pointer buffer, Distance buffer_size, T*) { Distance len = (last - first + 1) / 2; RandomAccessIterator middle = first + len; if (len > buffer_size) { __stable_sort_adaptive(first, middle, buffer, buffer_size, _RWSTD_STATIC_CAST(T*,0)); __stable_sort_adaptive(middle, last, buffer, buffer_size, _RWSTD_STATIC_CAST(T*,0)); } else { __merge_sort_with_buffer(first, middle, buffer, _RWSTD_STATIC_CAST(Distance*,0), _RWSTD_STATIC_CAST(T*,0)); __merge_sort_with_buffer(middle, last, buffer, _RWSTD_STATIC_CAST(Distance*,0), _RWSTD_STATIC_CAST(T*,0)); } __merge_adaptive(first, middle, last, Distance(middle - first), Distance(last - middle), buffer, buffer_size, _RWSTD_STATIC_CAST(T*,0)); } template void __stable_sort_adaptive (RandomAccessIterator first, RandomAccessIterator last, Pointer buffer, Distance buffer_size, T*, Compare _RWSTD_COMP) { Distance len = (last - first + 1) / 2; RandomAccessIterator middle = first + len; if (len > buffer_size) { __stable_sort_adaptive(first, middle, buffer, buffer_size,_RWSTD_STATIC_CAST(T*,0),_RWSTD_COMP); __stable_sort_adaptive(middle, last, buffer, buffer_size, _RWSTD_STATIC_CAST(T*,0),_RWSTD_COMP); } else { __merge_sort_with_buffer(first, middle, buffer, _RWSTD_STATIC_CAST(Distance*,0), _RWSTD_STATIC_CAST(T*,0), _RWSTD_COMP); __merge_sort_with_buffer(middle, last, buffer, _RWSTD_STATIC_CAST(Distance*,0), _RWSTD_STATIC_CAST(T*,0), _RWSTD_COMP); } __merge_adaptive(first, middle, last, Distance(middle - first), Distance(last-middle), buffer, buffer_size, _RWSTD_STATIC_CAST(T*,0),_RWSTD_COMP); } template void __partial_sort (RandomAccessIterator first, RandomAccessIterator middle, RandomAccessIterator last, T*) { make_heap(first, middle); for (RandomAccessIterator i = middle; i < last; ++i) if (*i < *first) __pop_heap(first, middle, i, T(*i), __distance_type(first)); sort_heap(first, middle); } template void __partial_sort (RandomAccessIterator first, RandomAccessIterator middle, RandomAccessIterator last, T*, Compare _RWSTD_COMP) { make_heap(first, middle, _RWSTD_COMP); for (RandomAccessIterator i = middle; i < last; ++i) if (_RWSTD_COMP(*i,*first)) __pop_heap(first, middle, i, T(*i), _RWSTD_COMP, __distance_type(first)); sort_heap(first, middle, _RWSTD_COMP); } template RandomAccessIterator __partial_sort_copy (InputIterator first, InputIterator last, RandomAccessIterator result_first, RandomAccessIterator result_last, Distance*, T*) { if (result_first == result_last) return result_last; RandomAccessIterator result_real_last = result_first; while(first != last && result_real_last != result_last) *result_real_last++ = *first++; make_heap(result_first, result_real_last); while (first != last) { if (*first < *result_first) __adjust_heap(result_first, Distance(0), Distance(result_real_last - result_first), T(*first)); ++first; } sort_heap(result_first, result_real_last); return result_real_last; } template RandomAccessIterator __partial_sort_copy (InputIterator first, InputIterator last, RandomAccessIterator result_first, RandomAccessIterator result_last, Compare _RWSTD_COMP, Distance*, T*) { if (result_first == result_last) return result_last; RandomAccessIterator result_real_last = result_first; while(first != last && result_real_last != result_last) *result_real_last++ = *first++; make_heap(result_first, result_real_last, _RWSTD_COMP); while (first != last) { if (_RWSTD_COMP(*first,*result_first)) __adjust_heap(result_first, Distance(0), Distance(result_real_last - result_first), T(*first), _RWSTD_COMP); ++first; } sort_heap(result_first, result_real_last, _RWSTD_COMP); return result_real_last; } template void __nth_element (RandomAccessIterator first, RandomAccessIterator nth, RandomAccessIterator last, T*) { while (last - first > 3) { RandomAccessIterator cut = __unguarded_partition (first, last, T(__median(*first, *(first + (last - first)/2), *(last - 1)))); if (cut <= nth) first = cut; else last = cut; } __insertion_sort(first, last); } template void __nth_element (RandomAccessIterator first, RandomAccessIterator nth, RandomAccessIterator last, T*, Compare _RWSTD_COMP) { while (last - first > 3) { RandomAccessIterator cut = __unguarded_partition (first, last, T(__median(*first, *(first + (last - first)/2), *(last - 1), _RWSTD_COMP)), _RWSTD_COMP); if (cut <= nth) first = cut; else last = cut; } __insertion_sort(first, last, _RWSTD_COMP); } // // Binary search. // template ForwardIterator __lower_bound (ForwardIterator first, ForwardIterator last, const T& value, Distance*, forward_iterator_tag) { Distance len; __initialize(len, Distance(0)); distance(first, last, len); Distance half; ForwardIterator middle; while (len > 0) { half = len / 2; middle = first; advance(middle, half); if (*middle < value) { first = middle; ++first; len = len - half - 1; } else len = half; } return first; } template RandomAccessIterator __lower_bound (RandomAccessIterator first, RandomAccessIterator last, const T& value, Distance*, random_access_iterator_tag) { Distance len = last - first; Distance half; RandomAccessIterator middle; while (len > 0) { half = len / 2; middle = first + half; if (*middle < value) { first = middle + 1; len = len - half - 1; } else len = half; } return first; } template ForwardIterator __lower_bound (ForwardIterator first, ForwardIterator last, const T& value, Compare _RWSTD_COMP, Distance*, forward_iterator_tag) { Distance len; __initialize(len, Distance(0)); distance(first, last, len); Distance half; ForwardIterator middle; while (len > 0) { half = len / 2; middle = first; advance(middle, half); if (_RWSTD_COMP(*middle, value)) { first = middle; ++first; len = len - half - 1; } else len = half; } return first; } template RandomAccessIterator __lower_bound (RandomAccessIterator first, RandomAccessIterator last, const T& value, Compare _RWSTD_COMP, Distance*, random_access_iterator_tag) { Distance len = last - first; Distance half; RandomAccessIterator middle; while (len > 0) { half = len / 2; middle = first + half; if (_RWSTD_COMP(*middle, value)) { first = middle + 1; len = len - half - 1; } else len = half; } return first; } template ForwardIterator __upper_bound (ForwardIterator first, ForwardIterator last, const T& value, Distance*, forward_iterator_tag) { Distance len; __initialize(len, Distance(0)); distance(first, last, len); Distance half; ForwardIterator middle; while (len > 0) { half = len / 2; middle = first; advance(middle, half); if (value < *middle) len = half; else { first = middle; ++first; len = len - half - 1; } } return first; } template RandomAccessIterator __upper_bound (RandomAccessIterator first, RandomAccessIterator last, const T& value, Distance*, random_access_iterator_tag) { Distance len = last - first; Distance half; RandomAccessIterator middle; while (len > 0) { half = len / 2; middle = first + half; if (value < *middle) len = half; else { first = middle + 1; len = len - half - 1; } } return first; } template ForwardIterator __upper_bound (ForwardIterator first, ForwardIterator last, const T& value, Compare _RWSTD_COMP, Distance*, forward_iterator_tag) { Distance len; __initialize(len, Distance(0)); distance(first, last, len); Distance half; ForwardIterator middle; while (len > 0) { half = len / 2; middle = first; advance(middle, half); if (_RWSTD_COMP(value, *middle)) len = half; else { first = middle; ++first; len = len - half - 1; } } return first; } template RandomAccessIterator __upper_bound (RandomAccessIterator first, RandomAccessIterator last, const T& value, Compare _RWSTD_COMP, Distance*, random_access_iterator_tag) { Distance len = last - first; Distance half; RandomAccessIterator middle; while (len > 0) { half = len / 2; middle = first + half; if (_RWSTD_COMP(value, *middle)) len = half; else { first = middle + 1; len = len - half - 1; } } return first; } template pair __equal_range (ForwardIterator first, ForwardIterator last, const T& value, Distance*, forward_iterator_tag) { Distance len; __initialize(len, Distance(0)); distance(first, last, len); Distance half; ForwardIterator middle, left, right; while (len > 0) { half = len / 2; middle = first; advance(middle, half); if (*middle < value) { first = middle; ++first; len = len - half - 1; } else if (value < *middle) len = half; else { left = lower_bound(first, middle, value); advance(first, len); right = upper_bound(++middle, first, value); pair tmp(left, right); return tmp; } } pair tmp(first, first); return tmp; } template pair __equal_range (RandomAccessIterator first, RandomAccessIterator last, const T& value, Distance*, random_access_iterator_tag) { Distance len = last - first; Distance half; RandomAccessIterator middle, left, right; while (len > 0) { half = len / 2; middle = first + half; if (*middle < value) { first = middle + 1; len = len - half - 1; } else if (value < *middle) len = half; else { left = lower_bound(first, middle, value); right = upper_bound(++middle, first + len, value); pair tmp(left,right); return tmp; } } pair tmp(first, first); return tmp; } template pair __equal_range (ForwardIterator first, ForwardIterator last, const T& value, Compare _RWSTD_COMP, Distance*, forward_iterator_tag) { Distance len; __initialize(len, Distance(0)); distance(first, last, len); Distance half; ForwardIterator middle, left, right; while (len > 0) { half = len / 2; middle = first; advance(middle, half); if (_RWSTD_COMP(*middle, value)) { first = middle; ++first; len = len - half - 1; } else if (_RWSTD_COMP(value, *middle)) len = half; else { left = lower_bound(first, middle, value, _RWSTD_COMP); advance(first, len); right = upper_bound(++middle, first, value, _RWSTD_COMP); pair tmp(left, right); return tmp; } } pair tmp(first, first); return tmp; } template pair __equal_range (RandomAccessIterator first, RandomAccessIterator last, const T& value, Compare _RWSTD_COMP, Distance*, random_access_iterator_tag) { Distance len = last - first; Distance half; RandomAccessIterator middle, left, right; while (len > 0) { half = len / 2; middle = first + half; if (_RWSTD_COMP(*middle, value)) { first = middle + 1; len = len - half - 1; } else if (_RWSTD_COMP(value, *middle)) len = half; else { left = lower_bound(first, middle, value, _RWSTD_COMP); right = upper_bound(++middle, first + len, value, _RWSTD_COMP); pair tmp(left, right); return tmp; } } pair tmp(first, first); return tmp; } // // Merge // template OutputIterator merge (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result) { while (first1 != last1 && first2 != last2) { if (*first2 < *first1) *result++ = *first2++; else *result++ = *first1++; } return copy(first2, last2, copy(first1, last1, result)); } template OutputIterator merge (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare _RWSTD_COMP) { while (first1 != last1 && first2 != last2) { if (_RWSTD_COMP(*first2, *first1)) *result++ = *first2++; else *result++ = *first1++; } return copy(first2, last2, copy(first1, last1, result)); } template void __merge_without_buffer (BidirectionalIterator first, BidirectionalIterator middle, BidirectionalIterator last, Distance len1, Distance len2) { if (len1 == 0 || len2 == 0) return; if (len1 + len2 == 2) { if (*middle < *first) iter_swap(first, middle); return; } BidirectionalIterator first_cut = first; BidirectionalIterator second_cut = middle; Distance len11; __initialize(len11, Distance(0)); Distance len22; __initialize(len22, Distance(0)); if (len1 > len2) { len11 = len1 / 2; advance(first_cut, len11); second_cut = lower_bound(middle, last, *first_cut); distance(middle, second_cut, len22); } else { len22 = len2 / 2; advance(second_cut, len22); first_cut = upper_bound(first, middle, *second_cut); distance(first, first_cut, len11); } rotate(first_cut, middle, second_cut); BidirectionalIterator new_middle = first_cut; advance(new_middle, len22); __merge_without_buffer(first, first_cut, new_middle, len11, len22); __merge_without_buffer(new_middle, second_cut, last, len1 - len11, len2 - len22); } template void __merge_without_buffer (BidirectionalIterator first, BidirectionalIterator middle, BidirectionalIterator last, Distance len1, Distance len2, Compare _RWSTD_COMP) { if (len1 == 0 || len2 == 0) return; if (len1 + len2 == 2) { if (_RWSTD_COMP(*middle, *first)) iter_swap(first, middle); return; } BidirectionalIterator first_cut = first; BidirectionalIterator second_cut = middle; Distance len11; __initialize(len11, Distance(0)); Distance len22; __initialize(len22, Distance(0)); if (len1 > len2) { len11 = len1 / 2; advance(first_cut, len11); second_cut = lower_bound(middle, last, *first_cut, _RWSTD_COMP); distance(middle, second_cut, len22); } else { len22 = len2 / 2; advance(second_cut, len22); first_cut = upper_bound(first, middle, *second_cut, _RWSTD_COMP); distance(first, first_cut, len11); } rotate(first_cut, middle, second_cut); BidirectionalIterator new_middle = first_cut; advance(new_middle, len22); __merge_without_buffer(first, first_cut, new_middle, len11, len22, _RWSTD_COMP); __merge_without_buffer(new_middle, second_cut, last, len1 - len11, len2 - len22, _RWSTD_COMP); } template BidirectionalIterator1 __rotate_adaptive (BidirectionalIterator1 first, BidirectionalIterator1 middle, BidirectionalIterator1 last, Distance len1, Distance len2, BidirectionalIterator2 buffer, Distance buffer_size) { BidirectionalIterator2 buffer_end; if (len1 > len2 && len2 <= buffer_size) { buffer_end = copy(middle, last, buffer); copy_backward(first, middle, last); return copy(buffer, buffer_end, first); } else if (len1 <= buffer_size) { buffer_end = copy(first, middle, buffer); copy(middle, last, first); return copy_backward(buffer, buffer_end, last); } else { rotate(first, middle, last); advance(first, len2); return first; } } template BidirectionalIterator3 __merge_backward (BidirectionalIterator1 first1, BidirectionalIterator1 last1, BidirectionalIterator2 first2, BidirectionalIterator2 last2, BidirectionalIterator3 result) { if (first1 == last1) return copy_backward(first2, last2, result); if (first2 == last2) return copy_backward(first1, last1, result); --last1; --last2; while (true) { if (*last2 < *last1) { *--result = *last1; if (first1 == last1) return copy_backward(first2, ++last2, result); --last1; } else { *--result = *last2; if (first2 == last2) return copy_backward(first1, ++last1, result); --last2; } } } template BidirectionalIterator3 __merge_backward (BidirectionalIterator1 first1, BidirectionalIterator1 last1, BidirectionalIterator2 first2, BidirectionalIterator2 last2, BidirectionalIterator3 result, Compare _RWSTD_COMP) { if (first1 == last1) return copy_backward(first2, last2, result); if (first2 == last2) return copy_backward(first1, last1, result); --last1; --last2; while (true) { if (_RWSTD_COMP(*last2, *last1)) { *--result = *last1; if (first1 == last1) return copy_backward(first2, ++last2, result); --last1; } else { *--result = *last2; if (first2 == last2) return copy_backward(first1, ++last1, result); --last2; } } } template void __merge_adaptive (BidirectionalIterator first, BidirectionalIterator middle, BidirectionalIterator last, Distance len1,Distance len2, Pointer buffer, Distance buffer_size, T*) { if (len1 <= len2 && len1 <= buffer_size) { Pointer end_buffer = copy(first, middle, buffer); merge(buffer, end_buffer, middle, last, first); } else if (len2 <= buffer_size) { Pointer end_buffer = copy(middle, last, buffer); __merge_backward(first, middle, buffer, end_buffer, last); } else { BidirectionalIterator first_cut = first; BidirectionalIterator second_cut = middle; Distance len11; __initialize(len11, Distance(0)); Distance len22; __initialize(len22, Distance(0)); if (len1 > len2) { len11 = len1 / 2; advance(first_cut, len11); second_cut = lower_bound(middle, last, *first_cut); distance(middle, second_cut, len22); } else { len22 = len2 / 2; advance(second_cut, len22); first_cut = upper_bound(first, middle, *second_cut); distance(first, first_cut, len11); } BidirectionalIterator new_middle = __rotate_adaptive(first_cut, middle, second_cut, len1 - len11, len22, buffer, buffer_size); __merge_adaptive(first, first_cut, new_middle, len11, len22, buffer, buffer_size, _RWSTD_STATIC_CAST(T*,0)); __merge_adaptive(new_middle, second_cut, last, len1 - len11, len2 - len22, buffer, buffer_size, _RWSTD_STATIC_CAST(T*,0)); } } template void __merge_adaptive (BidirectionalIterator first, BidirectionalIterator middle, BidirectionalIterator last, Distance len1,Distance len2, Pointer buffer, Distance buffer_size, T*, Compare _RWSTD_COMP) { if (len1 <= len2 && len1 <= buffer_size) { Pointer end_buffer = copy(first, middle, buffer); merge(buffer, end_buffer, middle, last, first, _RWSTD_COMP); } else if (len2 <= buffer_size) { Pointer end_buffer = copy(middle, last, buffer); __merge_backward(first, middle, buffer, end_buffer, last, _RWSTD_COMP); } else { BidirectionalIterator first_cut = first; BidirectionalIterator second_cut = middle; Distance len11; __initialize(len11, Distance(0)); Distance len22; __initialize(len22, Distance(0)); if (len1 > len2) { len11 = len1 / 2; advance(first_cut, len11); second_cut = lower_bound(middle, last, *first_cut, _RWSTD_COMP); distance(middle, second_cut, len22); } else { len22 = len2 / 2; advance(second_cut, len22); first_cut = upper_bound(first, middle, *second_cut, _RWSTD_COMP); distance(first, first_cut, len11); } BidirectionalIterator new_middle = __rotate_adaptive(first_cut, middle, second_cut, len1 - len11, len22, buffer, buffer_size); __merge_adaptive(first, first_cut, new_middle, len11, len22, buffer, buffer_size, _RWSTD_STATIC_CAST(T*,0), _RWSTD_COMP); __merge_adaptive(new_middle, second_cut, last, len1 - len11, len2 - len22, buffer, buffer_size, _RWSTD_STATIC_CAST(T*,0), _RWSTD_COMP); } } template void __inplace_merge (BidirectionalIterator first, BidirectionalIterator middle, BidirectionalIterator last, Distance len1, Distance len2, pair p, T*) { if (p.first == 0) __merge_without_buffer(first, middle, last, len1, len2); else { Distance len = min(p.second, len1 + len2); fill_n(raw_storage_iterator(p.first), len, *first); __merge_adaptive(first, middle, last, len1, len2, p.first, p.second, _RWSTD_STATIC_CAST(T*,0)); __RWSTD::__destroy(p.first, p.first + len); return_temporary_buffer(p.first); } } template void __inplace_merge (BidirectionalIterator first, BidirectionalIterator middle, BidirectionalIterator last, Distance len1, Distance len2, pair p, T*, Compare _RWSTD_COMP) { if (p.first == 0) __merge_without_buffer(first, middle, last, len1, len2, _RWSTD_COMP); else { Distance len = min(p.second, len1 + len2); fill_n(raw_storage_iterator(p.first), len, *first); __merge_adaptive(first, middle, last, len1, len2, p.first, p.second, _RWSTD_STATIC_CAST(T*,0), _RWSTD_COMP); __RWSTD::__destroy(p.first, p.first + len); return_temporary_buffer(p.first); } } // // Set operations. // template bool includes (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2) { while (first1 != last1 && first2 != last2) { if (*first2 < *first1) return false; else if(*first1 < *first2) ++first1; else ++first1, ++first2; } return first2 == last2; } template bool includes (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, Compare _RWSTD_COMP) { while (first1 != last1 && first2 != last2) { if (_RWSTD_COMP(*first2, *first1)) return false; else if(_RWSTD_COMP(*first1, *first2)) ++first1; else ++first1, ++first2; } return first2 == last2; } template OutputIterator set_union (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result) { while (first1 != last1 && first2 != last2) { if (*first1 < *first2) *result++ = *first1++; else if (*first2 < *first1) *result++ = *first2++; else { *result++ = *first1++; first2++; } } return copy(first2, last2, copy(first1, last1, result)); } template OutputIterator set_union (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare _RWSTD_COMP) { while (first1 != last1 && first2 != last2) { if (_RWSTD_COMP(*first1, *first2)) *result++ = *first1++; else if (_RWSTD_COMP(*first2, *first1)) *result++ = *first2++; else { *result++ = *first1++; ++first2; } } return copy(first2, last2, copy(first1, last1, result)); } template OutputIterator set_intersection (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result) { while (first1 != last1 && first2 != last2) { if (*first1 < *first2) ++first1; else if (*first2 < *first1) ++first2; else { *result++ = *first1++; ++first2; } } return result; } template OutputIterator set_intersection (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare _RWSTD_COMP) { while (first1 != last1 && first2 != last2) { if (_RWSTD_COMP(*first1, *first2)) ++first1; else if (_RWSTD_COMP(*first2, *first1)) ++first2; else { *result++ = *first1++; ++first2; } } return result; } template OutputIterator set_difference (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result) { while (first1 != last1 && first2 != last2) { if (*first1 < *first2) *result++ = *first1++; else if (*first2 < *first1) ++first2; else { ++first1; ++first2; } } return copy(first1, last1, result); } template OutputIterator set_difference (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare _RWSTD_COMP) { while (first1 != last1 && first2 != last2) { if (_RWSTD_COMP(*first1, *first2)) *result++ = *first1++; else if (_RWSTD_COMP(*first2, *first1)) ++first2; else { ++first1; ++first2; } } return copy(first1, last1, result); } template OutputIterator set_symmetric_difference (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result) { while (first1 != last1 && first2 != last2) { if (*first1 < *first2) *result++ = *first1++; else if (*first2 < *first1) *result++ = *first2++; else { ++first1; ++first2; } } return copy(first2, last2, copy(first1, last1, result)); } template OutputIterator set_symmetric_difference (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare _RWSTD_COMP) { while (first1 != last1 && first2 != last2) { if (_RWSTD_COMP(*first1, *first2)) *result++ = *first1++; else if (_RWSTD_COMP(*first2, *first1)) *result++ = *first2++; else { ++first1; ++first2; } } return copy(first2, last2, copy(first1, last1, result)); } // // Heap operations. // template void __push_heap (RandomAccessIterator first, Distance holeIndex, Distance topIndex, T value) { Distance parent = (holeIndex - 1) / 2; while (holeIndex > topIndex && *(first + parent) < value) { *(first + holeIndex) = *(first + parent); holeIndex = parent; parent = (holeIndex - 1) / 2; } *(first + holeIndex) = value; } template void __push_heap (RandomAccessIterator first, Distance holeIndex, Distance topIndex, T value, Compare _RWSTD_COMP) { Distance parent = (holeIndex - 1) / 2; while (holeIndex > topIndex && _RWSTD_COMP(*(first + parent), value)) { *(first + holeIndex) = *(first + parent); holeIndex = parent; parent = (holeIndex - 1) / 2; } *(first + holeIndex) = value; } template void __adjust_heap (RandomAccessIterator first, Distance holeIndex, Distance len, T value) { Distance topIndex = holeIndex; Distance secondChild = 2 * holeIndex + 2; while (secondChild < len) { if (*(first + secondChild) < *(first + (secondChild - 1))) secondChild--; *(first + holeIndex) = *(first + secondChild); holeIndex = secondChild; secondChild = 2 * (secondChild + 1); } if (secondChild == len) { *(first + holeIndex) = *(first + (secondChild - 1)); holeIndex = secondChild - 1; } __push_heap(first, holeIndex, topIndex, value); } template void __adjust_heap (RandomAccessIterator first, Distance holeIndex, Distance len, T value, Compare _RWSTD_COMP) { Distance topIndex = holeIndex; Distance secondChild = 2 * holeIndex + 2; while (secondChild < len) { if (_RWSTD_COMP(*(first + secondChild), *(first + (secondChild - 1)))) secondChild--; *(first + holeIndex) = *(first + secondChild); holeIndex = secondChild; secondChild = 2 * (secondChild + 1); } if (secondChild == len) { *(first + holeIndex) = *(first + (secondChild - 1)); holeIndex = secondChild - 1; } __push_heap(first, holeIndex, topIndex, value, _RWSTD_COMP); } template void __make_heap (RandomAccessIterator first, RandomAccessIterator last, T*, Distance*) { Distance len = last - first; Distance parent = (len - 2)/2; while (true) { __adjust_heap(first, parent, len, T(*(first + parent))); if (parent == 0) return; parent--; } } template void __make_heap (RandomAccessIterator first, RandomAccessIterator last, Compare _RWSTD_COMP, T*, Distance*) { Distance len = last - first; Distance parent = (len - 2)/2; while (true) { __adjust_heap(first, parent, len, T(*(first + parent)), _RWSTD_COMP); if (parent == 0) return; parent--; } } template void sort_heap (RandomAccessIterator first, RandomAccessIterator last) { while (last - first > 1) pop_heap(first, last--); } template void sort_heap (RandomAccessIterator first, RandomAccessIterator last, Compare _RWSTD_COMP) { while (last - first > 1) pop_heap(first, last--, _RWSTD_COMP); } // // Minimum and maximum. // template ForwardIterator min_element (ForwardIterator first, ForwardIterator last) { if (first == last) return first; ForwardIterator result = first; while (++first != last) if (*first < *result) result = first; return result; } template ForwardIterator min_element (ForwardIterator first, ForwardIterator last, Compare _RWSTD_COMP) { if (first == last) return first; ForwardIterator result = first; while (++first != last) if (_RWSTD_COMP(*first, *result)) result = first; return result; } template ForwardIterator max_element (ForwardIterator first, ForwardIterator last) { if (first == last) return first; ForwardIterator result = first; while (++first != last) if (*result < *first) result = first; return result; } template ForwardIterator max_element (ForwardIterator first, ForwardIterator last, Compare _RWSTD_COMP) { if (first == last) return first; ForwardIterator result = first; while (++first != last) if (_RWSTD_COMP(*result, *first)) result = first; return result; } template bool lexicographical_compare (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2) { while (first1 != last1 && first2 != last2) { if (*first1 < *first2) return true; if (*first2++ < *first1++) return false; } return first1 == last1 && first2 != last2; } template bool lexicographical_compare(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, Compare _RWSTD_COMP) { while (first1 != last1 && first2 != last2) { if (_RWSTD_COMP(*first1, *first2)) return true; if (_RWSTD_COMP(*first2++, *first1++)) return false; } return first1 == last1 && first2 != last2; } // // Permutations. // template bool next_permutation (BidirectionalIterator first, BidirectionalIterator last) { if (first == last) return false; BidirectionalIterator i = first; ++i; if (i == last) return false; i = last; --i; for (;;) { BidirectionalIterator ii = i--; if (*i < *ii) { BidirectionalIterator j = last; while (!(*i < *--j)) ; iter_swap(i, j); reverse(ii, last); return true; } if (i == first) { reverse(first, last); return false; } } } template bool next_permutation (BidirectionalIterator first, BidirectionalIterator last, Compare _RWSTD_COMP) { if (first == last) return false; BidirectionalIterator i = first; ++i; if (i == last) return false; i = last; --i; for (;;) { BidirectionalIterator ii = i--; if (_RWSTD_COMP(*i, *ii)) { BidirectionalIterator j = last; while (!_RWSTD_COMP(*i, *--j)) ; iter_swap(i, j); reverse(ii, last); return true; } if (i == first) { reverse(first, last); return false; } } } template bool prev_permutation (BidirectionalIterator first, BidirectionalIterator last) { if (first == last) return false; BidirectionalIterator i = first; ++i; if (i == last) return false; i = last; --i; for (;;) { BidirectionalIterator ii = i--; if (*ii < *i) { BidirectionalIterator j = last; while (!(*--j < *i)) ; iter_swap(i, j); reverse(ii, last); return true; } if (i == first) { reverse(first, last); return false; } } } template bool prev_permutation (BidirectionalIterator first, BidirectionalIterator last, Compare _RWSTD_COMP) { if (first == last) return false; BidirectionalIterator i = first; ++i; if (i == last) return false; i = last; --i; for(;;) { BidirectionalIterator ii = i--; if (_RWSTD_COMP(*ii, *i)) { BidirectionalIterator j = last; while (!_RWSTD_COMP(*--j, *i)) ; iter_swap(i, j); reverse(ii, last); return true; } if (i == first) { reverse(first, last); return false; } } } #ifndef _RWSTD_NO_NAMESPACE } #endif #pragma option pop #endif /* __ALGORITH_CC */