Initial import from FreeBSD RELENG_4:
[dragonfly.git] / contrib / libstdc++ / stl / stl_algo.h
1 /*
2  *
3  * Copyright (c) 1994
4  * Hewlett-Packard Company
5  *
6  * Permission to use, copy, modify, distribute and sell this software
7  * and its documentation for any purpose is hereby granted without fee,
8  * provided that the above copyright notice appear in all copies and
9  * that both that copyright notice and this permission notice appear
10  * in supporting documentation.  Hewlett-Packard Company makes no
11  * representations about the suitability of this software for any
12  * purpose.  It is provided "as is" without express or implied warranty.
13  *
14  *
15  * Copyright (c) 1996
16  * Silicon Graphics Computer Systems, Inc.
17  *
18  * Permission to use, copy, modify, distribute and sell this software
19  * and its documentation for any purpose is hereby granted without fee,
20  * provided that the above copyright notice appear in all copies and
21  * that both that copyright notice and this permission notice appear
22  * in supporting documentation.  Silicon Graphics makes no
23  * representations about the suitability of this software for any
24  * purpose.  It is provided "as is" without express or implied warranty.
25  */
26
27 /* NOTE: This is an internal header file, included by other STL headers.
28  *   You should not attempt to use it directly.
29  */
30
31 #ifndef __SGI_STL_INTERNAL_ALGO_H
32 #define __SGI_STL_INTERNAL_ALGO_H
33
34 #include <stl_heap.h>
35
36 __STL_BEGIN_NAMESPACE
37
38 #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
39 #pragma set woff 1209
40 #endif
41
42 // __median (an extension, not present in the C++ standard).
43
44 template <class _Tp>
45 inline const _Tp& __median(const _Tp& __a, const _Tp& __b, const _Tp& __c) {
46   if (__a < __b)
47     if (__b < __c)
48       return __b;
49     else if (__a < __c)
50       return __c;
51     else
52       return __a;
53   else if (__a < __c)
54     return __a;
55   else if (__b < __c)
56     return __c;
57   else
58     return __b;
59 }
60
61 template <class _Tp, class _Compare>
62 inline const _Tp&
63 __median(const _Tp& __a, const _Tp& __b, const _Tp& __c, _Compare __comp) {
64   if (__comp(__a, __b))
65     if (__comp(__b, __c))
66       return __b;
67     else if (__comp(__a, __c))
68       return __c;
69     else
70       return __a;
71   else if (__comp(__a, __c))
72     return __a;
73   else if (__comp(__b, __c))
74     return __c;
75   else
76     return __b;
77 }
78
79 // for_each.  Apply a function to every element of a range.
80 template <class _InputIter, class _Function>
81 _Function for_each(_InputIter __first, _InputIter __last, _Function __f) {
82   for ( ; __first != __last; ++__first)
83     __f(*__first);
84   return __f;
85 }
86
87 // find and find_if.
88
89 template <class _InputIter, class _Tp>
90 inline _InputIter find(_InputIter __first, _InputIter __last,
91                        const _Tp& __val,
92                        input_iterator_tag)
93 {
94   while (__first != __last && *__first != __val)
95     ++__first;
96   return __first;
97 }
98
99 template <class _InputIter, class _Predicate>
100 inline _InputIter find_if(_InputIter __first, _InputIter __last,
101                           _Predicate __pred,
102                           input_iterator_tag)
103 {
104   while (__first != __last && !__pred(*__first))
105     ++__first;
106   return __first;
107 }
108
109 #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
110
111 template <class _RandomAccessIter, class _Tp>
112 _RandomAccessIter find(_RandomAccessIter __first, _RandomAccessIter __last,
113                        const _Tp& __val,
114                        random_access_iterator_tag)
115 {
116   typename iterator_traits<_RandomAccessIter>::difference_type __trip_count
117     = (__last - __first) >> 2;
118
119   for ( ; __trip_count > 0 ; --__trip_count) {
120     if (*__first == __val) return __first;
121     ++__first;
122
123     if (*__first == __val) return __first;
124     ++__first;
125
126     if (*__first == __val) return __first;
127     ++__first;
128
129     if (*__first == __val) return __first;
130     ++__first;
131   }
132
133   switch(__last - __first) {
134   case 3:
135     if (*__first == __val) return __first;
136     ++__first;
137   case 2:
138     if (*__first == __val) return __first;
139     ++__first;
140   case 1:
141     if (*__first == __val) return __first;
142     ++__first;
143   case 0:
144   default:
145     return __last;
146   }
147 }
148
149 template <class _RandomAccessIter, class _Predicate>
150 _RandomAccessIter find_if(_RandomAccessIter __first, _RandomAccessIter __last,
151                           _Predicate __pred,
152                           random_access_iterator_tag)
153 {
154   typename iterator_traits<_RandomAccessIter>::difference_type __trip_count
155     = (__last - __first) >> 2;
156
157   for ( ; __trip_count > 0 ; --__trip_count) {
158     if (__pred(*__first)) return __first;
159     ++__first;
160
161     if (__pred(*__first)) return __first;
162     ++__first;
163
164     if (__pred(*__first)) return __first;
165     ++__first;
166
167     if (__pred(*__first)) return __first;
168     ++__first;
169   }
170
171   switch(__last - __first) {
172   case 3:
173     if (__pred(*__first)) return __first;
174     ++__first;
175   case 2:
176     if (__pred(*__first)) return __first;
177     ++__first;
178   case 1:
179     if (__pred(*__first)) return __first;
180     ++__first;
181   case 0:
182   default:
183     return __last;
184   }
185 }
186
187 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
188
189 template <class _InputIter, class _Tp>
190 inline _InputIter find(_InputIter __first, _InputIter __last,
191                        const _Tp& __val)
192 {
193   return find(__first, __last, __val, __ITERATOR_CATEGORY(__first));
194 }
195
196 template <class _InputIter, class _Predicate>
197 inline _InputIter find_if(_InputIter __first, _InputIter __last,
198                           _Predicate __pred) {
199   return find_if(__first, __last, __pred, __ITERATOR_CATEGORY(__first));
200 }
201
202 // adjacent_find.
203
204 template <class _ForwardIter>
205 _ForwardIter adjacent_find(_ForwardIter __first, _ForwardIter __last) {
206   if (__first == __last)
207     return __last;
208   _ForwardIter __next = __first;
209   while(++__next != __last) {
210     if (*__first == *__next)
211       return __first;
212     __first = __next;
213   }
214   return __last;
215 }
216
217 template <class _ForwardIter, class _BinaryPredicate>
218 _ForwardIter adjacent_find(_ForwardIter __first, _ForwardIter __last,
219                            _BinaryPredicate __binary_pred) {
220   if (__first == __last)
221     return __last;
222   _ForwardIter __next = __first;
223   while(++__next != __last) {
224     if (__binary_pred(*__first, *__next))
225       return __first;
226     __first = __next;
227   }
228   return __last;
229 }
230
231 // count and count_if.  There are two version of each, one whose return type
232 // type is void and one (present only if we have partial specialization)
233 // whose return type is iterator_traits<_InputIter>::difference_type.  The
234 // C++ standard only has the latter version, but the former, which was present
235 // in the HP STL, is retained for backward compatibility.
236
237 template <class _InputIter, class _Tp, class _Size>
238 void count(_InputIter __first, _InputIter __last, const _Tp& __value,
239            _Size& __n) {
240   for ( ; __first != __last; ++__first)
241     if (*__first == __value)
242       ++__n;
243 }
244
245 template <class _InputIter, class _Predicate, class _Size>
246 void count_if(_InputIter __first, _InputIter __last, _Predicate __pred,
247               _Size& __n) {
248   for ( ; __first != __last; ++__first)
249     if (__pred(*__first))
250       ++__n;
251 }
252
253 #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
254
255 template <class _InputIter, class _Tp>
256 typename iterator_traits<_InputIter>::difference_type
257 count(_InputIter __first, _InputIter __last, const _Tp& __value) {
258   typename iterator_traits<_InputIter>::difference_type __n = 0;
259   for ( ; __first != __last; ++__first)
260     if (*__first == __value)
261       ++__n;
262   return __n;
263 }
264
265 template <class _InputIter, class _Predicate>
266 typename iterator_traits<_InputIter>::difference_type
267 count_if(_InputIter __first, _InputIter __last, _Predicate __pred) {
268   typename iterator_traits<_InputIter>::difference_type __n = 0;
269   for ( ; __first != __last; ++__first)
270     if (__pred(*__first))
271       ++__n;
272   return __n;
273 }
274
275
276 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
277
278 // search.
279
280 template <class _ForwardIter1, class _ForwardIter2>
281 _ForwardIter1 search(_ForwardIter1 __first1, _ForwardIter1 __last1,
282                      _ForwardIter2 __first2, _ForwardIter2 __last2) 
283 {
284   // Test for empty ranges
285   if (__first1 == __last1 || __first2 == __last2)
286     return __first1;
287
288   // Test for a pattern of length 1.
289   _ForwardIter2 __tmp(__first2);
290   ++__tmp;
291   if (__tmp == __last2)
292     return find(__first1, __last1, *__first2);
293
294   // General case.
295
296   _ForwardIter2 __p1, __p;
297
298   __p1 = __first2; ++__p1;
299
300   _ForwardIter1 __current = __first1;
301
302   while (__first1 != __last1) {
303     __first1 = find(__first1, __last1, *__first2);
304     if (__first1 == __last1)
305       return __last1;
306
307     __p = __p1;
308     __current = __first1; 
309     if (++__current == __last1)
310       return __last1;
311
312     while (*__current == *__p) {
313       if (++__p == __last2)
314         return __first1;
315       if (++__current == __last1)
316         return __last1;
317     }
318
319     ++__first1;
320   }
321   return __first1;
322 }
323
324 template <class _ForwardIter1, class _ForwardIter2, class _BinaryPred>
325 _ForwardIter1 search(_ForwardIter1 __first1, _ForwardIter1 __last1,
326                      _ForwardIter2 __first2, _ForwardIter2 __last2,
327                      _BinaryPred  __predicate) 
328 {
329   // Test for empty ranges
330   if (__first1 == __last1 || __first2 == __last2)
331     return __first1;
332
333   // Test for a pattern of length 1.
334   _ForwardIter2 __tmp(__first2);
335   ++__tmp;
336   if (__tmp == __last2)
337     return find(__first1, __last1, *__first2);
338
339   // General case.
340
341   _ForwardIter2 __p1, __p;
342
343   __p1 = __first2; ++__p1;
344
345   _ForwardIter1 __current = __first1;
346
347   while (__first1 != __last1) {
348     while (__first1 != __last1) {
349       if (__predicate(*__first1, *__first2))
350         break;
351       ++__first1;
352     }
353     while (__first1 != __last1 && !__predicate(*__first1, *__first2))
354       ++__first1;
355     if (__first1 == __last1)
356       return __last1;
357
358     __p = __p1;
359     __current = __first1; 
360     if (++__current == __last1) return __last1;
361
362     while (__predicate(*__current, *__p)) {
363       if (++__p == __last2)
364         return __first1;
365       if (++__current == __last1)
366         return __last1;
367     }
368
369     ++__first1;
370   }
371   return __first1;
372 }
373
374 // search_n.  Search for __count consecutive copies of __val.
375
376 template <class _ForwardIter, class _Integer, class _Tp>
377 _ForwardIter search_n(_ForwardIter __first, _ForwardIter __last,
378                       _Integer __count, const _Tp& __val) {
379   if (__count <= 0)
380     return __first;
381   else {
382     __first = find(__first, __last, __val);
383     while (__first != __last) {
384       _Integer __n = __count - 1;
385       _ForwardIter __i = __first;
386       ++__i;
387       while (__i != __last && __n != 0 && *__i == __val) {
388         ++__i;
389         --__n;
390       }
391       if (__n == 0)
392         return __first;
393       else
394         __first = find(__i, __last, __val);
395     }
396     return __last;
397   }
398 }
399
400 template <class _ForwardIter, class _Integer, class _Tp, class _BinaryPred>
401 _ForwardIter search_n(_ForwardIter __first, _ForwardIter __last,
402                       _Integer __count, const _Tp& __val,
403                       _BinaryPred __binary_pred) {
404   if (__count <= 0)
405     return __first;
406   else {
407     while (__first != __last) {
408       if (__binary_pred(*__first, __val))
409         break;
410       ++__first;
411     }
412     while (__first != __last) {
413       _Integer __n = __count - 1;
414       _ForwardIter __i = __first;
415       ++__i;
416       while (__i != __last && __n != 0 && __binary_pred(*__i, __val)) {
417         ++__i;
418         --__n;
419       }
420       if (__n == 0)
421         return __first;
422       else {
423         while (__i != __last) {
424           if (__binary_pred(*__i, __val))
425             break;
426           ++__i;
427         }
428         __first = __i;
429       }
430     }
431     return __last;
432   }
433
434
435 // swap_ranges
436
437 template <class _ForwardIter1, class _ForwardIter2>
438 _ForwardIter2 swap_ranges(_ForwardIter1 __first1, _ForwardIter1 __last1,
439                           _ForwardIter2 __first2) {
440   for ( ; __first1 != __last1; ++__first1, ++__first2)
441     iter_swap(__first1, __first2);
442   return __first2;
443 }
444
445 // transform
446
447 template <class _InputIter, class _OutputIter, class _UnaryOperation>
448 _OutputIter transform(_InputIter __first, _InputIter __last,
449                       _OutputIter __result, _UnaryOperation __oper) {
450   for ( ; __first != __last; ++__first, ++__result)
451     *__result = __oper(*__first);
452   return __result;
453 }
454
455 template <class _InputIter1, class _InputIter2, class _OutputIter,
456           class _BinaryOperation>
457 _OutputIter transform(_InputIter1 __first1, _InputIter1 __last1,
458                       _InputIter2 __first2, _OutputIter __result,
459                       _BinaryOperation __binary_op) {
460   for ( ; __first1 != __last1; ++__first1, ++__first2, ++__result)
461     *__result = __binary_op(*__first1, *__first2);
462   return __result;
463 }
464
465 // replace, replace_if, replace_copy, replace_copy_if
466
467 template <class _ForwardIter, class _Tp>
468 void replace(_ForwardIter __first, _ForwardIter __last,
469              const _Tp& __old_value, const _Tp& __new_value) {
470   for ( ; __first != __last; ++__first)
471     if (*__first == __old_value)
472       *__first = __new_value;
473 }
474
475 template <class _ForwardIter, class _Predicate, class _Tp>
476 void replace_if(_ForwardIter __first, _ForwardIter __last,
477                 _Predicate __pred, const _Tp& __new_value) {
478   for ( ; __first != __last; ++__first)
479     if (__pred(*__first))
480       *__first = __new_value;
481 }
482
483 template <class _InputIter, class _OutputIter, class _Tp>
484 _OutputIter replace_copy(_InputIter __first, _InputIter __last,
485                          _OutputIter __result,
486                          const _Tp& __old_value, const _Tp& __new_value) {
487   for ( ; __first != __last; ++__first, ++__result)
488     *__result = *__first == __old_value ? __new_value : *__first;
489   return __result;
490 }
491
492 template <class Iterator, class _OutputIter, class _Predicate, class _Tp>
493 _OutputIter replace_copy_if(Iterator __first, Iterator __last,
494                             _OutputIter __result,
495                             _Predicate __pred, const _Tp& __new_value) {
496   for ( ; __first != __last; ++__first, ++__result)
497     *__result = __pred(*__first) ? __new_value : *__first;
498   return __result;
499 }
500
501 // generate and generate_n
502
503 template <class _ForwardIter, class _Generator>
504 void generate(_ForwardIter __first, _ForwardIter __last, _Generator __gen) {
505   for ( ; __first != __last; ++__first)
506     *__first = __gen();
507 }
508
509 template <class _OutputIter, class _Size, class _Generator>
510 _OutputIter generate_n(_OutputIter __first, _Size __n, _Generator __gen) {
511   for ( ; __n > 0; --__n, ++__first)
512     *__first = __gen();
513   return __first;
514 }
515
516 // remove, remove_if, remove_copy, remove_copy_if
517
518 template <class _InputIter, class _OutputIter, class _Tp>
519 _OutputIter remove_copy(_InputIter __first, _InputIter __last,
520                         _OutputIter __result, const _Tp& __value) {
521   for ( ; __first != __last; ++__first)
522     if (*__first != __value) {
523       *__result = *__first;
524       ++__result;
525     }
526   return __result;
527 }
528
529 template <class _InputIter, class _OutputIter, class _Predicate>
530 _OutputIter remove_copy_if(_InputIter __first, _InputIter __last,
531                            _OutputIter __result, _Predicate __pred) {
532   for ( ; __first != __last; ++__first)
533     if (!__pred(*__first)) {
534       *__result = *__first;
535       ++__result;
536     }
537   return __result;
538 }
539
540 template <class _ForwardIter, class _Tp>
541 _ForwardIter remove(_ForwardIter __first, _ForwardIter __last,
542                     const _Tp& __value) {
543   __first = find(__first, __last, __value);
544   _ForwardIter __i = __first;
545   return __first == __last ? __first 
546                            : remove_copy(++__i, __last, __first, __value);
547 }
548
549 template <class _ForwardIter, class _Predicate>
550 _ForwardIter remove_if(_ForwardIter __first, _ForwardIter __last,
551                        _Predicate __pred) {
552   __first = find_if(__first, __last, __pred);
553   _ForwardIter __i = __first;
554   return __first == __last ? __first 
555                            : remove_copy_if(++__i, __last, __first, __pred);
556 }
557
558 // unique and unique_copy
559
560 template <class _InputIter, class _OutputIter, class _Tp>
561 _OutputIter __unique_copy(_InputIter __first, _InputIter __last,
562                           _OutputIter __result, _Tp*) {
563   _Tp __value = *__first;
564   *__result = __value;
565   while (++__first != __last)
566     if (__value != *__first) {
567       __value = *__first;
568       *++__result = __value;
569     }
570   return ++__result;
571 }
572
573 template <class _InputIter, class _OutputIter>
574 inline _OutputIter __unique_copy(_InputIter __first, _InputIter __last,
575                                  _OutputIter __result, 
576                                  output_iterator_tag) {
577   return __unique_copy(__first, __last, __result, __VALUE_TYPE(__first));
578 }
579
580 template <class _InputIter, class _ForwardIter>
581 _ForwardIter __unique_copy(_InputIter __first, _InputIter __last,
582                            _ForwardIter __result, forward_iterator_tag) {
583   *__result = *__first;
584   while (++__first != __last)
585     if (*__result != *__first) *++__result = *__first;
586   return ++__result;
587 }
588
589 template <class _InputIter, class _OutputIter>
590 inline _OutputIter unique_copy(_InputIter __first, _InputIter __last,
591                                _OutputIter __result) {
592   if (__first == __last) return __result;
593   return __unique_copy(__first, __last, __result,
594                        __ITERATOR_CATEGORY(__result));
595 }
596
597 template <class _InputIter, class _OutputIter, class _BinaryPredicate,
598           class _Tp>
599 _OutputIter __unique_copy(_InputIter __first, _InputIter __last,
600                           _OutputIter __result,
601                           _BinaryPredicate __binary_pred, _Tp*) {
602   _Tp __value = *__first;
603   *__result = __value;
604   while (++__first != __last)
605     if (!__binary_pred(__value, *__first)) {
606       __value = *__first;
607       *++__result = __value;
608     }
609   return ++__result;
610 }
611
612 template <class _InputIter, class _OutputIter, class _BinaryPredicate>
613 inline _OutputIter __unique_copy(_InputIter __first, _InputIter __last,
614                                  _OutputIter __result,
615                                  _BinaryPredicate __binary_pred,
616                                  output_iterator_tag) {
617   return __unique_copy(__first, __last, __result, __binary_pred,
618                        __VALUE_TYPE(__first));
619 }
620
621 template <class _InputIter, class _ForwardIter, class _BinaryPredicate>
622 _ForwardIter __unique_copy(_InputIter __first, _InputIter __last,
623                            _ForwardIter __result, 
624                            _BinaryPredicate __binary_pred,
625                            forward_iterator_tag) {
626   *__result = *__first;
627   while (++__first != __last)
628     if (!__binary_pred(*__result, *__first)) *++__result = *__first;
629   return ++__result;
630 }
631
632 template <class _InputIter, class _OutputIter, class _BinaryPredicate>
633 inline _OutputIter unique_copy(_InputIter __first, _InputIter __last,
634                                _OutputIter __result,
635                                _BinaryPredicate __binary_pred) {
636   if (__first == __last) return __result;
637   return __unique_copy(__first, __last, __result, __binary_pred,
638                        __ITERATOR_CATEGORY(__result));
639 }
640
641 template <class _ForwardIter>
642 _ForwardIter unique(_ForwardIter __first, _ForwardIter __last) {
643   __first = adjacent_find(__first, __last);
644   return unique_copy(__first, __last, __first);
645 }
646
647 template <class _ForwardIter, class _BinaryPredicate>
648 _ForwardIter unique(_ForwardIter __first, _ForwardIter __last,
649                     _BinaryPredicate __binary_pred) {
650   __first = adjacent_find(__first, __last, __binary_pred);
651   return unique_copy(__first, __last, __first, __binary_pred);
652 }
653
654 // reverse and reverse_copy, and their auxiliary functions
655
656 template <class _BidirectionalIter>
657 void __reverse(_BidirectionalIter __first, _BidirectionalIter __last, 
658                bidirectional_iterator_tag) {
659   while (true)
660     if (__first == __last || __first == --__last)
661       return;
662     else
663       iter_swap(__first++, __last);
664 }
665
666 template <class _RandomAccessIter>
667 void __reverse(_RandomAccessIter __first, _RandomAccessIter __last,
668                random_access_iterator_tag) {
669   while (__first < __last)
670     iter_swap(__first++, --__last);
671 }
672
673 template <class _BidirectionalIter>
674 inline void reverse(_BidirectionalIter __first, _BidirectionalIter __last) {
675   __reverse(__first, __last, __ITERATOR_CATEGORY(__first));
676 }
677
678 template <class _BidirectionalIter, class _OutputIter>
679 _OutputIter reverse_copy(_BidirectionalIter __first,
680                             _BidirectionalIter __last,
681                             _OutputIter __result) {
682   while (__first != __last) {
683     --__last;
684     *__result = *__last;
685     ++__result;
686   }
687   return __result;
688 }
689
690 // rotate and rotate_copy, and their auxiliary functions
691
692 template <class _EuclideanRingElement>
693 _EuclideanRingElement __gcd(_EuclideanRingElement __m,
694                             _EuclideanRingElement __n)
695 {
696   while (__n != 0) {
697     _EuclideanRingElement __t = __m % __n;
698     __m = __n;
699     __n = __t;
700   }
701   return __m;
702 }
703
704 template <class _ForwardIter, class _Distance>
705 _ForwardIter __rotate(_ForwardIter __first,
706                       _ForwardIter __middle,
707                       _ForwardIter __last,
708                       _Distance*,
709                       forward_iterator_tag) {
710   if (__first == __middle)
711     return __last;
712   if (__last  == __middle)
713     return __first;
714
715   _ForwardIter __first2 = __middle;
716   do {
717     swap(*__first++, *__first2++);
718     if (__first == __middle)
719       __middle = __first2;
720   } while (__first2 != __last);
721
722   _ForwardIter __new_middle = __first;
723
724   __first2 = __middle;
725
726   while (__first2 != __last) {
727     swap (*__first++, *__first2++);
728     if (__first == __middle)
729       __middle = __first2;
730     else if (__first2 == __last)
731       __first2 = __middle;
732   }
733
734   return __new_middle;
735 }
736
737
738 template <class _BidirectionalIter, class _Distance>
739 _BidirectionalIter __rotate(_BidirectionalIter __first,
740                             _BidirectionalIter __middle,
741                             _BidirectionalIter __last,
742                             _Distance*,
743                             bidirectional_iterator_tag) {
744   if (__first == __middle)
745     return __last;
746   if (__last  == __middle)
747     return __first;
748
749   __reverse(__first,  __middle, bidirectional_iterator_tag());
750   __reverse(__middle, __last,   bidirectional_iterator_tag());
751
752   while (__first != __middle && __middle != __last)
753     swap (*__first++, *--__last);
754
755   if (__first == __middle) {
756     __reverse(__middle, __last,   bidirectional_iterator_tag());
757     return __last;
758   }
759   else {
760     __reverse(__first,  __middle, bidirectional_iterator_tag());
761     return __first;
762   }
763 }
764
765 template <class _RandomAccessIter, class _Distance, class _Tp>
766 _RandomAccessIter __rotate(_RandomAccessIter __first,
767                            _RandomAccessIter __middle,
768                            _RandomAccessIter __last,
769                            _Distance *, _Tp *) {
770
771   _Distance __n = __last   - __first;
772   _Distance __k = __middle - __first;
773   _Distance __l = __n - __k;
774   _RandomAccessIter __result = __first + (__last - __middle);
775
776   if (__k == __l) {
777     swap_ranges(__first, __middle, __middle);
778     return __result;
779   }
780
781   _Distance __d = __gcd(__n, __k);
782
783   for (_Distance __i = 0; __i < __d; __i++) {
784     _Tp __tmp = *__first;
785     _RandomAccessIter __p = __first;
786
787     if (__k < __l) {
788       for (_Distance __j = 0; __j < __l/__d; __j++) {
789         if (__p > __first + __l) {
790           *__p = *(__p - __l);
791           __p -= __l;
792         }
793
794         *__p = *(__p + __k);
795         __p += __k;
796       }
797     }
798
799     else {
800       for (_Distance __j = 0; __j < __k/__d - 1; __j ++) {
801         if (__p < __last - __k) {
802           *__p = *(__p + __k);
803           __p += __k;
804         }
805
806         *__p = * (__p - __l);
807         __p -= __l;
808       }
809     }
810
811     *__p = __tmp;
812     ++__first;
813   }
814
815   return __result;
816 }
817
818 template <class _ForwardIter>
819 inline _ForwardIter rotate(_ForwardIter __first, _ForwardIter __middle,
820                            _ForwardIter __last) {
821   return __rotate(__first, __middle, __last,
822                   __DISTANCE_TYPE(__first),
823                   __ITERATOR_CATEGORY(__first));
824 }
825
826 template <class _ForwardIter, class _OutputIter>
827 _OutputIter rotate_copy(_ForwardIter __first, _ForwardIter __middle,
828                             _ForwardIter __last, _OutputIter __result) {
829   return copy(__first, __middle, copy(__middle, __last, __result));
830 }
831
832 // Return a random number in the range [0, __n).  This function encapsulates
833 // whether we're using rand (part of the standard C library) or lrand48
834 // (not standard, but a much better choice whenever it's available).
835
836 template <class _Distance>
837 inline _Distance __random_number(_Distance __n) {
838 #ifdef __STL_NO_DRAND48
839   return rand() % __n;
840 #else
841   return lrand48() % __n;
842 #endif
843 }
844
845 // random_shuffle
846
847 template <class _RandomAccessIter>
848 inline void random_shuffle(_RandomAccessIter __first,
849                            _RandomAccessIter __last) {
850   if (__first == __last) return;
851   for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i)
852     iter_swap(__i, __first + __random_number((__i - __first) + 1));
853 }
854
855 template <class _RandomAccessIter, class _RandomNumberGenerator>
856 void random_shuffle(_RandomAccessIter __first, _RandomAccessIter __last,
857                     _RandomNumberGenerator& __rand) {
858   if (__first == __last) return;
859   for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i)
860     iter_swap(__i, __first + __rand((__i - __first) + 1));
861 }
862
863 // random_sample and random_sample_n (extensions, not part of the standard).
864
865 template <class _ForwardIter, class _OutputIter, class _Distance>
866 _OutputIter random_sample_n(_ForwardIter __first, _ForwardIter __last,
867                             _OutputIter __out, const _Distance __n)
868 {
869   _Distance __remaining = 0;
870   distance(__first, __last, __remaining);
871   _Distance __m = min(__n, __remaining);
872
873   while (__m > 0) {
874     if (__random_number(__remaining) < __m) {
875       *__out = *__first;
876       ++__out;
877       --__m;
878     }
879
880     --__remaining;
881     ++__first;
882   }
883   return __out;
884 }
885
886 template <class _ForwardIter, class _OutputIter, class _Distance,
887           class _RandomNumberGenerator>
888 _OutputIter random_sample_n(_ForwardIter __first, _ForwardIter __last,
889                             _OutputIter __out, const _Distance __n,
890                             _RandomNumberGenerator& __rand)
891 {
892   _Distance __remaining = 0;
893   distance(__first, __last, __remaining);
894   _Distance __m = min(__n, __remaining);
895
896   while (__m > 0) {
897     if (__rand(__remaining) < __m) {
898       *__out = *__first;
899       ++__out;
900       --__m;
901     }
902
903     --__remaining;
904     ++__first;
905   }
906   return __out;
907 }
908
909 template <class _InputIter, class _RandomAccessIter, class _Distance>
910 _RandomAccessIter __random_sample(_InputIter __first, _InputIter __last,
911                                   _RandomAccessIter __out,
912                                   const _Distance __n)
913 {
914   _Distance __m = 0;
915   _Distance __t = __n;
916   for ( ; __first != __last && __m < __n; ++__m, ++__first) 
917     __out[__m] = *__first;
918
919   while (__first != __last) {
920     ++__t;
921     _Distance __M = __random_number(__t);
922     if (__M < __n)
923       __out[__M] = *__first;
924     ++__first;
925   }
926
927   return __out + __m;
928 }
929
930 template <class _InputIter, class _RandomAccessIter,
931           class _RandomNumberGenerator, class _Distance>
932 _RandomAccessIter __random_sample(_InputIter __first, _InputIter __last,
933                                   _RandomAccessIter __out,
934                                   _RandomNumberGenerator& __rand,
935                                   const _Distance __n)
936 {
937   _Distance __m = 0;
938   _Distance __t = __n;
939   for ( ; __first != __last && __m < __n; ++__m, ++__first)
940     __out[__m] = *__first;
941
942   while (__first != __last) {
943     ++__t;
944     _Distance __M = __rand(__t);
945     if (__M < __n)
946       __out[__M] = *__first;
947     ++__first;
948   }
949
950   return __out + __m;
951 }
952
953 template <class _InputIter, class _RandomAccessIter>
954 inline _RandomAccessIter
955 random_sample(_InputIter __first, _InputIter __last,
956               _RandomAccessIter __out_first, _RandomAccessIter __out_last) 
957 {
958   return __random_sample(__first, __last,
959                          __out_first, __out_last - __out_first);
960 }
961
962
963 template <class _InputIter, class _RandomAccessIter, 
964           class _RandomNumberGenerator>
965 inline _RandomAccessIter
966 random_sample(_InputIter __first, _InputIter __last,
967               _RandomAccessIter __out_first, _RandomAccessIter __out_last,
968               _RandomNumberGenerator& __rand) 
969 {
970   return __random_sample(__first, __last,
971                          __out_first, __rand,
972                          __out_last - __out_first);
973 }
974
975 // partition, stable_partition, and their auxiliary functions
976
977 template <class _ForwardIter, class _Predicate>
978 _ForwardIter __partition(_ForwardIter __first,
979                          _ForwardIter __last,
980                          _Predicate   __pred,
981                          forward_iterator_tag) {
982   if (__first == __last) return __first;
983
984   while (__pred(*__first))
985     if (++__first == __last) return __first;
986
987   _ForwardIter __next = __first;
988
989   while (++__next != __last)
990     if (__pred(*__next)) {
991       swap(*__first, *__next);
992       ++__first;
993     }
994
995   return __first;
996 }
997
998 template <class _BidirectionalIter, class _Predicate>
999 _BidirectionalIter __partition(_BidirectionalIter __first,
1000                                _BidirectionalIter __last,
1001                                _Predicate __pred,
1002                                bidirectional_iterator_tag) {
1003   while (true) {
1004     while (true)
1005       if (__first == __last)
1006         return __first;
1007       else if (__pred(*__first))
1008         ++__first;
1009       else
1010         break;
1011     --__last;
1012     while (true)
1013       if (__first == __last)
1014         return __first;
1015       else if (!__pred(*__last))
1016         --__last;
1017       else
1018         break;
1019     iter_swap(__first, __last);
1020     ++__first;
1021   }
1022 }
1023
1024 template <class _ForwardIter, class _Predicate>
1025 inline _ForwardIter partition(_ForwardIter __first,
1026                               _ForwardIter __last,
1027                               _Predicate   __pred) {
1028   return __partition(__first, __last, __pred, __ITERATOR_CATEGORY(__first));
1029 }
1030
1031
1032 template <class _ForwardIter, class _Predicate, class _Distance>
1033 _ForwardIter __inplace_stable_partition(_ForwardIter __first,
1034                                         _ForwardIter __last,
1035                                         _Predicate __pred, _Distance __len) {
1036   if (__len == 1)
1037     return __pred(*__first) ? __last : __first;
1038   _ForwardIter __middle = __first;
1039   advance(__middle, __len / 2);
1040   return rotate(__inplace_stable_partition(__first, __middle, __pred, 
1041                                            __len / 2),
1042                 __middle,
1043                 __inplace_stable_partition(__middle, __last, __pred,
1044                                            __len - __len / 2));
1045 }
1046
1047 template <class _ForwardIter, class _Pointer, class _Predicate, 
1048           class _Distance>
1049 _ForwardIter __stable_partition_adaptive(_ForwardIter __first,
1050                                          _ForwardIter __last,
1051                                          _Predicate __pred, _Distance __len,
1052                                          _Pointer __buffer,
1053                                          _Distance __buffer_size) 
1054 {
1055   if (__len <= __buffer_size) {
1056     _ForwardIter __result1 = __first;
1057     _Pointer __result2 = __buffer;
1058     for ( ; __first != __last ; ++__first)
1059       if (__pred(*__first)) {
1060         *__result1 = *__first;
1061         ++__result1;
1062       }
1063       else {
1064         *__result2 = *__first;
1065         ++__result2;
1066       }
1067     copy(__buffer, __result2, __result1);
1068     return __result1;
1069   }
1070   else {
1071     _ForwardIter __middle = __first;
1072     advance(__middle, __len / 2);
1073     return rotate(__stable_partition_adaptive(
1074                           __first, __middle, __pred,
1075                           __len / 2, __buffer, __buffer_size),
1076                     __middle,
1077                     __stable_partition_adaptive(
1078                           __middle, __last, __pred,
1079                           __len - __len / 2, __buffer, __buffer_size));
1080   }
1081 }
1082
1083 template <class _ForwardIter, class _Predicate, class _Tp, class _Distance>
1084 inline _ForwardIter
1085 __stable_partition_aux(_ForwardIter __first, _ForwardIter __last, 
1086                        _Predicate __pred, _Tp*, _Distance*)
1087 {
1088   _Temporary_buffer<_ForwardIter, _Tp> __buf(__first, __last);
1089   if (__buf.size() > 0)
1090     return __stable_partition_adaptive(__first, __last, __pred,
1091                                        _Distance(__buf.requested_size()),
1092                                        __buf.begin(), __buf.size());
1093   else
1094     return __inplace_stable_partition(__first, __last, __pred, 
1095                                       _Distance(__buf.requested_size()));
1096 }
1097
1098 template <class _ForwardIter, class _Predicate>
1099 inline _ForwardIter stable_partition(_ForwardIter __first,
1100                                      _ForwardIter __last, 
1101                                      _Predicate __pred) {
1102   if (__first == __last)
1103     return __first;
1104   else
1105     return __stable_partition_aux(__first, __last, __pred,
1106                                   __VALUE_TYPE(__first),
1107                                   __DISTANCE_TYPE(__first));
1108 }
1109
1110 template <class _RandomAccessIter, class _Tp>
1111 _RandomAccessIter __unguarded_partition(_RandomAccessIter __first, 
1112                                         _RandomAccessIter __last, 
1113                                         _Tp __pivot) 
1114 {
1115   while (true) {
1116     while (*__first < __pivot)
1117       ++__first;
1118     --__last;
1119     while (__pivot < *__last)
1120       --__last;
1121     if (!(__first < __last))
1122       return __first;
1123     iter_swap(__first, __last);
1124     ++__first;
1125   }
1126 }    
1127
1128 template <class _RandomAccessIter, class _Tp, class _Compare>
1129 _RandomAccessIter __unguarded_partition(_RandomAccessIter __first, 
1130                                         _RandomAccessIter __last, 
1131                                         _Tp __pivot, _Compare __comp) 
1132 {
1133   while (true) {
1134     while (__comp(*__first, __pivot))
1135       ++__first;
1136     --__last;
1137     while (__comp(__pivot, *__last))
1138       --__last;
1139     if (!(__first < __last))
1140       return __first;
1141     iter_swap(__first, __last);
1142     ++__first;
1143   }
1144 }
1145
1146 const int __stl_threshold = 16;
1147
1148 // sort() and its auxiliary functions. 
1149
1150 template <class _RandomAccessIter, class _Tp>
1151 void __unguarded_linear_insert(_RandomAccessIter __last, _Tp __val) {
1152   _RandomAccessIter __next = __last;
1153   --__next;
1154   while (__val < *__next) {
1155     *__last = *__next;
1156     __last = __next;
1157     --__next;
1158   }
1159   *__last = __val;
1160 }
1161
1162 template <class _RandomAccessIter, class _Tp, class _Compare>
1163 void __unguarded_linear_insert(_RandomAccessIter __last, _Tp __val, 
1164                                _Compare __comp) {
1165   _RandomAccessIter __next = __last;
1166   --__next;  
1167   while (__comp(__val, *__next)) {
1168     *__last = *__next;
1169     __last = __next;
1170     --__next;
1171   }
1172   *__last = __val;
1173 }
1174
1175 template <class _RandomAccessIter, class _Tp>
1176 inline void __linear_insert(_RandomAccessIter __first, 
1177                             _RandomAccessIter __last, _Tp*) {
1178   _Tp __val = *__last;
1179   if (__val < *__first) {
1180     copy_backward(__first, __last, __last + 1);
1181     *__first = __val;
1182   }
1183   else
1184     __unguarded_linear_insert(__last, __val);
1185 }
1186
1187 template <class _RandomAccessIter, class _Tp, class _Compare>
1188 inline void __linear_insert(_RandomAccessIter __first, 
1189                             _RandomAccessIter __last, _Tp*, _Compare __comp) {
1190   _Tp __val = *__last;
1191   if (__comp(__val, *__first)) {
1192     copy_backward(__first, __last, __last + 1);
1193     *__first = __val;
1194   }
1195   else
1196     __unguarded_linear_insert(__last, __val, __comp);
1197 }
1198
1199 template <class _RandomAccessIter>
1200 void __insertion_sort(_RandomAccessIter __first, _RandomAccessIter __last) {
1201   if (__first == __last) return; 
1202   for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i)
1203     __linear_insert(__first, __i, __VALUE_TYPE(__first));
1204 }
1205
1206 template <class _RandomAccessIter, class _Compare>
1207 void __insertion_sort(_RandomAccessIter __first,
1208                       _RandomAccessIter __last, _Compare __comp) {
1209   if (__first == __last) return;
1210   for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i)
1211     __linear_insert(__first, __i, __VALUE_TYPE(__first), __comp);
1212 }
1213
1214 template <class _RandomAccessIter, class _Tp>
1215 void __unguarded_insertion_sort_aux(_RandomAccessIter __first, 
1216                                     _RandomAccessIter __last, _Tp*) {
1217   for (_RandomAccessIter __i = __first; __i != __last; ++__i)
1218     __unguarded_linear_insert(__i, _Tp(*__i));
1219 }
1220
1221 template <class _RandomAccessIter>
1222 inline void __unguarded_insertion_sort(_RandomAccessIter __first, 
1223                                 _RandomAccessIter __last) {
1224   __unguarded_insertion_sort_aux(__first, __last, __VALUE_TYPE(__first));
1225 }
1226
1227 template <class _RandomAccessIter, class _Tp, class _Compare>
1228 void __unguarded_insertion_sort_aux(_RandomAccessIter __first, 
1229                                     _RandomAccessIter __last,
1230                                     _Tp*, _Compare __comp) {
1231   for (_RandomAccessIter __i = __first; __i != __last; ++__i)
1232     __unguarded_linear_insert(__i, _Tp(*__i), __comp);
1233 }
1234
1235 template <class _RandomAccessIter, class _Compare>
1236 inline void __unguarded_insertion_sort(_RandomAccessIter __first, 
1237                                        _RandomAccessIter __last,
1238                                        _Compare __comp) {
1239   __unguarded_insertion_sort_aux(__first, __last, __VALUE_TYPE(__first),
1240                                  __comp);
1241 }
1242
1243 template <class _RandomAccessIter>
1244 void __final_insertion_sort(_RandomAccessIter __first, 
1245                             _RandomAccessIter __last) {
1246   if (__last - __first > __stl_threshold) {
1247     __insertion_sort(__first, __first + __stl_threshold);
1248     __unguarded_insertion_sort(__first + __stl_threshold, __last);
1249   }
1250   else
1251     __insertion_sort(__first, __last);
1252 }
1253
1254 template <class _RandomAccessIter, class _Compare>
1255 void __final_insertion_sort(_RandomAccessIter __first, 
1256                             _RandomAccessIter __last, _Compare __comp) {
1257   if (__last - __first > __stl_threshold) {
1258     __insertion_sort(__first, __first + __stl_threshold, __comp);
1259     __unguarded_insertion_sort(__first + __stl_threshold, __last, __comp);
1260   }
1261   else
1262     __insertion_sort(__first, __last, __comp);
1263 }
1264
1265 template <class _Size>
1266 inline _Size __lg(_Size __n) {
1267   _Size __k;
1268   for (__k = 0; __n != 1; __n >>= 1) ++__k;
1269   return __k;
1270 }
1271
1272 template <class _RandomAccessIter, class _Tp, class _Size>
1273 void __introsort_loop(_RandomAccessIter __first,
1274                       _RandomAccessIter __last, _Tp*,
1275                       _Size __depth_limit)
1276 {
1277   while (__last - __first > __stl_threshold) {
1278     if (__depth_limit == 0) {
1279       partial_sort(__first, __last, __last);
1280       return;
1281     }
1282     --__depth_limit;
1283     _RandomAccessIter __cut =
1284       __unguarded_partition(__first, __last,
1285                             _Tp(__median(*__first,
1286                                          *(__first + (__last - __first)/2),
1287                                          *(__last - 1))));
1288     __introsort_loop(__cut, __last, (_Tp*) 0, __depth_limit);
1289     __last = __cut;
1290   }
1291 }
1292
1293 template <class _RandomAccessIter, class _Tp, class _Size, class _Compare>
1294 void __introsort_loop(_RandomAccessIter __first,
1295                       _RandomAccessIter __last, _Tp*,
1296                       _Size __depth_limit, _Compare __comp)
1297 {
1298   while (__last - __first > __stl_threshold) {
1299     if (__depth_limit == 0) {
1300       partial_sort(__first, __last, __last, __comp);
1301       return;
1302     }
1303     --__depth_limit;
1304     _RandomAccessIter __cut =
1305       __unguarded_partition(__first, __last,
1306                             _Tp(__median(*__first,
1307                                          *(__first + (__last - __first)/2),
1308                                          *(__last - 1), __comp)),
1309        __comp);
1310     __introsort_loop(__cut, __last, (_Tp*) 0, __depth_limit, __comp);
1311     __last = __cut;
1312   }
1313 }
1314
1315 template <class _RandomAccessIter>
1316 inline void sort(_RandomAccessIter __first, _RandomAccessIter __last) {
1317   if (__first != __last) {
1318     __introsort_loop(__first, __last,
1319                      __VALUE_TYPE(__first),
1320                      __lg(__last - __first) * 2);
1321     __final_insertion_sort(__first, __last);
1322   }
1323 }
1324
1325 template <class _RandomAccessIter, class _Compare>
1326 inline void sort(_RandomAccessIter __first, _RandomAccessIter __last,
1327                  _Compare __comp) {
1328   if (__first != __last) {
1329     __introsort_loop(__first, __last,
1330                      __VALUE_TYPE(__first),
1331                      __lg(__last - __first) * 2,
1332                      __comp);
1333     __final_insertion_sort(__first, __last, __comp);
1334   }
1335 }
1336
1337 // stable_sort() and its auxiliary functions.
1338
1339 template <class _RandomAccessIter>
1340 void __inplace_stable_sort(_RandomAccessIter __first,
1341                            _RandomAccessIter __last) {
1342   if (__last - __first < 15) {
1343     __insertion_sort(__first, __last);
1344     return;
1345   }
1346   _RandomAccessIter __middle = __first + (__last - __first) / 2;
1347   __inplace_stable_sort(__first, __middle);
1348   __inplace_stable_sort(__middle, __last);
1349   __merge_without_buffer(__first, __middle, __last,
1350                          __middle - __first,
1351                          __last - __middle);
1352 }
1353
1354 template <class _RandomAccessIter, class _Compare>
1355 void __inplace_stable_sort(_RandomAccessIter __first,
1356                            _RandomAccessIter __last, _Compare __comp) {
1357   if (__last - __first < 15) {
1358     __insertion_sort(__first, __last, __comp);
1359     return;
1360   }
1361   _RandomAccessIter __middle = __first + (__last - __first) / 2;
1362   __inplace_stable_sort(__first, __middle, __comp);
1363   __inplace_stable_sort(__middle, __last, __comp);
1364   __merge_without_buffer(__first, __middle, __last,
1365                          __middle - __first,
1366                          __last - __middle,
1367                          __comp);
1368 }
1369
1370 template <class _RandomAccessIter1, class _RandomAccessIter2,
1371           class _Distance>
1372 void __merge_sort_loop(_RandomAccessIter1 __first,
1373                        _RandomAccessIter1 __last, 
1374                        _RandomAccessIter2 __result, _Distance __step_size) {
1375   _Distance __two_step = 2 * __step_size;
1376
1377   while (__last - __first >= __two_step) {
1378     __result = merge(__first, __first + __step_size,
1379                      __first + __step_size, __first + __two_step,
1380                      __result);
1381     __first += __two_step;
1382   }
1383
1384   __step_size = min(_Distance(__last - __first), __step_size);
1385   merge(__first, __first + __step_size, __first + __step_size, __last,
1386         __result);
1387 }
1388
1389 template <class _RandomAccessIter1, class _RandomAccessIter2,
1390           class _Distance, class _Compare>
1391 void __merge_sort_loop(_RandomAccessIter1 __first,
1392                        _RandomAccessIter1 __last, 
1393                        _RandomAccessIter2 __result, _Distance __step_size,
1394                        _Compare __comp) {
1395   _Distance __two_step = 2 * __step_size;
1396
1397   while (__last - __first >= __two_step) {
1398     __result = merge(__first, __first + __step_size,
1399                      __first + __step_size, __first + __two_step,
1400                      __result,
1401                      __comp);
1402     __first += __two_step;
1403   }
1404   __step_size = min(_Distance(__last - __first), __step_size);
1405
1406   merge(__first, __first + __step_size,
1407         __first + __step_size, __last,
1408         __result,
1409         __comp);
1410 }
1411
1412 const int __stl_chunk_size = 7;
1413         
1414 template <class _RandomAccessIter, class _Distance>
1415 void __chunk_insertion_sort(_RandomAccessIter __first, 
1416                             _RandomAccessIter __last, _Distance __chunk_size)
1417 {
1418   while (__last - __first >= __chunk_size) {
1419     __insertion_sort(__first, __first + __chunk_size);
1420     __first += __chunk_size;
1421   }
1422   __insertion_sort(__first, __last);
1423 }
1424
1425 template <class _RandomAccessIter, class _Distance, class _Compare>
1426 void __chunk_insertion_sort(_RandomAccessIter __first, 
1427                             _RandomAccessIter __last,
1428                             _Distance __chunk_size, _Compare __comp)
1429 {
1430   while (__last - __first >= __chunk_size) {
1431     __insertion_sort(__first, __first + __chunk_size, __comp);
1432     __first += __chunk_size;
1433   }
1434   __insertion_sort(__first, __last, __comp);
1435 }
1436
1437 template <class _RandomAccessIter, class _Pointer, class _Distance>
1438 void __merge_sort_with_buffer(_RandomAccessIter __first, 
1439                               _RandomAccessIter __last,
1440                               _Pointer __buffer, _Distance*) {
1441   _Distance __len = __last - __first;
1442   _Pointer __buffer_last = __buffer + __len;
1443
1444   _Distance __step_size = __stl_chunk_size;
1445   __chunk_insertion_sort(__first, __last, __step_size);
1446
1447   while (__step_size < __len) {
1448     __merge_sort_loop(__first, __last, __buffer, __step_size);
1449     __step_size *= 2;
1450     __merge_sort_loop(__buffer, __buffer_last, __first, __step_size);
1451     __step_size *= 2;
1452   }
1453 }
1454
1455 template <class _RandomAccessIter, class _Pointer, class _Distance,
1456           class _Compare>
1457 void __merge_sort_with_buffer(_RandomAccessIter __first, 
1458                               _RandomAccessIter __last, _Pointer __buffer,
1459                               _Distance*, _Compare __comp) {
1460   _Distance __len = __last - __first;
1461   _Pointer __buffer_last = __buffer + __len;
1462
1463   _Distance __step_size = __stl_chunk_size;
1464   __chunk_insertion_sort(__first, __last, __step_size, __comp);
1465
1466   while (__step_size < __len) {
1467     __merge_sort_loop(__first, __last, __buffer, __step_size, __comp);
1468     __step_size *= 2;
1469     __merge_sort_loop(__buffer, __buffer_last, __first, __step_size, __comp);
1470     __step_size *= 2;
1471   }
1472 }
1473
1474 template <class _RandomAccessIter, class _Pointer, class _Distance>
1475 void __stable_sort_adaptive(_RandomAccessIter __first, 
1476                             _RandomAccessIter __last, _Pointer __buffer,
1477                             _Distance __buffer_size) {
1478   _Distance __len = (__last - __first + 1) / 2;
1479   _RandomAccessIter __middle = __first + __len;
1480   if (__len > __buffer_size) {
1481     __stable_sort_adaptive(__first, __middle, __buffer, __buffer_size);
1482     __stable_sort_adaptive(__middle, __last, __buffer, __buffer_size);
1483   }
1484   else {
1485     __merge_sort_with_buffer(__first, __middle, __buffer, (_Distance*)0);
1486     __merge_sort_with_buffer(__middle, __last, __buffer, (_Distance*)0);
1487   }
1488   __merge_adaptive(__first, __middle, __last, _Distance(__middle - __first), 
1489                    _Distance(__last - __middle), __buffer, __buffer_size);
1490 }
1491
1492 template <class _RandomAccessIter, class _Pointer, class _Distance, 
1493           class _Compare>
1494 void __stable_sort_adaptive(_RandomAccessIter __first, 
1495                             _RandomAccessIter __last, _Pointer __buffer,
1496                             _Distance __buffer_size, _Compare __comp) {
1497   _Distance __len = (__last - __first + 1) / 2;
1498   _RandomAccessIter __middle = __first + __len;
1499   if (__len > __buffer_size) {
1500     __stable_sort_adaptive(__first, __middle, __buffer, __buffer_size, 
1501                            __comp);
1502     __stable_sort_adaptive(__middle, __last, __buffer, __buffer_size, 
1503                            __comp);
1504   }
1505   else {
1506     __merge_sort_with_buffer(__first, __middle, __buffer, (_Distance*)0,
1507                                __comp);
1508     __merge_sort_with_buffer(__middle, __last, __buffer, (_Distance*)0,
1509                                __comp);
1510   }
1511   __merge_adaptive(__first, __middle, __last, _Distance(__middle - __first), 
1512                    _Distance(__last - __middle), __buffer, __buffer_size,
1513                    __comp);
1514 }
1515
1516 template <class _RandomAccessIter, class _Tp, class _Distance>
1517 inline void __stable_sort_aux(_RandomAccessIter __first,
1518                               _RandomAccessIter __last, _Tp*, _Distance*) {
1519   _Temporary_buffer<_RandomAccessIter, _Tp> buf(__first, __last);
1520   if (buf.begin() == 0)
1521     __inplace_stable_sort(__first, __last);
1522   else 
1523     __stable_sort_adaptive(__first, __last, buf.begin(),
1524                            _Distance(buf.size()));
1525 }
1526
1527 template <class _RandomAccessIter, class _Tp, class _Distance, class _Compare>
1528 inline void __stable_sort_aux(_RandomAccessIter __first,
1529                               _RandomAccessIter __last, _Tp*, _Distance*,
1530                               _Compare __comp) {
1531   _Temporary_buffer<_RandomAccessIter, _Tp> buf(__first, __last);
1532   if (buf.begin() == 0)
1533     __inplace_stable_sort(__first, __last, __comp);
1534   else 
1535     __stable_sort_adaptive(__first, __last, buf.begin(),
1536                            _Distance(buf.size()),
1537                            __comp);
1538 }
1539
1540 template <class _RandomAccessIter>
1541 inline void stable_sort(_RandomAccessIter __first,
1542                         _RandomAccessIter __last) {
1543   __stable_sort_aux(__first, __last,
1544                     __VALUE_TYPE(__first),
1545                     __DISTANCE_TYPE(__first));
1546 }
1547
1548 template <class _RandomAccessIter, class _Compare>
1549 inline void stable_sort(_RandomAccessIter __first,
1550                         _RandomAccessIter __last, _Compare __comp) {
1551   __stable_sort_aux(__first, __last,
1552                     __VALUE_TYPE(__first),
1553                     __DISTANCE_TYPE(__first), 
1554                     __comp);
1555 }
1556
1557 // partial_sort, partial_sort_copy, and auxiliary functions.
1558
1559 template <class _RandomAccessIter, class _Tp>
1560 void __partial_sort(_RandomAccessIter __first, _RandomAccessIter __middle,
1561                     _RandomAccessIter __last, _Tp*) {
1562   make_heap(__first, __middle);
1563   for (_RandomAccessIter __i = __middle; __i < __last; ++__i)
1564     if (*__i < *__first) 
1565       __pop_heap(__first, __middle, __i, _Tp(*__i),
1566                  __DISTANCE_TYPE(__first));
1567   sort_heap(__first, __middle);
1568 }
1569
1570 template <class _RandomAccessIter>
1571 inline void partial_sort(_RandomAccessIter __first,
1572                          _RandomAccessIter __middle,
1573                          _RandomAccessIter __last) {
1574   __partial_sort(__first, __middle, __last, __VALUE_TYPE(__first));
1575 }
1576
1577 template <class _RandomAccessIter, class _Tp, class _Compare>
1578 void __partial_sort(_RandomAccessIter __first, _RandomAccessIter __middle,
1579                     _RandomAccessIter __last, _Tp*, _Compare __comp) {
1580   make_heap(__first, __middle, __comp);
1581   for (_RandomAccessIter __i = __middle; __i < __last; ++__i)
1582     if (__comp(*__i, *__first))
1583       __pop_heap(__first, __middle, __i, _Tp(*__i), __comp,
1584                  __DISTANCE_TYPE(__first));
1585   sort_heap(__first, __middle, __comp);
1586 }
1587
1588 template <class _RandomAccessIter, class _Compare>
1589 inline void partial_sort(_RandomAccessIter __first,
1590                          _RandomAccessIter __middle,
1591                          _RandomAccessIter __last, _Compare __comp) {
1592   __partial_sort(__first, __middle, __last, __VALUE_TYPE(__first), __comp);
1593 }
1594
1595 template <class _InputIter, class _RandomAccessIter, class _Distance,
1596           class _Tp>
1597 _RandomAccessIter __partial_sort_copy(_InputIter __first,
1598                                          _InputIter __last,
1599                                          _RandomAccessIter __result_first,
1600                                          _RandomAccessIter __result_last, 
1601                                          _Distance*, _Tp*) {
1602   if (__result_first == __result_last) return __result_last;
1603   _RandomAccessIter __result_real_last = __result_first;
1604   while(__first != __last && __result_real_last != __result_last) {
1605     *__result_real_last = *__first;
1606     ++__result_real_last;
1607     ++__first;
1608   }
1609   make_heap(__result_first, __result_real_last);
1610   while (__first != __last) {
1611     if (*__first < *__result_first) 
1612       __adjust_heap(__result_first, _Distance(0),
1613                     _Distance(__result_real_last - __result_first),
1614                     _Tp(*__first));
1615     ++__first;
1616   }
1617   sort_heap(__result_first, __result_real_last);
1618   return __result_real_last;
1619 }
1620
1621 template <class _InputIter, class _RandomAccessIter>
1622 inline _RandomAccessIter
1623 partial_sort_copy(_InputIter __first, _InputIter __last,
1624                   _RandomAccessIter __result_first,
1625                   _RandomAccessIter __result_last) {
1626   return __partial_sort_copy(__first, __last, __result_first, __result_last, 
1627                              __DISTANCE_TYPE(__result_first),
1628                              __VALUE_TYPE(__first));
1629 }
1630
1631 template <class _InputIter, class _RandomAccessIter, class _Compare,
1632           class _Distance, class _Tp>
1633 _RandomAccessIter __partial_sort_copy(_InputIter __first,
1634                                          _InputIter __last,
1635                                          _RandomAccessIter __result_first,
1636                                          _RandomAccessIter __result_last,
1637                                          _Compare __comp, _Distance*, _Tp*) {
1638   if (__result_first == __result_last) return __result_last;
1639   _RandomAccessIter __result_real_last = __result_first;
1640   while(__first != __last && __result_real_last != __result_last) {
1641     *__result_real_last = *__first;
1642     ++__result_real_last;
1643     ++__first;
1644   }
1645   make_heap(__result_first, __result_real_last, __comp);
1646   while (__first != __last) {
1647     if (__comp(*__first, *__result_first))
1648       __adjust_heap(__result_first, _Distance(0),
1649                     _Distance(__result_real_last - __result_first),
1650                     _Tp(*__first),
1651                     __comp);
1652     ++__first;
1653   }
1654   sort_heap(__result_first, __result_real_last, __comp);
1655   return __result_real_last;
1656 }
1657
1658 template <class _InputIter, class _RandomAccessIter, class _Compare>
1659 inline _RandomAccessIter
1660 partial_sort_copy(_InputIter __first, _InputIter __last,
1661                   _RandomAccessIter __result_first,
1662                   _RandomAccessIter __result_last, _Compare __comp) {
1663   return __partial_sort_copy(__first, __last, __result_first, __result_last,
1664                              __comp,
1665                              __DISTANCE_TYPE(__result_first),
1666                              __VALUE_TYPE(__first));
1667 }
1668
1669 // nth_element() and its auxiliary functions.  
1670
1671 template <class _RandomAccessIter, class _Tp>
1672 void __nth_element(_RandomAccessIter __first, _RandomAccessIter __nth,
1673                    _RandomAccessIter __last, _Tp*) {
1674   while (__last - __first > 3) {
1675     _RandomAccessIter __cut =
1676       __unguarded_partition(__first, __last,
1677                             _Tp(__median(*__first,
1678                                          *(__first + (__last - __first)/2),
1679                                          *(__last - 1))));
1680     if (__cut <= __nth)
1681       __first = __cut;
1682     else 
1683       __last = __cut;
1684   }
1685   __insertion_sort(__first, __last);
1686 }
1687
1688 template <class _RandomAccessIter>
1689 inline void nth_element(_RandomAccessIter __first, _RandomAccessIter __nth,
1690                         _RandomAccessIter __last) {
1691   __nth_element(__first, __nth, __last, __VALUE_TYPE(__first));
1692 }
1693
1694 template <class _RandomAccessIter, class _Tp, class _Compare>
1695 void __nth_element(_RandomAccessIter __first, _RandomAccessIter __nth,
1696                    _RandomAccessIter __last, _Tp*, _Compare __comp) {
1697   while (__last - __first > 3) {
1698     _RandomAccessIter __cut =
1699       __unguarded_partition(__first, __last,
1700                             _Tp(__median(*__first,
1701                                          *(__first + (__last - __first)/2), 
1702                                          *(__last - 1),
1703                                          __comp)),
1704                             __comp);
1705     if (__cut <= __nth)
1706       __first = __cut;
1707     else 
1708       __last = __cut;
1709   }
1710   __insertion_sort(__first, __last, __comp);
1711 }
1712
1713 template <class _RandomAccessIter, class _Compare>
1714 inline void nth_element(_RandomAccessIter __first, _RandomAccessIter __nth,
1715                  _RandomAccessIter __last, _Compare __comp) {
1716   __nth_element(__first, __nth, __last, __VALUE_TYPE(__first), __comp);
1717 }
1718
1719
1720 // Binary search (lower_bound, upper_bound, equal_range, binary_search).
1721
1722 template <class _ForwardIter, class _Tp, class _Distance>
1723 _ForwardIter __lower_bound(_ForwardIter __first, _ForwardIter __last,
1724                            const _Tp& __val, _Distance*) 
1725 {
1726   _Distance __len = 0;
1727   distance(__first, __last, __len);
1728   _Distance __half;
1729   _ForwardIter __middle;
1730
1731   while (__len > 0) {
1732     __half = __len >> 1;
1733     __middle = __first;
1734     advance(__middle, __half);
1735     if (*__middle < __val) {
1736       __first = __middle;
1737       ++__first;
1738       __len = __len - __half - 1;
1739     }
1740     else
1741       __len = __half;
1742   }
1743   return __first;
1744 }
1745
1746 template <class _ForwardIter, class _Tp>
1747 inline _ForwardIter lower_bound(_ForwardIter __first, _ForwardIter __last,
1748                                    const _Tp& __val) {
1749   return __lower_bound(__first, __last, __val,
1750                        __DISTANCE_TYPE(__first));
1751 }
1752
1753 template <class _ForwardIter, class _Tp, class _Compare, class _Distance>
1754 _ForwardIter __lower_bound(_ForwardIter __first, _ForwardIter __last,
1755                               const _Tp& __val, _Compare __comp, _Distance*)
1756 {
1757   _Distance __len = 0;
1758   distance(__first, __last, __len);
1759   _Distance __half;
1760   _ForwardIter __middle;
1761
1762   while (__len > 0) {
1763     __half = __len >> 1;
1764     __middle = __first;
1765     advance(__middle, __half);
1766     if (__comp(*__middle, __val)) {
1767       __first = __middle;
1768       ++__first;
1769       __len = __len - __half - 1;
1770     }
1771     else
1772       __len = __half;
1773   }
1774   return __first;
1775 }
1776
1777 template <class _ForwardIter, class _Tp, class _Compare>
1778 inline _ForwardIter lower_bound(_ForwardIter __first, _ForwardIter __last,
1779                                 const _Tp& __val, _Compare __comp) {
1780   return __lower_bound(__first, __last, __val, __comp,
1781                        __DISTANCE_TYPE(__first));
1782 }
1783
1784 template <class _ForwardIter, class _Tp, class _Distance>
1785 _ForwardIter __upper_bound(_ForwardIter __first, _ForwardIter __last,
1786                            const _Tp& __val, _Distance*)
1787 {
1788   _Distance __len = 0;
1789   distance(__first, __last, __len);
1790   _Distance __half;
1791   _ForwardIter __middle;
1792
1793   while (__len > 0) {
1794     __half = __len >> 1;
1795     __middle = __first;
1796     advance(__middle, __half);
1797     if (__val < *__middle)
1798       __len = __half;
1799     else {
1800       __first = __middle;
1801       ++__first;
1802       __len = __len - __half - 1;
1803     }
1804   }
1805   return __first;
1806 }
1807
1808 template <class _ForwardIter, class _Tp>
1809 inline _ForwardIter upper_bound(_ForwardIter __first, _ForwardIter __last,
1810                                 const _Tp& __val) {
1811   return __upper_bound(__first, __last, __val,
1812                        __DISTANCE_TYPE(__first));
1813 }
1814
1815 template <class _ForwardIter, class _Tp, class _Compare, class _Distance>
1816 _ForwardIter __upper_bound(_ForwardIter __first, _ForwardIter __last,
1817                            const _Tp& __val, _Compare __comp, _Distance*)
1818 {
1819   _Distance __len = 0;
1820   distance(__first, __last, __len);
1821   _Distance __half;
1822   _ForwardIter __middle;
1823
1824   while (__len > 0) {
1825     __half = __len >> 1;
1826     __middle = __first;
1827     advance(__middle, __half);
1828     if (__comp(__val, *__middle))
1829       __len = __half;
1830     else {
1831       __first = __middle;
1832       ++__first;
1833       __len = __len - __half - 1;
1834     }
1835   }
1836   return __first;
1837 }
1838
1839 template <class _ForwardIter, class _Tp, class _Compare>
1840 inline _ForwardIter upper_bound(_ForwardIter __first, _ForwardIter __last,
1841                                 const _Tp& __val, _Compare __comp) {
1842   return __upper_bound(__first, __last, __val, __comp,
1843                        __DISTANCE_TYPE(__first));
1844 }
1845
1846 template <class _ForwardIter, class _Tp, class _Distance>
1847 pair<_ForwardIter, _ForwardIter>
1848 __equal_range(_ForwardIter __first, _ForwardIter __last, const _Tp& __val,
1849               _Distance*)
1850 {
1851   _Distance __len = 0;
1852   distance(__first, __last, __len);
1853   _Distance __half;
1854   _ForwardIter __middle, __left, __right;
1855
1856   while (__len > 0) {
1857     __half = __len >> 1;
1858     __middle = __first;
1859     advance(__middle, __half);
1860     if (*__middle < __val) {
1861       __first = __middle;
1862       ++__first;
1863       __len = __len - __half - 1;
1864     }
1865     else if (__val < *__middle)
1866       __len = __half;
1867     else {
1868       __left = lower_bound(__first, __middle, __val);
1869       advance(__first, __len);
1870       __right = upper_bound(++__middle, __first, __val);
1871       return pair<_ForwardIter, _ForwardIter>(__left, __right);
1872     }
1873   }
1874   return pair<_ForwardIter, _ForwardIter>(__first, __first);
1875 }
1876
1877 template <class _ForwardIter, class _Tp>
1878 inline pair<_ForwardIter, _ForwardIter>
1879 equal_range(_ForwardIter __first, _ForwardIter __last, const _Tp& __val) {
1880   return __equal_range(__first, __last, __val,
1881                        __DISTANCE_TYPE(__first));
1882 }
1883
1884 template <class _ForwardIter, class _Tp, class _Compare, class _Distance>
1885 pair<_ForwardIter, _ForwardIter>
1886 __equal_range(_ForwardIter __first, _ForwardIter __last, const _Tp& __val,
1887               _Compare __comp, _Distance*)
1888 {
1889   _Distance __len = 0;
1890   distance(__first, __last, __len);
1891   _Distance __half;
1892   _ForwardIter __middle, __left, __right;
1893
1894   while (__len > 0) {
1895     __half = __len >> 1;
1896     __middle = __first;
1897     advance(__middle, __half);
1898     if (__comp(*__middle, __val)) {
1899       __first = __middle;
1900       ++__first;
1901       __len = __len - __half - 1;
1902     }
1903     else if (__comp(__val, *__middle))
1904       __len = __half;
1905     else {
1906       __left = lower_bound(__first, __middle, __val, __comp);
1907       advance(__first, __len);
1908       __right = upper_bound(++__middle, __first, __val, __comp);
1909       return pair<_ForwardIter, _ForwardIter>(__left, __right);
1910     }
1911   }
1912   return pair<_ForwardIter, _ForwardIter>(__first, __first);
1913 }           
1914
1915 template <class _ForwardIter, class _Tp, class _Compare>
1916 inline pair<_ForwardIter, _ForwardIter>
1917 equal_range(_ForwardIter __first, _ForwardIter __last, const _Tp& __val,
1918             _Compare __comp) {
1919   return __equal_range(__first, __last, __val, __comp,
1920                        __DISTANCE_TYPE(__first));
1921
1922
1923 template <class _ForwardIter, class _Tp>
1924 bool binary_search(_ForwardIter __first, _ForwardIter __last,
1925                    const _Tp& __val) {
1926   _ForwardIter __i = lower_bound(__first, __last, __val);
1927   return __i != __last && !(__val < *__i);
1928 }
1929
1930 template <class _ForwardIter, class _Tp, class _Compare>
1931 bool binary_search(_ForwardIter __first, _ForwardIter __last,
1932                    const _Tp& __val,
1933                    _Compare __comp) {
1934   _ForwardIter __i = lower_bound(__first, __last, __val, __comp);
1935   return __i != __last && !__comp(__val, *__i);
1936 }
1937
1938 // merge, with and without an explicitly supplied comparison function.
1939
1940 template <class _InputIter1, class _InputIter2, class _OutputIter>
1941 _OutputIter merge(_InputIter1 __first1, _InputIter1 __last1,
1942                   _InputIter2 __first2, _InputIter2 __last2,
1943                   _OutputIter __result) {
1944   while (__first1 != __last1 && __first2 != __last2) {
1945     if (*__first2 < *__first1) {
1946       *__result = *__first2;
1947       ++__first2;
1948     }
1949     else {
1950       *__result = *__first1;
1951       ++__first1;
1952     }
1953     ++__result;
1954   }
1955   return copy(__first2, __last2, copy(__first1, __last1, __result));
1956 }
1957
1958 template <class _InputIter1, class _InputIter2, class _OutputIter,
1959           class _Compare>
1960 _OutputIter merge(_InputIter1 __first1, _InputIter1 __last1,
1961                   _InputIter2 __first2, _InputIter2 __last2,
1962                   _OutputIter __result, _Compare __comp) {
1963   while (__first1 != __last1 && __first2 != __last2) {
1964     if (__comp(*__first2, *__first1)) {
1965       *__result = *__first2;
1966       ++__first2;
1967     }
1968     else {
1969       *__result = *__first1;
1970       ++__first1;
1971     }
1972     ++__result;
1973   }
1974   return copy(__first2, __last2, copy(__first1, __last1, __result));
1975 }
1976
1977 // inplace_merge and its auxiliary functions. 
1978
1979 template <class _BidirectionalIter, class _Distance>
1980 void __merge_without_buffer(_BidirectionalIter __first,
1981                             _BidirectionalIter __middle,
1982                             _BidirectionalIter __last,
1983                             _Distance __len1, _Distance __len2) {
1984   if (__len1 == 0 || __len2 == 0)
1985     return;
1986   if (__len1 + __len2 == 2) {
1987     if (*__middle < *__first)
1988       iter_swap(__first, __middle);
1989     return;
1990   }
1991   _BidirectionalIter __first_cut = __first;
1992   _BidirectionalIter __second_cut = __middle;
1993   _Distance __len11 = 0;
1994   _Distance __len22 = 0;
1995   if (__len1 > __len2) {
1996     __len11 = __len1 / 2;
1997     advance(__first_cut, __len11);
1998     __second_cut = lower_bound(__middle, __last, *__first_cut);
1999     distance(__middle, __second_cut, __len22);
2000   }
2001   else {
2002     __len22 = __len2 / 2;
2003     advance(__second_cut, __len22);
2004     __first_cut = upper_bound(__first, __middle, *__second_cut);
2005     distance(__first, __first_cut, __len11);
2006   }
2007   _BidirectionalIter __new_middle
2008     = rotate(__first_cut, __middle, __second_cut);
2009   __merge_without_buffer(__first, __first_cut, __new_middle,
2010                          __len11, __len22);
2011   __merge_without_buffer(__new_middle, __second_cut, __last, __len1 - __len11,
2012                          __len2 - __len22);
2013 }
2014
2015 template <class _BidirectionalIter, class _Distance, class _Compare>
2016 void __merge_without_buffer(_BidirectionalIter __first,
2017                             _BidirectionalIter __middle,
2018                             _BidirectionalIter __last,
2019                             _Distance __len1, _Distance __len2,
2020                             _Compare __comp) {
2021   if (__len1 == 0 || __len2 == 0)
2022     return;
2023   if (__len1 + __len2 == 2) {
2024     if (__comp(*__middle, *__first))
2025       iter_swap(__first, __middle);
2026     return;
2027   }
2028   _BidirectionalIter __first_cut = __first;
2029   _BidirectionalIter __second_cut = __middle;
2030   _Distance __len11 = 0;
2031   _Distance __len22 = 0;
2032   if (__len1 > __len2) {
2033     __len11 = __len1 / 2;
2034     advance(__first_cut, __len11);
2035     __second_cut = lower_bound(__middle, __last, *__first_cut, __comp);
2036     distance(__middle, __second_cut, __len22);
2037   }
2038   else {
2039     __len22 = __len2 / 2;
2040     advance(__second_cut, __len22);
2041     __first_cut = upper_bound(__first, __middle, *__second_cut, __comp);
2042     distance(__first, __first_cut, __len11);
2043   }
2044   _BidirectionalIter __new_middle
2045     = rotate(__first_cut, __middle, __second_cut);
2046   __merge_without_buffer(__first, __first_cut, __new_middle, __len11, __len22,
2047                          __comp);
2048   __merge_without_buffer(__new_middle, __second_cut, __last, __len1 - __len11,
2049                          __len2 - __len22, __comp);
2050 }
2051
2052 template <class _BidirectionalIter1, class _BidirectionalIter2,
2053           class _Distance>
2054 _BidirectionalIter1 __rotate_adaptive(_BidirectionalIter1 __first,
2055                                       _BidirectionalIter1 __middle,
2056                                       _BidirectionalIter1 __last,
2057                                       _Distance __len1, _Distance __len2,
2058                                       _BidirectionalIter2 __buffer,
2059                                       _Distance __buffer_size) {
2060   _BidirectionalIter2 __buffer_end;
2061   if (__len1 > __len2 && __len2 <= __buffer_size) {
2062     __buffer_end = copy(__middle, __last, __buffer);
2063     copy_backward(__first, __middle, __last);
2064     return copy(__buffer, __buffer_end, __first);
2065   }
2066   else if (__len1 <= __buffer_size) {
2067     __buffer_end = copy(__first, __middle, __buffer);
2068     copy(__middle, __last, __first);
2069     return copy_backward(__buffer, __buffer_end, __last);
2070   }
2071   else
2072     return rotate(__first, __middle, __last);
2073 }
2074
2075 template <class _BidirectionalIter1, class _BidirectionalIter2,
2076           class _BidirectionalIter3>
2077 _BidirectionalIter3 __merge_backward(_BidirectionalIter1 __first1,
2078                                      _BidirectionalIter1 __last1,
2079                                      _BidirectionalIter2 __first2,
2080                                      _BidirectionalIter2 __last2,
2081                                      _BidirectionalIter3 __result) {
2082   if (__first1 == __last1)
2083     return copy_backward(__first2, __last2, __result);
2084   if (__first2 == __last2)
2085     return copy_backward(__first1, __last1, __result);
2086   --__last1;
2087   --__last2;
2088   while (true) {
2089     if (*__last2 < *__last1) {
2090       *--__result = *__last1;
2091       if (__first1 == __last1)
2092         return copy_backward(__first2, ++__last2, __result);
2093       --__last1;
2094     }
2095     else {
2096       *--__result = *__last2;
2097       if (__first2 == __last2)
2098         return copy_backward(__first1, ++__last1, __result);
2099       --__last2;
2100     }
2101   }
2102 }
2103
2104 template <class _BidirectionalIter1, class _BidirectionalIter2,
2105           class _BidirectionalIter3, class _Compare>
2106 _BidirectionalIter3 __merge_backward(_BidirectionalIter1 __first1,
2107                                      _BidirectionalIter1 __last1,
2108                                      _BidirectionalIter2 __first2,
2109                                      _BidirectionalIter2 __last2,
2110                                      _BidirectionalIter3 __result,
2111                                      _Compare __comp) {
2112   if (__first1 == __last1)
2113     return copy_backward(__first2, __last2, __result);
2114   if (__first2 == __last2)
2115     return copy_backward(__first1, __last1, __result);
2116   --__last1;
2117   --__last2;
2118   while (true) {
2119     if (__comp(*__last2, *__last1)) {
2120       *--__result = *__last1;
2121       if (__first1 == __last1)
2122         return copy_backward(__first2, ++__last2, __result);
2123       --__last1;
2124     }
2125     else {
2126       *--__result = *__last2;
2127       if (__first2 == __last2)
2128         return copy_backward(__first1, ++__last1, __result);
2129       --__last2;
2130     }
2131   }
2132 }
2133
2134 template <class _BidirectionalIter, class _Distance, class _Pointer>
2135 void __merge_adaptive(_BidirectionalIter __first,
2136                       _BidirectionalIter __middle, 
2137                       _BidirectionalIter __last,
2138                       _Distance __len1, _Distance __len2,
2139                       _Pointer __buffer, _Distance __buffer_size) {
2140   if (__len1 <= __len2 && __len1 <= __buffer_size) {
2141     _Pointer __buffer_end = copy(__first, __middle, __buffer);
2142     merge(__buffer, __buffer_end, __middle, __last, __first);
2143   }
2144   else if (__len2 <= __buffer_size) {
2145     _Pointer __buffer_end = copy(__middle, __last, __buffer);
2146     __merge_backward(__first, __middle, __buffer, __buffer_end, __last);
2147   }
2148   else {
2149     _BidirectionalIter __first_cut = __first;
2150     _BidirectionalIter __second_cut = __middle;
2151     _Distance __len11 = 0;
2152     _Distance __len22 = 0;
2153     if (__len1 > __len2) {
2154       __len11 = __len1 / 2;
2155       advance(__first_cut, __len11);
2156       __second_cut = lower_bound(__middle, __last, *__first_cut);
2157       distance(__middle, __second_cut, __len22); 
2158     }
2159     else {
2160       __len22 = __len2 / 2;
2161       advance(__second_cut, __len22);
2162       __first_cut = upper_bound(__first, __middle, *__second_cut);
2163       distance(__first, __first_cut, __len11);
2164     }
2165     _BidirectionalIter __new_middle =
2166       __rotate_adaptive(__first_cut, __middle, __second_cut, __len1 - __len11,
2167                         __len22, __buffer, __buffer_size);
2168     __merge_adaptive(__first, __first_cut, __new_middle, __len11,
2169                      __len22, __buffer, __buffer_size);
2170     __merge_adaptive(__new_middle, __second_cut, __last, __len1 - __len11,
2171                      __len2 - __len22, __buffer, __buffer_size);
2172   }
2173 }
2174
2175 template <class _BidirectionalIter, class _Distance, class _Pointer,
2176           class _Compare>
2177 void __merge_adaptive(_BidirectionalIter __first, 
2178                       _BidirectionalIter __middle, 
2179                       _BidirectionalIter __last,
2180                       _Distance __len1, _Distance __len2,
2181                       _Pointer __buffer, _Distance __buffer_size,
2182                       _Compare __comp) {
2183   if (__len1 <= __len2 && __len1 <= __buffer_size) {
2184     _Pointer __buffer_end = copy(__first, __middle, __buffer);
2185     merge(__buffer, __buffer_end, __middle, __last, __first, __comp);
2186   }
2187   else if (__len2 <= __buffer_size) {
2188     _Pointer __buffer_end = copy(__middle, __last, __buffer);
2189     __merge_backward(__first, __middle, __buffer, __buffer_end, __last,
2190                      __comp);
2191   }
2192   else {
2193     _BidirectionalIter __first_cut = __first;
2194     _BidirectionalIter __second_cut = __middle;
2195     _Distance __len11 = 0;
2196     _Distance __len22 = 0;
2197     if (__len1 > __len2) {
2198       __len11 = __len1 / 2;
2199       advance(__first_cut, __len11);
2200       __second_cut = lower_bound(__middle, __last, *__first_cut, __comp);
2201       distance(__middle, __second_cut, __len22);   
2202     }
2203     else {
2204       __len22 = __len2 / 2;
2205       advance(__second_cut, __len22);
2206       __first_cut = upper_bound(__first, __middle, *__second_cut, __comp);
2207       distance(__first, __first_cut, __len11);
2208     }
2209     _BidirectionalIter __new_middle =
2210       __rotate_adaptive(__first_cut, __middle, __second_cut, __len1 - __len11,
2211                         __len22, __buffer, __buffer_size);
2212     __merge_adaptive(__first, __first_cut, __new_middle, __len11,
2213                      __len22, __buffer, __buffer_size, __comp);
2214     __merge_adaptive(__new_middle, __second_cut, __last, __len1 - __len11,
2215                      __len2 - __len22, __buffer, __buffer_size, __comp);
2216   }
2217 }
2218
2219 template <class _BidirectionalIter, class _Tp, class _Distance>
2220 inline void __inplace_merge_aux(_BidirectionalIter __first,
2221                                 _BidirectionalIter __middle,
2222                                 _BidirectionalIter __last, _Tp*, _Distance*) {
2223   _Distance __len1 = 0;
2224   distance(__first, __middle, __len1);
2225   _Distance __len2 = 0;
2226   distance(__middle, __last, __len2);
2227
2228   _Temporary_buffer<_BidirectionalIter, _Tp> __buf(__first, __last);
2229   if (__buf.begin() == 0)
2230     __merge_without_buffer(__first, __middle, __last, __len1, __len2);
2231   else
2232     __merge_adaptive(__first, __middle, __last, __len1, __len2,
2233                      __buf.begin(), _Distance(__buf.size()));
2234 }
2235
2236 template <class _BidirectionalIter, class _Tp, 
2237           class _Distance, class _Compare>
2238 inline void __inplace_merge_aux(_BidirectionalIter __first,
2239                                 _BidirectionalIter __middle,
2240                                 _BidirectionalIter __last, _Tp*, _Distance*,
2241                                 _Compare __comp) {
2242   _Distance __len1 = 0;
2243   distance(__first, __middle, __len1);
2244   _Distance __len2 = 0;
2245   distance(__middle, __last, __len2);
2246
2247   _Temporary_buffer<_BidirectionalIter, _Tp> __buf(__first, __last);
2248   if (__buf.begin() == 0)
2249     __merge_without_buffer(__first, __middle, __last, __len1, __len2, __comp);
2250   else
2251     __merge_adaptive(__first, __middle, __last, __len1, __len2,
2252                      __buf.begin(), _Distance(__buf.size()),
2253                      __comp);
2254 }
2255
2256 template <class _BidirectionalIter>
2257 inline void inplace_merge(_BidirectionalIter __first,
2258                           _BidirectionalIter __middle,
2259                           _BidirectionalIter __last) {
2260   if (__first == __middle || __middle == __last)
2261     return;
2262   __inplace_merge_aux(__first, __middle, __last,
2263                       __VALUE_TYPE(__first), __DISTANCE_TYPE(__first));
2264 }
2265
2266 template <class _BidirectionalIter, class _Compare>
2267 inline void inplace_merge(_BidirectionalIter __first,
2268                           _BidirectionalIter __middle,
2269                           _BidirectionalIter __last, _Compare __comp) {
2270   if (__first == __middle || __middle == __last)
2271     return;
2272   __inplace_merge_aux(__first, __middle, __last,
2273                       __VALUE_TYPE(__first), __DISTANCE_TYPE(__first),
2274                       __comp);
2275 }
2276
2277 // Set algorithms: includes, set_union, set_intersection, set_difference,
2278 // set_symmetric_difference.  All of these algorithms have the precondition
2279 // that their input ranges are sorted and the postcondition that their output
2280 // ranges are sorted.
2281
2282 template <class _InputIter1, class _InputIter2>
2283 bool includes(_InputIter1 __first1, _InputIter1 __last1,
2284               _InputIter2 __first2, _InputIter2 __last2) {
2285   while (__first1 != __last1 && __first2 != __last2)
2286     if (*__first2 < *__first1)
2287       return false;
2288     else if(*__first1 < *__first2) 
2289       ++__first1;
2290     else
2291       ++__first1, ++__first2;
2292
2293   return __first2 == __last2;
2294 }
2295
2296 template <class _InputIter1, class _InputIter2, class _Compare>
2297 bool includes(_InputIter1 __first1, _InputIter1 __last1,
2298               _InputIter2 __first2, _InputIter2 __last2, _Compare __comp) {
2299   while (__first1 != __last1 && __first2 != __last2)
2300     if (__comp(*__first2, *__first1))
2301       return false;
2302     else if(__comp(*__first1, *__first2)) 
2303       ++__first1;
2304     else
2305       ++__first1, ++__first2;
2306
2307   return __first2 == __last2;
2308 }
2309
2310 template <class _InputIter1, class _InputIter2, class _OutputIter>
2311 _OutputIter set_union(_InputIter1 __first1, _InputIter1 __last1,
2312                       _InputIter2 __first2, _InputIter2 __last2,
2313                       _OutputIter __result) {
2314   while (__first1 != __last1 && __first2 != __last2) {
2315     if (*__first1 < *__first2) {
2316       *__result = *__first1;
2317       ++__first1;
2318     }
2319     else if (*__first2 < *__first1) {
2320       *__result = *__first2;
2321       ++__first2;
2322     }
2323     else {
2324       *__result = *__first1;
2325       ++__first1;
2326       ++__first2;
2327     }
2328     ++__result;
2329   }
2330   return copy(__first2, __last2, copy(__first1, __last1, __result));
2331 }
2332
2333 template <class _InputIter1, class _InputIter2, class _OutputIter,
2334           class _Compare>
2335 _OutputIter set_union(_InputIter1 __first1, _InputIter1 __last1,
2336                       _InputIter2 __first2, _InputIter2 __last2,
2337                       _OutputIter __result, _Compare __comp) {
2338   while (__first1 != __last1 && __first2 != __last2) {
2339     if (__comp(*__first1, *__first2)) {
2340       *__result = *__first1;
2341       ++__first1;
2342     }
2343     else if (__comp(*__first2, *__first1)) {
2344       *__result = *__first2;
2345       ++__first2;
2346     }
2347     else {
2348       *__result = *__first1;
2349       ++__first1;
2350       ++__first2;
2351     }
2352     ++__result;
2353   }
2354   return copy(__first2, __last2, copy(__first1, __last1, __result));
2355 }
2356
2357 template <class _InputIter1, class _InputIter2, class _OutputIter>
2358 _OutputIter set_intersection(_InputIter1 __first1, _InputIter1 __last1,
2359                              _InputIter2 __first2, _InputIter2 __last2,
2360                              _OutputIter __result) {
2361   while (__first1 != __last1 && __first2 != __last2) 
2362     if (*__first1 < *__first2) 
2363       ++__first1;
2364     else if (*__first2 < *__first1) 
2365       ++__first2;
2366     else {
2367       *__result = *__first1;
2368       ++__first1;
2369       ++__first2;
2370       ++__result;
2371     }
2372   return __result;
2373 }
2374
2375 template <class _InputIter1, class _InputIter2, class _OutputIter,
2376           class _Compare>
2377 _OutputIter set_intersection(_InputIter1 __first1, _InputIter1 __last1,
2378                              _InputIter2 __first2, _InputIter2 __last2,
2379                              _OutputIter __result, _Compare __comp) {
2380   while (__first1 != __last1 && __first2 != __last2)
2381     if (__comp(*__first1, *__first2))
2382       ++__first1;
2383     else if (__comp(*__first2, *__first1))
2384       ++__first2;
2385     else {
2386       *__result = *__first1;
2387       ++__first1;
2388       ++__first2;
2389       ++__result;
2390     }
2391   return __result;
2392 }
2393
2394 template <class _InputIter1, class _InputIter2, class _OutputIter>
2395 _OutputIter set_difference(_InputIter1 __first1, _InputIter1 __last1,
2396                            _InputIter2 __first2, _InputIter2 __last2,
2397                            _OutputIter __result) {
2398   while (__first1 != __last1 && __first2 != __last2)
2399     if (*__first1 < *__first2) {
2400       *__result = *__first1;
2401       ++__first1;
2402       ++__result;
2403     }
2404     else if (*__first2 < *__first1)
2405       ++__first2;
2406     else {
2407       ++__first1;
2408       ++__first2;
2409     }
2410   return copy(__first1, __last1, __result);
2411 }
2412
2413 template <class _InputIter1, class _InputIter2, class _OutputIter, 
2414           class _Compare>
2415 _OutputIter set_difference(_InputIter1 __first1, _InputIter1 __last1,
2416                            _InputIter2 __first2, _InputIter2 __last2, 
2417                            _OutputIter __result, _Compare __comp) {
2418   while (__first1 != __last1 && __first2 != __last2)
2419     if (__comp(*__first1, *__first2)) {
2420       *__result = *__first1;
2421       ++__first1;
2422       ++__result;
2423     }
2424     else if (__comp(*__first2, *__first1))
2425       ++__first2;
2426     else {
2427       ++__first1;
2428       ++__first2;
2429     }
2430   return copy(__first1, __last1, __result);
2431 }
2432
2433 template <class _InputIter1, class _InputIter2, class _OutputIter>
2434 _OutputIter 
2435 set_symmetric_difference(_InputIter1 __first1, _InputIter1 __last1,
2436                          _InputIter2 __first2, _InputIter2 __last2,
2437                          _OutputIter __result) {
2438   while (__first1 != __last1 && __first2 != __last2)
2439     if (*__first1 < *__first2) {
2440       *__result = *__first1;
2441       ++__first1;
2442       ++__result;
2443     }
2444     else if (*__first2 < *__first1) {
2445       *__result = *__first2;
2446       ++__first2;
2447       ++__result;
2448     }
2449     else {
2450       ++__first1;
2451       ++__first2;
2452     }
2453   return copy(__first2, __last2, copy(__first1, __last1, __result));
2454 }
2455
2456 template <class _InputIter1, class _InputIter2, class _OutputIter,
2457           class _Compare>
2458 _OutputIter 
2459 set_symmetric_difference(_InputIter1 __first1, _InputIter1 __last1,
2460                          _InputIter2 __first2, _InputIter2 __last2,
2461                          _OutputIter __result,
2462                          _Compare __comp) {
2463   while (__first1 != __last1 && __first2 != __last2)
2464     if (__comp(*__first1, *__first2)) {
2465       *__result = *__first1;
2466       ++__first1;
2467       ++__result;
2468     }
2469     else if (__comp(*__first2, *__first1)) {
2470       *__result = *__first2;
2471       ++__first2;
2472       ++__result;
2473     }
2474     else {
2475       ++__first1;
2476       ++__first2;
2477     }
2478   return copy(__first2, __last2, copy(__first1, __last1, __result));
2479 }
2480
2481 // min_element and max_element, with and without an explicitly supplied
2482 // comparison function.
2483
2484 template <class _ForwardIter>
2485 _ForwardIter max_element(_ForwardIter __first, _ForwardIter __last) {
2486   if (__first == __last) return __first;
2487   _ForwardIter __result = __first;
2488   while (++__first != __last) 
2489     if (*__result < *__first)
2490       __result = __first;
2491   return __result;
2492 }
2493
2494 template <class _ForwardIter, class _Compare>
2495 _ForwardIter max_element(_ForwardIter __first, _ForwardIter __last,
2496                             _Compare __comp) {
2497   if (__first == __last) return __first;
2498   _ForwardIter __result = __first;
2499   while (++__first != __last) 
2500     if (__comp(*__result, *__first)) __result = __first;
2501   return __result;
2502 }
2503
2504 template <class _ForwardIter>
2505 _ForwardIter min_element(_ForwardIter __first, _ForwardIter __last) {
2506   if (__first == __last) return __first;
2507   _ForwardIter __result = __first;
2508   while (++__first != __last) 
2509     if (*__first < *__result)
2510       __result = __first;
2511   return __result;
2512 }
2513
2514 template <class _ForwardIter, class _Compare>
2515 _ForwardIter min_element(_ForwardIter __first, _ForwardIter __last,
2516                             _Compare __comp) {
2517   if (__first == __last) return __first;
2518   _ForwardIter __result = __first;
2519   while (++__first != __last) 
2520     if (__comp(*__first, *__result))
2521       __result = __first;
2522   return __result;
2523 }
2524
2525 // next_permutation and prev_permutation, with and without an explicitly 
2526 // supplied comparison function.
2527
2528 template <class _BidirectionalIter>
2529 bool next_permutation(_BidirectionalIter __first, _BidirectionalIter __last) {
2530   if (__first == __last)
2531     return false;
2532   _BidirectionalIter __i = __first;
2533   ++__i;
2534   if (__i == __last)
2535     return false;
2536   __i = __last;
2537   --__i;
2538
2539   for(;;) {
2540     _BidirectionalIter __ii = __i;
2541     --__i;
2542     if (*__i < *__ii) {
2543       _BidirectionalIter __j = __last;
2544       while (!(*__i < *--__j))
2545         {}
2546       iter_swap(__i, __j);
2547       reverse(__ii, __last);
2548       return true;
2549     }
2550     if (__i == __first) {
2551       reverse(__first, __last);
2552       return false;
2553     }
2554   }
2555 }
2556
2557 template <class _BidirectionalIter, class _Compare>
2558 bool next_permutation(_BidirectionalIter __first, _BidirectionalIter __last,
2559                       _Compare __comp) {
2560   if (__first == __last)
2561     return false;
2562   _BidirectionalIter __i = __first;
2563   ++__i;
2564   if (__i == __last)
2565     return false;
2566   __i = __last;
2567   --__i;
2568
2569   for(;;) {
2570     _BidirectionalIter __ii = __i;
2571     --__i;
2572     if (__comp(*__i, *__ii)) {
2573       _BidirectionalIter __j = __last;
2574       while (!__comp(*__i, *--__j))
2575         {}
2576       iter_swap(__i, __j);
2577       reverse(__ii, __last);
2578       return true;
2579     }
2580     if (__i == __first) {
2581       reverse(__first, __last);
2582       return false;
2583     }
2584   }
2585 }
2586
2587 template <class _BidirectionalIter>
2588 bool prev_permutation(_BidirectionalIter __first, _BidirectionalIter __last) {
2589   if (__first == __last)
2590     return false;
2591   _BidirectionalIter __i = __first;
2592   ++__i;
2593   if (__i == __last)
2594     return false;
2595   __i = __last;
2596   --__i;
2597
2598   for(;;) {
2599     _BidirectionalIter __ii = __i;
2600     --__i;
2601     if (*__ii < *__i) {
2602       _BidirectionalIter __j = __last;
2603       while (!(*--__j < *__i))
2604         {}
2605       iter_swap(__i, __j);
2606       reverse(__ii, __last);
2607       return true;
2608     }
2609     if (__i == __first) {
2610       reverse(__first, __last);
2611       return false;
2612     }
2613   }
2614 }
2615
2616 template <class _BidirectionalIter, class _Compare>
2617 bool prev_permutation(_BidirectionalIter __first, _BidirectionalIter __last,
2618                       _Compare __comp) {
2619   if (__first == __last)
2620     return false;
2621   _BidirectionalIter __i = __first;
2622   ++__i;
2623   if (__i == __last)
2624     return false;
2625   __i = __last;
2626   --__i;
2627
2628   for(;;) {
2629     _BidirectionalIter __ii = __i;
2630     --__i;
2631     if (__comp(*__ii, *__i)) {
2632       _BidirectionalIter __j = __last;
2633       while (!__comp(*--__j, *__i))
2634         {}
2635       iter_swap(__i, __j);
2636       reverse(__ii, __last);
2637       return true;
2638     }
2639     if (__i == __first) {
2640       reverse(__first, __last);
2641       return false;
2642     }
2643   }
2644 }
2645
2646 // find_first_of, with and without an explicitly supplied comparison function.
2647
2648 template <class _InputIter, class _ForwardIter>
2649 _InputIter find_first_of(_InputIter __first1, _InputIter __last1,
2650                          _ForwardIter __first2, _ForwardIter __last2)
2651 {
2652   for ( ; __first1 != __last1; ++__first1) 
2653     for (_ForwardIter __iter = __first2; __iter != __last2; ++__iter)
2654       if (*__first1 == *__iter)
2655         return __first1;
2656   return __last1;
2657 }
2658
2659 template <class _InputIter, class _ForwardIter, class _BinaryPredicate>
2660 _InputIter find_first_of(_InputIter __first1, _InputIter __last1,
2661                          _ForwardIter __first2, _ForwardIter __last2,
2662                          _BinaryPredicate __comp)
2663 {
2664   for ( ; __first1 != __last1; ++__first1) 
2665     for (_ForwardIter __iter = __first2; __iter != __last2; ++__iter)
2666       if (__comp(*__first1, *__iter))
2667         return __first1;
2668   return __last1;
2669 }
2670
2671
2672 // find_end, with and without an explicitly supplied comparison function.
2673 // Search [first2, last2) as a subsequence in [first1, last1), and return
2674 // the *last* possible match.  Note that find_end for bidirectional iterators
2675 // is much faster than for forward iterators.
2676
2677 // find_end for forward iterators. 
2678 template <class _ForwardIter1, class _ForwardIter2>
2679 _ForwardIter1 __find_end(_ForwardIter1 __first1, _ForwardIter1 __last1,
2680                          _ForwardIter2 __first2, _ForwardIter2 __last2,
2681                          forward_iterator_tag, forward_iterator_tag)
2682 {
2683   if (__first2 == __last2)
2684     return __last1;
2685   else {
2686     _ForwardIter1 __result = __last1;
2687     while (1) {
2688       _ForwardIter1 __new_result
2689         = search(__first1, __last1, __first2, __last2);
2690       if (__new_result == __last1)
2691         return __result;
2692       else {
2693         __result = __new_result;
2694         __first1 = __new_result;
2695         ++__first1;
2696       }
2697     }
2698   }
2699 }
2700
2701 template <class _ForwardIter1, class _ForwardIter2,
2702           class _BinaryPredicate>
2703 _ForwardIter1 __find_end(_ForwardIter1 __first1, _ForwardIter1 __last1,
2704                          _ForwardIter2 __first2, _ForwardIter2 __last2,
2705                          forward_iterator_tag, forward_iterator_tag,
2706                          _BinaryPredicate __comp)
2707 {
2708   if (__first2 == __last2)
2709     return __last1;
2710   else {
2711     _ForwardIter1 __result = __last1;
2712     while (1) {
2713       _ForwardIter1 __new_result
2714         = search(__first1, __last1, __first2, __last2, __comp);
2715       if (__new_result == __last1)
2716         return __result;
2717       else {
2718         __result = __new_result;
2719         __first1 = __new_result;
2720         ++__first1;
2721       }
2722     }
2723   }
2724 }
2725
2726 // find_end for bidirectional iterators.  Requires partial specialization.
2727 #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
2728
2729 template <class _BidirectionalIter1, class _BidirectionalIter2>
2730 _BidirectionalIter1
2731 __find_end(_BidirectionalIter1 __first1, _BidirectionalIter1 __last1,
2732            _BidirectionalIter2 __first2, _BidirectionalIter2 __last2,
2733            bidirectional_iterator_tag, bidirectional_iterator_tag)
2734 {
2735   typedef reverse_iterator<_BidirectionalIter1> _RevIter1;
2736   typedef reverse_iterator<_BidirectionalIter2> _RevIter2;
2737
2738   _RevIter1 __rlast1(__first1);
2739   _RevIter2 __rlast2(__first2);
2740   _RevIter1 __rresult = search(_RevIter1(__last1), __rlast1,
2741                                _RevIter2(__last2), __rlast2);
2742
2743   if (__rresult == __rlast1)
2744     return __last1;
2745   else {
2746     _BidirectionalIter1 __result = __rresult.base();
2747     advance(__result, -distance(__first2, __last2));
2748     return __result;
2749   }
2750 }
2751
2752 template <class _BidirectionalIter1, class _BidirectionalIter2,
2753           class _BinaryPredicate>
2754 _BidirectionalIter1
2755 __find_end(_BidirectionalIter1 __first1, _BidirectionalIter1 __last1,
2756            _BidirectionalIter2 __first2, _BidirectionalIter2 __last2,
2757            bidirectional_iterator_tag, bidirectional_iterator_tag, 
2758            _BinaryPredicate __comp)
2759 {
2760   typedef reverse_iterator<_BidirectionalIter1> _RevIter1;
2761   typedef reverse_iterator<_BidirectionalIter2> _RevIter2;
2762
2763   _RevIter1 __rlast1(__first1);
2764   _RevIter2 __rlast2(__first2);
2765   _RevIter1 __rresult = search(_RevIter1(__last1), __rlast1,
2766                                _RevIter2(__last2), __rlast2,
2767                                __comp);
2768
2769   if (__rresult == __rlast1)
2770     return __last1;
2771   else {
2772     _BidirectionalIter1 __result = __rresult.base();
2773     advance(__result, -distance(__first2, __last2));
2774     return __result;
2775   }
2776 }
2777 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
2778
2779 // Dispatching functions for find_end.
2780
2781 template <class _ForwardIter1, class _ForwardIter2>
2782 inline _ForwardIter1 
2783 find_end(_ForwardIter1 __first1, _ForwardIter1 __last1, 
2784          _ForwardIter2 __first2, _ForwardIter2 __last2)
2785 {
2786   return __find_end(__first1, __last1, __first2, __last2,
2787                     __ITERATOR_CATEGORY(__first1),
2788                     __ITERATOR_CATEGORY(__first2));
2789 }
2790
2791 template <class _ForwardIter1, class _ForwardIter2, 
2792           class _BinaryPredicate>
2793 inline _ForwardIter1 
2794 find_end(_ForwardIter1 __first1, _ForwardIter1 __last1, 
2795          _ForwardIter2 __first2, _ForwardIter2 __last2,
2796          _BinaryPredicate __comp)
2797 {
2798   return __find_end(__first1, __last1, __first2, __last2,
2799                     __ITERATOR_CATEGORY(__first1),
2800                     __ITERATOR_CATEGORY(__first2),
2801                     __comp);
2802 }
2803
2804 // is_heap, a predicate testing whether or not a range is
2805 // a heap.  This function is an extension, not part of the C++
2806 // standard.
2807
2808 template <class _RandomAccessIter, class _Distance>
2809 bool __is_heap(_RandomAccessIter __first, _Distance __n)
2810 {
2811   _Distance __parent = 0;
2812   for (_Distance __child = 1; __child < __n; ++__child) {
2813     if (__first[__parent] < __first[__child]) 
2814       return false;
2815     if ((__child & 1) == 0)
2816       ++__parent;
2817   }
2818   return true;
2819 }
2820
2821 template <class _RandomAccessIter, class _Distance, class _StrictWeakOrdering>
2822 bool __is_heap(_RandomAccessIter __first, _StrictWeakOrdering __comp,
2823                _Distance __n)
2824 {
2825   _Distance __parent = 0;
2826   for (_Distance __child = 1; __child < __n; ++__child) {
2827     if (__comp(__first[__parent], __first[__child]))
2828       return false;
2829     if ((__child & 1) == 0)
2830       ++__parent;
2831   }
2832   return true;
2833 }
2834
2835 template <class _RandomAccessIter>
2836 inline bool is_heap(_RandomAccessIter __first, _RandomAccessIter __last)
2837 {
2838   return __is_heap(__first, __last - __first);
2839 }
2840
2841
2842 template <class _RandomAccessIter, class _StrictWeakOrdering>
2843 inline bool is_heap(_RandomAccessIter __first, _RandomAccessIter __last,
2844                     _StrictWeakOrdering __comp)
2845 {
2846   return __is_heap(__first, __comp, __last - __first);
2847 }
2848
2849 // is_sorted, a predicated testing whether a range is sorted in
2850 // nondescending order.  This is an extension, not part of the C++
2851 // standard.
2852
2853 template <class _ForwardIter>
2854 bool is_sorted(_ForwardIter __first, _ForwardIter __last)
2855 {
2856   if (__first == __last)
2857     return true;
2858
2859   _ForwardIter __next = __first;
2860   for (++__next; __next != __last; __first = __next, ++__next) {
2861     if (*__next < *__first)
2862       return false;
2863   }
2864
2865   return true;
2866 }
2867
2868 template <class _ForwardIter, class _StrictWeakOrdering>
2869 bool is_sorted(_ForwardIter __first, _ForwardIter __last,
2870                _StrictWeakOrdering __comp)
2871 {
2872   if (__first == __last)
2873     return true;
2874
2875   _ForwardIter __next = __first;
2876   for (++__next; __next != __last; __first = __next, ++__next) {
2877     if (__comp(*__next, *__first))
2878       return false;
2879   }
2880
2881   return true;
2882 }
2883
2884 #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
2885 #pragma reset woff 1209
2886 #endif
2887
2888 __STL_END_NAMESPACE
2889
2890 #endif /* __SGI_STL_INTERNAL_ALGO_H */
2891
2892 // Local Variables:
2893 // mode:C++
2894 // End: