home *** CD-ROM | disk | FTP | other *** search
/ PC World 2000 January / PCWorld_2000-01_cd.bin / Software / Servis / Devc / _SETUP.4 / Group3 / stl_algo.h < prev    next >
C/C++ Source or Header  |  1998-03-08  |  86KB  |  2,675 lines

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