home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / stlpt453.zip / STLport-4.5.3 / stlport / stl / _algo.c < prev    next >
C/C++ Source or Header  |  2002-02-02  |  61KB  |  1,766 lines

  1. /*
  2.  *
  3.  * Copyright (c) 1994
  4.  * Hewlett-Packard Company
  5.  *
  6.  * Copyright (c) 1996,1997
  7.  * Silicon Graphics Computer Systems, Inc.
  8.  *
  9.  * Copyright (c) 1997
  10.  * Moscow Center for SPARC Technology
  11.  *
  12.  * Copyright (c) 1999 
  13.  * Boris Fomitchev
  14.  *
  15.  * This material is provided "as is", with absolutely no warranty expressed
  16.  * or implied. Any use is at your own risk.
  17.  *
  18.  * Permission to use or copy this software for any purpose is hereby granted 
  19.  * without fee, provided the above notices are retained on all copies.
  20.  * Permission to modify the code and to distribute modified code is granted,
  21.  * provided the above notices are retained, and a notice that the code was
  22.  * modified is included with the above copyright notice.
  23.  *
  24.  */
  25.  
  26. #ifndef _STLP_ALGO_C
  27. # define _STLP_ALGO_C
  28.  
  29. # if !defined (_STLP_INTERNAL_ALGO_H)
  30. #  include <stl/_algo.h>
  31. # endif
  32.  
  33. _STLP_BEGIN_NAMESPACE
  34.  
  35. template <class _BidirectionalIter, class _Distance, class _Compare>
  36. void __merge_without_buffer(_BidirectionalIter __first,
  37.                             _BidirectionalIter __middle,
  38.                             _BidirectionalIter __last,
  39.                             _Distance __len1, _Distance __len2,
  40.                             _Compare __comp);
  41.  
  42.  
  43. template <class _BidirectionalIter1, class _BidirectionalIter2,
  44.           class _BidirectionalIter3, class _Compare>
  45. _BidirectionalIter3 __merge_backward(_BidirectionalIter1 __first1,
  46.                                      _BidirectionalIter1 __last1,
  47.                                      _BidirectionalIter2 __first2,
  48.                                      _BidirectionalIter2 __last2,
  49.                                      _BidirectionalIter3 __result,
  50.                                      _Compare __comp);
  51.  
  52. template <class _Tp>
  53. # if !(defined (__SUNPRO_CC) && (__SUNPRO_CC < 0x420 ))
  54. inline 
  55. # endif
  56. const _Tp& __median(const _Tp& __a, const _Tp& __b, const _Tp& __c) {
  57.   if (__a < __b)
  58.     if (__b < __c)
  59.       return __b;
  60.     else if (__a < __c)
  61.       return __c;
  62.     else
  63.       return __a;
  64.   else if (__a < __c)
  65.     return __a;
  66.   else if (__b < __c)
  67.     return __c;
  68.   else
  69.     return __b;
  70. }
  71.  
  72. template <class _Tp, class _Compare>
  73. # if !(defined (__SUNPRO_CC) && (__SUNPRO_CC < 0x420 ))
  74. inline 
  75. # endif
  76. const _Tp&
  77. __median(const _Tp& __a, const _Tp& __b, const _Tp& __c, _Compare __comp) {
  78.   if (__comp(__a, __b))
  79.     if (__comp(__b, __c))
  80.       return __b;
  81.     else if (__comp(__a, __c))
  82.       return __c;
  83.     else
  84.       return __a;
  85.   else if (__comp(__a, __c))
  86.     return __a;
  87.   else if (__comp(__b, __c))
  88.     return __c;
  89.   else
  90.     return __b;
  91. }
  92.  
  93. template <class _ForwardIter1, class _ForwardIter2>
  94. _ForwardIter1 search(_ForwardIter1 __first1, _ForwardIter1 __last1,
  95.                      _ForwardIter2 __first2, _ForwardIter2 __last2) 
  96. {
  97.   _STLP_DEBUG_CHECK(__check_range(__first1, __last1))
  98.   _STLP_DEBUG_CHECK(__check_range(__first2, __last2))
  99.   // Test for empty ranges
  100.   if (__first1 == __last1 || __first2 == __last2)
  101.     return __first1;
  102.  
  103.   // Test for a pattern of length 1.
  104.   _ForwardIter2 __tmp(__first2);
  105.   ++__tmp;
  106.   if (__tmp == __last2)
  107.     return find(__first1, __last1, *__first2);
  108.  
  109.   // General case.
  110.   _ForwardIter2 __p1 = __first2; 
  111.   ++__p1;
  112.  
  113.   _ForwardIter1 __current = __first1;
  114.  
  115.   while (__first1 != __last1) {
  116.     __first1 = find(__first1, __last1, *__first2);
  117.     if (__first1 == __last1)
  118.       return __last1;
  119.  
  120.     _ForwardIter2 __p = __p1;
  121.     __current = __first1; 
  122.     if (++__current == __last1)
  123.       return __last1;
  124.  
  125.     while (*__current == *__p) {
  126.       if (++__p == __last2)
  127.         return __first1;
  128.       if (++__current == __last1)
  129.         return __last1;
  130.     }
  131.  
  132.     ++__first1;
  133.   }
  134.   return __first1;
  135. }
  136.  
  137. // search_n.  Search for __count consecutive copies of __val.
  138.  
  139. template <class _ForwardIter, class _Integer, class _Tp>
  140. _ForwardIter search_n(_ForwardIter __first, _ForwardIter __last,
  141.                       _Integer __count, const _Tp& __val) {
  142.   _STLP_DEBUG_CHECK(__check_range(__first, __last))
  143.   if (__count <= 0)
  144.     return __first;
  145.   else {
  146.     __first = find(__first, __last, __val);
  147.     while (__first != __last) {
  148.       _Integer __n = __count - 1;
  149.       _ForwardIter __i = __first;
  150.       ++__i;
  151.       while (__i != __last && __n != 0 && *__i == __val) {
  152.         ++__i;
  153.         --__n;
  154.       }
  155.       if (__n == 0)
  156.         return __first;
  157.       else
  158.         __first = find(__i, __last, __val);
  159.     }
  160.     return __last;
  161.   }
  162. }
  163.  
  164. template <class _ForwardIter, class _Integer, class _Tp, class _BinaryPred>
  165. _ForwardIter search_n(_ForwardIter __first, _ForwardIter __last,
  166.                       _Integer __count, const _Tp& __val,
  167.                       _BinaryPred __binary_pred) {
  168.   _STLP_DEBUG_CHECK(__check_range(__first, __last))
  169.   if (__count <= 0)
  170.     return __first;
  171.   else {
  172.     while (__first != __last) {
  173.       if (__binary_pred(*__first, __val))
  174.         break;
  175.       ++__first;
  176.     }
  177.     while (__first != __last) {
  178.       _Integer __n = __count - 1;
  179.       _ForwardIter __i = __first;
  180.       ++__i;
  181.       while (__i != __last && __n != 0 && __binary_pred(*__i, __val)) {
  182.         ++__i;
  183.         --__n;
  184.       }
  185.       if (__n == 0)
  186.         return __first;
  187.       else {
  188.         while (__i != __last) {
  189.           if (__binary_pred(*__i, __val))
  190.             break;
  191.           ++__i;
  192.         }
  193.         __first = __i;
  194.       }
  195.     }
  196.     return __last;
  197.   }
  198.  
  199. template <class _ForwardIter1, class _ForwardIter2>
  200. _ForwardIter1 
  201. find_end(_ForwardIter1 __first1, _ForwardIter1 __last1, 
  202.          _ForwardIter2 __first2, _ForwardIter2 __last2)
  203. {
  204.   _STLP_DEBUG_CHECK(__check_range(__first1, __last1))
  205.   _STLP_DEBUG_CHECK(__check_range(__first2, __last2))
  206.   return __find_end(__first1, __last1, __first2, __last2,
  207. # if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
  208.                     _STLP_ITERATOR_CATEGORY(__first1, _ForwardIter1),
  209.                     _STLP_ITERATOR_CATEGORY(__first2, _ForwardIter2),
  210. # else
  211.             forward_iterator_tag(),
  212.                     forward_iterator_tag(),
  213. # endif
  214.                     __equal_to(_STLP_VALUE_TYPE(__first1, _ForwardIter1))
  215.     );
  216. }
  217.  
  218. // unique and unique_copy
  219. template <class _InputIterator, class _OutputIterator, class _BinaryPredicate,
  220.                         class _Tp>
  221. _STLP_INLINE_LOOP _OutputIterator 
  222. __unique_copy(_InputIterator __first, _InputIterator __last,
  223.               _OutputIterator __result,
  224.               _BinaryPredicate __binary_pred, _Tp*) {
  225.   _Tp __val = *__first;
  226.   *__result = __val;
  227.   while (++__first != __last)
  228.     if (!__binary_pred(__val, *__first)) {
  229.       __val = *__first;
  230.       *++__result = __val;
  231.     }
  232.   return ++__result;
  233. }
  234.  
  235. template <class _InputIter, class _OutputIter, class _BinaryPredicate>
  236. inline _OutputIter 
  237. __unique_copy(_InputIter __first, _InputIter __last,_OutputIter __result,
  238.               _BinaryPredicate __binary_pred, const output_iterator_tag &) {
  239.   return __unique_copy(__first, __last, __result, __binary_pred, _STLP_VALUE_TYPE(__first, _InputIter));
  240. }
  241.  
  242. template <class _InputIter, class _ForwardIter, class _BinaryPredicate>
  243. _STLP_INLINE_LOOP _ForwardIter 
  244. __unique_copy(_InputIter __first, _InputIter __last, _ForwardIter __result, 
  245.               _BinaryPredicate __binary_pred, const forward_iterator_tag &) {
  246.   *__result = *__first;
  247.   while (++__first != __last)
  248.     if (!__binary_pred(*__result, *__first)) *++__result = *__first;
  249.   return ++__result;
  250. }
  251.  
  252. # if defined (_STLP_NONTEMPL_BASE_MATCH_BUG)
  253. template <class _InputIterator, class _BidirectionalIterator, class _BinaryPredicate>
  254. inline _BidirectionalIterator 
  255. __unique_copy(_InputIterator __first, _InputIterator __last,
  256.               _BidirectionalIterator __result, _BinaryPredicate __binary_pred,
  257.               const bidirectional_iterator_tag &) {
  258.   return __unique_copy(__first, __last, __result, __binary_pred, forward_iterator_tag());
  259. }
  260.  
  261. template <class _InputIterator, class _RandomAccessIterator, class _BinaryPredicate>
  262. inline _RandomAccessIterator 
  263. __unique_copy(_InputIterator __first, _InputIterator __last,
  264.               _RandomAccessIterator __result, _BinaryPredicate __binary_pred,
  265.               const random_access_iterator_tag &) {
  266.   return __unique_copy(__first, __last, __result, __binary_pred, forward_iterator_tag());
  267. }
  268. # endif /* _STLP_NONTEMPL_BASE_MATCH_BUG */
  269.  
  270.  
  271. template <class _InputIter, class _OutputIter>
  272. _OutputIter 
  273. unique_copy(_InputIter __first, _InputIter __last, _OutputIter __result) {
  274.   _STLP_DEBUG_CHECK(__check_range(__first, __last))
  275.   if (__first == __last) return __result;
  276.   return __unique_copy(__first, __last, __result, __equal_to(_STLP_VALUE_TYPE(__first, _InputIter)),
  277.                        _STLP_ITERATOR_CATEGORY(__result, _OutputIter));
  278. }
  279.  
  280. template <class _InputIter, class _OutputIter, class _BinaryPredicate>
  281. _OutputIter 
  282. unique_copy(_InputIter __first, _InputIter __last,_OutputIter __result,
  283.             _BinaryPredicate __binary_pred) {
  284.   _STLP_DEBUG_CHECK(__check_range(__first, __last))
  285.   if (__first == __last) return __result;
  286.   return __unique_copy(__first, __last, __result, __binary_pred,
  287.                        _STLP_ITERATOR_CATEGORY(__result, _OutputIter));
  288. }
  289.  
  290. // rotate and rotate_copy, and their auxiliary functions
  291.  
  292. template <class _ForwardIter, class _Distance>
  293. _ForwardIter __rotate(_ForwardIter __first,
  294.                       _ForwardIter __middle,
  295.                       _ForwardIter __last,
  296.                       _Distance*,
  297.                       const forward_iterator_tag &) {
  298.   if (__first == __middle)
  299.     return __last;
  300.   if (__last  == __middle)
  301.     return __first;
  302.  
  303.   _ForwardIter __first2 = __middle;
  304.   do {
  305.     swap(*__first++, *__first2++);
  306.     if (__first == __middle)
  307.       __middle = __first2;
  308.   } while (__first2 != __last);
  309.  
  310.   _ForwardIter __new_middle = __first;
  311.  
  312.   __first2 = __middle;
  313.  
  314.   while (__first2 != __last) {
  315.     swap (*__first++, *__first2++);
  316.     if (__first == __middle)
  317.       __middle = __first2;
  318.     else if (__first2 == __last)
  319.       __first2 = __middle;
  320.   }
  321.  
  322.   return __new_middle;
  323. }
  324.  
  325. template <class _BidirectionalIter, class _Distance>
  326. _BidirectionalIter __rotate(_BidirectionalIter __first,
  327.                             _BidirectionalIter __middle,
  328.                             _BidirectionalIter __last,
  329.                             _Distance*,
  330.                             const bidirectional_iterator_tag &) {
  331.   if (__first == __middle)
  332.     return __last;
  333.   if (__last  == __middle)
  334.     return __first;
  335.  
  336.   __reverse(__first,  __middle, bidirectional_iterator_tag());
  337.   __reverse(__middle, __last,   bidirectional_iterator_tag());
  338.  
  339.   while (__first != __middle && __middle != __last)
  340.     swap (*__first++, *--__last);
  341.  
  342.   if (__first == __middle) {
  343.     __reverse(__middle, __last,   bidirectional_iterator_tag());
  344.     return __last;
  345.   }
  346.   else {
  347.     __reverse(__first,  __middle, bidirectional_iterator_tag());
  348.     return __first;
  349.   }
  350. }
  351.  
  352. template <class _RandomAccessIter, class _Distance, class _Tp>
  353. _RandomAccessIter __rotate(_RandomAccessIter __first,
  354.                            _RandomAccessIter __middle,
  355.                            _RandomAccessIter __last,
  356.                            _Distance *, _Tp *) {
  357.  
  358.   _Distance __n = __last   - __first;
  359.   _Distance __k = __middle - __first;
  360.   _Distance __l = __n - __k;
  361.   _RandomAccessIter __result = __first + (__last - __middle);
  362.  
  363.   if (__k==0)  /* __first == middle */
  364.     return __last;
  365.  
  366.   if (__k == __l) {
  367.     swap_ranges(__first, __middle, __middle);
  368.     return __result;
  369.   }
  370.  
  371.   _Distance __d = __gcd(__n, __k);
  372.  
  373.   for (_Distance __i = 0; __i < __d; __i++) {
  374.     _Tp __tmp = *__first;
  375.     _RandomAccessIter __p = __first;
  376.  
  377.     if (__k < __l) {
  378.       for (_Distance __j = 0; __j < __l/__d; __j++) {
  379.     if (__p > __first + __l) {
  380.           *__p = *(__p - __l);
  381.           __p -= __l;
  382.         }
  383.  
  384.         *__p = *(__p + __k);
  385.         __p += __k;
  386.       }
  387.     }
  388.  
  389.     else {
  390.       for (_Distance __j = 0; __j < __k/__d - 1; __j ++) {
  391.         if (__p < __last - __k) {
  392.           *__p = *(__p + __k);
  393.           __p += __k;
  394.         }
  395.  
  396.         *__p = * (__p - __l);
  397.         __p -= __l;
  398.       }
  399.     }
  400.  
  401.     *__p = __tmp;
  402.     ++__first;
  403.   }
  404.  
  405.   return __result;
  406. }
  407.  
  408. template <class _RandomAccessIter, class _Distance>
  409. inline _RandomAccessIter 
  410. __rotate(_RandomAccessIter __first, _RandomAccessIter __middle, _RandomAccessIter __last,
  411.          _Distance * __dis, const random_access_iterator_tag &) {
  412.   return __rotate(__first, __middle, __last,
  413.                   __dis, _STLP_VALUE_TYPE(__first, _RandomAccessIter));
  414. }
  415.  
  416. template <class _ForwardIter>
  417. _ForwardIter 
  418. rotate(_ForwardIter __first, _ForwardIter __middle, _ForwardIter __last) {
  419.   _STLP_DEBUG_CHECK(__check_range(__first, __middle))
  420.   _STLP_DEBUG_CHECK(__check_range(__middle, __last))
  421.   return __rotate(__first, __middle, __last,
  422.                   _STLP_DISTANCE_TYPE(__first, _ForwardIter),
  423.                   _STLP_ITERATOR_CATEGORY(__first, _ForwardIter));
  424. }
  425.  
  426. // Return a random number in the range [0, __n).  This function encapsulates
  427. // whether we're using rand (part of the standard C library) or lrand48
  428. // (not standard, but a much better choice whenever it's available).
  429.  
  430. template <class _Distance>
  431. inline _Distance __random_number(_Distance __n) {
  432. #ifdef _STLP_NO_DRAND48
  433.   return rand() % __n;
  434. #else
  435.   return lrand48() % __n;
  436. #endif
  437. }
  438.  
  439. template <class _RandomAccessIter>
  440. void random_shuffle(_RandomAccessIter __first,
  441.             _RandomAccessIter __last) {
  442.   _STLP_DEBUG_CHECK(__check_range(__first, __last))
  443.   if (__first == __last) return;
  444.   for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i)
  445.     iter_swap(__i, __first + __random_number((__i - __first) + 1));
  446. }
  447.  
  448. template <class _RandomAccessIter, class _RandomNumberGenerator>
  449. void random_shuffle(_RandomAccessIter __first, _RandomAccessIter __last,
  450.                     _RandomNumberGenerator& __rand) {
  451.   _STLP_DEBUG_CHECK(__check_range(__first, __last))
  452.   if (__first == __last) return;
  453.   for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i)
  454.     iter_swap(__i, __first + __rand((__i - __first) + 1));
  455. }
  456.  
  457. # ifndef _STLP_NO_EXTENSIONS
  458.  
  459. // random_sample and random_sample_n (extensions, not part of the standard).
  460.  
  461. template <class _ForwardIter, class _OutputIter, class _Distance>
  462. _OutputIter random_sample_n(_ForwardIter __first, _ForwardIter __last,
  463.                             _OutputIter __out, const _Distance __n)
  464. {
  465.   _STLP_DEBUG_CHECK(__check_range(__first, __last))
  466.   _Distance __remaining = distance(__first, __last);
  467.   _Distance __m = (min) (__n, __remaining);
  468.  
  469.   while (__m > 0) {
  470.     if (__random_number(__remaining) < __m) {
  471.       *__out = *__first;
  472.       ++__out;
  473.       --__m;
  474.     }
  475.  
  476.     --__remaining;
  477.     ++__first;
  478.   }
  479.   return __out;
  480. }
  481.  
  482.  
  483. template <class _ForwardIter, class _OutputIter, class _Distance,
  484.           class _RandomNumberGenerator>
  485. _OutputIter random_sample_n(_ForwardIter __first, _ForwardIter __last,
  486.                             _OutputIter __out, const _Distance __n,
  487.                             _RandomNumberGenerator& __rand)
  488. {
  489.   _STLP_DEBUG_CHECK(__check_range(__first, __last))
  490.   _Distance __remaining = distance(__first, __last);
  491.   _Distance __m = (min) (__n, __remaining);
  492.  
  493.   while (__m > 0) {
  494.     if (__rand(__remaining) < __m) {
  495.       *__out = *__first;
  496.       ++__out;
  497.       --__m;
  498.     }
  499.  
  500.     --__remaining;
  501.     ++__first;
  502.   }
  503.   return __out;
  504. }
  505.  
  506. template <class _InputIter, class _RandomAccessIter, class _Distance>
  507. _RandomAccessIter __random_sample(_InputIter __first, _InputIter __last,
  508.                                   _RandomAccessIter __out,
  509.                                   const _Distance __n)
  510. {
  511.   _Distance __m = 0;
  512.   _Distance __t = __n;
  513.   for ( ; __first != __last && __m < __n; ++__m, ++__first) 
  514.     __out[__m] = *__first;
  515.  
  516.   while (__first != __last) {
  517.     ++__t;
  518.     _Distance __M = __random_number(__t);
  519.     if (__M < __n)
  520.       __out[__M] = *__first;
  521.     ++__first;
  522.   }
  523.  
  524.   return __out + __m;
  525. }
  526.  
  527. template <class _InputIter, class _RandomAccessIter,
  528.           class _RandomNumberGenerator, class _Distance>
  529. _RandomAccessIter __random_sample(_InputIter __first, _InputIter __last,
  530.                                   _RandomAccessIter __out,
  531.                                   _RandomNumberGenerator& __rand,
  532.                                   const _Distance __n)
  533. {
  534.   _Distance __m = 0;
  535.   _Distance __t = __n;
  536.   for ( ; __first != __last && __m < __n; ++__m, ++__first)
  537.     __out[__m] = *__first;
  538.  
  539.   while (__first != __last) {
  540.     ++__t;
  541.     _Distance __M = __rand(__t);
  542.     if (__M < __n)
  543.       __out[__M] = *__first;
  544.     ++__first;
  545.   }
  546.  
  547.   return __out + __m;
  548. }
  549.  
  550. template <class _InputIter, class _RandomAccessIter>
  551. _RandomAccessIter
  552. random_sample(_InputIter __first, _InputIter __last,
  553.               _RandomAccessIter __out_first, _RandomAccessIter __out_last) 
  554. {
  555.   _STLP_DEBUG_CHECK(__check_range(__first, __last))
  556.   _STLP_DEBUG_CHECK(__check_range(__out_first, __out_last))
  557.   return __random_sample(__first, __last,
  558.                          __out_first, __out_last - __out_first);
  559. }
  560.  
  561. template <class _InputIter, class _RandomAccessIter, class _RandomNumberGenerator>
  562. _RandomAccessIter
  563. random_sample(_InputIter __first, _InputIter __last,
  564.               _RandomAccessIter __out_first, _RandomAccessIter __out_last,
  565.               _RandomNumberGenerator& __rand) 
  566. {
  567.   _STLP_DEBUG_CHECK(__check_range(__first, __last))
  568.   _STLP_DEBUG_CHECK(__check_range(__out_first, __out_last))
  569.   return __random_sample(__first, __last,
  570.                          __out_first, __rand,
  571.                          __out_last - __out_first);
  572. }
  573.  
  574. # endif /* _STLP_NO_EXTENSIONS */
  575.  
  576. // partition, stable_partition, and their auxiliary functions
  577.  
  578. template <class _ForwardIter, class _Predicate>
  579. _STLP_INLINE_LOOP _ForwardIter __partition(_ForwardIter __first,
  580.                                            _ForwardIter __last,
  581.                                            _Predicate   __pred,
  582.                                            const forward_iterator_tag &) {
  583.   if (__first == __last) return __first;
  584.  
  585.   while (__pred(*__first))
  586.     if (++__first == __last) return __first;
  587.  
  588.   _ForwardIter __next = __first;
  589.  
  590.   while (++__next != __last)
  591.     if (__pred(*__next)) {
  592.       swap(*__first, *__next);
  593.       ++__first;
  594.     }
  595.   return __first;
  596. }
  597.  
  598. template <class _BidirectionalIter, class _Predicate>
  599. _STLP_INLINE_LOOP _BidirectionalIter __partition(_BidirectionalIter __first,
  600.                                                  _BidirectionalIter __last,
  601.                                                  _Predicate __pred,
  602.                                                  const bidirectional_iterator_tag &) {
  603.   while (true) {
  604.     while (true)
  605.       if (__first == __last)
  606.         return __first;
  607.       else if (__pred(*__first))
  608.         ++__first;
  609.       else
  610.         break;
  611.     --__last;
  612.     while (true)
  613.       if (__first == __last)
  614.         return __first;
  615.       else if (!__pred(*__last))
  616.         --__last;
  617.       else
  618.         break;
  619.     iter_swap(__first, __last);
  620.     ++__first;
  621.   }
  622. }
  623.  
  624. # if defined (_STLP_NONTEMPL_BASE_MATCH_BUG)
  625. template <class _BidirectionalIter, class _Predicate>
  626. inline
  627. _BidirectionalIter __partition(_BidirectionalIter __first,
  628.                                _BidirectionalIter __last,
  629.                    _Predicate __pred,
  630.                    const random_access_iterator_tag &) {
  631.   return __partition(__first, __last, __pred, bidirectional_iterator_tag());
  632. }
  633. # endif
  634.  
  635. template <class _ForwardIter, class _Predicate>
  636. _ForwardIter partition(_ForwardIter __first, _ForwardIter __last, _Predicate   __pred) {
  637.   _STLP_DEBUG_CHECK(__check_range(__first, __last))
  638.   return __partition(__first, __last, __pred, _STLP_ITERATOR_CATEGORY(__first, _ForwardIter));
  639. }
  640.  
  641.  
  642. template <class _ForwardIter, class _Predicate, class _Distance>
  643. _ForwardIter __inplace_stable_partition(_ForwardIter __first,
  644.                                         _ForwardIter __last,
  645.                                         _Predicate __pred, _Distance __len) {
  646.   if (__len == 1)
  647.     return __pred(*__first) ? __last : __first;
  648.   _ForwardIter __middle = __first;
  649.   advance(__middle, __len / 2);
  650.   return rotate(__inplace_stable_partition(__first, __middle, __pred, 
  651.                                            __len / 2),
  652.                 __middle,
  653.                 __inplace_stable_partition(__middle, __last, __pred,
  654.                                            __len - __len / 2));
  655. }
  656.  
  657. template <class _ForwardIter, class _Pointer, class _Predicate, 
  658.           class _Distance>
  659. _ForwardIter __stable_partition_adaptive(_ForwardIter __first,
  660.                                          _ForwardIter __last,
  661.                                          _Predicate __pred, _Distance __len,
  662.                                          _Pointer __buffer,
  663.                                          _Distance __buffer_size) 
  664. {
  665.   if (__len <= __buffer_size) {
  666.     _ForwardIter __result1 = __first;
  667.     _Pointer __result2 = __buffer;
  668.     for ( ; __first != __last ; ++__first)
  669.       if (__pred(*__first)) {
  670.         *__result1 = *__first;
  671.         ++__result1;
  672.       }
  673.       else {
  674.         *__result2 = *__first;
  675.         ++__result2;
  676.       }
  677.     copy(__buffer, __result2, __result1);
  678.     return __result1;
  679.   }
  680.   else {
  681.     _ForwardIter __middle = __first;
  682.     advance(__middle, __len / 2);
  683.     return rotate(__stable_partition_adaptive(
  684.                           __first, __middle, __pred,
  685.                           __len / 2, __buffer, __buffer_size),
  686.                     __middle,
  687.                     __stable_partition_adaptive(
  688.                           __middle, __last, __pred,
  689.                           __len - __len / 2, __buffer, __buffer_size));
  690.   }
  691. }
  692.  
  693. template <class _ForwardIter, class _Predicate, class _Tp, class _Distance>
  694. inline _ForwardIter
  695. __stable_partition_aux(_ForwardIter __first, _ForwardIter __last, 
  696.                        _Predicate __pred, _Tp*, _Distance*)
  697. {
  698.   _Temporary_buffer<_ForwardIter, _Tp> __buf(__first, __last);
  699.   _STLP_MPWFIX_TRY        //*TY 06/01/2000 - they forget to call dtor for _Temporary_buffer if no try/catch block is present
  700.   return (__buf.size() > 0) ?
  701.     __stable_partition_adaptive(__first, __last, __pred,
  702.                 _Distance(__buf.requested_size()),
  703.                 __buf.begin(), __buf.size())  :
  704.     __inplace_stable_partition(__first, __last, __pred, 
  705.                    _Distance(__buf.requested_size()));
  706.   _STLP_MPWFIX_CATCH    //*TY 06/01/2000 - they forget to call dtor for _Temporary_buffer if no try/catch block is present
  707. }
  708.  
  709. template <class _ForwardIter, class _Predicate>
  710. _ForwardIter 
  711. stable_partition(_ForwardIter __first, _ForwardIter __last, _Predicate __pred) {
  712.   _STLP_DEBUG_CHECK(__check_range(__first, __last))
  713.   if (__first == __last)
  714.     return __first;
  715.   else
  716.     return __stable_partition_aux(__first, __last, __pred,
  717.                                   _STLP_VALUE_TYPE(__first, _ForwardIter),
  718.                                   _STLP_DISTANCE_TYPE(__first, _ForwardIter));
  719. }
  720.  
  721. template <class _RandomAccessIter, class _Tp, class _Compare>
  722. _RandomAccessIter __unguarded_partition(_RandomAccessIter __first, 
  723.                                         _RandomAccessIter __last, 
  724.                                         _Tp __pivot, _Compare __comp) 
  725. {
  726.   while (true) {
  727.     while (__comp(*__first, __pivot))
  728.       ++__first;
  729.     --__last;
  730.     while (__comp(__pivot, *__last))
  731.       --__last;
  732.     if (!(__first < __last))
  733.       return __first;
  734.     iter_swap(__first, __last);
  735.     ++__first;
  736.   }
  737. }
  738.  
  739. // sort() and its auxiliary functions. 
  740.  
  741. # define  __stl_threshold  16
  742.  
  743. template <class _RandomAccessIter, class _Tp, class _Compare>
  744. void __unguarded_linear_insert(_RandomAccessIter __last, _Tp __val, 
  745.                                _Compare __comp) {
  746.   _RandomAccessIter __next = __last;
  747.   --__next;  
  748.   while (__comp(__val, *__next)) {
  749.     *__last = *__next;
  750.     __last = __next;
  751.     --__next;
  752.   }
  753.   *__last = __val;
  754. }
  755.  
  756. template <class _RandomAccessIter, class _Tp, class _Compare>
  757. inline void __linear_insert(_RandomAccessIter __first, 
  758.                             _RandomAccessIter __last, _Tp __val, _Compare __comp) {        
  759.   //*TY 12/26/1998 - added __val as a paramter
  760.   //  _Tp __val = *__last;            //*TY 12/26/1998 - __val supplied by caller
  761.   if (__comp(__val, *__first)) {
  762.     copy_backward(__first, __last, __last + 1);
  763.     *__first = __val;
  764.   }
  765.   else
  766.     __unguarded_linear_insert(__last, __val, __comp);
  767. }
  768.  
  769. template <class _RandomAccessIter, class _Compare>
  770. void __insertion_sort(_RandomAccessIter __first,
  771.                       _RandomAccessIter __last, _Compare __comp) {
  772.   if (__first == __last) return;
  773.   for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i)
  774.     __linear_insert(__first, __i, *__i, __comp);    //*TY 12/26/1998 - supply *__i as __val
  775. }
  776.  
  777. template <class _RandomAccessIter, class _Tp, class _Compare>
  778. void __unguarded_insertion_sort_aux(_RandomAccessIter __first, 
  779.                                     _RandomAccessIter __last,
  780.                                     _Tp*, _Compare __comp) {
  781.   for (_RandomAccessIter __i = __first; __i != __last; ++__i)
  782.     __unguarded_linear_insert(__i, _Tp(*__i), __comp);
  783. }
  784.  
  785. template <class _RandomAccessIter, class _Compare>
  786. inline void __unguarded_insertion_sort(_RandomAccessIter __first, 
  787.                                        _RandomAccessIter __last,
  788.                                        _Compare __comp) {
  789.   __unguarded_insertion_sort_aux(__first, __last, _STLP_VALUE_TYPE(__first, _RandomAccessIter), __comp);
  790. }
  791.  
  792. template <class _RandomAccessIter, class _Compare>
  793. void __final_insertion_sort(_RandomAccessIter __first, 
  794.                             _RandomAccessIter __last, _Compare __comp) {
  795.   if (__last - __first > __stl_threshold) {
  796.     __insertion_sort(__first, __first + __stl_threshold, __comp);
  797.     __unguarded_insertion_sort(__first + __stl_threshold, __last, __comp);
  798.   }
  799.   else
  800.     __insertion_sort(__first, __last, __comp);
  801. }
  802.  
  803. template <class _RandomAccessIter, class _Tp, class _Size, class _Compare>
  804. void __introsort_loop(_RandomAccessIter __first,
  805.                       _RandomAccessIter __last, _Tp*,
  806.                       _Size __depth_limit, _Compare __comp)
  807. {
  808.   while (__last - __first > __stl_threshold) {
  809.     if (__depth_limit == 0) {
  810.       partial_sort(__first, __last, __last, __comp);
  811.       return;
  812.     }
  813.     --__depth_limit;
  814.     _RandomAccessIter __cut =
  815.       __unguarded_partition(__first, __last,
  816.                             _Tp(__median(*__first,
  817.                                          *(__first + (__last - __first)/2),
  818.                                          *(__last - 1), __comp)),
  819.        __comp);
  820.     __introsort_loop(__cut, __last, (_Tp*) 0, __depth_limit, __comp);
  821.     __last = __cut;
  822.   }
  823. }
  824.  
  825. template <class _RandomAccessIter>
  826. void sort(_RandomAccessIter __first, _RandomAccessIter __last) {
  827.   _STLP_DEBUG_CHECK(__check_range(__first, __last))
  828.   if (__first != __last) {
  829.     __introsort_loop(__first, __last,
  830.                      _STLP_VALUE_TYPE(__first, _RandomAccessIter),
  831.                      __lg(__last - __first) * 2, __less(_STLP_VALUE_TYPE(__first, _RandomAccessIter)) );
  832.     __final_insertion_sort(__first, __last, __less(_STLP_VALUE_TYPE(__first, _RandomAccessIter)));
  833.   }
  834. }
  835.  
  836. template <class _RandomAccessIter, class _Compare>
  837. void sort(_RandomAccessIter __first, _RandomAccessIter __last, _Compare __comp) {
  838.   _STLP_DEBUG_CHECK(__check_range(__first, __last))
  839.   if (__first != __last) {
  840.     __introsort_loop(__first, __last,
  841.                      _STLP_VALUE_TYPE(__first, _RandomAccessIter),
  842.                      __lg(__last - __first) * 2,
  843.                      __comp);
  844.     __final_insertion_sort(__first, __last, __comp);
  845.   }
  846. }
  847.  
  848. // stable_sort() and its auxiliary functions.
  849.  
  850. template <class _RandomAccessIter, class _Compare>
  851. void __inplace_stable_sort(_RandomAccessIter __first,
  852.                            _RandomAccessIter __last, _Compare __comp) {
  853.   if (__last - __first < 15) {
  854.     __insertion_sort(__first, __last, __comp);
  855.     return;
  856.   }
  857.   _RandomAccessIter __middle = __first + (__last - __first) / 2;
  858.   __inplace_stable_sort(__first, __middle, __comp);
  859.   __inplace_stable_sort(__middle, __last, __comp);
  860.   __merge_without_buffer(__first, __middle, __last,
  861.                          __middle - __first,
  862.                          __last - __middle,
  863.                          __comp);
  864. }
  865.  
  866. template <class _RandomAccessIter1, class _RandomAccessIter2,
  867.           class _Distance, class _Compare>
  868. void __merge_sort_loop(_RandomAccessIter1 __first,
  869.                        _RandomAccessIter1 __last, 
  870.                        _RandomAccessIter2 __result, _Distance __step_size,
  871.                        _Compare __comp) {
  872.   _Distance __two_step = 2 * __step_size;
  873.  
  874.   while (__last - __first >= __two_step) {
  875.     __result = merge(__first, __first + __step_size,
  876.                      __first + __step_size, __first + __two_step,
  877.                      __result,
  878.                      __comp);
  879.     __first += __two_step;
  880.   }
  881.   __step_size = (min) (_Distance(__last - __first), __step_size);
  882.  
  883.   merge(__first, __first + __step_size,
  884.         __first + __step_size, __last,
  885.         __result,
  886.         __comp);
  887. }
  888.  
  889. const int __stl_chunk_size = 7;
  890.         
  891. template <class _RandomAccessIter, class _Distance, class _Compare>
  892. void __chunk_insertion_sort(_RandomAccessIter __first, 
  893.                             _RandomAccessIter __last,
  894.                             _Distance __chunk_size, _Compare __comp)
  895. {
  896.   while (__last - __first >= __chunk_size) {
  897.     __insertion_sort(__first, __first + __chunk_size, __comp);
  898.     __first += __chunk_size;
  899.   }
  900.   __insertion_sort(__first, __last, __comp);
  901. }
  902.  
  903. template <class _RandomAccessIter, class _Pointer, class _Distance,
  904.           class _Compare>
  905. void __merge_sort_with_buffer(_RandomAccessIter __first, 
  906.                               _RandomAccessIter __last, _Pointer __buffer,
  907.                               _Distance*, _Compare __comp) {
  908.   _Distance __len = __last - __first;
  909.   _Pointer __buffer_last = __buffer + __len;
  910.  
  911.   _Distance __step_size = __stl_chunk_size;
  912.   __chunk_insertion_sort(__first, __last, __step_size, __comp);
  913.  
  914.   while (__step_size < __len) {
  915.     __merge_sort_loop(__first, __last, __buffer, __step_size, __comp);
  916.     __step_size *= 2;
  917.     __merge_sort_loop(__buffer, __buffer_last, __first, __step_size, __comp);
  918.     __step_size *= 2;
  919.   }
  920. }
  921.  
  922. template <class _BidirectionalIter1, class _BidirectionalIter2,
  923.           class _Distance>
  924. _BidirectionalIter1 __rotate_adaptive(_BidirectionalIter1 __first,
  925.                                       _BidirectionalIter1 __middle,
  926.                                       _BidirectionalIter1 __last,
  927.                                       _Distance __len1, _Distance __len2,
  928.                                       _BidirectionalIter2 __buffer,
  929.                                       _Distance __buffer_size) {
  930.   if (__len1 > __len2 && __len2 <= __buffer_size) {
  931.     _BidirectionalIter2 __buffer_end = copy(__middle, __last, __buffer);
  932.     copy_backward(__first, __middle, __last);
  933.     return copy(__buffer, __buffer_end, __first);
  934.   }
  935.   else if (__len1 <= __buffer_size) {
  936.     _BidirectionalIter2 __buffer_end = copy(__first, __middle, __buffer);
  937.     copy(__middle, __last, __first);
  938.     return copy_backward(__buffer, __buffer_end, __last);
  939.   }
  940.   else
  941.     return rotate(__first, __middle, __last);
  942. }
  943.  
  944. template <class _BidirectionalIter, class _Distance, class _Pointer,
  945.           class _Compare>
  946. void __merge_adaptive(_BidirectionalIter __first, 
  947.                       _BidirectionalIter __middle, 
  948.                       _BidirectionalIter __last,
  949.                       _Distance __len1, _Distance __len2,
  950.                       _Pointer __buffer, _Distance __buffer_size,
  951.                       _Compare __comp) {
  952.   if (__len1 <= __len2 && __len1 <= __buffer_size) {
  953.     _Pointer __buffer_end = copy(__first, __middle, __buffer);
  954.     merge(__buffer, __buffer_end, __middle, __last, __first, __comp);
  955.   }
  956.   else if (__len2 <= __buffer_size) {
  957.     _Pointer __buffer_end = copy(__middle, __last, __buffer);
  958.     __merge_backward(__first, __middle, __buffer, __buffer_end, __last,
  959.                      __comp);
  960.   }
  961.   else {
  962.     _BidirectionalIter __first_cut = __first;
  963.     _BidirectionalIter __second_cut = __middle;
  964.     _Distance __len11 = 0;
  965.     _Distance __len22 = 0;
  966.     if (__len1 > __len2) {
  967.       __len11 = __len1 / 2;
  968.       advance(__first_cut, __len11);
  969.       __second_cut = lower_bound(__middle, __last, *__first_cut, __comp);
  970.       __len22 += distance(__middle, __second_cut);   
  971.     }
  972.     else {
  973.       __len22 = __len2 / 2;
  974.       advance(__second_cut, __len22);
  975.       __first_cut = upper_bound(__first, __middle, *__second_cut, __comp);
  976.       __len11 += distance(__first, __first_cut);
  977.     }
  978.     _BidirectionalIter __new_middle =
  979.       __rotate_adaptive(__first_cut, __middle, __second_cut, __len1 - __len11,
  980.                         __len22, __buffer, __buffer_size);
  981.     __merge_adaptive(__first, __first_cut, __new_middle, __len11,
  982.                      __len22, __buffer, __buffer_size, __comp);
  983.     __merge_adaptive(__new_middle, __second_cut, __last, __len1 - __len11,
  984.                      __len2 - __len22, __buffer, __buffer_size, __comp);
  985.   }
  986. }
  987.  
  988. template <class _RandomAccessIter, class _Pointer, class _Distance, 
  989.           class _Compare>
  990. void __stable_sort_adaptive(_RandomAccessIter __first, 
  991.                             _RandomAccessIter __last, _Pointer __buffer,
  992.                             _Distance __buffer_size, _Compare __comp) {
  993.   _Distance __len = (__last - __first + 1) / 2;
  994.   _RandomAccessIter __middle = __first + __len;
  995.   if (__len > __buffer_size) {
  996.     __stable_sort_adaptive(__first, __middle, __buffer, __buffer_size, 
  997.                            __comp);
  998.     __stable_sort_adaptive(__middle, __last, __buffer, __buffer_size, 
  999.                            __comp);
  1000.   }
  1001.   else {
  1002.     __merge_sort_with_buffer(__first, __middle, __buffer, (_Distance*)0,
  1003.                                __comp);
  1004.     __merge_sort_with_buffer(__middle, __last, __buffer, (_Distance*)0,
  1005.                                __comp);
  1006.   }
  1007.   __merge_adaptive(__first, __middle, __last, _Distance(__middle - __first), 
  1008.                    _Distance(__last - __middle), __buffer, __buffer_size,
  1009.                    __comp);
  1010. }
  1011.  
  1012. template <class _RandomAccessIter, class _Tp, class _Distance, class _Compare>
  1013. void __stable_sort_aux(_RandomAccessIter __first,
  1014.                   _RandomAccessIter __last, _Tp*, _Distance*,
  1015.                   _Compare __comp) {
  1016.   _Temporary_buffer<_RandomAccessIter, _Tp> buf(__first, __last);
  1017.   if (buf.begin() == 0)
  1018.     __inplace_stable_sort(__first, __last, __comp);
  1019.   else 
  1020.     __stable_sort_adaptive(__first, __last, buf.begin(),
  1021.                            _Distance(buf.size()),
  1022.                            __comp);
  1023. }
  1024.  
  1025. template <class _RandomAccessIter>
  1026. void stable_sort(_RandomAccessIter __first,
  1027.          _RandomAccessIter __last) {
  1028.   _STLP_DEBUG_CHECK(__check_range(__first, __last))
  1029.   __stable_sort_aux(__first, __last,
  1030.                     _STLP_VALUE_TYPE(__first, _RandomAccessIter),
  1031.                     _STLP_DISTANCE_TYPE(__first, _RandomAccessIter),
  1032.                     __less(_STLP_VALUE_TYPE(__first, _RandomAccessIter)));
  1033. }
  1034.  
  1035. template <class _RandomAccessIter, class _Compare>
  1036. void stable_sort(_RandomAccessIter __first,
  1037.          _RandomAccessIter __last, _Compare __comp) {
  1038.   _STLP_DEBUG_CHECK(__check_range(__first, __last))
  1039.   __stable_sort_aux(__first, __last,
  1040.                     _STLP_VALUE_TYPE(__first, _RandomAccessIter),
  1041.                     _STLP_DISTANCE_TYPE(__first, _RandomAccessIter), 
  1042.                     __comp);
  1043. }
  1044.  
  1045. // partial_sort, partial_sort_copy, and auxiliary functions.
  1046.  
  1047. template <class _RandomAccessIter, class _Tp, class _Compare>
  1048. void __partial_sort(_RandomAccessIter __first, _RandomAccessIter __middle,
  1049.                     _RandomAccessIter __last, _Tp*, _Compare __comp) {
  1050.   make_heap(__first, __middle, __comp);
  1051.   for (_RandomAccessIter __i = __middle; __i < __last; ++__i)
  1052.     if (__comp(*__i, *__first))
  1053.       __pop_heap(__first, __middle, __i, _Tp(*__i), __comp,
  1054.                  _STLP_DISTANCE_TYPE(__first, _RandomAccessIter));
  1055.   sort_heap(__first, __middle, __comp);
  1056. }
  1057.  
  1058.  
  1059. template <class _RandomAccessIter>
  1060. void 
  1061. partial_sort(_RandomAccessIter __first,_RandomAccessIter __middle, _RandomAccessIter __last) {
  1062.   _STLP_DEBUG_CHECK(__check_range(__first, __middle))
  1063.   _STLP_DEBUG_CHECK(__check_range(__middle, __last))
  1064.   __partial_sort(__first, __middle, __last, _STLP_VALUE_TYPE(__first, _RandomAccessIter), 
  1065.                  __less(_STLP_VALUE_TYPE(__first, _RandomAccessIter)));
  1066. }
  1067.  
  1068. template <class _RandomAccessIter, class _Compare>
  1069. void partial_sort(_RandomAccessIter __first,_RandomAccessIter __middle,
  1070.                   _RandomAccessIter __last, _Compare __comp) {
  1071.   _STLP_DEBUG_CHECK(__check_range(__first, __middle))
  1072.   _STLP_DEBUG_CHECK(__check_range(__middle, __last))
  1073.   __partial_sort(__first, __middle, __last, _STLP_VALUE_TYPE(__first, _RandomAccessIter), __comp);
  1074. }
  1075.  
  1076. template <class _InputIter, class _RandomAccessIter, class _Compare,
  1077.           class _Distance, class _Tp>
  1078. _RandomAccessIter __partial_sort_copy(_InputIter __first,
  1079.                                          _InputIter __last,
  1080.                                          _RandomAccessIter __result_first,
  1081.                                          _RandomAccessIter __result_last,
  1082.                                          _Compare __comp, _Distance*, _Tp*) {
  1083.   if (__result_first == __result_last) return __result_last;
  1084.   _RandomAccessIter __result_real_last = __result_first;
  1085.   while(__first != __last && __result_real_last != __result_last) {
  1086.     *__result_real_last = *__first;
  1087.     ++__result_real_last;
  1088.     ++__first;
  1089.   }
  1090.   make_heap(__result_first, __result_real_last, __comp);
  1091.   while (__first != __last) {
  1092.     if (__comp(*__first, *__result_first))
  1093.       __adjust_heap(__result_first, _Distance(0),
  1094.                     _Distance(__result_real_last - __result_first),
  1095.                     _Tp(*__first),
  1096.                     __comp);
  1097.     ++__first;
  1098.   }
  1099.   sort_heap(__result_first, __result_real_last, __comp);
  1100.   return __result_real_last;
  1101. }
  1102.  
  1103. template <class _InputIter, class _RandomAccessIter>
  1104. _RandomAccessIter
  1105. partial_sort_copy(_InputIter __first, _InputIter __last,
  1106.                   _RandomAccessIter __result_first, _RandomAccessIter __result_last) {
  1107.   _STLP_DEBUG_CHECK(__check_range(__first, __last))
  1108.   _STLP_DEBUG_CHECK(__check_range(__result_first, __result_last))
  1109.   return __partial_sort_copy(__first, __last, __result_first, __result_last, 
  1110.                              __less(_STLP_VALUE_TYPE(__first, _InputIter)),
  1111.                              _STLP_DISTANCE_TYPE(__result_first, _RandomAccessIter),
  1112.                              _STLP_VALUE_TYPE(__first, _InputIter));
  1113. }
  1114.  
  1115. template <class _InputIter, class _RandomAccessIter, class _Compare>
  1116. _RandomAccessIter
  1117. partial_sort_copy(_InputIter __first, _InputIter __last,
  1118.                   _RandomAccessIter __result_first,
  1119.                   _RandomAccessIter __result_last, _Compare __comp) {
  1120.   _STLP_DEBUG_CHECK(__check_range(__first, __last))
  1121.   _STLP_DEBUG_CHECK(__check_range(__result_first, __result_last))
  1122.   return __partial_sort_copy(__first, __last, __result_first, __result_last,
  1123.                              __comp,
  1124.                              _STLP_DISTANCE_TYPE(__result_first, _RandomAccessIter),
  1125.                              _STLP_VALUE_TYPE(__first, _InputIter));
  1126. }
  1127.  
  1128. // nth_element() and its auxiliary functions.  
  1129.  
  1130. template <class _RandomAccessIter, class _Tp, class _Compare>
  1131. void __nth_element(_RandomAccessIter __first, _RandomAccessIter __nth,
  1132.                    _RandomAccessIter __last, _Tp*, _Compare __comp) {
  1133.   while (__last - __first > 3) {
  1134.     _RandomAccessIter __cut =
  1135.       __unguarded_partition(__first, __last,
  1136.                             _Tp(__median(*__first,
  1137.                                          *(__first + (__last - __first)/2), 
  1138.                                          *(__last - 1),
  1139.                                          __comp)),
  1140.                             __comp);
  1141.     if (__cut <= __nth)
  1142.       __first = __cut;
  1143.     else 
  1144.       __last = __cut;
  1145.   }
  1146.   __insertion_sort(__first, __last, __comp);
  1147. }
  1148.  
  1149.  
  1150. template <class _RandomAccessIter>
  1151. void nth_element(_RandomAccessIter __first, _RandomAccessIter __nth,
  1152.                  _RandomAccessIter __last) {
  1153.   _STLP_DEBUG_CHECK(__check_range(__first, __nth))
  1154.   _STLP_DEBUG_CHECK(__check_range(__nth, __last))
  1155.   __nth_element(__first, __nth, __last, _STLP_VALUE_TYPE(__first, _RandomAccessIter), 
  1156.                 __less(_STLP_VALUE_TYPE(__first, _RandomAccessIter)));
  1157. }
  1158.  
  1159. template <class _RandomAccessIter, class _Compare>
  1160. void nth_element(_RandomAccessIter __first, _RandomAccessIter __nth,
  1161.                  _RandomAccessIter __last, _Compare __comp) {
  1162.   _STLP_DEBUG_CHECK(__check_range(__first, __nth))
  1163.   _STLP_DEBUG_CHECK(__check_range(__nth, __last))
  1164.   __nth_element(__first, __nth, __last, _STLP_VALUE_TYPE(__first, _RandomAccessIter), __comp);
  1165. }
  1166.  
  1167. // Binary search (lower_bound, upper_bound, equal_range, binary_search).
  1168.  
  1169. template <class _ForwardIter, class _Tp, class _Compare, class _Distance>
  1170. _ForwardIter __upper_bound(_ForwardIter __first, _ForwardIter __last,
  1171.                            const _Tp& __val, _Compare __comp, _Distance*)
  1172. {
  1173.   _Distance __len = distance(__first, __last);
  1174.   _Distance __half;
  1175.  
  1176.   while (__len > 0) {
  1177.     __half = __len >> 1;
  1178.     _ForwardIter __middle = __first;
  1179.     advance(__middle, __half);
  1180.     if (__comp(__val, *__middle))
  1181.       __len = __half;
  1182.     else {
  1183.       __first = __middle;
  1184.       ++__first;
  1185.       __len = __len - __half - 1;
  1186.     }
  1187.   }
  1188.   return __first;
  1189. }
  1190.  
  1191. template <class _ForwardIter, class _Tp, class _Compare, class _Distance>
  1192. pair<_ForwardIter, _ForwardIter>
  1193. __equal_range(_ForwardIter __first, _ForwardIter __last, const _Tp& __val,
  1194.               _Compare __comp, _Distance*)
  1195. {
  1196.   _Distance __len = distance(__first, __last);
  1197.   _Distance __half;
  1198.  
  1199.   while (__len > 0) {
  1200.     __half = __len >> 1;
  1201.     _ForwardIter __middle = __first;
  1202.     advance(__middle, __half);
  1203.     if (__comp(*__middle, __val)) {
  1204.       __first = __middle;
  1205.       ++__first;
  1206.       __len = __len - __half - 1;
  1207.     }
  1208.     else if (__comp(__val, *__middle))
  1209.       __len = __half;
  1210.     else {
  1211.       _ForwardIter __left = lower_bound(__first, __middle, __val, __comp);
  1212.       advance(__first, __len);
  1213.       _ForwardIter __right = upper_bound(++__middle, __first, __val, __comp);
  1214.       return pair<_ForwardIter, _ForwardIter>(__left, __right);
  1215.     }
  1216.   }
  1217.   return pair<_ForwardIter, _ForwardIter>(__first, __first);
  1218. }           
  1219.  
  1220. template <class _InputIter1, class _InputIter2, class _OutputIter>
  1221. _OutputIter merge(_InputIter1 __first1, _InputIter1 __last1,
  1222.                   _InputIter2 __first2, _InputIter2 __last2,
  1223.                   _OutputIter __result) {
  1224.   _STLP_DEBUG_CHECK(__check_range(__first1, __last1))
  1225.   _STLP_DEBUG_CHECK(__check_range(__first2, __last2))
  1226.   while (__first1 != __last1 && __first2 != __last2) {
  1227.     if (*__first2 < *__first1) {
  1228.       *__result = *__first2;
  1229.       ++__first2;
  1230.     }
  1231.     else {
  1232.       *__result = *__first1;
  1233.       ++__first1;
  1234.     }
  1235.     ++__result;
  1236.   }
  1237.   return copy(__first2, __last2, copy(__first1, __last1, __result));
  1238. }
  1239.  
  1240. template <class _InputIter1, class _InputIter2, class _OutputIter,
  1241.           class _Compare>
  1242. _OutputIter merge(_InputIter1 __first1, _InputIter1 __last1,
  1243.                   _InputIter2 __first2, _InputIter2 __last2,
  1244.                   _OutputIter __result, _Compare __comp) {
  1245.   _STLP_DEBUG_CHECK(__check_range(__first1, __last1))
  1246.   _STLP_DEBUG_CHECK(__check_range(__first2, __last2))
  1247.   while (__first1 != __last1 && __first2 != __last2) {
  1248.     if (__comp(*__first2, *__first1)) {
  1249.       *__result = *__first2;
  1250.       ++__first2;
  1251.     }
  1252.     else {
  1253.       *__result = *__first1;
  1254.       ++__first1;
  1255.     }
  1256.     ++__result;
  1257.   }
  1258.   return copy(__first2, __last2, copy(__first1, __last1, __result));
  1259. }
  1260.  
  1261. template <class _BidirectionalIter, class _Distance, class _Compare>
  1262. void __merge_without_buffer(_BidirectionalIter __first,
  1263.                             _BidirectionalIter __middle,
  1264.                             _BidirectionalIter __last,
  1265.                             _Distance __len1, _Distance __len2,
  1266.                             _Compare __comp) {
  1267.   if (__len1 == 0 || __len2 == 0)
  1268.     return;
  1269.   if (__len1 + __len2 == 2) {
  1270.     if (__comp(*__middle, *__first))
  1271.       iter_swap(__first, __middle);
  1272.     return;
  1273.   }
  1274.   _BidirectionalIter __first_cut = __first;
  1275.   _BidirectionalIter __second_cut = __middle;
  1276.   _Distance __len11 = 0;
  1277.   _Distance __len22 = 0;
  1278.   if (__len1 > __len2) {
  1279.     __len11 = __len1 / 2;
  1280.     advance(__first_cut, __len11);
  1281.     __second_cut = lower_bound(__middle, __last, *__first_cut, __comp);
  1282.     __len22 += distance(__middle, __second_cut);
  1283.   }
  1284.   else {
  1285.     __len22 = __len2 / 2;
  1286.     advance(__second_cut, __len22);
  1287.     __first_cut = upper_bound(__first, __middle, *__second_cut, __comp);
  1288.     __len11 +=distance(__first, __first_cut);
  1289.   }
  1290.   _BidirectionalIter __new_middle
  1291.     = rotate(__first_cut, __middle, __second_cut);
  1292.   __merge_without_buffer(__first, __first_cut, __new_middle, __len11, __len22,
  1293.                          __comp);
  1294.   __merge_without_buffer(__new_middle, __second_cut, __last, __len1 - __len11,
  1295.                          __len2 - __len22, __comp);
  1296. }
  1297.  
  1298. template <class _BidirectionalIter1, class _BidirectionalIter2,
  1299.           class _BidirectionalIter3, class _Compare>
  1300. _BidirectionalIter3 __merge_backward(_BidirectionalIter1 __first1,
  1301.                                      _BidirectionalIter1 __last1,
  1302.                                      _BidirectionalIter2 __first2,
  1303.                                      _BidirectionalIter2 __last2,
  1304.                                      _BidirectionalIter3 __result,
  1305.                                      _Compare __comp) {
  1306.   if (__first1 == __last1)
  1307.     return copy_backward(__first2, __last2, __result);
  1308.   if (__first2 == __last2)
  1309.     return copy_backward(__first1, __last1, __result);
  1310.   --__last1;
  1311.   --__last2;
  1312.   while (true) {
  1313.     if (__comp(*__last2, *__last1)) {
  1314.       *--__result = *__last1;
  1315.       if (__first1 == __last1)
  1316.         return copy_backward(__first2, ++__last2, __result);
  1317.       --__last1;
  1318.     }
  1319.     else {
  1320.       *--__result = *__last2;
  1321.       if (__first2 == __last2)
  1322.         return copy_backward(__first1, ++__last1, __result);
  1323.       --__last2;
  1324.     }
  1325.   }
  1326. }
  1327.  
  1328. template <class _BidirectionalIter, class _Tp, 
  1329.           class _Distance, class _Compare>
  1330. inline void __inplace_merge_aux(_BidirectionalIter __first,
  1331.                                 _BidirectionalIter __middle,
  1332.                                 _BidirectionalIter __last, _Tp*, _Distance*,
  1333.                                 _Compare __comp) {
  1334.   _Distance __len1 = distance(__first, __middle);
  1335.   _Distance __len2 = distance(__middle, __last);
  1336.  
  1337.   _Temporary_buffer<_BidirectionalIter, _Tp> __buf(__first, __last);
  1338.   if (__buf.begin() == 0)
  1339.     __merge_without_buffer(__first, __middle, __last, __len1, __len2, __comp);
  1340.   else
  1341.     __merge_adaptive(__first, __middle, __last, __len1, __len2,
  1342.                      __buf.begin(), _Distance(__buf.size()),
  1343.                      __comp);
  1344. }
  1345.  
  1346. template <class _BidirectionalIter>
  1347. void inplace_merge(_BidirectionalIter __first,
  1348.            _BidirectionalIter __middle,
  1349.            _BidirectionalIter __last) {
  1350.   _STLP_DEBUG_CHECK(__check_range(__first, __middle))
  1351.   _STLP_DEBUG_CHECK(__check_range(__middle, __last))
  1352.   if (__first == __middle || __middle == __last)
  1353.     return;
  1354.   __inplace_merge_aux(__first, __middle, __last,
  1355.                       _STLP_VALUE_TYPE(__first, _BidirectionalIter), _STLP_DISTANCE_TYPE(__first, _BidirectionalIter),
  1356.                       __less(_STLP_VALUE_TYPE(__first, _BidirectionalIter)));
  1357. }
  1358.  
  1359. template <class _BidirectionalIter, class _Compare>
  1360. void inplace_merge(_BidirectionalIter __first,
  1361.            _BidirectionalIter __middle,
  1362.            _BidirectionalIter __last, _Compare __comp) {
  1363.   _STLP_DEBUG_CHECK(__check_range(__first, __middle))
  1364.   _STLP_DEBUG_CHECK(__check_range(__middle, __last))
  1365.   if (__first == __middle || __middle == __last)
  1366.     return;
  1367.   __inplace_merge_aux(__first, __middle, __last,
  1368.                       _STLP_VALUE_TYPE(__first, _BidirectionalIter), _STLP_DISTANCE_TYPE(__first, _BidirectionalIter),
  1369.                       __comp);
  1370. }
  1371.  
  1372.  
  1373. template <class _InputIter1, class _InputIter2, class _Compare>
  1374. bool __includes(_InputIter1 __first1, _InputIter1 __last1,
  1375.                 _InputIter2 __first2, _InputIter2 __last2, _Compare __comp) {
  1376.   _STLP_DEBUG_CHECK(__check_range(__first1, __last1))
  1377.   _STLP_DEBUG_CHECK(__check_range(__first2, __last2))
  1378.   while (__first1 != __last1 && __first2 != __last2)
  1379.     if (__comp(*__first2, *__first1))
  1380.       return false;
  1381.     else if(__comp(*__first1, *__first2)) 
  1382.       ++__first1;
  1383.     else
  1384.       ++__first1, ++__first2;
  1385.  
  1386.   return __first2 == __last2;
  1387. }
  1388.  
  1389. template <class _InputIter1, class _InputIter2, class _Compare>
  1390. bool includes(_InputIter1 __first1, _InputIter1 __last1,
  1391.               _InputIter2 __first2, _InputIter2 __last2, _Compare __comp) {
  1392.   return __includes(__first1, __last1, __first2, __last2, __comp);
  1393. }
  1394.  
  1395. template <class _InputIter1, class _InputIter2>
  1396. bool includes(_InputIter1 __first1, _InputIter1 __last1,
  1397.               _InputIter2 __first2, _InputIter2 __last2) {
  1398.   return __includes(__first1, __last1, __first2, __last2, __less(_STLP_VALUE_TYPE(__first1, _InputIter1)));
  1399. }
  1400.  
  1401. template <class _InputIter1, class _InputIter2, class _OutputIter,
  1402.           class _Compare>
  1403. _OutputIter __set_union(_InputIter1 __first1, _InputIter1 __last1,
  1404.                         _InputIter2 __first2, _InputIter2 __last2,
  1405.                         _OutputIter __result, _Compare __comp) {
  1406.   _STLP_DEBUG_CHECK(__check_range(__first1, __last1))
  1407.   _STLP_DEBUG_CHECK(__check_range(__first2, __last2))
  1408.   while (__first1 != __last1 && __first2 != __last2) {
  1409.     if (__comp(*__first1, *__first2)) {
  1410.       *__result = *__first1;
  1411.       ++__first1;
  1412.     }
  1413.     else if (__comp(*__first2, *__first1)) {
  1414.       *__result = *__first2;
  1415.       ++__first2;
  1416.     }
  1417.     else {
  1418.       *__result = *__first1;
  1419.       ++__first1;
  1420.       ++__first2;
  1421.     }
  1422.     ++__result;
  1423.   }
  1424.   return copy(__first2, __last2, copy(__first1, __last1, __result));
  1425. }
  1426.  
  1427. template <class _InputIter1, class _InputIter2, class _OutputIter>
  1428. _OutputIter set_union(_InputIter1 __first1, _InputIter1 __last1,
  1429.                       _InputIter2 __first2, _InputIter2 __last2,
  1430.                       _OutputIter __result) {
  1431.   return __set_union(__first1, __last1, __first2, __last2, __result, __less(_STLP_VALUE_TYPE(__first1, _InputIter1)));  
  1432. }
  1433.  
  1434. template <class _InputIter1, class _InputIter2, class _OutputIter,
  1435.           class _Compare>
  1436. _OutputIter set_union(_InputIter1 __first1, _InputIter1 __last1,
  1437.                       _InputIter2 __first2, _InputIter2 __last2,
  1438.                       _OutputIter __result, _Compare __comp) {
  1439.   return __set_union(__first1, __last1, __first2, __last2, __result, __comp);
  1440. }
  1441.  
  1442. template <class _InputIter1, class _InputIter2, class _OutputIter,
  1443.           class _Compare>
  1444. _OutputIter __set_intersection(_InputIter1 __first1, _InputIter1 __last1,
  1445.                                _InputIter2 __first2, _InputIter2 __last2,
  1446.                                _OutputIter __result, _Compare __comp) {
  1447.   _STLP_DEBUG_CHECK(__check_range(__first1, __last1))
  1448.   _STLP_DEBUG_CHECK(__check_range(__first2, __last2))
  1449.   while (__first1 != __last1 && __first2 != __last2)
  1450.     if (__comp(*__first1, *__first2))
  1451.       ++__first1;
  1452.     else if (__comp(*__first2, *__first1))
  1453.       ++__first2;
  1454.     else {
  1455.       *__result = *__first1;
  1456.       ++__first1;
  1457.       ++__first2;
  1458.       ++__result;
  1459.     }
  1460.   return __result;
  1461. }
  1462.  
  1463. template <class _InputIter1, class _InputIter2, class _OutputIter>
  1464. _OutputIter set_intersection(_InputIter1 __first1, _InputIter1 __last1,
  1465.                              _InputIter2 __first2, _InputIter2 __last2,
  1466.                              _OutputIter __result) {
  1467.   return __set_intersection(__first1, __last1, __first2, __last2, __result, __less(_STLP_VALUE_TYPE(__first1, _InputIter1)));  
  1468. }
  1469.  
  1470. template <class _InputIter1, class _InputIter2, class _OutputIter,
  1471.           class _Compare>
  1472. _OutputIter set_intersection(_InputIter1 __first1, _InputIter1 __last1,
  1473.                              _InputIter2 __first2, _InputIter2 __last2,
  1474.                              _OutputIter __result, _Compare __comp) {
  1475.   return __set_intersection(__first1, __last1, __first2, __last2, __result, __comp);
  1476. }
  1477.  
  1478. template <class _InputIter1, class _InputIter2, class _OutputIter, 
  1479.           class _Compare>
  1480. _OutputIter __set_difference(_InputIter1 __first1, _InputIter1 __last1,
  1481.                              _InputIter2 __first2, _InputIter2 __last2, 
  1482.                              _OutputIter __result, _Compare __comp) {
  1483.   _STLP_DEBUG_CHECK(__check_range(__first1, __last1))
  1484.   _STLP_DEBUG_CHECK(__check_range(__first2, __last2))
  1485.   while (__first1 != __last1 && __first2 != __last2)
  1486.     if (__comp(*__first1, *__first2)) {
  1487.       *__result = *__first1;
  1488.       ++__first1;
  1489.       ++__result;
  1490.     }
  1491.     else if (__comp(*__first2, *__first1))
  1492.       ++__first2;
  1493.     else {
  1494.       ++__first1;
  1495.       ++__first2;
  1496.     }
  1497.   return copy(__first1, __last1, __result);
  1498. }
  1499.  
  1500. template <class _InputIter1, class _InputIter2, class _OutputIter>
  1501. _OutputIter set_difference(_InputIter1 __first1, _InputIter1 __last1,
  1502.                            _InputIter2 __first2, _InputIter2 __last2,
  1503.                            _OutputIter __result) {
  1504.   return __set_difference(__first1, __last1, __first2, __last2, __result, 
  1505.                           __less(_STLP_VALUE_TYPE(__first1, _InputIter1)));  
  1506. }
  1507.  
  1508. template <class _InputIter1, class _InputIter2, class _OutputIter, 
  1509.           class _Compare>
  1510. _OutputIter set_difference(_InputIter1 __first1, _InputIter1 __last1,
  1511.                            _InputIter2 __first2, _InputIter2 __last2, 
  1512.                            _OutputIter __result, _Compare __comp) {
  1513.   return __set_difference(__first1, __last1, __first2, __last2, __result, __comp);
  1514. }
  1515.  
  1516. template <class _InputIter1, class _InputIter2, class _OutputIter, class _Compare>
  1517. _OutputIter 
  1518. __set_symmetric_difference(_InputIter1 __first1, _InputIter1 __last1,
  1519.                            _InputIter2 __first2, _InputIter2 __last2,
  1520.                            _OutputIter __result, _Compare __comp) {
  1521.   _STLP_DEBUG_CHECK(__check_range(__first1, __last1))
  1522.   _STLP_DEBUG_CHECK(__check_range(__first2, __last2))
  1523.   while (__first1 != __last1 && __first2 != __last2)
  1524.     if (__comp(*__first1, *__first2)) {
  1525.       *__result = *__first1;
  1526.       ++__first1;
  1527.       ++__result;
  1528.     }
  1529.     else if (__comp(*__first2, *__first1)) {
  1530.       *__result = *__first2;
  1531.       ++__first2;
  1532.       ++__result;
  1533.     }
  1534.     else {
  1535.       ++__first1;
  1536.       ++__first2;
  1537.     }
  1538.   return copy(__first2, __last2, copy(__first1, __last1, __result));
  1539. }
  1540.  
  1541. template <class _InputIter1, class _InputIter2, class _OutputIter>
  1542. _OutputIter 
  1543. set_symmetric_difference(_InputIter1 __first1, _InputIter1 __last1,
  1544.                          _InputIter2 __first2, _InputIter2 __last2,
  1545.                          _OutputIter __result) {
  1546.   return __set_symmetric_difference(__first1, __last1, __first2, __last2, __result,
  1547.                                     __less(_STLP_VALUE_TYPE(__first1, _InputIter1)));  
  1548. }
  1549.  
  1550. template <class _InputIter1, class _InputIter2, class _OutputIter, class _Compare>
  1551. _OutputIter 
  1552. set_symmetric_difference(_InputIter1 __first1, _InputIter1 __last1,
  1553.                          _InputIter2 __first2, _InputIter2 __last2,
  1554.                          _OutputIter __result,
  1555.                          _Compare __comp) {
  1556.   return __set_symmetric_difference(__first1, __last1, __first2, __last2, __result, __comp);
  1557. }
  1558.  
  1559. // min_element and max_element, with and without an explicitly supplied
  1560. // comparison function.
  1561.  
  1562. template <class _ForwardIter, class _Compare>
  1563. _ForwardIter max_element(_ForwardIter __first, _ForwardIter __last,
  1564.                             _Compare __comp) {
  1565.   _STLP_DEBUG_CHECK(__check_range(__first, __last))
  1566.   if (__first == __last) return __first;
  1567.   _ForwardIter __result = __first;
  1568.   while (++__first != __last) 
  1569.     if (__comp(*__result, *__first)) __result = __first;
  1570.   return __result;
  1571. }
  1572.  
  1573. template <class _ForwardIter>
  1574. _ForwardIter max_element(_ForwardIter __first, _ForwardIter __last) {
  1575.   _STLP_DEBUG_CHECK(__check_range(__first, __last))
  1576.   if (__first == __last) return __first;
  1577.   _ForwardIter __result = __first;
  1578.   while (++__first != __last) 
  1579.     if (*__result < *__first)
  1580.       __result = __first;
  1581.   return __result;
  1582. }
  1583.  
  1584. template <class _ForwardIter>
  1585. _ForwardIter min_element(_ForwardIter __first, _ForwardIter __last) {
  1586.   _STLP_DEBUG_CHECK(__check_range(__first, __last))
  1587.   if (__first == __last) return __first;
  1588.   _ForwardIter __result = __first;
  1589.   while (++__first != __last) 
  1590.     if (*__first < *__result)
  1591.       __result = __first;
  1592.   return __result;
  1593. }
  1594.  
  1595. template <class _ForwardIter, class _Compare>
  1596. _ForwardIter min_element(_ForwardIter __first, _ForwardIter __last,
  1597.                             _Compare __comp) {
  1598.   _STLP_DEBUG_CHECK(__check_range(__first, __last))
  1599.   if (__first == __last) return __first;
  1600.   _ForwardIter __result = __first;
  1601.   while (++__first != __last) 
  1602.     if (__comp(*__first, *__result)) __result = __first;
  1603.   return __result;
  1604. }
  1605.  
  1606. // next_permutation and prev_permutation, with and without an explicitly 
  1607. // supplied comparison function.
  1608. template <class _BidirectionalIter, class _Compare>
  1609. bool __next_permutation(_BidirectionalIter __first, _BidirectionalIter __last,
  1610.                         _Compare __comp) {
  1611.   _STLP_DEBUG_CHECK(__check_range(__first, __last))
  1612.   if (__first == __last)
  1613.     return false;
  1614.   _BidirectionalIter __i = __first;
  1615.   ++__i;
  1616.   if (__i == __last)
  1617.     return false;
  1618.   __i = __last;
  1619.   --__i;
  1620.  
  1621.   for(;;) {
  1622.     _BidirectionalIter __ii = __i;
  1623.     --__i;
  1624.     if (__comp(*__i, *__ii)) {
  1625.       _BidirectionalIter __j = __last;
  1626.       while (!__comp(*__i, *--__j))
  1627.         {}
  1628.       iter_swap(__i, __j);
  1629.       reverse(__ii, __last);
  1630.       return true;
  1631.     }
  1632.     if (__i == __first) {
  1633.       reverse(__first, __last);
  1634.       return false;
  1635.     }
  1636.   }
  1637. #if defined(_STLP_NEED_UNREACHABLE_RETURN)
  1638.     return 0;
  1639. #endif
  1640. }
  1641.  
  1642. template <class _BidirectionalIter>
  1643. bool next_permutation(_BidirectionalIter __first, _BidirectionalIter __last) {
  1644.   _STLP_DEBUG_CHECK(__check_range(__first, __last))
  1645.   return __next_permutation(__first, __last, __less(_STLP_VALUE_TYPE(__first, _BidirectionalIter)));
  1646. }
  1647.  
  1648. template <class _BidirectionalIter, class _Compare>
  1649. bool next_permutation(_BidirectionalIter __first, _BidirectionalIter __last,
  1650.                       _Compare __comp) {
  1651.   _STLP_DEBUG_CHECK(__check_range(__first, __last))
  1652.   return __next_permutation(__first, __last, __comp);
  1653. }
  1654.  
  1655. template <class _BidirectionalIter, class _Compare>
  1656. bool __prev_permutation(_BidirectionalIter __first, _BidirectionalIter __last,
  1657.                       _Compare __comp) {
  1658.   if (__first == __last)
  1659.     return false;
  1660.   _BidirectionalIter __i = __first;
  1661.   ++__i;
  1662.   if (__i == __last)
  1663.     return false;
  1664.   __i = __last;
  1665.   --__i;
  1666.  
  1667.   for(;;) {
  1668.     _BidirectionalIter __ii = __i;
  1669.     --__i;
  1670.     if (__comp(*__ii, *__i)) {
  1671.       _BidirectionalIter __j = __last;
  1672.       while (!__comp(*--__j, *__i))
  1673.         {}
  1674.       iter_swap(__i, __j);
  1675.       reverse(__ii, __last);
  1676.       return true;
  1677.     }
  1678.     if (__i == __first) {
  1679.       reverse(__first, __last);
  1680.       return false;
  1681.     }
  1682.   }
  1683. #if defined(_STLP_NEED_UNREACHABLE_RETURN)
  1684.     return 0;
  1685. #endif
  1686. }
  1687.  
  1688. template <class _BidirectionalIter>
  1689. bool prev_permutation(_BidirectionalIter __first, _BidirectionalIter __last) {
  1690.   _STLP_DEBUG_CHECK(__check_range(__first, __last))
  1691.   return __prev_permutation(__first, __last, __less(_STLP_VALUE_TYPE(__first, _BidirectionalIter)));
  1692. }
  1693.  
  1694. template <class _BidirectionalIter, class _Compare>
  1695. bool prev_permutation(_BidirectionalIter __first, _BidirectionalIter __last,
  1696.                       _Compare __comp) {
  1697.   _STLP_DEBUG_CHECK(__check_range(__first, __last))
  1698.   return __prev_permutation(__first, __last, __comp);
  1699. }
  1700.  
  1701. # ifndef _STLP_NO_EXTENSIONS
  1702.  
  1703. // is_heap, a predicate testing whether or not a range is
  1704. // a heap.  This function is an extension, not part of the C++
  1705. // standard.
  1706.  
  1707.  
  1708. template <class _RandomAccessIter, class _Distance, class _StrictWeakOrdering>
  1709. bool __is_heap(_RandomAccessIter __first, _StrictWeakOrdering __comp,
  1710.                _Distance __n)
  1711. {
  1712.   _Distance __parent = 0;
  1713.   for (_Distance __child = 1; __child < __n; ++__child) {
  1714.     if (__comp(__first[__parent], __first[__child]))
  1715.       return false;
  1716.     if ((__child & 1) == 0)
  1717.       ++__parent;
  1718.   }
  1719.   return true;
  1720. }
  1721.  
  1722. template <class _RandomAccessIter>
  1723. bool is_heap(_RandomAccessIter __first, _RandomAccessIter __last)
  1724. {
  1725.   _STLP_DEBUG_CHECK(__check_range(__first, __last))
  1726.   return __is_heap(__first, __less(_STLP_VALUE_TYPE(__first, _RandomAccessIter)), __last - __first);
  1727. }
  1728.  
  1729. template <class _RandomAccessIter, class _StrictWeakOrdering>
  1730. bool is_heap(_RandomAccessIter __first, _RandomAccessIter __last,
  1731.          _StrictWeakOrdering __comp)
  1732. {
  1733.   _STLP_DEBUG_CHECK(__check_range(__first, __last))
  1734.   return __is_heap(__first, __comp, __last - __first);
  1735. }
  1736.  
  1737.  
  1738. template <class _ForwardIter, class _StrictWeakOrdering>
  1739. bool __is_sorted(_ForwardIter __first, _ForwardIter __last,
  1740.                  _StrictWeakOrdering __comp)
  1741. {
  1742.   _STLP_DEBUG_CHECK(__check_range(__first, __last))
  1743.   if (__first == __last)
  1744.     return true;
  1745.  
  1746.   _ForwardIter __next = __first;
  1747.   for (++__next; __next != __last; __first = __next, ++__next) {
  1748.     if (__comp(*__next, *__first))
  1749.       return false;
  1750.   }
  1751.  
  1752.   return true;
  1753. }
  1754.  
  1755. # endif /* _STLP_NO_EXTENSIONS */
  1756.  
  1757. _STLP_END_NAMESPACE
  1758.  
  1759. # undef __stl_threshold
  1760.  
  1761. #endif /* _STLP_ALGO_C */
  1762. // Local Variables:
  1763. // mode:C++
  1764. // End:
  1765.