This repository has been archived on 2024-12-16. You can view files and clone it, but cannot push or open issues or pull requests.
CodeBlocksPortable/Borland/BCC55/Include/algorith.cc

2513 lines
77 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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 <stdcomp.h>
#ifndef _RWSTD_NO_NAMESPACE
namespace std {
#endif
//
// Forward declare raw_storage_iterator
//
template <class OutputIterator, class T>
class raw_storage_iterator;
//
// Non-modifying sequence operations.
//
template <class InputIterator, class Function>
Function for_each (InputIterator first, InputIterator last, Function f)
{
while (first != last) f(*first++);
return f;
}
template <class InputIterator, class T>
InputIterator find (InputIterator first, InputIterator last, const T& value)
{
while (first != last && *first != value)
++first;
return first;
}
template <class InputIterator, class Predicate>
InputIterator find_if (InputIterator first, InputIterator last, Predicate pred)
{
while (first != last && !pred(*first)) ++first;
return first;
}
template <class ForwardIterator1, class ForwardIterator2,
class Distance>
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 <class ForwardIterator1, class ForwardIterator2>
ForwardIterator1 find_end (ForwardIterator1 first1,
ForwardIterator1 last1,
ForwardIterator2 first2,
ForwardIterator2 last2)
{
return __find_end(first1,last1,first2,last2,
__distance_type(first1));
}
template <class ForwardIterator1, class ForwardIterator2,
class BinaryPredicate, class Distance>
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 <class ForwardIterator1, class ForwardIterator2,
class BinaryPredicate>
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 <class ForwardIterator1, class ForwardIterator2>
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 <class ForwardIterator1, class ForwardIterator2,
class BinaryPredicate>
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 <class ForwardIterator>
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 <class ForwardIterator, class BinaryPredicate>
ForwardIterator adjacent_find (ForwardIterator first, ForwardIterator last,
BinaryPredicate binary_pred)
{
if (first == last) return last;
ForwardIterator next = first;
while (++next != last)
{
if (binary_pred(*first, *next)) return first;
first = next;
}
return last;
}
#ifndef _RWSTD_NO_CLASS_PARTIAL_SPEC
template <class InputIterator, class T>
_TYPENAME iterator_traits<InputIterator>::difference_type
count (InputIterator first, InputIterator last, const T& value)
{
_TYPENAME iterator_traits<InputIterator>::difference_type n = 0;
while (first != last)
if (*first++ == value) ++n;
return n;
}
template <class InputIterator, class Predicate>
_TYPENAME iterator_traits<InputIterator>::difference_type
count_if (InputIterator first, InputIterator last, Predicate pred)
{
_TYPENAME iterator_traits<InputIterator>::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 <class InputIterator, class T, class Size>
void count (InputIterator first, InputIterator last, const T& value, Size& n)
{
while (first != last)
if (*first++ == value) ++n;
}
template <class InputIterator, class Predicate, class Size>
void count_if (InputIterator first, InputIterator last, Predicate pred,
Size& n)
{
while (first != last)
if (pred(*first++)) ++n;
}
#endif /* _RWSTD_NO_OLD_COUNT */
template <class InputIterator1, class InputIterator2>
pair<InputIterator1, InputIterator2> mismatch(InputIterator1 first1,
InputIterator1 last1,
InputIterator2 first2)
{
while (first1 != last1 && *first1 == *first2)
{
++first1;
++first2;
}
pair<InputIterator1, InputIterator2> tmp(first1, first2);
return tmp;
}
template <class InputIterator1, class InputIterator2, class BinaryPredicate>
pair<InputIterator1, InputIterator2> mismatch (InputIterator1 first1,
InputIterator1 last1,
InputIterator2 first2,
BinaryPredicate binary_pred)
{
while (first1 != last1 && binary_pred(*first1, *first2))
{
++first1;
++first2;
}
pair<InputIterator1, InputIterator2> tmp(first1, first2);
return tmp;
}
template <class ForwardIterator1, class ForwardIterator2,
class Distance1, class Distance2>
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 <class ForwardIterator1, class ForwardIterator2,
class BinaryPredicate, class Distance1, class Distance2>
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 <class ForwardIterator, class Distance, class Size, class T>
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 <class ForwardIterator, class Distance, class Size, class T,
class BinaryPredicate>
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 <class InputIterator, class OutputIterator>
OutputIterator copy (InputIterator first, InputIterator last,
OutputIterator result)
{
while (first != last) *result++ = *first++;
return result;
}
template <class BidirectionalIterator1, class BidirectionalIterator2>
BidirectionalIterator2 copy_backward (BidirectionalIterator1 first,
BidirectionalIterator1 last,
BidirectionalIterator2 result)
{
while (first != last) *--result = *--last;
return result;
}
template <class ForwardIterator1, class ForwardIterator2>
ForwardIterator2 swap_ranges (ForwardIterator1 first1, ForwardIterator1 last1,
ForwardIterator2 first2)
{
while (first1 != last1) iter_swap(first1++, first2++);
return first2;
}
template <class InputIterator, class OutputIterator, class UnaryOperation>
OutputIterator transform (InputIterator first, InputIterator last,
OutputIterator result, UnaryOperation op)
{
while (first != last) *result++ = op(*first++);
return result;
}
template <class InputIterator1, class InputIterator2, class OutputIterator,
class BinaryOperation>
OutputIterator transform (InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, OutputIterator result,
BinaryOperation binary_op)
{
while (first1 != last1) *result++ = binary_op(*first1++, *first2++);
return result;
}
template <class ForwardIterator, class T>
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 <class ForwardIterator, class Predicate, class T>
void replace_if (ForwardIterator first, ForwardIterator last, Predicate pred,
const T& new_value)
{
while (first != last)
{
if (pred(*first)) *first = new_value;
++first;
}
}
template <class InputIterator, class OutputIterator, class T>
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 <class Iterator, class OutputIterator, class Predicate, class T>
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 <class ForwardIterator, class T>
#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 <class OutputIterator, class Size, class T>
void fill_n (OutputIterator first, Size n, const T& value)
{
while (n-- > 0) *first++ = value;
}
template <class ForwardIterator, class Generator>
void generate (ForwardIterator first, ForwardIterator last, Generator gen)
{
while (first != last) *first++ = gen();
}
template <class OutputIterator, class Size, class Generator>
void generate_n (OutputIterator first, Size n, Generator gen)
{
while (n-- > 0) *first++ = gen();
}
template <class InputIterator, class OutputIterator, class T>
OutputIterator remove_copy (InputIterator first, InputIterator last,
OutputIterator result, const T& value)
{
while (first != last)
{
if (*first != value) *result++ = *first;
++first;
}
return result;
}
template <class InputIterator, class OutputIterator, class Predicate>
OutputIterator remove_copy_if (InputIterator first, InputIterator last,
OutputIterator result, Predicate pred)
{
while (first != last)
{
if (!pred(*first)) *result++ = *first;
++first;
}
return result;
}
template <class InputIterator, class ForwardIterator>
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 <class InputIterator, class OutputIterator, class T>
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 <class InputIterator, class ForwardIterator, class BinaryPredicate>
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 <class InputIterator, class OutputIterator, class BinaryPredicate,
class T>
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 <class BidirectionalIterator>
void __reverse (BidirectionalIterator first, BidirectionalIterator last,
bidirectional_iterator_tag)
{
while (true)
if (first == last || first == --last)
return;
else
iter_swap(first++, last);
}
template <class RandomAccessIterator>
void __reverse (RandomAccessIterator first, RandomAccessIterator last,
random_access_iterator_tag)
{
while (first < last) iter_swap(first++, --last);
}
template <class BidirectionalIterator, class OutputIterator>
OutputIterator reverse_copy (BidirectionalIterator first,
BidirectionalIterator last,
OutputIterator result)
{
while (first != last) *result++ = *--last;
return result;
}
template <class ForwardIterator, class Distance>
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 <class EuclideanRingElement>
EuclideanRingElement __gcd (EuclideanRingElement m, EuclideanRingElement n)
{
while (n != 0)
{
EuclideanRingElement t = m % n;
m = n;
n = t;
}
return m;
}
template <class RandomAccessIterator, class Distance, class T>
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 <class RandomAccessIterator, class Distance>
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 <class RandomAccessIterator, class Distance>
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 <class RandomAccessIterator, class RandomNumberGenerator>
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 <class BidirectionalIterator, class Predicate>
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 <class BidirectionalIterator, class Predicate, class Distance>
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 <class BidirectionalIterator, class Pointer, class Predicate,
class Distance, class T>
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<Pointer, T> 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 <class BidirectionalIterator, class Predicate, class Pointer,
class Distance>
BidirectionalIterator __stable_partition (BidirectionalIterator first,
BidirectionalIterator last,
Predicate pred, Distance len,
pair<Pointer, Distance> 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 <class RandomAccessIterator, class T>
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 <class RandomAccessIterator, class T, class Compare>
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 <class RandomAccessIterator, class T>
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 <class RandomAccessIterator, class T, class Compare>
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 <class RandomAccessIterator, class T>
void __unguarded_linear_insert (RandomAccessIterator last, T value)
{
RandomAccessIterator next = last;
--next;
while (value < *next)
{
*last = *next;
last = next--;
}
*last = value;
}
template <class RandomAccessIterator, class T, class Compare>
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 <class RandomAccessIterator>
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 <class RandomAccessIterator, class Compare>
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 <class RandomAccessIterator, class T>
void __unguarded_insertion_sort_aux (RandomAccessIterator first,
RandomAccessIterator last, T*)
{
for (RandomAccessIterator i = first; i != last; ++i)
__unguarded_linear_insert(i, T(*i));
}
template <class RandomAccessIterator, class T, class Compare>
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 <class RandomAccessIterator>
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 <class RandomAccessIterator, class Compare>
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 <class RandomAccessIterator1, class RandomAccessIterator2,
class Distance>
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 <class RandomAccessIterator1, class RandomAccessIterator2,
class Distance, class Compare>
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 <class RandomAccessIterator, class Distance>
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 <class RandomAccessIterator, class Distance, class Compare>
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 <class RandomAccessIterator, class Pointer, class Distance, class T>
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 <class RandomAccessIterator, class Pointer, class Distance, class T,
class Compare>
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 <class RandomAccessIterator, class Pointer, class Distance, class T>
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 <class RandomAccessIterator, class Pointer, class Distance, class T,
class Compare>
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 <class RandomAccessIterator, class T>
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 <class RandomAccessIterator, class T, class Compare>
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 <class InputIterator, class RandomAccessIterator, class Distance,
class T>
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 <class InputIterator, class RandomAccessIterator, class Compare,
class Distance, class T>
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 <class RandomAccessIterator, class T>
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 <class RandomAccessIterator, class T, class Compare>
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 <class ForwardIterator, class T, class Distance>
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 <class RandomAccessIterator, class T, class Distance>
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 <class ForwardIterator, class T, class Compare, class Distance>
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 <class RandomAccessIterator, class T, class Compare, class Distance>
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 <class ForwardIterator, class T, class Distance>
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 <class RandomAccessIterator, class T, class Distance>
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 <class ForwardIterator, class T, class Compare, class Distance>
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 <class RandomAccessIterator, class T, class Compare, class Distance>
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 <class ForwardIterator, class T, class Distance>
pair<ForwardIterator, ForwardIterator>
__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<ForwardIterator, ForwardIterator> tmp(left, right);
return tmp;
}
}
pair<ForwardIterator, ForwardIterator> tmp(first, first);
return tmp;
}
template <class RandomAccessIterator, class T, class Distance>
pair<RandomAccessIterator, RandomAccessIterator>
__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<RandomAccessIterator,RandomAccessIterator> tmp(left,right);
return tmp;
}
}
pair<RandomAccessIterator, RandomAccessIterator> tmp(first, first);
return tmp;
}
template <class ForwardIterator, class T, class Compare, class Distance>
pair<ForwardIterator, ForwardIterator>
__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<ForwardIterator, ForwardIterator> tmp(left, right);
return tmp;
}
}
pair<ForwardIterator, ForwardIterator> tmp(first, first);
return tmp;
}
template <class RandomAccessIterator, class T, class Compare, class Distance>
pair<RandomAccessIterator, RandomAccessIterator>
__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<RandomAccessIterator,RandomAccessIterator> tmp(left, right);
return tmp;
}
}
pair<RandomAccessIterator, RandomAccessIterator> tmp(first, first);
return tmp;
}
//
// Merge
//
template <class InputIterator1, class InputIterator2, class OutputIterator>
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 <class InputIterator1, class InputIterator2, class OutputIterator,
class Compare>
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 <class BidirectionalIterator, class Distance>
void __merge_without_buffer (BidirectionalIterator first,
BidirectionalIterator middle,
BidirectionalIterator last,
Distance len1, Distance len2)
{
if (len1 == 0 || len2 == 0) return;
if (len1 + len2 == 2)
{
if (*middle < *first) 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 <class BidirectionalIterator, class Distance, class Compare>
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 <class BidirectionalIterator1, class BidirectionalIterator2,
class Distance>
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 <class BidirectionalIterator1, class BidirectionalIterator2,
class BidirectionalIterator3>
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 <class BidirectionalIterator1, class BidirectionalIterator2,
class BidirectionalIterator3, class Compare>
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 <class BidirectionalIterator, class Distance, class Pointer, class T>
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 <class BidirectionalIterator, class Distance, class Pointer, class T,
class Compare>
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 <class BidirectionalIterator, class Distance, class Pointer, class T>
void __inplace_merge (BidirectionalIterator first,
BidirectionalIterator middle,
BidirectionalIterator last, Distance len1,
Distance len2, pair<Pointer, Distance> 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<Pointer, T>(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 <class BidirectionalIterator, class Distance, class Pointer, class T,
class Compare>
void __inplace_merge (BidirectionalIterator first,
BidirectionalIterator middle,
BidirectionalIterator last, Distance len1,
Distance len2, pair<Pointer, Distance> 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<Pointer, T>(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 <class InputIterator1, class InputIterator2>
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 <class InputIterator1, class InputIterator2, class Compare>
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 <class InputIterator1, class InputIterator2, class OutputIterator>
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 <class InputIterator1, class InputIterator2, class OutputIterator,
class Compare>
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 <class InputIterator1, class InputIterator2, class OutputIterator>
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 <class InputIterator1, class InputIterator2, class OutputIterator,
class Compare>
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 <class InputIterator1, class InputIterator2, class OutputIterator>
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 <class InputIterator1, class InputIterator2, class OutputIterator,
class Compare>
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 <class InputIterator1, class InputIterator2, class OutputIterator>
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 <class InputIterator1, class InputIterator2, class OutputIterator,
class Compare>
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 <class RandomAccessIterator, class Distance, class T>
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 <class RandomAccessIterator, class Distance, class T, class Compare>
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 <class RandomAccessIterator, class Distance, class T>
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 <class RandomAccessIterator, class Distance, class T, class Compare>
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 <class RandomAccessIterator, class T, class Distance>
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 <class RandomAccessIterator, class Compare, class T, class Distance>
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 <class RandomAccessIterator>
void sort_heap (RandomAccessIterator first, RandomAccessIterator last)
{
while (last - first > 1) pop_heap(first, last--);
}
template <class RandomAccessIterator, class Compare>
void sort_heap (RandomAccessIterator first, RandomAccessIterator last,
Compare _RWSTD_COMP)
{
while (last - first > 1) pop_heap(first, last--, _RWSTD_COMP);
}
//
// Minimum and maximum.
//
template <class ForwardIterator>
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 <class ForwardIterator, class Compare>
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 <class ForwardIterator>
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 <class ForwardIterator, class Compare>
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 <class InputIterator1, class InputIterator2>
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 <class InputIterator1, class InputIterator2, class Compare>
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 <class BidirectionalIterator>
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 <class BidirectionalIterator, class Compare>
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 <class BidirectionalIterator>
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 <class BidirectionalIterator, class Compare>
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 */