4 * Hewlett-Packard Company
6 * Copyright (c) 1996,1997
7 * Silicon Graphics Computer Systems, Inc.
10 * Moscow Center for SPARC Technology
15 * This material is provided "as is", with absolutely no warranty expressed
16 * or implied. Any use is at your own risk.
18 * Permission to use or copy this software for any purpose is hereby granted
19 * without fee, provided the above notices are retained on all copies.
20 * Permission to modify the code and to distribute modified code is granted,
21 * provided the above notices are retained, and a notice that the code was
22 * modified is included with the above copyright notice.
29 # if !defined (_STLP_INTERNAL_ALGO_H)
30 # include <stl/_algo.h>
35 template <class _BidirectionalIter, class _Distance, class _Compare>
36 void __merge_without_buffer(_BidirectionalIter __first,
37 _BidirectionalIter __middle,
38 _BidirectionalIter __last,
39 _Distance __len1, _Distance __len2,
43 template <class _BidirectionalIter1, class _BidirectionalIter2,
44 class _BidirectionalIter3, class _Compare>
45 _BidirectionalIter3 __merge_backward(_BidirectionalIter1 __first1,
46 _BidirectionalIter1 __last1,
47 _BidirectionalIter2 __first2,
48 _BidirectionalIter2 __last2,
49 _BidirectionalIter3 __result,
53 # if !(defined (__SUNPRO_CC) && (__SUNPRO_CC < 0x420 ))
56 const _Tp& __median(const _Tp& __a, const _Tp& __b, const _Tp& __c) {
72 template <class _Tp, class _Compare>
73 # if !(defined (__SUNPRO_CC) && (__SUNPRO_CC < 0x420 ))
77 __median(const _Tp& __a, const _Tp& __b, const _Tp& __c, _Compare __comp) {
81 else if (__comp(__a, __c))
85 else if (__comp(__a, __c))
87 else if (__comp(__b, __c))
93 template <class _ForwardIter1, class _ForwardIter2>
94 _ForwardIter1 search(_ForwardIter1 __first1, _ForwardIter1 __last1,
95 _ForwardIter2 __first2, _ForwardIter2 __last2)
97 _STLP_DEBUG_CHECK(__check_range(__first1, __last1))
98 _STLP_DEBUG_CHECK(__check_range(__first2, __last2))
99 // Test for empty ranges
100 if (__first1 == __last1 || __first2 == __last2)
103 // Test for a pattern of length 1.
104 _ForwardIter2 __tmp(__first2);
106 if (__tmp == __last2)
107 return find(__first1, __last1, *__first2);
110 _ForwardIter2 __p1 = __first2;
113 _ForwardIter1 __current = __first1;
115 while (__first1 != __last1) {
116 __first1 = find(__first1, __last1, *__first2);
117 if (__first1 == __last1)
120 _ForwardIter2 __p = __p1;
121 __current = __first1;
122 if (++__current == __last1)
125 while (*__current == *__p) {
126 if (++__p == __last2)
128 if (++__current == __last1)
137 // search_n. Search for __count consecutive copies of __val.
139 template <class _ForwardIter, class _Integer, class _Tp>
140 _ForwardIter search_n(_ForwardIter __first, _ForwardIter __last,
141 _Integer __count, const _Tp& __val) {
142 _STLP_DEBUG_CHECK(__check_range(__first, __last))
146 __first = find(__first, __last, __val);
147 while (__first != __last) {
148 _Integer __n = __count - 1;
149 _ForwardIter __i = __first;
151 while (__i != __last && __n != 0 && *__i == __val) {
158 __first = find(__i, __last, __val);
164 template <class _ForwardIter, class _Integer, class _Tp, class _BinaryPred>
165 _ForwardIter search_n(_ForwardIter __first, _ForwardIter __last,
166 _Integer __count, const _Tp& __val,
167 _BinaryPred __binary_pred) {
168 _STLP_DEBUG_CHECK(__check_range(__first, __last))
172 while (__first != __last) {
173 if (__binary_pred(*__first, __val))
177 while (__first != __last) {
178 _Integer __n = __count - 1;
179 _ForwardIter __i = __first;
181 while (__i != __last && __n != 0 && __binary_pred(*__i, __val)) {
188 while (__i != __last) {
189 if (__binary_pred(*__i, __val))
200 template <class _ForwardIter1, class _ForwardIter2>
202 find_end(_ForwardIter1 __first1, _ForwardIter1 __last1,
203 _ForwardIter2 __first2, _ForwardIter2 __last2)
205 _STLP_DEBUG_CHECK(__check_range(__first1, __last1))
206 _STLP_DEBUG_CHECK(__check_range(__first2, __last2))
207 return __find_end(__first1, __last1, __first2, __last2,
208 # if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
209 _STLP_ITERATOR_CATEGORY(__first1, _ForwardIter1),
210 _STLP_ITERATOR_CATEGORY(__first2, _ForwardIter2),
212 forward_iterator_tag(),
213 forward_iterator_tag(),
215 __equal_to(_STLP_VALUE_TYPE(__first1, _ForwardIter1))
219 // unique and unique_copy
220 template <class _InputIterator, class _OutputIterator, class _BinaryPredicate,
222 _STLP_INLINE_LOOP _OutputIterator
223 __unique_copy(_InputIterator __first, _InputIterator __last,
224 _OutputIterator __result,
225 _BinaryPredicate __binary_pred, _Tp*) {
226 _Tp __val = *__first;
227 _STLP_PUSH_STACK_ITEM(_Tp, &__val)
229 while (++__first != __last)
230 if (!__binary_pred(__val, *__first)) {
237 template <class _InputIter, class _OutputIter, class _BinaryPredicate>
239 __unique_copy(_InputIter __first, _InputIter __last,_OutputIter __result,
240 _BinaryPredicate __binary_pred, const output_iterator_tag &) {
241 return __unique_copy(__first, __last, __result, __binary_pred, _STLP_VALUE_TYPE(__first, _InputIter));
244 template <class _InputIter, class _ForwardIter, class _BinaryPredicate>
245 _STLP_INLINE_LOOP _ForwardIter
246 __unique_copy(_InputIter __first, _InputIter __last, _ForwardIter __result,
247 _BinaryPredicate __binary_pred, const forward_iterator_tag &) {
248 *__result = *__first;
249 while (++__first != __last)
250 if (!__binary_pred(*__result, *__first)) *++__result = *__first;
254 # if defined (_STLP_NONTEMPL_BASE_MATCH_BUG)
255 template <class _InputIterator, class _BidirectionalIterator, class _BinaryPredicate>
256 inline _BidirectionalIterator
257 __unique_copy(_InputIterator __first, _InputIterator __last,
258 _BidirectionalIterator __result, _BinaryPredicate __binary_pred,
259 const bidirectional_iterator_tag &) {
260 return __unique_copy(__first, __last, __result, __binary_pred, forward_iterator_tag());
263 template <class _InputIterator, class _RandomAccessIterator, class _BinaryPredicate>
264 inline _RandomAccessIterator
265 __unique_copy(_InputIterator __first, _InputIterator __last,
266 _RandomAccessIterator __result, _BinaryPredicate __binary_pred,
267 const random_access_iterator_tag &) {
268 return __unique_copy(__first, __last, __result, __binary_pred, forward_iterator_tag());
270 # endif /* _STLP_NONTEMPL_BASE_MATCH_BUG */
273 template <class _InputIter, class _OutputIter>
275 unique_copy(_InputIter __first, _InputIter __last, _OutputIter __result) {
276 _STLP_DEBUG_CHECK(__check_range(__first, __last))
277 if (__first == __last) return __result;
278 return __unique_copy(__first, __last, __result, __equal_to(_STLP_VALUE_TYPE(__first, _InputIter)),
279 _STLP_ITERATOR_CATEGORY(__result, _OutputIter));
282 template <class _InputIter, class _OutputIter, class _BinaryPredicate>
284 unique_copy(_InputIter __first, _InputIter __last,_OutputIter __result,
285 _BinaryPredicate __binary_pred) {
286 _STLP_DEBUG_CHECK(__check_range(__first, __last))
287 if (__first == __last) return __result;
288 return __unique_copy(__first, __last, __result, __binary_pred,
289 _STLP_ITERATOR_CATEGORY(__result, _OutputIter));
292 // rotate and rotate_copy, and their auxiliary functions
294 template <class _ForwardIter, class _Distance>
295 _ForwardIter __rotate(_ForwardIter __first,
296 _ForwardIter __middle,
299 const forward_iterator_tag &) {
300 if (__first == __middle)
302 if (__last == __middle)
305 _ForwardIter __first2 = __middle;
307 swap(*__first++, *__first2++);
308 if (__first == __middle)
310 } while (__first2 != __last);
312 _ForwardIter __new_middle = __first;
316 while (__first2 != __last) {
317 swap (*__first++, *__first2++);
318 if (__first == __middle)
320 else if (__first2 == __last)
327 template <class _BidirectionalIter, class _Distance>
328 _BidirectionalIter __rotate(_BidirectionalIter __first,
329 _BidirectionalIter __middle,
330 _BidirectionalIter __last,
332 const bidirectional_iterator_tag &) {
333 if (__first == __middle)
335 if (__last == __middle)
338 __reverse(__first, __middle, bidirectional_iterator_tag());
339 __reverse(__middle, __last, bidirectional_iterator_tag());
341 while (__first != __middle && __middle != __last)
342 swap (*__first++, *--__last);
344 if (__first == __middle) {
345 __reverse(__middle, __last, bidirectional_iterator_tag());
349 __reverse(__first, __middle, bidirectional_iterator_tag());
354 template <class _RandomAccessIter, class _Distance, class _Tp>
355 _RandomAccessIter __rotate(_RandomAccessIter __first,
356 _RandomAccessIter __middle,
357 _RandomAccessIter __last,
358 _Distance *, _Tp *) {
360 _Distance __n = __last - __first;
361 _Distance __k = __middle - __first;
362 _Distance __l = __n - __k;
363 _RandomAccessIter __result = __first + (__last - __middle);
365 if (__k==0) /* __first == middle */
369 swap_ranges(__first, __middle, __middle);
373 _Distance __d = __gcd(__n, __k);
375 for (_Distance __i = 0; __i < __d; __i++) {
376 _Tp __tmp = *__first;
377 _STLP_PUSH_STACK_ITEM(_Tp, &__tmp)
378 _RandomAccessIter __p = __first;
381 for (_Distance __j = 0; __j < __l/__d; __j++) {
382 if (__p > __first + __l) {
393 for (_Distance __j = 0; __j < __k/__d - 1; __j ++) {
394 if (__p < __last - __k) {
399 *__p = * (__p - __l);
411 template <class _RandomAccessIter, class _Distance>
412 inline _RandomAccessIter
413 __rotate(_RandomAccessIter __first, _RandomAccessIter __middle, _RandomAccessIter __last,
414 _Distance * __dis, const random_access_iterator_tag &) {
415 return __rotate(__first, __middle, __last,
416 __dis, _STLP_VALUE_TYPE(__first, _RandomAccessIter));
419 template <class _ForwardIter>
421 rotate(_ForwardIter __first, _ForwardIter __middle, _ForwardIter __last) {
422 _STLP_DEBUG_CHECK(__check_range(__first, __middle))
423 _STLP_DEBUG_CHECK(__check_range(__middle, __last))
424 return __rotate(__first, __middle, __last,
425 _STLP_DISTANCE_TYPE(__first, _ForwardIter),
426 _STLP_ITERATOR_CATEGORY(__first, _ForwardIter));
429 // Return a random number in the range [0, __n). This function encapsulates
430 // whether we're using rand (part of the standard C library) or lrand48
431 // (not standard, but a much better choice whenever it's available).
433 template <class _Distance>
434 inline _Distance __random_number(_Distance __n) {
435 #ifdef _STLP_NO_DRAND48
438 return lrand48() % __n;
442 template <class _RandomAccessIter>
443 void random_shuffle(_RandomAccessIter __first,
444 _RandomAccessIter __last) {
445 _STLP_DEBUG_CHECK(__check_range(__first, __last))
446 if (__first == __last) return;
447 for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i)
448 iter_swap(__i, __first + __random_number((__i - __first) + 1));
451 template <class _RandomAccessIter, class _RandomNumberGenerator>
452 void random_shuffle(_RandomAccessIter __first, _RandomAccessIter __last,
453 _RandomNumberGenerator& __rand) {
454 _STLP_DEBUG_CHECK(__check_range(__first, __last))
455 if (__first == __last) return;
456 for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i)
457 iter_swap(__i, __first + __rand((__i - __first) + 1));
460 # ifndef _STLP_NO_EXTENSIONS
462 // random_sample and random_sample_n (extensions, not part of the standard).
464 template <class _ForwardIter, class _OutputIter, class _Distance>
465 _OutputIter random_sample_n(_ForwardIter __first, _ForwardIter __last,
466 _OutputIter __stl_out, const _Distance __n)
468 _STLP_DEBUG_CHECK(__check_range(__first, __last))
469 _Distance __remaining = distance(__first, __last);
470 _Distance __m = (min) (__n, __remaining);
473 if (__random_number(__remaining) < __m) {
474 *__stl_out = *__first;
486 template <class _ForwardIter, class _OutputIter, class _Distance,
487 class _RandomNumberGenerator>
488 _OutputIter random_sample_n(_ForwardIter __first, _ForwardIter __last,
489 _OutputIter __stl_out, const _Distance __n,
490 _RandomNumberGenerator& __rand)
492 _STLP_DEBUG_CHECK(__check_range(__first, __last))
493 _Distance __remaining = distance(__first, __last);
494 _Distance __m = (min) (__n, __remaining);
497 if (__rand(__remaining) < __m) {
498 *__stl_out = *__first;
509 template <class _InputIter, class _RandomAccessIter, class _Distance>
510 _RandomAccessIter __random_sample(_InputIter __first, _InputIter __last,
511 _RandomAccessIter __stl_out,
516 for ( ; __first != __last && __m < __n; ++__m, ++__first)
517 __stl_out[__m] = *__first;
519 while (__first != __last) {
521 _Distance __M = __random_number(__t);
523 __stl_out[__M] = *__first;
527 return __stl_out + __m;
530 template <class _InputIter, class _RandomAccessIter,
531 class _RandomNumberGenerator, class _Distance>
532 _RandomAccessIter __random_sample(_InputIter __first, _InputIter __last,
533 _RandomAccessIter __stl_out,
534 _RandomNumberGenerator& __rand,
539 for ( ; __first != __last && __m < __n; ++__m, ++__first)
540 __stl_out[__m] = *__first;
542 while (__first != __last) {
544 _Distance __M = __rand(__t);
546 __stl_out[__M] = *__first;
550 return __stl_out + __m;
553 template <class _InputIter, class _RandomAccessIter>
555 random_sample(_InputIter __first, _InputIter __last,
556 _RandomAccessIter __out_first, _RandomAccessIter __out_last)
558 _STLP_DEBUG_CHECK(__check_range(__first, __last))
559 _STLP_DEBUG_CHECK(__check_range(__out_first, __out_last))
560 return __random_sample(__first, __last,
561 __out_first, __out_last - __out_first);
564 template <class _InputIter, class _RandomAccessIter, class _RandomNumberGenerator>
566 random_sample(_InputIter __first, _InputIter __last,
567 _RandomAccessIter __out_first, _RandomAccessIter __out_last,
568 _RandomNumberGenerator& __rand)
570 _STLP_DEBUG_CHECK(__check_range(__first, __last))
571 _STLP_DEBUG_CHECK(__check_range(__out_first, __out_last))
572 return __random_sample(__first, __last,
574 __out_last - __out_first);
577 # endif /* _STLP_NO_EXTENSIONS */
579 // partition, stable_partition, and their auxiliary functions
581 template <class _ForwardIter, class _Predicate>
582 _STLP_INLINE_LOOP _ForwardIter __partition(_ForwardIter __first,
585 const forward_iterator_tag &) {
586 if (__first == __last) return __first;
588 while (__pred(*__first))
589 if (++__first == __last) return __first;
591 _ForwardIter __next = __first;
593 while (++__next != __last)
594 if (__pred(*__next)) {
595 swap(*__first, *__next);
603 template <class _ForwardIter>
605 __rotate(_ForwardIter __first, _ForwardIter __middle, _ForwardIter __last) {
606 _STLP_DEBUG_CHECK(__check_range(__first, __middle))
607 _STLP_DEBUG_CHECK(__check_range(__middle, __last))
608 return __rotate_aux(__first, __middle, __last,
609 _STLP_DISTANCE_TYPE(__first, _ForwardIter),
610 _STLP_ITERATOR_CATEGORY(__first, _ForwardIter));
613 template <class _ForwardIter, class _Distance>
614 _ForwardIter __rotate_aux(_ForwardIter __first,
615 _ForwardIter __middle,
618 const forward_iterator_tag &) {
619 if (__first == __middle)
621 if (__last == __middle)
624 _ForwardIter __first2 = __middle;
626 swap(*__first++, *__first2++);
627 if (__first == __middle)
629 } while (__first2 != __last);
631 _ForwardIter __new_middle = __first;
635 while (__first2 != __last) {
636 swap (*__first++, *__first2++);
637 if (__first == __middle)
639 else if (__first2 == __last)
647 template <class _ForwardIter, class _Pointer, class _Predicate,
649 _ForwardIter __stable_partition_adaptive(_ForwardIter __first,
651 _Predicate __pred, _Distance __len,
652 _Pointer __buffer, _Distance __buffer_size,
653 bool __pred_of_first, bool __pred_of_before_last) {
654 if (__len <= __buffer_size) {
655 _ForwardIter __result1 = __first;
656 _Pointer __result2 = __buffer;
657 if ((__first != __last) && (!__pred_of_first || __pred(*__first))) {
658 *__result2 = *__first;
659 ++__result2; ++__first; --__len;
661 for (; __first != __last ; ++__first, --__len) {
662 if (((__len == 1) && (__pred_of_before_last || __pred(*__first))) ||
663 ((__len != 1) && __pred(*__first))){
664 *__result1 = *__first;
668 *__result2 = *__first;
672 copy(__buffer, __result2, __result1);
676 _ForwardIter __middle = __first;
677 _Distance __half_len = __len / 2;
678 advance(__middle, __half_len);
679 return __rotate(__stable_partition_adaptive(
680 __first, __middle, __pred,
681 __half_len, __buffer, __buffer_size,
682 __pred_of_first, false),
684 __stable_partition_adaptive(
685 __middle, __last, __pred,
686 __len - __half_len, __buffer, __buffer_size,
687 true, __pred_of_before_last));
692 template <class _ForwardIter, class _Predicate, class _Distance>
693 _ForwardIter __inplace_stable_partition(_ForwardIter __first,
695 _Predicate __pred, _Distance __len,
696 bool __pred_of_first, bool __pred_of_before_last) {
698 return (__pred_of_first && (__pred_of_before_last || __pred(*__first))) ? __last : __first;
699 _ForwardIter __middle = __first;
700 _Distance __half_len = __len / 2;
701 advance(__middle, __half_len);
702 return __rotate(__inplace_stable_partition(__first, __middle, __pred, __half_len, __pred_of_first, false),
704 __inplace_stable_partition(__middle, __last, __pred, __len - __half_len, true, __pred_of_before_last));
709 template <class _ForwardIter, class _Predicate>
711 stable_partition(_ForwardIter __first, _ForwardIter __last, _Predicate __pred) {
712 _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first, __last))
714 if (__first == __last)
716 else if (__pred(*__first))
721 return __stable_partition_aux(__first, __last, __pred,
722 _STLP_ITERATOR_CATEGORY(__first, _ForwardIter));
726 template <class _ForwardIter, class _Predicate, class _Tp, class _Distance>
728 __stable_partition_aux_aux(_ForwardIter __first, _ForwardIter __last,
729 _Predicate __pred, _Tp*, _Distance*, bool __pred_of_before_last = false) {
730 _Temporary_buffer<_ForwardIter, _Tp> __buf(__first, __last);
731 return (__buf.size() > 0) ?
732 __stable_partition_adaptive(__first, __last, __pred,
733 _Distance(__buf.requested_size()),
734 __buf.begin(), __buf.size(),
735 false, __pred_of_before_last) :
736 __inplace_stable_partition(__first, __last, __pred,
737 _Distance(__buf.requested_size()),
738 false, __pred_of_before_last);
742 template <class _ForwardIter, class _Predicate>
744 __stable_partition_aux(_ForwardIter __first, _ForwardIter __last, _Predicate __pred,
745 const forward_iterator_tag &) {
746 return __stable_partition_aux_aux(__first, __last, __pred,
747 _STLP_VALUE_TYPE(__first, _ForwardIter),
748 _STLP_DISTANCE_TYPE(__first, _ForwardIter));
756 template <class _BidirectionalIter, class _Predicate>
757 _STLP_INLINE_LOOP _BidirectionalIter __partition(_BidirectionalIter __first,
758 _BidirectionalIter __last,
760 const bidirectional_iterator_tag &) {
763 if (__first == __last)
765 else if (__pred(*__first))
771 if (__first == __last)
773 else if (!__pred(*__last))
777 iter_swap(__first, __last);
782 # if defined (_STLP_NONTEMPL_BASE_MATCH_BUG)
783 template <class _BidirectionalIter, class _Predicate>
785 _BidirectionalIter __partition(_BidirectionalIter __first,
786 _BidirectionalIter __last,
788 const random_access_iterator_tag &) {
789 return __partition(__first, __last, __pred, bidirectional_iterator_tag());
793 template <class _ForwardIter, class _Predicate>
794 _ForwardIter partition(_ForwardIter __first, _ForwardIter __last, _Predicate __pred) {
795 _STLP_DEBUG_CHECK(__check_range(__first, __last))
796 return __partition(__first, __last, __pred, _STLP_ITERATOR_CATEGORY(__first, _ForwardIter));
800 template <class _ForwardIter, class _Predicate, class _Distance>
801 _ForwardIter __inplace_stable_partition(_ForwardIter __first,
803 _Predicate __pred, _Distance __len) {
805 return __pred(*__first) ? __last : __first;
806 _ForwardIter __middle = __first;
807 advance(__middle, __len / 2);
808 return rotate(__inplace_stable_partition(__first, __middle, __pred,
811 __inplace_stable_partition(__middle, __last, __pred,
816 template <class _ForwardIter, class _Pointer, class _Predicate,
818 _ForwardIter __stable_partition_adaptive(_ForwardIter __first,
820 _Predicate __pred, _Distance __len,
822 _Distance __buffer_size)
824 if (__len <= __buffer_size) {
825 _ForwardIter __result1 = __first;
826 _Pointer __result2 = __buffer;
827 for ( ; __first != __last ; ++__first)
828 if (__pred(*__first)) {
829 *__result1 = *__first;
833 *__result2 = *__first;
836 copy(__buffer, __result2, __result1);
840 _ForwardIter __middle = __first;
841 advance(__middle, __len / 2);
842 return rotate(__stable_partition_adaptive(
843 __first, __middle, __pred,
844 _Distance(__len / 2), __buffer, __buffer_size),
846 __stable_partition_adaptive(
847 __middle, __last, __pred,
848 _Distance(__len - __len / 2), __buffer, __buffer_size));
852 template <class _ForwardIter, class _Predicate, class _Tp, class _Distance>
854 __stable_partition_aux(_ForwardIter __first, _ForwardIter __last,
855 _Predicate __pred, _Tp*, _Distance*)
857 typedef _Temporary_buffer<_ForwardIter, _Tp> _TmpBuf;
858 _Temporary_buffer<_ForwardIter, _Tp> __buf(__first, __last);
859 _STLP_PUSH_STACK_ITEM(_TmpBuf, &__buf);
861 _STLP_MPWFIX_TRY //*TY 06/01/2000 - they forget to call dtor for _Temporary_buffer if no try/catch block is present
862 return (__buf.size() > 0) ?
863 __stable_partition_adaptive(__first, __last, __pred,
864 _Distance(__buf.requested_size()),
865 __buf.begin(), _Distance(__buf.size())) :
866 __inplace_stable_partition(__first, __last, __pred,
867 _Distance(__buf.requested_size()));
868 _STLP_MPWFIX_CATCH //*TY 06/01/2000 - they forget to call dtor for _Temporary_buffer if no try/catch block is present
871 template <class _ForwardIter, class _Predicate>
873 stable_partition(_ForwardIter __first, _ForwardIter __last, _Predicate __pred) {
874 _STLP_DEBUG_CHECK(__check_range(__first, __last))
875 if (__first == __last)
878 return __stable_partition_aux(__first, __last, __pred,
879 _STLP_VALUE_TYPE(__first, _ForwardIter),
880 _STLP_DISTANCE_TYPE(__first, _ForwardIter));
883 template <class _RandomAccessIter, class _Tp, class _Compare>
884 _RandomAccessIter __unguarded_partition(_RandomAccessIter __first,
885 _RandomAccessIter __last,
886 _Tp __pivot, _Compare __comp)
888 _STLP_PUSH_STACK_ITEM(_Tp, &__pivot)
890 while (__comp(*__first, __pivot))
893 while (__comp(__pivot, *__last))
895 if (!(__first < __last))
897 iter_swap(__first, __last);
902 // sort() and its auxiliary functions.
904 # define __stl_threshold 16
906 template <class _RandomAccessIter, class _Tp, class _Compare>
907 void __unguarded_linear_insert(_RandomAccessIter __last, _Tp __val,
909 _STLP_PUSH_STACK_ITEM(_Tp, &__val)
910 _RandomAccessIter __next = __last;
912 while (__comp(__val, *__next)) {
920 template <class _RandomAccessIter, class _Tp, class _Compare>
921 inline void __linear_insert(_RandomAccessIter __first,
922 _RandomAccessIter __last, _Tp __val, _Compare __comp) {
923 _STLP_PUSH_STACK_ITEM(_Tp, &__val)
924 if (__comp(__val, *__first)) {
925 copy_backward(__first, __last, __last + 1);
929 __unguarded_linear_insert(__last, __val, __comp);
932 template <class _RandomAccessIter, class _Compare>
933 void __insertion_sort(_RandomAccessIter __first,
934 _RandomAccessIter __last, _Compare __comp) {
935 if (__first == __last) return;
936 for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i)
937 __linear_insert(__first, __i, *__i, __comp); //*TY 12/26/1998 - supply *__i as __val
940 template <class _RandomAccessIter, class _Tp, class _Compare>
941 void __unguarded_insertion_sort_aux(_RandomAccessIter __first,
942 _RandomAccessIter __last,
943 _Tp*, _Compare __comp) {
944 for (_RandomAccessIter __i = __first; __i != __last; ++__i)
945 __unguarded_linear_insert(__i, _Tp(*__i), __comp);
948 template <class _RandomAccessIter, class _Compare>
949 inline void __unguarded_insertion_sort(_RandomAccessIter __first,
950 _RandomAccessIter __last,
952 __unguarded_insertion_sort_aux(__first, __last, _STLP_VALUE_TYPE(__first, _RandomAccessIter), __comp);
955 template <class _RandomAccessIter, class _Compare>
956 void __final_insertion_sort(_RandomAccessIter __first,
957 _RandomAccessIter __last, _Compare __comp) {
958 if (__last - __first > __stl_threshold) {
959 __insertion_sort(__first, __first + __stl_threshold, __comp);
960 __unguarded_insertion_sort(__first + __stl_threshold, __last, __comp);
963 __insertion_sort(__first, __last, __comp);
966 template <class _RandomAccessIter, class _Tp, class _Size, class _Compare>
967 void __introsort_loop(_RandomAccessIter __first,
968 _RandomAccessIter __last, _Tp*,
969 _Size __depth_limit, _Compare __comp)
971 while (__last - __first > __stl_threshold) {
972 if (__depth_limit == 0) {
973 partial_sort(__first, __last, __last, __comp);
977 _RandomAccessIter __cut =
978 __unguarded_partition(__first, __last,
979 _Tp(__median(*__first,
980 *(__first + (__last - __first)/2),
981 *(__last - 1), __comp)),
983 __introsort_loop(__cut, __last, (_Tp*) 0, __depth_limit, __comp);
988 template <class _RandomAccessIter>
989 void sort(_RandomAccessIter __first, _RandomAccessIter __last) {
990 _STLP_DEBUG_CHECK(__check_range(__first, __last))
991 if (__first != __last) {
992 __introsort_loop(__first, __last,
993 _STLP_VALUE_TYPE(__first, _RandomAccessIter),
994 __lg(__last - __first) * 2, __less(_STLP_VALUE_TYPE(__first, _RandomAccessIter)) );
995 __final_insertion_sort(__first, __last, __less(_STLP_VALUE_TYPE(__first, _RandomAccessIter)));
999 template <class _RandomAccessIter, class _Compare>
1000 void sort(_RandomAccessIter __first, _RandomAccessIter __last, _Compare __comp) {
1001 _STLP_DEBUG_CHECK(__check_range(__first, __last))
1002 if (__first != __last) {
1003 __introsort_loop(__first, __last,
1004 _STLP_VALUE_TYPE(__first, _RandomAccessIter),
1005 __lg(__last - __first) * 2,
1007 __final_insertion_sort(__first, __last, __comp);
1011 // stable_sort() and its auxiliary functions.
1013 template <class _RandomAccessIter, class _Compare>
1014 void __inplace_stable_sort(_RandomAccessIter __first,
1015 _RandomAccessIter __last, _Compare __comp) {
1016 if (__last - __first < 15) {
1017 __insertion_sort(__first, __last, __comp);
1020 _RandomAccessIter __middle = __first + (__last - __first) / 2;
1021 __inplace_stable_sort(__first, __middle, __comp);
1022 __inplace_stable_sort(__middle, __last, __comp);
1023 __merge_without_buffer(__first, __middle, __last,
1029 template <class _RandomAccessIter1, class _RandomAccessIter2,
1030 class _Distance, class _Compare>
1031 void __merge_sort_loop(_RandomAccessIter1 __first,
1032 _RandomAccessIter1 __last,
1033 _RandomAccessIter2 __result, _Distance __step_size,
1035 _Distance __two_step = 2 * __step_size;
1037 while (__last - __first >= __two_step) {
1038 __result = merge(__first, __first + __step_size,
1039 __first + __step_size, __first + __two_step,
1042 __first += __two_step;
1044 __step_size = (min) (_Distance(__last - __first), __step_size);
1046 merge(__first, __first + __step_size,
1047 __first + __step_size, __last,
1052 const int __stl_chunk_size = 7;
1054 template <class _RandomAccessIter, class _Distance, class _Compare>
1055 void __chunk_insertion_sort(_RandomAccessIter __first,
1056 _RandomAccessIter __last,
1057 _Distance __chunk_size, _Compare __comp)
1059 while (__last - __first >= __chunk_size) {
1060 __insertion_sort(__first, __first + __chunk_size, __comp);
1061 __first += __chunk_size;
1063 __insertion_sort(__first, __last, __comp);
1066 template <class _RandomAccessIter, class _Pointer, class _Distance,
1068 void __merge_sort_with_buffer(_RandomAccessIter __first,
1069 _RandomAccessIter __last, _Pointer __buffer,
1070 _Distance*, _Compare __comp) {
1071 _Distance __len = __last - __first;
1072 _Pointer __buffer_last = __buffer + __len;
1074 _Distance __step_size = __stl_chunk_size;
1075 __chunk_insertion_sort(__first, __last, __step_size, __comp);
1077 while (__step_size < __len) {
1078 __merge_sort_loop(__first, __last, __buffer, __step_size, __comp);
1080 __merge_sort_loop(__buffer, __buffer_last, __first, __step_size, __comp);
1085 template <class _BidirectionalIter1, class _BidirectionalIter2,
1087 _BidirectionalIter1 __rotate_adaptive(_BidirectionalIter1 __first,
1088 _BidirectionalIter1 __middle,
1089 _BidirectionalIter1 __last,
1090 _Distance __len1, _Distance __len2,
1091 _BidirectionalIter2 __buffer,
1092 _Distance __buffer_size) {
1093 if (__len1 > __len2 && __len2 <= __buffer_size) {
1094 _BidirectionalIter2 __buffer_end = copy(__middle, __last, __buffer);
1095 copy_backward(__first, __middle, __last);
1096 return copy(__buffer, __buffer_end, __first);
1098 else if (__len1 <= __buffer_size) {
1099 _BidirectionalIter2 __buffer_end = copy(__first, __middle, __buffer);
1100 copy(__middle, __last, __first);
1101 return copy_backward(__buffer, __buffer_end, __last);
1104 return rotate(__first, __middle, __last);
1107 template <class _BidirectionalIter, class _Distance, class _Pointer,
1109 void __merge_adaptive(_BidirectionalIter __first,
1110 _BidirectionalIter __middle,
1111 _BidirectionalIter __last,
1112 _Distance __len1, _Distance __len2,
1113 _Pointer __buffer, _Distance __buffer_size,
1115 if (__len1 <= __len2 && __len1 <= __buffer_size) {
1116 _Pointer __buffer_end = copy(__first, __middle, __buffer);
1117 merge(__buffer, __buffer_end, __middle, __last, __first, __comp);
1119 else if (__len2 <= __buffer_size) {
1120 _Pointer __buffer_end = copy(__middle, __last, __buffer);
1121 __merge_backward(__first, __middle, __buffer, __buffer_end, __last,
1125 _BidirectionalIter __first_cut = __first;
1126 _BidirectionalIter __second_cut = __middle;
1127 _Distance __len11 = 0;
1128 _Distance __len22 = 0;
1129 if (__len1 > __len2) {
1130 __len11 = __len1 / 2;
1131 advance(__first_cut, __len11);
1132 __second_cut = lower_bound(__middle, __last, *__first_cut, __comp);
1133 __len22 += distance(__middle, __second_cut);
1136 __len22 = __len2 / 2;
1137 advance(__second_cut, __len22);
1138 __first_cut = upper_bound(__first, __middle, *__second_cut, __comp);
1139 __len11 += distance(__first, __first_cut);
1141 _BidirectionalIter __new_middle =
1142 __rotate_adaptive(__first_cut, __middle, __second_cut, __len1 - __len11,
1143 __len22, __buffer, __buffer_size);
1144 __merge_adaptive(__first, __first_cut, __new_middle, __len11,
1145 __len22, __buffer, __buffer_size, __comp);
1146 __merge_adaptive(__new_middle, __second_cut, __last, __len1 - __len11,
1147 __len2 - __len22, __buffer, __buffer_size, __comp);
1151 template <class _RandomAccessIter, class _Pointer, class _Distance,
1153 void __stable_sort_adaptive(_RandomAccessIter __first,
1154 _RandomAccessIter __last, _Pointer __buffer,
1155 _Distance __buffer_size, _Compare __comp) {
1156 _Distance __len = (__last - __first + 1) / 2;
1157 _RandomAccessIter __middle = __first + __len;
1158 if (__len > __buffer_size) {
1159 __stable_sort_adaptive(__first, __middle, __buffer, __buffer_size,
1161 __stable_sort_adaptive(__middle, __last, __buffer, __buffer_size,
1165 __merge_sort_with_buffer(__first, __middle, __buffer, (_Distance*)0,
1167 __merge_sort_with_buffer(__middle, __last, __buffer, (_Distance*)0,
1170 __merge_adaptive(__first, __middle, __last, _Distance(__middle - __first),
1171 _Distance(__last - __middle), __buffer, __buffer_size,
1175 template <class _RandomAccessIter, class _Tp, class _Distance, class _Compare>
1176 void __stable_sort_aux(_RandomAccessIter __first,
1177 _RandomAccessIter __last, _Tp*, _Distance*,
1180 typedef _Temporary_buffer<_RandomAccessIter, _Tp> _TmpBuf;
1181 _TmpBuf __buf(__first, __last);
1182 _STLP_PUSH_STACK_ITEM(_TmpBuf, &__buf);
1184 if (__buf.begin() == 0)
1185 __inplace_stable_sort(__first, __last, __comp);
1187 __stable_sort_adaptive(__first, __last, __buf.begin(),
1188 _Distance(__buf.size()),
1192 template <class _RandomAccessIter>
1193 void stable_sort(_RandomAccessIter __first,
1194 _RandomAccessIter __last) {
1195 _STLP_DEBUG_CHECK(__check_range(__first, __last))
1196 __stable_sort_aux(__first, __last,
1197 _STLP_VALUE_TYPE(__first, _RandomAccessIter),
1198 _STLP_DISTANCE_TYPE(__first, _RandomAccessIter),
1199 __less(_STLP_VALUE_TYPE(__first, _RandomAccessIter)));
1202 template <class _RandomAccessIter, class _Compare>
1203 void stable_sort(_RandomAccessIter __first,
1204 _RandomAccessIter __last, _Compare __comp) {
1205 _STLP_DEBUG_CHECK(__check_range(__first, __last))
1206 __stable_sort_aux(__first, __last,
1207 _STLP_VALUE_TYPE(__first, _RandomAccessIter),
1208 _STLP_DISTANCE_TYPE(__first, _RandomAccessIter),
1212 // partial_sort, partial_sort_copy, and auxiliary functions.
1214 template <class _RandomAccessIter, class _Tp, class _Compare>
1215 void __partial_sort(_RandomAccessIter __first, _RandomAccessIter __middle,
1216 _RandomAccessIter __last, _Tp*, _Compare __comp) {
1217 make_heap(__first, __middle, __comp);
1218 for (_RandomAccessIter __i = __middle; __i < __last; ++__i)
1219 if (__comp(*__i, *__first))
1220 __pop_heap(__first, __middle, __i, _Tp(*__i), __comp,
1221 _STLP_DISTANCE_TYPE(__first, _RandomAccessIter));
1222 sort_heap(__first, __middle, __comp);
1226 template <class _RandomAccessIter>
1228 partial_sort(_RandomAccessIter __first,_RandomAccessIter __middle, _RandomAccessIter __last) {
1229 _STLP_DEBUG_CHECK(__check_range(__first, __middle))
1230 _STLP_DEBUG_CHECK(__check_range(__middle, __last))
1231 __partial_sort(__first, __middle, __last, _STLP_VALUE_TYPE(__first, _RandomAccessIter),
1232 __less(_STLP_VALUE_TYPE(__first, _RandomAccessIter)));
1235 template <class _RandomAccessIter, class _Compare>
1236 void partial_sort(_RandomAccessIter __first,_RandomAccessIter __middle,
1237 _RandomAccessIter __last, _Compare __comp) {
1238 _STLP_DEBUG_CHECK(__check_range(__first, __middle))
1239 _STLP_DEBUG_CHECK(__check_range(__middle, __last))
1240 __partial_sort(__first, __middle, __last, _STLP_VALUE_TYPE(__first, _RandomAccessIter), __comp);
1243 template <class _InputIter, class _RandomAccessIter, class _Compare,
1244 class _Distance, class _Tp>
1245 _RandomAccessIter __partial_sort_copy(_InputIter __first,
1247 _RandomAccessIter __result_first,
1248 _RandomAccessIter __result_last,
1249 _Compare __comp, _Distance*, _Tp*) {
1250 if (__result_first == __result_last) return __result_last;
1251 _RandomAccessIter __result_real_last = __result_first;
1252 while(__first != __last && __result_real_last != __result_last) {
1253 *__result_real_last = *__first;
1254 ++__result_real_last;
1257 make_heap(__result_first, __result_real_last, __comp);
1258 while (__first != __last) {
1259 if (__comp(*__first, *__result_first))
1260 __adjust_heap(__result_first, _Distance(0),
1261 _Distance(__result_real_last - __result_first),
1266 sort_heap(__result_first, __result_real_last, __comp);
1267 return __result_real_last;
1270 template <class _InputIter, class _RandomAccessIter>
1272 partial_sort_copy(_InputIter __first, _InputIter __last,
1273 _RandomAccessIter __result_first, _RandomAccessIter __result_last) {
1274 _STLP_DEBUG_CHECK(__check_range(__first, __last))
1275 _STLP_DEBUG_CHECK(__check_range(__result_first, __result_last))
1276 return __partial_sort_copy(__first, __last, __result_first, __result_last,
1277 __less(_STLP_VALUE_TYPE(__first, _InputIter)),
1278 _STLP_DISTANCE_TYPE(__result_first, _RandomAccessIter),
1279 _STLP_VALUE_TYPE(__first, _InputIter));
1282 template <class _InputIter, class _RandomAccessIter, class _Compare>
1284 partial_sort_copy(_InputIter __first, _InputIter __last,
1285 _RandomAccessIter __result_first,
1286 _RandomAccessIter __result_last, _Compare __comp) {
1287 _STLP_DEBUG_CHECK(__check_range(__first, __last))
1288 _STLP_DEBUG_CHECK(__check_range(__result_first, __result_last))
1289 return __partial_sort_copy(__first, __last, __result_first, __result_last,
1291 _STLP_DISTANCE_TYPE(__result_first, _RandomAccessIter),
1292 _STLP_VALUE_TYPE(__first, _InputIter));
1295 // nth_element() and its auxiliary functions.
1297 template <class _RandomAccessIter, class _Tp, class _Compare>
1298 void __nth_element(_RandomAccessIter __first, _RandomAccessIter __nth,
1299 _RandomAccessIter __last, _Tp*, _Compare __comp) {
1300 while (__last - __first > 3) {
1301 _RandomAccessIter __cut =
1302 __unguarded_partition(__first, __last,
1303 _Tp(__median(*__first,
1304 *(__first + (__last - __first)/2),
1313 __insertion_sort(__first, __last, __comp);
1317 template <class _RandomAccessIter>
1318 void nth_element(_RandomAccessIter __first, _RandomAccessIter __nth,
1319 _RandomAccessIter __last) {
1320 _STLP_DEBUG_CHECK(__check_range(__first, __nth))
1321 _STLP_DEBUG_CHECK(__check_range(__nth, __last))
1322 __nth_element(__first, __nth, __last, _STLP_VALUE_TYPE(__first, _RandomAccessIter),
1323 __less(_STLP_VALUE_TYPE(__first, _RandomAccessIter)));
1326 template <class _RandomAccessIter, class _Compare>
1327 void nth_element(_RandomAccessIter __first, _RandomAccessIter __nth,
1328 _RandomAccessIter __last, _Compare __comp) {
1329 _STLP_DEBUG_CHECK(__check_range(__first, __nth))
1330 _STLP_DEBUG_CHECK(__check_range(__nth, __last))
1331 __nth_element(__first, __nth, __last, _STLP_VALUE_TYPE(__first, _RandomAccessIter), __comp);
1334 // Binary search (lower_bound, upper_bound, equal_range, binary_search).
1336 template <class _ForwardIter, class _Tp, class _Compare, class _Distance>
1337 _ForwardIter __upper_bound(_ForwardIter __first, _ForwardIter __last,
1338 const _Tp& __val, _Compare __comp, _Distance*)
1340 _Distance __len = distance(__first, __last);
1344 __half = __len >> 1;
1345 _ForwardIter __middle = __first;
1346 advance(__middle, __half);
1347 if (__comp(__val, *__middle))
1352 __len = __len - __half - 1;
1358 template <class _ForwardIter, class _Tp, class _Compare, class _Distance>
1359 pair<_ForwardIter, _ForwardIter>
1360 __equal_range(_ForwardIter __first, _ForwardIter __last, const _Tp& __val,
1361 _Compare __comp, _Distance*)
1363 _Distance __len = distance(__first, __last);
1367 __half = __len >> 1;
1368 _ForwardIter __middle = __first;
1369 advance(__middle, __half);
1370 if (__comp(*__middle, __val)) {
1373 __len = __len - __half - 1;
1375 else if (__comp(__val, *__middle))
1378 _ForwardIter __left = lower_bound(__first, __middle, __val, __comp);
1379 advance(__first, __len);
1380 _ForwardIter __right = upper_bound(++__middle, __first, __val, __comp);
1381 return pair<_ForwardIter, _ForwardIter>(__left, __right);
1384 return pair<_ForwardIter, _ForwardIter>(__first, __first);
1387 template <class _InputIter1, class _InputIter2, class _OutputIter>
1388 _OutputIter merge(_InputIter1 __first1, _InputIter1 __last1,
1389 _InputIter2 __first2, _InputIter2 __last2,
1390 _OutputIter __result) {
1391 _STLP_DEBUG_CHECK(__check_range(__first1, __last1))
1392 _STLP_DEBUG_CHECK(__check_range(__first2, __last2))
1393 while (__first1 != __last1 && __first2 != __last2) {
1394 if (*__first2 < *__first1) {
1395 *__result = *__first2;
1399 *__result = *__first1;
1404 return copy(__first2, __last2, copy(__first1, __last1, __result));
1407 template <class _InputIter1, class _InputIter2, class _OutputIter,
1409 _OutputIter merge(_InputIter1 __first1, _InputIter1 __last1,
1410 _InputIter2 __first2, _InputIter2 __last2,
1411 _OutputIter __result, _Compare __comp) {
1412 _STLP_DEBUG_CHECK(__check_range(__first1, __last1))
1413 _STLP_DEBUG_CHECK(__check_range(__first2, __last2))
1414 while (__first1 != __last1 && __first2 != __last2) {
1415 if (__comp(*__first2, *__first1)) {
1416 *__result = *__first2;
1420 *__result = *__first1;
1425 return copy(__first2, __last2, copy(__first1, __last1, __result));
1428 template <class _BidirectionalIter, class _Distance, class _Compare>
1429 void __merge_without_buffer(_BidirectionalIter __first,
1430 _BidirectionalIter __middle,
1431 _BidirectionalIter __last,
1432 _Distance __len1, _Distance __len2,
1434 if (__len1 == 0 || __len2 == 0)
1436 if (__len1 + __len2 == 2) {
1437 if (__comp(*__middle, *__first))
1438 iter_swap(__first, __middle);
1441 _BidirectionalIter __first_cut = __first;
1442 _BidirectionalIter __second_cut = __middle;
1443 _Distance __len11 = 0;
1444 _Distance __len22 = 0;
1445 if (__len1 > __len2) {
1446 __len11 = __len1 / 2;
1447 advance(__first_cut, __len11);
1448 __second_cut = lower_bound(__middle, __last, *__first_cut, __comp);
1449 __len22 += distance(__middle, __second_cut);
1452 __len22 = __len2 / 2;
1453 advance(__second_cut, __len22);
1454 __first_cut = upper_bound(__first, __middle, *__second_cut, __comp);
1455 __len11 +=distance(__first, __first_cut);
1457 _BidirectionalIter __new_middle
1458 = rotate(__first_cut, __middle, __second_cut);
1459 __merge_without_buffer(__first, __first_cut, __new_middle, __len11, __len22,
1461 __merge_without_buffer(__new_middle, __second_cut, __last, __len1 - __len11,
1462 __len2 - __len22, __comp);
1465 template <class _BidirectionalIter1, class _BidirectionalIter2,
1466 class _BidirectionalIter3, class _Compare>
1467 _BidirectionalIter3 __merge_backward(_BidirectionalIter1 __first1,
1468 _BidirectionalIter1 __last1,
1469 _BidirectionalIter2 __first2,
1470 _BidirectionalIter2 __last2,
1471 _BidirectionalIter3 __result,
1473 if (__first1 == __last1)
1474 return copy_backward(__first2, __last2, __result);
1475 if (__first2 == __last2)
1476 return copy_backward(__first1, __last1, __result);
1480 if (__comp(*__last2, *__last1)) {
1481 *--__result = *__last1;
1482 if (__first1 == __last1)
1483 return copy_backward(__first2, ++__last2, __result);
1487 *--__result = *__last2;
1488 if (__first2 == __last2)
1489 return copy_backward(__first1, ++__last1, __result);
1495 template <class _BidirectionalIter, class _Tp,
1496 class _Distance, class _Compare>
1497 inline void __inplace_merge_aux(_BidirectionalIter __first,
1498 _BidirectionalIter __middle,
1499 _BidirectionalIter __last, _Tp*, _Distance*,
1501 _Distance __len1 = distance(__first, __middle);
1502 _Distance __len2 = distance(__middle, __last);
1504 typedef _Temporary_buffer<_BidirectionalIter, _Tp> _TmpBuf;
1505 _TmpBuf __buf(__first, __last);
1506 _STLP_PUSH_STACK_ITEM(_TmpBuf, &__buf);
1508 if (__buf.begin() == 0)
1509 __merge_without_buffer(__first, __middle, __last, __len1, __len2, __comp);
1511 __merge_adaptive(__first, __middle, __last, __len1, __len2,
1512 __buf.begin(), _Distance(__buf.size()),
1516 template <class _BidirectionalIter>
1517 void inplace_merge(_BidirectionalIter __first,
1518 _BidirectionalIter __middle,
1519 _BidirectionalIter __last) {
1520 _STLP_DEBUG_CHECK(__check_range(__first, __middle))
1521 _STLP_DEBUG_CHECK(__check_range(__middle, __last))
1522 if (__first == __middle || __middle == __last)
1524 __inplace_merge_aux(__first, __middle, __last,
1525 _STLP_VALUE_TYPE(__first, _BidirectionalIter), _STLP_DISTANCE_TYPE(__first, _BidirectionalIter),
1526 __less(_STLP_VALUE_TYPE(__first, _BidirectionalIter)));
1529 template <class _BidirectionalIter, class _Compare>
1530 void inplace_merge(_BidirectionalIter __first,
1531 _BidirectionalIter __middle,
1532 _BidirectionalIter __last, _Compare __comp) {
1533 _STLP_DEBUG_CHECK(__check_range(__first, __middle))
1534 _STLP_DEBUG_CHECK(__check_range(__middle, __last))
1535 if (__first == __middle || __middle == __last)
1537 __inplace_merge_aux(__first, __middle, __last,
1538 _STLP_VALUE_TYPE(__first, _BidirectionalIter), _STLP_DISTANCE_TYPE(__first, _BidirectionalIter),
1543 template <class _InputIter1, class _InputIter2, class _Compare>
1544 bool __includes(_InputIter1 __first1, _InputIter1 __last1,
1545 _InputIter2 __first2, _InputIter2 __last2, _Compare __comp) {
1546 _STLP_DEBUG_CHECK(__check_range(__first1, __last1))
1547 _STLP_DEBUG_CHECK(__check_range(__first2, __last2))
1548 while (__first1 != __last1 && __first2 != __last2)
1549 if (__comp(*__first2, *__first1))
1551 else if(__comp(*__first1, *__first2))
1554 ++__first1, ++__first2;
1556 return __first2 == __last2;
1559 template <class _InputIter1, class _InputIter2, class _Compare>
1560 bool includes(_InputIter1 __first1, _InputIter1 __last1,
1561 _InputIter2 __first2, _InputIter2 __last2, _Compare __comp) {
1562 return __includes(__first1, __last1, __first2, __last2, __comp);
1565 template <class _InputIter1, class _InputIter2>
1566 bool includes(_InputIter1 __first1, _InputIter1 __last1,
1567 _InputIter2 __first2, _InputIter2 __last2) {
1568 return __includes(__first1, __last1, __first2, __last2, __less(_STLP_VALUE_TYPE(__first1, _InputIter1)));
1571 template <class _InputIter1, class _InputIter2, class _OutputIter,
1573 _OutputIter __set_union(_InputIter1 __first1, _InputIter1 __last1,
1574 _InputIter2 __first2, _InputIter2 __last2,
1575 _OutputIter __result, _Compare __comp) {
1576 _STLP_DEBUG_CHECK(__check_range(__first1, __last1))
1577 _STLP_DEBUG_CHECK(__check_range(__first2, __last2))
1578 while (__first1 != __last1 && __first2 != __last2) {
1579 if (__comp(*__first1, *__first2)) {
1580 *__result = *__first1;
1583 else if (__comp(*__first2, *__first1)) {
1584 *__result = *__first2;
1588 *__result = *__first1;
1594 return copy(__first2, __last2, copy(__first1, __last1, __result));
1597 template <class _InputIter1, class _InputIter2, class _OutputIter>
1598 _OutputIter set_union(_InputIter1 __first1, _InputIter1 __last1,
1599 _InputIter2 __first2, _InputIter2 __last2,
1600 _OutputIter __result) {
1601 return __set_union(__first1, __last1, __first2, __last2, __result, __less(_STLP_VALUE_TYPE(__first1, _InputIter1)));
1604 template <class _InputIter1, class _InputIter2, class _OutputIter,
1606 _OutputIter set_union(_InputIter1 __first1, _InputIter1 __last1,
1607 _InputIter2 __first2, _InputIter2 __last2,
1608 _OutputIter __result, _Compare __comp) {
1609 return __set_union(__first1, __last1, __first2, __last2, __result, __comp);
1612 template <class _InputIter1, class _InputIter2, class _OutputIter,
1614 _OutputIter __set_intersection(_InputIter1 __first1, _InputIter1 __last1,
1615 _InputIter2 __first2, _InputIter2 __last2,
1616 _OutputIter __result, _Compare __comp) {
1617 _STLP_DEBUG_CHECK(__check_range(__first1, __last1))
1618 _STLP_DEBUG_CHECK(__check_range(__first2, __last2))
1619 while (__first1 != __last1 && __first2 != __last2)
1620 if (__comp(*__first1, *__first2))
1622 else if (__comp(*__first2, *__first1))
1625 *__result = *__first1;
1633 template <class _InputIter1, class _InputIter2, class _OutputIter>
1634 _OutputIter set_intersection(_InputIter1 __first1, _InputIter1 __last1,
1635 _InputIter2 __first2, _InputIter2 __last2,
1636 _OutputIter __result) {
1637 return __set_intersection(__first1, __last1, __first2, __last2, __result, __less(_STLP_VALUE_TYPE(__first1, _InputIter1)));
1640 template <class _InputIter1, class _InputIter2, class _OutputIter,
1642 _OutputIter set_intersection(_InputIter1 __first1, _InputIter1 __last1,
1643 _InputIter2 __first2, _InputIter2 __last2,
1644 _OutputIter __result, _Compare __comp) {
1645 return __set_intersection(__first1, __last1, __first2, __last2, __result, __comp);
1648 template <class _InputIter1, class _InputIter2, class _OutputIter,
1650 _OutputIter __set_difference(_InputIter1 __first1, _InputIter1 __last1,
1651 _InputIter2 __first2, _InputIter2 __last2,
1652 _OutputIter __result, _Compare __comp) {
1653 _STLP_DEBUG_CHECK(__check_range(__first1, __last1))
1654 _STLP_DEBUG_CHECK(__check_range(__first2, __last2))
1655 while (__first1 != __last1 && __first2 != __last2)
1656 if (__comp(*__first1, *__first2)) {
1657 *__result = *__first1;
1661 else if (__comp(*__first2, *__first1))
1667 return copy(__first1, __last1, __result);
1670 template <class _InputIter1, class _InputIter2, class _OutputIter>
1671 _OutputIter set_difference(_InputIter1 __first1, _InputIter1 __last1,
1672 _InputIter2 __first2, _InputIter2 __last2,
1673 _OutputIter __result) {
1674 return __set_difference(__first1, __last1, __first2, __last2, __result,
1675 __less(_STLP_VALUE_TYPE(__first1, _InputIter1)));
1678 template <class _InputIter1, class _InputIter2, class _OutputIter,
1680 _OutputIter set_difference(_InputIter1 __first1, _InputIter1 __last1,
1681 _InputIter2 __first2, _InputIter2 __last2,
1682 _OutputIter __result, _Compare __comp) {
1683 return __set_difference(__first1, __last1, __first2, __last2, __result, __comp);
1686 template <class _InputIter1, class _InputIter2, class _OutputIter, class _Compare>
1688 __set_symmetric_difference(_InputIter1 __first1, _InputIter1 __last1,
1689 _InputIter2 __first2, _InputIter2 __last2,
1690 _OutputIter __result, _Compare __comp) {
1691 _STLP_DEBUG_CHECK(__check_range(__first1, __last1))
1692 _STLP_DEBUG_CHECK(__check_range(__first2, __last2))
1693 while (__first1 != __last1 && __first2 != __last2)
1694 if (__comp(*__first1, *__first2)) {
1695 *__result = *__first1;
1699 else if (__comp(*__first2, *__first1)) {
1700 *__result = *__first2;
1708 return copy(__first2, __last2, copy(__first1, __last1, __result));
1711 template <class _InputIter1, class _InputIter2, class _OutputIter>
1713 set_symmetric_difference(_InputIter1 __first1, _InputIter1 __last1,
1714 _InputIter2 __first2, _InputIter2 __last2,
1715 _OutputIter __result) {
1716 return __set_symmetric_difference(__first1, __last1, __first2, __last2, __result,
1717 __less(_STLP_VALUE_TYPE(__first1, _InputIter1)));
1720 template <class _InputIter1, class _InputIter2, class _OutputIter, class _Compare>
1722 set_symmetric_difference(_InputIter1 __first1, _InputIter1 __last1,
1723 _InputIter2 __first2, _InputIter2 __last2,
1724 _OutputIter __result,
1726 return __set_symmetric_difference(__first1, __last1, __first2, __last2, __result, __comp);
1729 // min_element and max_element, with and without an explicitly supplied
1730 // comparison function.
1732 template <class _ForwardIter, class _Compare>
1733 _ForwardIter max_element(_ForwardIter __first, _ForwardIter __last,
1735 _STLP_DEBUG_CHECK(__check_range(__first, __last))
1736 if (__first == __last) return __first;
1737 _ForwardIter __result = __first;
1738 while (++__first != __last)
1739 if (__comp(*__result, *__first)) __result = __first;
1743 template <class _ForwardIter>
1744 _ForwardIter max_element(_ForwardIter __first, _ForwardIter __last) {
1745 _STLP_DEBUG_CHECK(__check_range(__first, __last))
1746 if (__first == __last) return __first;
1747 _ForwardIter __result = __first;
1748 while (++__first != __last)
1749 if (*__result < *__first)
1754 template <class _ForwardIter>
1755 _ForwardIter min_element(_ForwardIter __first, _ForwardIter __last) {
1756 _STLP_DEBUG_CHECK(__check_range(__first, __last))
1757 if (__first == __last) return __first;
1758 _ForwardIter __result = __first;
1759 while (++__first != __last)
1760 if (*__first < *__result)
1765 template <class _ForwardIter, class _Compare>
1766 _ForwardIter min_element(_ForwardIter __first, _ForwardIter __last,
1768 _STLP_DEBUG_CHECK(__check_range(__first, __last))
1769 if (__first == __last) return __first;
1770 _ForwardIter __result = __first;
1771 while (++__first != __last)
1772 if (__comp(*__first, *__result)) __result = __first;
1776 // next_permutation and prev_permutation, with and without an explicitly
1777 // supplied comparison function.
1778 template <class _BidirectionalIter, class _Compare>
1779 bool __next_permutation(_BidirectionalIter __first, _BidirectionalIter __last,
1781 _STLP_DEBUG_CHECK(__check_range(__first, __last))
1782 if (__first == __last)
1784 _BidirectionalIter __i = __first;
1792 _BidirectionalIter __ii = __i;
1794 if (__comp(*__i, *__ii)) {
1795 _BidirectionalIter __j = __last;
1796 while (!__comp(*__i, *--__j))
1798 iter_swap(__i, __j);
1799 reverse(__ii, __last);
1802 if (__i == __first) {
1803 reverse(__first, __last);
1807 #if defined(_STLP_NEED_UNREACHABLE_RETURN)
1812 template <class _BidirectionalIter>
1813 bool next_permutation(_BidirectionalIter __first, _BidirectionalIter __last) {
1814 _STLP_DEBUG_CHECK(__check_range(__first, __last))
1815 return __next_permutation(__first, __last, __less(_STLP_VALUE_TYPE(__first, _BidirectionalIter)));
1818 template <class _BidirectionalIter, class _Compare>
1819 bool next_permutation(_BidirectionalIter __first, _BidirectionalIter __last,
1821 _STLP_DEBUG_CHECK(__check_range(__first, __last))
1822 return __next_permutation(__first, __last, __comp);
1825 template <class _BidirectionalIter, class _Compare>
1826 bool __prev_permutation(_BidirectionalIter __first, _BidirectionalIter __last,
1828 if (__first == __last)
1830 _BidirectionalIter __i = __first;
1838 _BidirectionalIter __ii = __i;
1840 if (__comp(*__ii, *__i)) {
1841 _BidirectionalIter __j = __last;
1842 while (!__comp(*--__j, *__i))
1844 iter_swap(__i, __j);
1845 reverse(__ii, __last);
1848 if (__i == __first) {
1849 reverse(__first, __last);
1853 #if defined(_STLP_NEED_UNREACHABLE_RETURN)
1858 template <class _BidirectionalIter>
1859 bool prev_permutation(_BidirectionalIter __first, _BidirectionalIter __last) {
1860 _STLP_DEBUG_CHECK(__check_range(__first, __last))
1861 return __prev_permutation(__first, __last, __less(_STLP_VALUE_TYPE(__first, _BidirectionalIter)));
1864 template <class _BidirectionalIter, class _Compare>
1865 bool prev_permutation(_BidirectionalIter __first, _BidirectionalIter __last,
1867 _STLP_DEBUG_CHECK(__check_range(__first, __last))
1868 return __prev_permutation(__first, __last, __comp);
1871 # ifndef _STLP_NO_EXTENSIONS
1873 // is_heap, a predicate testing whether or not a range is
1874 // a heap. This function is an extension, not part of the C++
1878 template <class _RandomAccessIter, class _Distance, class _StrictWeakOrdering>
1879 bool __is_heap(_RandomAccessIter __first, _StrictWeakOrdering __comp,
1882 _Distance __parent = 0;
1883 for (_Distance __child = 1; __child < __n; ++__child) {
1884 if (__comp(__first[__parent], __first[__child]))
1886 if ((__child & 1) == 0)
1892 template <class _RandomAccessIter>
1893 bool is_heap(_RandomAccessIter __first, _RandomAccessIter __last)
1895 _STLP_DEBUG_CHECK(__check_range(__first, __last))
1896 return __is_heap(__first, __less(_STLP_VALUE_TYPE(__first, _RandomAccessIter)), __last - __first);
1899 template <class _RandomAccessIter, class _StrictWeakOrdering>
1900 bool is_heap(_RandomAccessIter __first, _RandomAccessIter __last,
1901 _StrictWeakOrdering __comp)
1903 _STLP_DEBUG_CHECK(__check_range(__first, __last))
1904 return __is_heap(__first, __comp, __last - __first);
1908 template <class _ForwardIter, class _StrictWeakOrdering>
1909 bool __is_sorted(_ForwardIter __first, _ForwardIter __last,
1910 _StrictWeakOrdering __comp)
1912 _STLP_DEBUG_CHECK(__check_range(__first, __last))
1913 if (__first == __last)
1916 _ForwardIter __next = __first;
1917 for (++__next; __next != __last; __first = __next, ++__next) {
1918 if (__comp(*__next, *__first))
1925 # endif /* _STLP_NO_EXTENSIONS */
1929 # undef __stl_threshold
1931 #endif /* _STLP_ALGO_C */