home *** CD-ROM | disk | FTP | other *** search
/ DOS/V Power Report 1997 May / VPR9705A.ISO / VPR_DATA / PROGRAM / CBTRIAL / SETUP / DATA.Z / ALGORITH.H < prev    next >
C/C++ Source or Header  |  1997-02-14  |  109KB  |  3,316 lines

  1. #ifndef __STD_ALGORITHM
  2. #define __STD_ALGORITHM
  3. /* $Revision:   8.1  $ */
  4.  
  5. /***************************************************************************
  6.  *
  7.  * algorithm - Declarations for the Standard Library algorithms
  8.  *
  9.  * $Id: algorithm,v 1.54 1995/09/29 02:02:22 hart Exp $
  10.  *
  11.  ***************************************************************************
  12.  *
  13.  * Copyright (c) 1994
  14.  * Hewlett-Packard Company
  15.  *
  16.  * Permission to use, copy, modify, distribute and sell this software
  17.  * and its documentation for any purpose is hereby granted without fee,
  18.  * provided that the above copyright notice appear in all copies and
  19.  * that both that copyright notice and this permission notice appear
  20.  * in supporting documentation.  Hewlett-Packard Company makes no
  21.  * representations about the suitability of this software for any
  22.  * purpose.  It is provided "as is" without express or implied warranty.
  23.  *
  24.  *
  25.  ***************************************************************************
  26.  *
  27.  * (c) Copyright 1994, 1995 Rogue Wave Software, Inc.
  28.  * ALL RIGHTS RESERVED
  29.  *
  30.  * The software and information contained herein are proprietary to, and
  31.  * comprise valuable trade secrets of, Rogue Wave Software, Inc., which
  32.  * intends to preserve as trade secrets such software and information.
  33.  * This software is furnished pursuant to a written license agreement and
  34.  * may be used, copied, transmitted, and stored only in accordance with
  35.  * the terms of such license and with the inclusion of the above copyright
  36.  * notice.  This software and information or any other copies thereof may
  37.  * not be provided or otherwise made available to any other person.
  38.  *
  39.  * Notwithstanding any other lease or license that may pertain to, or
  40.  * accompany the delivery of, this computer software and information, the
  41.  * rights of the Government regarding its use, reproduction and disclosure
  42.  * are as set forth in Section 52.227-19 of the FARS Computer
  43.  * Software-Restricted Rights clause.
  44.  *
  45.  * Use, duplication, or disclosure by the Government is subject to
  46.  * restrictions as set forth in subparagraph (c)(1)(ii) of the Rights in
  47.  * Technical Data and Computer Software clause at DFARS 252.227-7013.
  48.  * Contractor/Manufacturer is Rogue Wave Software, Inc.,
  49.  * P.O. Box 2328, Corvallis, Oregon 97339.
  50.  *
  51.  * This computer software and information is distributed with "restricted
  52.  * rights."  Use, duplication or disclosure is subject to restrictions as
  53.  * set forth in NASA FAR SUP 18-52.227-79 (April 1985) "Commercial
  54.  * Computer Software-Restricted Rights (April 1985)."  If the Clause at
  55.  * 18-52.227-74 "Rights in Data General" is specified in the contract,
  56.  * then the "Alternate III" clause applies.
  57.  *
  58.  **************************************************************************/
  59.  
  60. #include <stdcomp.h>
  61.  
  62. #include <function>
  63. #include <iterator>
  64.  
  65. #ifndef RWSTD_NO_NEW_HEADER
  66. #include <cstdlib>
  67. #else
  68. #include <stdlib.h>
  69. #endif
  70.  
  71. // Some compilers have min and max macros
  72. // We use function templates in their stead
  73. #ifdef max
  74. # undef max
  75. #endif
  76. #ifdef min
  77. # undef min
  78. #endif
  79.  
  80. #include <memory>
  81.  
  82. #ifndef RWSTD_NO_NAMESPACE
  83. namespace std {
  84. #endif
  85.  
  86. template <class T>
  87. inline void __initialize (T& t, T val) { t = val; }
  88.  
  89. //
  90. // Non-modifying sequence operations.
  91. //
  92.  
  93. template <class InputIterator, class Function>
  94. Function for_each (InputIterator first, InputIterator last, Function f)
  95. {
  96.     while (first != last) f(*first++);
  97.     return f;
  98. }
  99.  
  100. template <class InputIterator, class T>
  101. InputIterator find (InputIterator first, InputIterator last, const T& value)
  102. {
  103.     while (first != last && *first != value)
  104.         ++first;
  105.     return first;
  106. }
  107.  
  108. template <class InputIterator, class Predicate>
  109. InputIterator find_if (InputIterator first, InputIterator last, Predicate pred)
  110. {
  111.     while (first != last && !pred(*first)) ++first;
  112.     return first;
  113. }
  114.  
  115.  
  116. template <class ForwardIterator1, class ForwardIterator2>
  117. ForwardIterator1 find_end (ForwardIterator1 first1,
  118.                                   ForwardIterator1 last1,
  119.                                   ForwardIterator2 first2,
  120.                                   ForwardIterator2 last2)
  121. {
  122.     ForwardIterator1 end = find_first_of(first1,last1,first2,last2);
  123.     ForwardIterator1 next = last1;
  124.     while (end != last1)
  125.     {
  126.         next = end;
  127.         end = find_first_of(++end,last1,first2,last2);
  128.     }
  129.     return next;
  130. }
  131.  
  132. template <class ForwardIterator1, class ForwardIterator2,
  133.           class BinaryPredicate>
  134. ForwardIterator1 find_end (ForwardIterator1 first1,
  135.                                   ForwardIterator1 last1,
  136.                                   ForwardIterator2 first2,
  137.                                   ForwardIterator2 last2,
  138.                                   BinaryPredicate pred)
  139. {
  140.     ForwardIterator1 end = find_first_of(first1,last1,first2,last2,pred);
  141.     ForwardIterator1 next = last1;
  142.     while (end != last1)
  143.     {
  144.         next = end;
  145.         end = find_first_of(++end,last1,first2,last2,pred);
  146.     }
  147.     return next;
  148. }
  149.  
  150. template <class ForwardIterator1, class ForwardIterator2>
  151. ForwardIterator1 find_first_of (ForwardIterator1 first1, ForwardIterator1 last1,
  152.                                 ForwardIterator2 first2, ForwardIterator2 last2)
  153. {
  154.     ForwardIterator1 next = first1;
  155.     while (next != last1)
  156.     {
  157.         if (find(first2,last2,*next) != last2)
  158.             return next;
  159.         next++;
  160.     }
  161.     return last1;
  162. }
  163.  
  164. template <class ForwardIterator1, class ForwardIterator2,
  165.           class BinaryPredicate>
  166. ForwardIterator1 find_first_of (ForwardIterator1 first1,ForwardIterator1 last1,
  167.                                 ForwardIterator2 first2,ForwardIterator2 last2,
  168.                                 BinaryPredicate pred)
  169. {
  170.     ForwardIterator1 next = first1;
  171.     while (next != last1)
  172.     {
  173.         if (find_if(first2,last2,bind1st(pred,*next)) != last2)
  174.             return next;
  175.         next++;
  176.     }
  177.     return last1;
  178. }
  179.  
  180.  
  181. template <class ForwardIterator>
  182. ForwardIterator adjacent_find (ForwardIterator first, ForwardIterator last)
  183. {
  184.     if (first == last) return last;
  185.     ForwardIterator next = first;
  186.     while (++next != last)
  187.     {
  188.         if (*first == *next) return first;
  189.         first = next;
  190.     }
  191.     return last;
  192. }
  193.  
  194. template <class ForwardIterator, class BinaryPredicate>
  195. ForwardIterator adjacent_find (ForwardIterator first, ForwardIterator last,
  196.                              BinaryPredicate binary_pred)
  197. {
  198.     if (first == last) return last;
  199.     ForwardIterator next = first;
  200.     while (++next != last)
  201.     {
  202.         if (binary_pred(*first, *next)) return first;
  203.         first = next;
  204.     }
  205.     return last;
  206. }
  207.  
  208. template <class InputIterator, class T, class Size>
  209. void count (InputIterator first, InputIterator last, const T& value, Size& n)
  210. {
  211.     while (first != last)
  212.         if (*first++ == value) ++n;
  213. }
  214.  
  215. template <class InputIterator, class Predicate, class Size>
  216. void count_if (InputIterator first, InputIterator last, Predicate pred,
  217.                Size& n)
  218. {
  219.     while (first != last)
  220.     if (pred(*first++)) ++n;
  221. }
  222.  
  223. template <class InputIterator1, class InputIterator2>
  224. pair<InputIterator1, InputIterator2> mismatch(InputIterator1 first1,
  225.                                               InputIterator1 last1,
  226.                                               InputIterator2 first2)
  227. {
  228.     while (first1 != last1 && *first1 == *first2)
  229.     {
  230.         ++first1;
  231.         ++first2;
  232.     }
  233.     pair<InputIterator1, InputIterator2> tmp(first1, first2);
  234.     return tmp;
  235. }
  236.  
  237. template <class InputIterator1, class InputIterator2, class BinaryPredicate>
  238. pair<InputIterator1, InputIterator2> mismatch (InputIterator1 first1,
  239.                                                InputIterator1 last1,
  240.                                                InputIterator2 first2,
  241.                                                BinaryPredicate binary_pred)
  242. {
  243.     while (first1 != last1 && binary_pred(*first1, *first2))
  244.     {
  245.         ++first1;
  246.         ++first2;
  247.     }
  248.     pair<InputIterator1, InputIterator2> tmp(first1, first2);
  249.     return tmp;
  250. }
  251.  
  252. template <class InputIterator1, class InputIterator2>
  253. inline bool equal (InputIterator1 first1, InputIterator1 last1,
  254.                    InputIterator2 first2)
  255. {
  256.     return mismatch(first1, last1, first2).first == last1;
  257. }
  258.  
  259. template <class InputIterator1, class InputIterator2, class BinaryPredicate>
  260. inline bool equal (InputIterator1 first1, InputIterator1 last1,
  261.                    InputIterator2 first2, BinaryPredicate binary_pred)
  262. {
  263.     return mismatch(first1, last1, first2, binary_pred).first == last1;
  264. }
  265.  
  266. template <class ForwardIterator1, class ForwardIterator2,
  267.       class Distance1, class Distance2>
  268. ForwardIterator1 __search (ForwardIterator1 first1, ForwardIterator1 last1,
  269.                            ForwardIterator2 first2, ForwardIterator2 last2,
  270.                            Distance1*, Distance2*)
  271. {
  272.     Distance1 d1;
  273.     __initialize(d1, Distance1(0));
  274.     distance(first1, last1, d1);
  275.     Distance2 d2;
  276.     __initialize(d2, Distance2(0));
  277.     distance(first2, last2, d2);
  278.  
  279.     if (d1 < d2) return last1;
  280.  
  281.     ForwardIterator1 current1 = first1;
  282.     ForwardIterator2 current2 = first2;
  283.  
  284.     while (current2 != last2)
  285.     {
  286.         if (*current1++ != *current2++)
  287.             if (d1-- == d2)
  288.                 return last1;
  289.             else
  290.             {
  291.                 current1 = ++first1;
  292.                 current2 = first2;
  293.             }
  294.     }
  295.     return (current2 == last2) ? first1 : last1;
  296. }
  297.  
  298. template <class ForwardIterator1, class ForwardIterator2>
  299. inline ForwardIterator1 search (ForwardIterator1 first1,ForwardIterator1 last1,
  300.                                 ForwardIterator2 first2,ForwardIterator2 last2)
  301. {
  302.     return __search(first1, last1, first2, last2, distance_type(first1),
  303.                     distance_type(first2));
  304. }
  305.  
  306. template <class ForwardIterator1, class ForwardIterator2,
  307.           class BinaryPredicate, class Distance1, class Distance2>
  308. ForwardIterator1 __search (ForwardIterator1 first1, ForwardIterator1 last1,
  309.                            ForwardIterator2 first2, ForwardIterator2 last2,
  310.                            BinaryPredicate binary_pred, Distance1*, Distance2*)
  311. {
  312.     Distance1 d1;
  313.     __initialize(d1, Distance1(0));
  314.     distance(first1, last1, d1);
  315.     Distance2 d2;
  316.     __initialize(d2, Distance2(0));
  317.     distance(first2, last2, d2);
  318.  
  319.     if (d1 < d2) return last1;
  320.  
  321.     ForwardIterator1 current1 = first1;
  322.     ForwardIterator2 current2 = first2;
  323.  
  324.     while (current2 != last2)
  325.     {
  326.         if (!binary_pred(*current1++, *current2++))
  327.             if (d1-- == d2)
  328.                 return last1;
  329.             else
  330.             {
  331.                 current1 = ++first1;
  332.                 current2 = first2;
  333.             }
  334.     }
  335.     return (current2 == last2) ? first1 : last1;
  336. }
  337.  
  338. template <class ForwardIterator1, class ForwardIterator2,
  339.           class BinaryPredicate>
  340. inline ForwardIterator1 search (ForwardIterator1 first1,ForwardIterator1 last1,
  341.                                 ForwardIterator2 first2,ForwardIterator2 last2,
  342.                                 BinaryPredicate binary_pred)
  343. {
  344.     return __search(first1, last1, first2, last2, binary_pred,
  345.                     distance_type(first1), distance_type(first2));
  346. }
  347.  
  348. template <class ForwardIterator, class Distance, class Size, class T>
  349. ForwardIterator __search_n (ForwardIterator first, ForwardIterator last,
  350.                             Distance*, Size count, const T& value)
  351. {
  352.     Distance d;
  353.     __initialize(d, Distance(0));
  354.     distance(first, last, d);
  355.  
  356.     if (d < count || count <= 0) return last;
  357.  
  358.     Distance        span    = d - count;
  359.     Size            matches = 0;
  360.     ForwardIterator current = first;
  361.  
  362.     while (current != last)
  363.     {
  364.         if (*current++ != value)
  365.         {
  366.             if (span < matches + 1)
  367.               return last;
  368.             span   -= matches + 1;
  369.             matches = 0;
  370.             first   = current;
  371.         }
  372.         else
  373.             if (++matches == count)
  374.                 return first;
  375.     }
  376.  
  377.     return last;
  378. }
  379.  
  380. template <class ForwardIterator, class Size, class T>
  381. inline ForwardIterator search_n (ForwardIterator first, ForwardIterator last,
  382.                                  Size count, const T& value)
  383. {
  384.     return __search_n(first, last, distance_type(first), count, value);
  385. }
  386.  
  387. template <class ForwardIterator, class Distance, class Size, class T,
  388.           class BinaryPredicate>
  389. ForwardIterator __search_n (ForwardIterator first, ForwardIterator last,
  390.                             Distance*, Size count, const T& value,
  391.                             BinaryPredicate pred)
  392. {
  393.     Distance d;
  394.     __initialize(d, Distance(0));
  395.     distance(first, last, d);
  396.  
  397.     if (d < count || count <= 0) return last;
  398.  
  399.     Distance        span    = d - count;
  400.     Size            matches = 0;
  401.     ForwardIterator current = first;
  402.  
  403.     while (current != last)
  404.     {
  405.         if (!pred(*current++, value))
  406.         {
  407.             if (span < matches + 1)
  408.               return last;
  409.             span   -= matches + 1;
  410.             matches = 0;
  411.             first   = current;
  412.         }
  413.         else
  414.             if (++matches == count)
  415.                 return first;
  416.     }
  417.  
  418.     return last;
  419. }
  420.  
  421. template <class ForwardIterator, class Size, class T, class BinaryPredicate>
  422. inline ForwardIterator search_n (ForwardIterator first, ForwardIterator last,
  423.                                  Size count, const T& value,
  424.                                  BinaryPredicate pred)
  425. {
  426.     return __search_n(first, last, distance_type(first), count, value, pred);
  427. }
  428.  
  429. //
  430. // Modifying sequence operations.
  431. //
  432.  
  433. template <class InputIterator, class OutputIterator>
  434. OutputIterator copy (InputIterator first, InputIterator last,
  435.                      OutputIterator result)
  436. {
  437.     while (first != last) *result++ = *first++;
  438.     return result;
  439. }
  440.  
  441. template <class BidirectionalIterator1, class BidirectionalIterator2>
  442. BidirectionalIterator2 copy_backward (BidirectionalIterator1 first,
  443.                                       BidirectionalIterator1 last,
  444.                                       BidirectionalIterator2 result)
  445. {
  446.     while (first != last) *--result = *--last;
  447.     return result;
  448. }
  449.  
  450. template <class T>
  451. inline void swap (T& a, T& b)
  452. {
  453.     T tmp = a;
  454.     a = b;
  455.     b = tmp;
  456. }
  457.  
  458. template <class ForwardIterator1, class ForwardIterator2, class T>
  459. inline void __iter_swap (ForwardIterator1 a, ForwardIterator2 b, T*)
  460. {
  461.     T tmp = *a;
  462.     *a = *b;
  463.     *b = tmp;
  464. }
  465.  
  466. template <class ForwardIterator1, class ForwardIterator2>
  467. inline void iter_swap (ForwardIterator1 a, ForwardIterator2 b)
  468. {
  469.     __iter_swap(a, b, RWSTD_VALUE_TYPE(a));
  470. }
  471.  
  472. template <class ForwardIterator1, class ForwardIterator2>
  473. ForwardIterator2 swap_ranges (ForwardIterator1 first1, ForwardIterator1 last1,
  474.                               ForwardIterator2 first2)
  475. {
  476.     while (first1 != last1) iter_swap(first1++, first2++);
  477.     return first2;
  478. }
  479.  
  480. template <class InputIterator, class OutputIterator, class UnaryOperation>
  481. OutputIterator transform (InputIterator first, InputIterator last,
  482.                           OutputIterator result, UnaryOperation op)
  483. {
  484.     while (first != last) *result++ = op(*first++);
  485.     return result;
  486. }
  487.  
  488. template <class InputIterator1, class InputIterator2, class OutputIterator,
  489.       class BinaryOperation>
  490. OutputIterator transform (InputIterator1 first1, InputIterator1 last1,
  491.                           InputIterator2 first2, OutputIterator result,
  492.                           BinaryOperation binary_op)
  493. {
  494.     while (first1 != last1) *result++ = binary_op(*first1++, *first2++);
  495.     return result;
  496. }
  497.  
  498. template <class ForwardIterator, class T>
  499. void replace (ForwardIterator first, ForwardIterator last, const T& old_value,
  500.               const T& new_value)
  501. {
  502.     while (first != last)
  503.     {
  504.         if (*first == old_value) *first = new_value;
  505.         ++first;
  506.     }
  507. }
  508.  
  509. template <class ForwardIterator, class Predicate, class T>
  510. void replace_if (ForwardIterator first, ForwardIterator last, Predicate pred,
  511.                  const T& new_value)
  512. {
  513.     while (first != last)
  514.     {
  515.         if (pred(*first)) *first = new_value;
  516.         ++first;
  517.     }
  518. }
  519.  
  520. template <class InputIterator, class OutputIterator, class T>
  521. OutputIterator replace_copy (InputIterator first, InputIterator last,
  522.                              OutputIterator result, const T& old_value,
  523.                              const T& new_value)
  524. {
  525.     while (first != last)
  526.     {
  527.         *result++ = *first == old_value ? new_value : *first;
  528.         ++first;
  529.     }
  530.     return result;
  531. }
  532.  
  533. template <class Iterator, class OutputIterator, class Predicate, class T>
  534. OutputIterator replace_copy_if (Iterator first, Iterator last,
  535.                                 OutputIterator result, Predicate pred,
  536.                                 const T& new_value)
  537. {
  538.     while (first != last)
  539.     {
  540.         if(pred(*first))
  541.            *result++ = new_value;
  542.         else
  543.            *result++ = *first;
  544.         ++first;
  545.     }
  546.     return result;
  547. }
  548.  
  549. template <class ForwardIterator, class T>
  550. void fill (ForwardIterator first, ForwardIterator last, const T& value)
  551. {
  552.     while (first != last) *first++ = value;
  553. }
  554.  
  555. template <class OutputIterator, class Size, class T>
  556. OutputIterator fill_n (OutputIterator first, Size n, const T& value)
  557. {
  558.     while (n-- > 0) *first++ = value;
  559.     return first;
  560. }
  561.  
  562. template <class ForwardIterator, class Generator>
  563. void generate (ForwardIterator first, ForwardIterator last, Generator gen)
  564. {
  565.     while (first != last) *first++ = gen();
  566. }
  567.  
  568. template <class OutputIterator, class Size, class Generator>
  569. OutputIterator generate_n (OutputIterator first, Size n, Generator gen)
  570. {
  571.     while (n-- > 0) *first++ = gen();
  572.     return first;
  573. }
  574.  
  575. template <class InputIterator, class OutputIterator, class T>
  576. OutputIterator remove_copy (InputIterator first, InputIterator last,
  577.                             OutputIterator result, const T& value)
  578. {
  579.     while (first != last)
  580.     {
  581.         if (*first != value) *result++ = *first;
  582.         ++first;
  583.     }
  584.     return result;
  585. }
  586.  
  587. template <class InputIterator, class OutputIterator, class Predicate>
  588. OutputIterator remove_copy_if (InputIterator first, InputIterator last,
  589.                                OutputIterator result, Predicate pred)
  590. {
  591.     while (first != last)
  592.     {
  593.         if (!pred(*first)) *result++ = *first;
  594.         ++first;
  595.     }
  596.     return result;
  597. }
  598.  
  599. template <class ForwardIterator, class T>
  600. inline ForwardIterator remove (ForwardIterator first, ForwardIterator last,
  601.                                const T& value)
  602. {
  603.     first = find(first, last, value);
  604.     ForwardIterator next = first;
  605.     return first == last ? first : remove_copy(++next, last, first, value);
  606. }
  607.  
  608. template <class ForwardIterator, class Predicate>
  609. inline ForwardIterator remove_if (ForwardIterator first, ForwardIterator last,
  610.                                   Predicate pred)
  611. {
  612.     first = find_if(first, last, pred);
  613.     ForwardIterator next = first;
  614.     return first == last ? first : remove_copy_if(++next, last, first, pred);
  615. }
  616.  
  617. template <class InputIterator, class ForwardIterator>
  618. ForwardIterator __unique_copy (InputIterator first, InputIterator last,
  619.                                ForwardIterator result, forward_iterator_tag)
  620. {
  621.     *result = *first;
  622.     while (++first != last)
  623.         if (*result != *first) *++result = *first;
  624.     return ++result;
  625. }
  626.  
  627. template <class InputIterator, class BidirectionalIterator>
  628. inline BidirectionalIterator __unique_copy (InputIterator first,
  629.                                             InputIterator last,
  630.                                             BidirectionalIterator result,
  631.                                             bidirectional_iterator_tag)
  632. {
  633.     return __unique_copy(first, last, result, forward_iterator_tag());
  634. }
  635.  
  636. template <class InputIterator, class RandomAccessIterator>
  637. inline RandomAccessIterator __unique_copy (InputIterator first,
  638.                                            InputIterator last,
  639.                                            RandomAccessIterator result,
  640.                                            random_access_iterator_tag)
  641. {
  642.     return __unique_copy(first, last, result, forward_iterator_tag());
  643. }
  644.  
  645. template <class InputIterator, class OutputIterator, class T>
  646. OutputIterator __unique_copy (InputIterator first, InputIterator last,
  647.                               OutputIterator result, T*)
  648. {
  649.     T value = *first;
  650.     *result = value;
  651.     while (++first != last)
  652.     {
  653.         if (value != *first)
  654.         {
  655.             value = *first;
  656.             *++result = value;
  657.         }
  658.     }
  659.     return ++result;
  660. }
  661.  
  662. template <class InputIterator, class OutputIterator>
  663. inline OutputIterator __unique_copy (InputIterator first, InputIterator last,
  664.                                      OutputIterator result,
  665.                                      output_iterator_tag)
  666. {
  667.     return __unique_copy(first, last, result, RWSTD_VALUE_TYPE(first));
  668. }
  669.  
  670. template <class InputIterator, class OutputIterator>
  671. inline OutputIterator unique_copy (InputIterator first, InputIterator last,
  672.                                    OutputIterator result)
  673. {
  674.     return first == last ? result :
  675. #ifndef RWSTD_NO_BASE_CLASS_MATCH
  676.         __unique_copy(first, last, result, iterator_category(result));
  677. #else
  678.         __unique_copy(first, last, result, output_iterator_tag());
  679. #endif
  680. }
  681.  
  682. template <class InputIterator, class ForwardIterator, class BinaryPredicate>
  683. ForwardIterator __unique_copy (InputIterator first, InputIterator last,
  684.                                ForwardIterator result,
  685.                                BinaryPredicate binary_pred,
  686.                                forward_iterator_tag)
  687. {
  688.     *result = *first;
  689.     while (++first != last)
  690.         if (!binary_pred(*result, *first)) *++result = *first;
  691.     return ++result;
  692. }
  693.  
  694. template <class InputIterator, class BidirectionalIterator,
  695.           class BinaryPredicate>
  696. inline BidirectionalIterator __unique_copy (InputIterator first,
  697.                                             InputIterator last,
  698.                                             BidirectionalIterator result,
  699.                                             BinaryPredicate binary_pred,
  700.                                             bidirectional_iterator_tag)
  701. {
  702.     return __unique_copy(first, last, result, binary_pred,
  703.                          forward_iterator_tag());
  704. }
  705.  
  706. template <class InputIterator, class RandomAccessIterator,
  707.           class BinaryPredicate>
  708. inline RandomAccessIterator __unique_copy (InputIterator first,
  709.                                            InputIterator last,
  710.                                            RandomAccessIterator result,
  711.                                            BinaryPredicate binary_pred,
  712.                                            random_access_iterator_tag)
  713. {
  714.     return __unique_copy(first, last, result, binary_pred,
  715.                          forward_iterator_tag());
  716. }
  717.  
  718. template <class InputIterator, class OutputIterator, class BinaryPredicate,
  719.           class T>
  720. OutputIterator __unique_copy (InputIterator first, InputIterator last,
  721.                               OutputIterator result,
  722.                               BinaryPredicate binary_pred, T*)
  723. {
  724.     T value = *first;
  725.     *result = value;
  726.     while (++first != last)
  727.     {
  728.         if (!binary_pred(value, *first))
  729.         {
  730.             value = *first;
  731.             *++result = value;
  732.         }
  733.     }
  734.     return ++result;
  735. }
  736.  
  737. template <class InputIterator, class OutputIterator, class BinaryPredicate>
  738. inline OutputIterator __unique_copy (InputIterator first, InputIterator last,
  739.                                      OutputIterator result,
  740.                                      BinaryPredicate binary_pred,
  741.                                      output_iterator_tag)
  742. {
  743.     return __unique_copy(first, last, result, binary_pred,
  744.                          RWSTD_VALUE_TYPE(first));
  745. }
  746.  
  747. template <class InputIterator, class OutputIterator, class BinaryPredicate>
  748. inline OutputIterator unique_copy (InputIterator first, InputIterator last,
  749.                                    OutputIterator result,
  750.                                    BinaryPredicate binary_pred)
  751. {
  752.     return first == last ? result :
  753.         __unique_copy(first, last, result, binary_pred,
  754. #ifndef RWSTD_NO_BASE_CLASS_MATCH
  755.                       iterator_category(result));
  756. #else
  757.                       output_iterator_tag());
  758. #endif
  759. }
  760.  
  761. template <class ForwardIterator>
  762. inline ForwardIterator unique (ForwardIterator first, ForwardIterator last)
  763. {
  764.     first = adjacent_find(first, last);
  765.     return unique_copy(first, last, first);
  766. }
  767.  
  768. template <class ForwardIterator, class BinaryPredicate>
  769. inline ForwardIterator unique (ForwardIterator first, ForwardIterator last,
  770.                                BinaryPredicate binary_pred)
  771. {
  772.     first = adjacent_find(first, last, binary_pred);
  773.     return unique_copy(first, last, first, binary_pred);
  774. }
  775.  
  776. template <class BidirectionalIterator>
  777. void __reverse (BidirectionalIterator first, BidirectionalIterator last,
  778.                 bidirectional_iterator_tag)
  779. {
  780.     while (true)
  781.         if (first == last || first == --last)
  782.             return;
  783.         else
  784.             iter_swap(first++, last);
  785. }
  786.  
  787. template <class RandomAccessIterator>
  788. void __reverse (RandomAccessIterator first, RandomAccessIterator last,
  789.                 random_access_iterator_tag)
  790. {
  791.     while (first < last) iter_swap(first++, --last);
  792. }
  793.  
  794. template <class BidirectionalIterator>
  795. inline void reverse (BidirectionalIterator first, BidirectionalIterator last)
  796. {
  797. #ifndef RWSTD_NO_BASE_CLASS_MATCH
  798.     __reverse(first, last, iterator_category(first));
  799. #else
  800.     __reverse(first, last, bidirectional_iterator_tag());
  801. #endif
  802. }
  803.  
  804. template <class BidirectionalIterator, class OutputIterator>
  805. OutputIterator reverse_copy (BidirectionalIterator first,
  806.                              BidirectionalIterator last,
  807.                              OutputIterator result)
  808. {
  809.     while (first != last) *result++ = *--last;
  810.     return result;
  811. }
  812.  
  813. template <class ForwardIterator, class Distance>
  814. void __rotate (ForwardIterator first, ForwardIterator middle,
  815.                ForwardIterator last, Distance*, forward_iterator_tag)
  816. {
  817.     for (ForwardIterator i = middle; ;)
  818.     {
  819.         iter_swap(first++, i++);
  820.         if (first == middle)
  821.         {
  822.             if (i == last) return;
  823.                 middle = i;
  824.         }
  825.         else if (i == last)
  826.             i = middle;
  827.     }
  828. }
  829.  
  830. template <class BidirectionalIterator, class Distance>
  831. void __rotate (BidirectionalIterator first, BidirectionalIterator middle,
  832.                BidirectionalIterator last, Distance*,
  833.                bidirectional_iterator_tag)
  834. {
  835.     reverse(first, middle);
  836.     reverse(middle, last);
  837.     reverse(first, last);
  838. }
  839.  
  840. template <class EuclideanRingElement>
  841. EuclideanRingElement __gcd (EuclideanRingElement m, EuclideanRingElement n)
  842. {
  843.     while (n != 0)
  844.     {
  845.         EuclideanRingElement t = m % n;
  846.         m = n;
  847.         n = t;
  848.     }
  849.     return m;
  850. }
  851.  
  852. template <class RandomAccessIterator, class Distance, class T>
  853. void __rotate_cycle (RandomAccessIterator first, RandomAccessIterator last,
  854.                      RandomAccessIterator initial, Distance shift, T*)
  855. {
  856.     T value = *initial;
  857.     RandomAccessIterator ptr1 = initial;
  858.     RandomAccessIterator ptr2 = ptr1 + shift;
  859.     while (ptr2 != initial)
  860.     {
  861.         *ptr1 = *ptr2;
  862.         ptr1 = ptr2;
  863.         if (last - ptr2 > shift)
  864.             ptr2 += shift;
  865.         else
  866.             ptr2 = first + (shift - (last - ptr2));
  867.     }
  868.     *ptr1 = value;
  869. }
  870.  
  871. template <class RandomAccessIterator, class Distance>
  872. void __rotate (RandomAccessIterator first, RandomAccessIterator middle,
  873.                RandomAccessIterator last, Distance*,
  874.                random_access_iterator_tag)
  875. {
  876.     Distance n = __gcd(last - first, middle - first);
  877.     while (n--)
  878.         __rotate_cycle(first, last, first + n, middle - first,
  879.                        RWSTD_VALUE_TYPE(first));
  880. }
  881.  
  882. template <class ForwardIterator>
  883. inline void rotate (ForwardIterator first, ForwardIterator middle,
  884.                     ForwardIterator last)
  885. {
  886.     if (!(first == middle || middle == last))
  887.     {
  888.         __rotate(first, middle, last, distance_type(first),
  889. #ifndef RWSTD_NO_BASE_CLASS_MATCH
  890.                  iterator_category(first));
  891. #else
  892.                  forward_iterator_tag());
  893. #endif
  894.     }
  895. }
  896.  
  897. template <class ForwardIterator, class OutputIterator>
  898. inline OutputIterator rotate_copy (ForwardIterator first,
  899.                                    ForwardIterator middle,
  900.                                    ForwardIterator last,
  901.                                    OutputIterator result)
  902. {
  903.     return copy(first, middle, copy(middle, last, result));
  904. }
  905.  
  906. extern unsigned long __long_random (unsigned long);
  907.  
  908. template <class RandomAccessIterator, class Distance>
  909. void __random_shuffle (RandomAccessIterator first, RandomAccessIterator last,
  910.                        Distance*)
  911. {
  912.     if (!(first == last))
  913.         for (RandomAccessIterator i = first + 1; i != last; ++i)
  914.             iter_swap(i, first + Distance(__long_random((i - first) + 1)));
  915. }
  916.  
  917. template <class RandomAccessIterator>
  918. inline void random_shuffle (RandomAccessIterator first,
  919.                             RandomAccessIterator last)
  920. {
  921.     __random_shuffle(first, last, distance_type(first));
  922. }
  923.  
  924. template <class RandomAccessIterator, class RandomNumberGenerator>
  925. void random_shuffle (RandomAccessIterator first, RandomAccessIterator last,
  926.                      RandomNumberGenerator& rand)
  927. {
  928.     if (!(first == last))
  929.         for (RandomAccessIterator i = first + 1; i != last; ++i)
  930.             iter_swap(i, first + rand((i - first) + 1));
  931. }
  932.  
  933. template <class BidirectionalIterator, class Predicate>
  934. BidirectionalIterator partition (BidirectionalIterator first,
  935.                                  BidirectionalIterator last, Predicate pred)
  936. {
  937.     while (true)
  938.     {
  939.         while (true)
  940.         {
  941.             if (first == last)
  942.                 return first;
  943.             else if (pred(*first))
  944.                 ++first;
  945.             else
  946.                 break;
  947.         }
  948.         --last;
  949.         while (true)
  950.         {
  951.             if (first == last)
  952.                 return first;
  953.             else if (!pred(*last))
  954.                 --last;
  955.             else
  956.                 break;
  957.         }
  958.         iter_swap(first, last);
  959.         ++first;
  960.     }
  961. }
  962.  
  963. template <class BidirectionalIterator, class Predicate, class Distance>
  964. BidirectionalIterator __inplace_stable_partition (BidirectionalIterator first,
  965.                                                   BidirectionalIterator last,
  966.                                                   Predicate pred,
  967.                                                   Distance len)
  968. {
  969.     if (len == 1) return pred(*first) ? last : first;
  970.     BidirectionalIterator middle = first;
  971.     advance(middle, len / 2);
  972.     BidirectionalIterator
  973.     first_cut = __inplace_stable_partition(first, middle, pred, len / 2);
  974.     BidirectionalIterator
  975.     second_cut = __inplace_stable_partition(middle, last, pred, len - len / 2);
  976.     rotate(first_cut, middle, second_cut);
  977.     __initialize(len, Distance(0));
  978.     distance(middle, second_cut, len);
  979.     advance(first_cut, len);
  980.     return first_cut;
  981. }
  982.  
  983. template <class BidirectionalIterator, class Pointer, class Predicate,
  984.           class Distance, class T>
  985. BidirectionalIterator __stable_partition_adaptive (BidirectionalIterator first,
  986.                                                    BidirectionalIterator last,
  987.                                                    Predicate pred, Distance len,
  988.                                                    Pointer buffer,
  989.                                                    Distance buffer_size,
  990.                                                    Distance& fill_pointer, T*)
  991. {
  992.     if (len <= buffer_size)
  993.     {
  994.         len = 0;
  995.         BidirectionalIterator result1 = first;
  996.         Pointer result2 = buffer;
  997.         while (first != last && len < fill_pointer)
  998.         {
  999.             if (pred(*first))
  1000.                 *result1++ = *first++;
  1001.             else
  1002.             {
  1003.                 *result2++ = *first++;
  1004.                 ++len;
  1005.             }
  1006.         }
  1007.         if (first != last)
  1008.         {
  1009.             raw_storage_iterator<Pointer, T> result3 = result2;
  1010.             while (first != last)
  1011.             {
  1012.                 if (pred(*first))
  1013.                     *result1++ = *first++;
  1014.                 else
  1015.                 {
  1016.                     *result3++ = *first++;
  1017.                     ++len;
  1018.                 }
  1019.             }
  1020.             fill_pointer = len;
  1021.         }
  1022.         copy(buffer, buffer + len, result1);
  1023.         return result1;
  1024.     }
  1025.     BidirectionalIterator middle = first;
  1026.     advance(middle, len / 2);
  1027.     BidirectionalIterator first_cut = __stable_partition_adaptive
  1028.      (first, middle, pred, len / 2, buffer, buffer_size, fill_pointer, (T*)0);
  1029.     BidirectionalIterator second_cut = __stable_partition_adaptive
  1030.      (middle, last, pred, len-len/2, buffer, buffer_size, fill_pointer, (T*)0);
  1031.     rotate(first_cut, middle, second_cut);
  1032.     __initialize(len, Distance(0));
  1033.     distance(middle, second_cut, len);
  1034.     advance(first_cut, len);
  1035.     return first_cut;
  1036. }
  1037.  
  1038. template <class BidirectionalIterator, class Predicate, class Pointer,
  1039.           class Distance>
  1040. BidirectionalIterator __stable_partition (BidirectionalIterator first,
  1041.                                           BidirectionalIterator last,
  1042.                                           Predicate pred, Distance len,
  1043.                                           pair<Pointer, Distance> p)
  1044. {
  1045.     if (p.first == 0)
  1046.         return __inplace_stable_partition(first, last, pred, len);
  1047.     Distance fill_pointer = 0;
  1048.     BidirectionalIterator result =
  1049.         __stable_partition_adaptive(first, last, pred, len, p.first,
  1050.                                     p.second, fill_pointer,
  1051.                                     RWSTD_VALUE_TYPE(first));
  1052.     destroy(p.first, p.first + fill_pointer);
  1053.     return_temporary_buffer(p.first);
  1054.     return result;
  1055. }
  1056.  
  1057. template <class BidirectionalIterator, class Predicate, class Distance>
  1058. inline BidirectionalIterator __stable_partition_aux (BidirectionalIterator first,
  1059.                                                      BidirectionalIterator last,
  1060.                                                      Predicate pred,
  1061.                                                      Distance*)
  1062. {
  1063.     Distance len;
  1064.     __initialize(len, Distance(0));
  1065.     distance(first, last, len);
  1066.  
  1067.     return len == 0 ? last :
  1068.         __stable_partition(first, last, pred, len,
  1069.                            get_temporary_buffer(len,RWSTD_VALUE_TYPE(first)));
  1070. }
  1071.  
  1072. template <class BidirectionalIterator, class Predicate>
  1073. inline BidirectionalIterator stable_partition (BidirectionalIterator first,
  1074.                                                BidirectionalIterator last,
  1075.                                                Predicate pred)
  1076. {
  1077.     return __stable_partition_aux(first, last, pred, distance_type(first));
  1078. }
  1079.  
  1080. //
  1081. // Sorting and related operations.
  1082. //
  1083.  
  1084. template <class T>
  1085. inline const T& __median (const T& a, const T& b, const T& c)
  1086. {
  1087.     if (a < b)
  1088.         if (b < c)
  1089.             return b;
  1090.         else if (a < c)
  1091.             return c;
  1092.         else
  1093.             return a;
  1094.     else if (a < c)
  1095.         return a;
  1096.     else if (b < c)
  1097.         return c;
  1098.     else
  1099.         return b;
  1100. }
  1101.  
  1102. template <class T, class Compare>
  1103. inline const T& __median (const T& a, const T& b, const T& c, Compare comp)
  1104. {
  1105.     if (comp(a, b))
  1106.         if (comp(b, c))
  1107.             return b;
  1108.         else if (comp(a, c))
  1109.             return c;
  1110.         else
  1111.             return a;
  1112.     else if (comp(a, c))
  1113.         return a;
  1114.     else if (comp(b, c))
  1115.         return c;
  1116.     else
  1117.         return b;
  1118. }
  1119.  
  1120. template <class RandomAccessIterator, class T>
  1121. RandomAccessIterator __unguarded_partition (RandomAccessIterator first,
  1122.                                             RandomAccessIterator last,
  1123.                                             T pivot)
  1124. {
  1125.     while (true)
  1126.     {
  1127.         while (*first < pivot) ++first;
  1128.         --last;
  1129.         while (pivot < *last) --last;
  1130.         if (!(first < last)) return first;
  1131.         iter_swap(first, last);
  1132.         ++first;
  1133.     }
  1134. }
  1135.  
  1136. template <class RandomAccessIterator, class T, class Compare>
  1137. RandomAccessIterator __unguarded_partition (RandomAccessIterator first,
  1138.                                             RandomAccessIterator last,
  1139.                                             T pivot, Compare comp)
  1140. {
  1141.     while (true)
  1142.     {
  1143.         while (comp(*first, pivot)) ++first;
  1144.         --last;
  1145.         while (comp(pivot, *last)) --last;
  1146.         if (!(first < last)) return first;
  1147.         iter_swap(first, last);
  1148.         ++first;
  1149.     }
  1150. }
  1151.  
  1152. const int __stl_threshold = 16;
  1153.  
  1154. template <class RandomAccessIterator, class T>
  1155. void __quick_sort_loop_aux (RandomAccessIterator first,
  1156.                             RandomAccessIterator last, T*)
  1157. {
  1158.     while (last - first > __stl_threshold)
  1159.     {
  1160.         RandomAccessIterator cut = __unguarded_partition
  1161.             (first, last, T(__median(*first, *(first + (last - first)/2),
  1162.                          *(last - 1))));
  1163.         if (cut - first >= last - cut)
  1164.         {
  1165.             __quick_sort_loop(cut, last);
  1166.             last = cut;
  1167.         }
  1168.         else
  1169.         {
  1170.             __quick_sort_loop(first, cut);
  1171.             first = cut;
  1172.         }
  1173.     }
  1174. }
  1175.  
  1176. template <class RandomAccessIterator>
  1177. inline void __quick_sort_loop (RandomAccessIterator first,
  1178.                                RandomAccessIterator last)
  1179. {
  1180.     __quick_sort_loop_aux(first, last, RWSTD_VALUE_TYPE(first));
  1181. }
  1182.  
  1183. template <class RandomAccessIterator, class T, class Compare>
  1184. void __quick_sort_loop_aux (RandomAccessIterator first,
  1185.                             RandomAccessIterator last, T*, Compare comp)
  1186. {
  1187.     while (last - first > __stl_threshold)
  1188.     {
  1189.         RandomAccessIterator cut = __unguarded_partition
  1190.             (first, last, T(__median(*first, *(first + (last - first)/2),
  1191.                        *(last - 1), comp)), comp);
  1192.         if (cut - first >= last - cut)
  1193.         {
  1194.             __quick_sort_loop(cut, last, comp);
  1195.             last = cut;
  1196.         }
  1197.         else
  1198.         {
  1199.             __quick_sort_loop(first, cut, comp);
  1200.             first = cut;
  1201.         }
  1202.     }
  1203. }
  1204.  
  1205. template <class RandomAccessIterator, class Compare>
  1206. inline void __quick_sort_loop (RandomAccessIterator first,
  1207.                                RandomAccessIterator last, Compare comp)
  1208. {
  1209.     __quick_sort_loop_aux(first, last, RWSTD_VALUE_TYPE(first), comp);
  1210. }
  1211.  
  1212. template <class RandomAccessIterator, class T>
  1213. void __unguarded_linear_insert (RandomAccessIterator last, T value)
  1214. {
  1215.     RandomAccessIterator next = last;
  1216.     --next;
  1217.     while (value < *next)
  1218.     {
  1219.         *last = *next;
  1220.         last = next--;
  1221.     }
  1222.     *last = value;
  1223. }
  1224.  
  1225. template <class RandomAccessIterator, class T, class Compare>
  1226. void __unguarded_linear_insert (RandomAccessIterator last,T value,Compare comp)
  1227. {
  1228.     RandomAccessIterator next = last;
  1229.     --next;
  1230.     while (comp(value , *next))
  1231.     {
  1232.         *last = *next;
  1233.         last = next--;
  1234.     }
  1235.     *last = value;
  1236. }
  1237.  
  1238. template <class RandomAccessIterator, class T>
  1239. inline void __linear_insert (RandomAccessIterator first,
  1240.                              RandomAccessIterator last, T*)
  1241. {
  1242.     T value = *last;
  1243.     if (value < *first)
  1244.     {
  1245.         copy_backward(first, last, last + 1);
  1246.         *first = value;
  1247.     }
  1248.     else
  1249.         __unguarded_linear_insert(last, value);
  1250. }
  1251.  
  1252. template <class RandomAccessIterator, class T, class Compare>
  1253. inline void __linear_insert (RandomAccessIterator first,
  1254.                              RandomAccessIterator last, T*, Compare comp)
  1255. {
  1256.     T value = *last;
  1257.     if (comp(value, *first))
  1258.     {
  1259.         copy_backward(first, last, last + 1);
  1260.         *first = value;
  1261.     }
  1262.     else
  1263.         __unguarded_linear_insert(last, value, comp);
  1264. }
  1265.  
  1266. template <class RandomAccessIterator>
  1267. void __insertion_sort (RandomAccessIterator first, RandomAccessIterator last)
  1268. {
  1269.     if (!(first == last))
  1270.         for (RandomAccessIterator i = first + 1; i != last; ++i)
  1271.             __linear_insert(first, i, RWSTD_VALUE_TYPE(first));
  1272. }
  1273.  
  1274. template <class RandomAccessIterator, class Compare>
  1275. void __insertion_sort (RandomAccessIterator first,
  1276.                        RandomAccessIterator last, Compare comp)
  1277. {
  1278.     if (!(first == last))
  1279.         for (RandomAccessIterator i = first + 1; i != last; ++i)
  1280.             __linear_insert(first, i, RWSTD_VALUE_TYPE(first), comp);
  1281. }
  1282.  
  1283. template <class RandomAccessIterator, class T>
  1284. void __unguarded_insertion_sort_aux (RandomAccessIterator first,
  1285.                                      RandomAccessIterator last, T*)
  1286. {
  1287.     for (RandomAccessIterator i = first; i != last; ++i)
  1288.         __unguarded_linear_insert(i, T(*i));
  1289. }
  1290.  
  1291. template <class RandomAccessIterator>
  1292. inline void __unguarded_insertion_sort(RandomAccessIterator first,
  1293.                                        RandomAccessIterator last)
  1294. {
  1295.     __unguarded_insertion_sort_aux(first, last, RWSTD_VALUE_TYPE(first));
  1296. }
  1297.  
  1298. template <class RandomAccessIterator, class T, class Compare>
  1299. void __unguarded_insertion_sort_aux (RandomAccessIterator first,
  1300.                                      RandomAccessIterator last,
  1301.                                      T*, Compare comp)
  1302. {
  1303.     for (RandomAccessIterator i = first; i != last; ++i)
  1304.         __unguarded_linear_insert(i, T(*i), comp);
  1305. }
  1306.  
  1307. template <class RandomAccessIterator, class Compare>
  1308. inline void __unguarded_insertion_sort (RandomAccessIterator first,
  1309.                                         RandomAccessIterator last,
  1310.                                         Compare comp)
  1311. {
  1312.     __unguarded_insertion_sort_aux(first, last, RWSTD_VALUE_TYPE(first), comp);
  1313. }
  1314.  
  1315. template <class RandomAccessIterator>
  1316. inline void __final_insertion_sort (RandomAccessIterator first,
  1317.                                     RandomAccessIterator last)
  1318. {
  1319.     if (last - first > __stl_threshold)
  1320.     {
  1321.         __insertion_sort(first, first + __stl_threshold);
  1322.         __unguarded_insertion_sort(first + __stl_threshold, last);
  1323.     }
  1324.     else
  1325.         __insertion_sort(first, last);
  1326. }
  1327.  
  1328. template <class RandomAccessIterator, class Compare>
  1329. inline void __final_insertion_sort (RandomAccessIterator first,
  1330.                                     RandomAccessIterator last, Compare comp)
  1331. {
  1332.     if (last - first > __stl_threshold)
  1333.     {
  1334.         __insertion_sort(first, first + __stl_threshold, comp);
  1335.         __unguarded_insertion_sort(first + __stl_threshold, last, comp);
  1336.     }
  1337.     else
  1338.         __insertion_sort(first, last, comp);
  1339. }
  1340.  
  1341. template <class RandomAccessIterator>
  1342. void sort (RandomAccessIterator first, RandomAccessIterator last)
  1343. {
  1344.     if (!(first == last))
  1345.     {
  1346.         __quick_sort_loop(first, last);
  1347.         __final_insertion_sort(first, last);
  1348.     }
  1349. }
  1350.  
  1351. template <class RandomAccessIterator, class Compare>
  1352. void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp)
  1353. {
  1354.     if (!(first == last))
  1355.     {
  1356.         __quick_sort_loop(first, last, comp);
  1357.         __final_insertion_sort(first, last, comp);
  1358.     }
  1359. }
  1360.  
  1361. template <class RandomAccessIterator>
  1362. void __inplace_stable_sort (RandomAccessIterator first,
  1363.                             RandomAccessIterator last)
  1364. {
  1365.     if (last - first < 15)
  1366.         __insertion_sort(first, last);
  1367.     else
  1368.     {
  1369.         RandomAccessIterator middle = first + (last - first) / 2;
  1370.         __inplace_stable_sort(first, middle);
  1371.         __inplace_stable_sort(middle, last);
  1372.         __merge_without_buffer(first, middle, last, middle - first,
  1373.                                last - middle);
  1374.     }
  1375. }
  1376.  
  1377. template <class RandomAccessIterator, class Compare>
  1378. void __inplace_stable_sort (RandomAccessIterator first,
  1379.                             RandomAccessIterator last, Compare comp)
  1380. {
  1381.     if (last - first < 15)
  1382.         __insertion_sort(first, last, comp);
  1383.     else
  1384.     {
  1385.         RandomAccessIterator middle = first + (last - first) / 2;
  1386.         __inplace_stable_sort(first, middle, comp);
  1387.         __inplace_stable_sort(middle, last, comp);
  1388.         __merge_without_buffer(first, middle, last, middle - first,
  1389.                                last - middle, comp);
  1390.     }
  1391. }
  1392.  
  1393. template <class RandomAccessIterator1, class RandomAccessIterator2,
  1394.           class Distance>
  1395. void __merge_sort_loop (RandomAccessIterator1 first,
  1396.                         RandomAccessIterator1 last,
  1397.                         RandomAccessIterator2 result, Distance step_size)
  1398. {
  1399.     Distance two_step = 2 * step_size;
  1400.  
  1401.     while (last - first >= two_step)
  1402.     {
  1403.         result = merge(first, first + step_size,
  1404.                        first + step_size, first + two_step, result);
  1405.         first += two_step;
  1406.     }
  1407.     step_size = min(Distance(last - first), step_size);
  1408.  
  1409.     merge(first, first + step_size, first + step_size, last, result);
  1410. }
  1411.  
  1412. template <class RandomAccessIterator1, class RandomAccessIterator2,
  1413.           class Distance, class Compare>
  1414. void __merge_sort_loop (RandomAccessIterator1 first,
  1415.                         RandomAccessIterator1 last,
  1416.                         RandomAccessIterator2 result, Distance step_size,
  1417.                         Compare comp)
  1418. {
  1419.     Distance two_step = 2 * step_size;
  1420.  
  1421.     while (last - first >= two_step)
  1422.     {
  1423.         result = merge(first, first + step_size,
  1424.                        first + step_size, first + two_step, result, comp);
  1425.         first += two_step;
  1426.     }
  1427.     step_size = min(Distance(last - first), step_size);
  1428.  
  1429.     merge(first, first + step_size, first + step_size, last, result, comp);
  1430. }
  1431.  
  1432. const int __stl_chunk_size = 7;
  1433.  
  1434. template <class RandomAccessIterator, class Distance>
  1435. void __chunk_insertion_sort (RandomAccessIterator first,
  1436.                              RandomAccessIterator last, Distance chunk_size)
  1437. {
  1438.     while (last - first >= chunk_size)
  1439.     {
  1440.         __insertion_sort(first, first + chunk_size);
  1441.         first += chunk_size;
  1442.     }
  1443.     __insertion_sort(first, last);
  1444. }
  1445.  
  1446. template <class RandomAccessIterator, class Distance, class Compare>
  1447. void __chunk_insertion_sort (RandomAccessIterator first,
  1448.                              RandomAccessIterator last,
  1449.                              Distance chunk_size, Compare comp)
  1450. {
  1451.     while (last - first >= chunk_size)
  1452.     {
  1453.         __insertion_sort(first, first + chunk_size, comp);
  1454.         first += chunk_size;
  1455.     }
  1456.     __insertion_sort(first, last, comp);
  1457. }
  1458.  
  1459. template <class RandomAccessIterator, class Pointer, class Distance, class T>
  1460. void __merge_sort_with_buffer (RandomAccessIterator first,
  1461.                                RandomAccessIterator last,
  1462.                                Pointer buffer, Distance*, T*)
  1463. {
  1464.     Distance len = last - first;
  1465.     Pointer buffer_last = buffer + len;
  1466.  
  1467.     Distance step_size = __stl_chunk_size;
  1468.     __chunk_insertion_sort(first, last, step_size);
  1469.  
  1470.     while (step_size < len)
  1471.     {
  1472.         __merge_sort_loop(first, last, buffer, step_size);
  1473.         step_size *= 2;
  1474.         __merge_sort_loop(buffer, buffer_last, first, step_size);
  1475.         step_size *= 2;
  1476.     }
  1477. }
  1478.  
  1479. template <class RandomAccessIterator, class Pointer, class Distance, class T,
  1480.           class Compare>
  1481. void __merge_sort_with_buffer (RandomAccessIterator first,
  1482.                                RandomAccessIterator last, Pointer buffer,
  1483.                                Distance*, T*, Compare comp)
  1484. {
  1485.     Distance len = last - first;
  1486.     Pointer buffer_last = buffer + len;
  1487.  
  1488.     Distance step_size = __stl_chunk_size;
  1489.     __chunk_insertion_sort(first, last, step_size, comp);
  1490.  
  1491.     while (step_size < len)
  1492.     {
  1493.         __merge_sort_loop(first, last, buffer, step_size, comp);
  1494.         step_size *= 2;
  1495.         __merge_sort_loop(buffer, buffer_last, first, step_size, comp);
  1496.         step_size *= 2;
  1497.     }
  1498. }
  1499.  
  1500. template <class RandomAccessIterator, class Pointer, class Distance, class T>
  1501. void __stable_sort_adaptive (RandomAccessIterator first,
  1502.                              RandomAccessIterator last, Pointer buffer,
  1503.                              Distance buffer_size, T*)
  1504. {
  1505.     Distance len = (last - first + 1) / 2;
  1506.     RandomAccessIterator middle = first + len;
  1507.     if (len > buffer_size)
  1508.     {
  1509.         __stable_sort_adaptive(first, middle, buffer, buffer_size, (T*)0);
  1510.         __stable_sort_adaptive(middle, last, buffer, buffer_size, (T*)0);
  1511.     }
  1512.     else
  1513.     {
  1514.         __merge_sort_with_buffer(first, middle, buffer, (Distance*)0, (T*)0);
  1515.         __merge_sort_with_buffer(middle, last, buffer, (Distance*)0, (T*)0);
  1516.     }
  1517.     __merge_adaptive(first, middle, last, Distance(middle - first),
  1518.              Distance(last - middle), buffer, buffer_size, (T*)0);
  1519. }
  1520.  
  1521. template <class RandomAccessIterator, class Pointer, class Distance, class T,
  1522.           class Compare>
  1523. void __stable_sort_adaptive (RandomAccessIterator first,
  1524.                              RandomAccessIterator last, Pointer buffer,
  1525.                              Distance buffer_size, T*, Compare comp)
  1526. {
  1527.     Distance len = (last - first + 1) / 2;
  1528.     RandomAccessIterator middle = first + len;
  1529.     if (len > buffer_size)
  1530.     {
  1531.         __stable_sort_adaptive(first, middle, buffer, buffer_size, (T*)0,comp);
  1532.         __stable_sort_adaptive(middle, last, buffer, buffer_size, (T*)0, comp);
  1533.     }
  1534.     else
  1535.     {
  1536.         __merge_sort_with_buffer(first, middle, buffer, (Distance*)0, (T*)0,
  1537.                                  comp);
  1538.         __merge_sort_with_buffer(middle, last, buffer, (Distance*)0, (T*)0,
  1539.                                  comp);
  1540.     }
  1541.     __merge_adaptive(first, middle, last, Distance(middle - first),
  1542.                      Distance(last-middle), buffer, buffer_size, (T*)0, comp);
  1543. }
  1544.  
  1545. template <class RandomAccessIterator, class Pointer, class Distance, class T>
  1546. inline void __stable_sort (RandomAccessIterator first,
  1547.                            RandomAccessIterator last,
  1548.                            pair<Pointer, Distance>& p, T*)
  1549. {
  1550.     if (p.first == 0)
  1551.         __inplace_stable_sort(first, last);
  1552.     else
  1553.     {
  1554.         Distance len = min(p.second, last - first);
  1555.         copy(first, first + len, raw_storage_iterator<Pointer, T>(p.first));
  1556.         __stable_sort_adaptive(first, last, p.first, p.second, (T*)0);
  1557.         destroy(p.first, p.first + len);
  1558.         return_temporary_buffer(p.first);
  1559.     }
  1560. }
  1561.  
  1562. template <class RandomAccessIterator, class Pointer, class Distance, class T,
  1563.       class Compare>
  1564. inline void __stable_sort (RandomAccessIterator first,
  1565.                            RandomAccessIterator last,
  1566.                            pair<Pointer, Distance>& p, T*, Compare comp)
  1567. {
  1568.     if (p.first == 0)
  1569.         __inplace_stable_sort(first, last, comp);
  1570.     else
  1571.     {
  1572.         Distance len = min(p.second, last - first);
  1573.         copy(first, first + len, raw_storage_iterator<Pointer, T>(p.first));
  1574.         __stable_sort_adaptive(first, last, p.first, p.second, (T*)0, comp);
  1575.         destroy(p.first, p.first + len);
  1576.         return_temporary_buffer(p.first);
  1577.     }
  1578. }
  1579.  
  1580. template <class RandomAccessIterator, class T, class Distance>
  1581. inline void __stable_sort_aux (RandomAccessIterator first,
  1582.                                RandomAccessIterator last, T*, Distance*)
  1583. {
  1584.     pair<T*, Distance> tmp = get_temporary_buffer(Distance(last-first),(T*)0);
  1585.     __stable_sort(first, last, tmp, (T*)0);
  1586. }
  1587.  
  1588. template <class RandomAccessIterator, class T, class Distance, class Compare>
  1589. inline void __stable_sort_aux (RandomAccessIterator first,
  1590.                                RandomAccessIterator last, T*, Distance*,
  1591.                                Compare comp)
  1592. {
  1593.    pair<T*, Distance> tmp = get_temporary_buffer(Distance(last-first),(T*)0);
  1594.    __stable_sort(first, last, tmp, (T*)0, comp);
  1595. }
  1596.  
  1597. template <class RandomAccessIterator>
  1598. inline void stable_sort (RandomAccessIterator first,
  1599.                          RandomAccessIterator last)
  1600. {
  1601.    if (!(first == last))
  1602.    {
  1603.       __stable_sort_aux(first, last, RWSTD_VALUE_TYPE(first),
  1604.                       distance_type(first));
  1605.    }
  1606. }
  1607.  
  1608. template <class RandomAccessIterator, class Compare>
  1609. inline void stable_sort (RandomAccessIterator first,
  1610.                          RandomAccessIterator last, Compare comp)
  1611. {
  1612.     if (!(first == last))
  1613.     {
  1614.        __stable_sort_aux(first, last, RWSTD_VALUE_TYPE(first),
  1615.                       distance_type(first), comp);
  1616.     }
  1617. }
  1618.  
  1619. template <class RandomAccessIterator, class T>
  1620. void __partial_sort (RandomAccessIterator first, RandomAccessIterator middle,
  1621.                      RandomAccessIterator last, T*)
  1622. {
  1623.     make_heap(first, middle);
  1624.     for (RandomAccessIterator i = middle; i < last; ++i)
  1625.         if (*i < *first)
  1626.             __pop_heap(first, middle, i, T(*i), distance_type(first));
  1627.     sort_heap(first, middle);
  1628. }
  1629.  
  1630. template <class RandomAccessIterator>
  1631. inline void partial_sort (RandomAccessIterator first,
  1632.                           RandomAccessIterator middle,
  1633.                           RandomAccessIterator last)
  1634. {
  1635.     if (!(first == middle))
  1636.        __partial_sort(first, middle, last, RWSTD_VALUE_TYPE(first));
  1637. }
  1638.  
  1639. template <class RandomAccessIterator, class T, class Compare>
  1640. void __partial_sort (RandomAccessIterator first, RandomAccessIterator middle,
  1641.                      RandomAccessIterator last, T*, Compare comp)
  1642. {
  1643.     make_heap(first, middle, comp);
  1644.     for (RandomAccessIterator i = middle; i < last; ++i)
  1645.         if (comp(*i,*first))
  1646.             __pop_heap(first, middle, i, T(*i), comp, distance_type(first));
  1647.     sort_heap(first, middle, comp);
  1648. }
  1649.  
  1650. template <class RandomAccessIterator, class Compare>
  1651. inline void partial_sort (RandomAccessIterator first,
  1652.                           RandomAccessIterator middle,
  1653.                           RandomAccessIterator last, Compare comp)
  1654. {
  1655.     if (!(first == middle))
  1656.        __partial_sort(first, middle, last, RWSTD_VALUE_TYPE(first), comp);
  1657. }
  1658.  
  1659. template <class InputIterator, class RandomAccessIterator, class Distance,
  1660.           class T>
  1661. RandomAccessIterator __partial_sort_copy (InputIterator first,
  1662.                                           InputIterator last,
  1663.                                           RandomAccessIterator result_first,
  1664.                                           RandomAccessIterator result_last,
  1665.                                           Distance*, T*)
  1666. {
  1667.     if (result_first == result_last) return result_last;
  1668.     RandomAccessIterator result_real_last = result_first;
  1669.     while(first != last && result_real_last != result_last)
  1670.         *result_real_last++ = *first++;
  1671.     make_heap(result_first, result_real_last);
  1672.     while (first != last)
  1673.     {
  1674.         if (*first < *result_first)
  1675.             __adjust_heap(result_first, Distance(0),
  1676.                           Distance(result_real_last - result_first),
  1677.                           T(*first));
  1678.         ++first;
  1679.     }
  1680.     sort_heap(result_first, result_real_last);
  1681.     return result_real_last;
  1682. }
  1683.  
  1684. template <class InputIterator, class RandomAccessIterator>
  1685. inline RandomAccessIterator
  1686. partial_sort_copy (InputIterator first, InputIterator last,
  1687.                    RandomAccessIterator result_first,
  1688.                    RandomAccessIterator result_last)
  1689. {
  1690.     return first == last ? result_first :
  1691.         __partial_sort_copy(first, last, result_first, result_last,
  1692.                             distance_type(result_first),
  1693.                             RWSTD_VALUE_TYPE(first));
  1694. }
  1695.  
  1696. template <class InputIterator, class RandomAccessIterator, class Compare,
  1697.           class Distance, class T>
  1698. RandomAccessIterator __partial_sort_copy (InputIterator first,
  1699.                                           InputIterator last,
  1700.                                           RandomAccessIterator result_first,
  1701.                                           RandomAccessIterator result_last,
  1702.                                           Compare comp, Distance*, T*)
  1703. {
  1704.     if (result_first == result_last) return result_last;
  1705.     RandomAccessIterator result_real_last = result_first;
  1706.     while(first != last && result_real_last != result_last)
  1707.         *result_real_last++ = *first++;
  1708.     make_heap(result_first, result_real_last, comp);
  1709.     while (first != last)
  1710.     {
  1711.         if (comp(*first,*result_first))
  1712.             __adjust_heap(result_first, Distance(0),
  1713.                           Distance(result_real_last - result_first), T(*first),
  1714.                           comp);
  1715.         ++first;
  1716.     }
  1717.     sort_heap(result_first, result_real_last, comp);
  1718.     return result_real_last;
  1719. }
  1720.  
  1721. template <class InputIterator, class RandomAccessIterator, class Compare>
  1722. inline RandomAccessIterator
  1723. partial_sort_copy (InputIterator first, InputIterator last,
  1724.                    RandomAccessIterator result_first,
  1725.                    RandomAccessIterator result_last, Compare comp)
  1726. {
  1727.     return first == last ? result_first :
  1728.         __partial_sort_copy(first, last, result_first, result_last, comp,
  1729.                             distance_type(result_first),
  1730.                             RWSTD_VALUE_TYPE(first));
  1731. }
  1732.  
  1733. template <class RandomAccessIterator, class T>
  1734. void __nth_element (RandomAccessIterator first, RandomAccessIterator nth,
  1735.                     RandomAccessIterator last, T*)
  1736. {
  1737.     while (last - first > 3)
  1738.     {
  1739.         RandomAccessIterator cut = __unguarded_partition
  1740.             (first, last, T(__median(*first, *(first + (last - first)/2),
  1741.                          *(last - 1))));
  1742.         if (cut <= nth)
  1743.             first = cut;
  1744.         else
  1745.             last = cut;
  1746.     }
  1747.     __insertion_sort(first, last);
  1748. }
  1749.  
  1750. template <class RandomAccessIterator>
  1751. inline void nth_element (RandomAccessIterator first, RandomAccessIterator nth,
  1752.                          RandomAccessIterator last)
  1753. {
  1754.     if (!(first == last))
  1755.         __nth_element(first, nth, last, RWSTD_VALUE_TYPE(first));
  1756. }
  1757.  
  1758. template <class RandomAccessIterator, class T, class Compare>
  1759. void __nth_element (RandomAccessIterator first, RandomAccessIterator nth,
  1760.                     RandomAccessIterator last, T*, Compare comp)
  1761. {
  1762.     while (last - first > 3)
  1763.     {
  1764.         RandomAccessIterator cut = __unguarded_partition
  1765.             (first, last, T(__median(*first, *(first + (last - first)/2),
  1766.                      *(last - 1), comp)), comp);
  1767.         if (cut <= nth)
  1768.             first = cut;
  1769.         else
  1770.             last = cut;
  1771.         }
  1772.     __insertion_sort(first, last, comp);
  1773. }
  1774.  
  1775. template <class RandomAccessIterator, class Compare>
  1776. inline void nth_element (RandomAccessIterator first, RandomAccessIterator nth,
  1777.                          RandomAccessIterator last, Compare comp)
  1778. {
  1779.     if (!(first == last))
  1780.         __nth_element(first, nth, last, RWSTD_VALUE_TYPE(first), comp);
  1781. }
  1782.  
  1783. //
  1784. // Binary search.
  1785. //
  1786.  
  1787. template <class ForwardIterator, class T, class Distance>
  1788. ForwardIterator __lower_bound (ForwardIterator first, ForwardIterator last,
  1789.                                const T& value, Distance*,
  1790.                                forward_iterator_tag)
  1791. {
  1792.     Distance len;
  1793.     __initialize(len, Distance(0));
  1794.     distance(first, last, len);
  1795.     Distance half;
  1796.     ForwardIterator middle;
  1797.  
  1798.     while (len > 0)
  1799.     {
  1800.         half = len / 2;
  1801.         middle = first;
  1802.         advance(middle, half);
  1803.         if (*middle < value)
  1804.         {
  1805.             first = middle;
  1806.             ++first;
  1807.             len = len - half - 1;
  1808.         }
  1809.         else
  1810.             len = half;
  1811.     }
  1812.     return first;
  1813. }
  1814.  
  1815. template <class ForwardIterator, class T, class Distance>
  1816. inline ForwardIterator __lower_bound (ForwardIterator first,
  1817.                                       ForwardIterator last,
  1818.                                       const T& value, Distance*,
  1819.                                       bidirectional_iterator_tag)
  1820. {
  1821.     return __lower_bound(first, last, value, (Distance*)0,
  1822.                          forward_iterator_tag());
  1823. }
  1824.  
  1825. template <class RandomAccessIterator, class T, class Distance>
  1826. RandomAccessIterator __lower_bound (RandomAccessIterator first,
  1827.                                     RandomAccessIterator last, const T& value,
  1828.                                     Distance*, random_access_iterator_tag)
  1829. {
  1830.     Distance len = last - first;
  1831.     Distance half;
  1832.     RandomAccessIterator middle;
  1833.  
  1834.     while (len > 0)
  1835.     {
  1836.         half = len / 2;
  1837.         middle = first + half;
  1838.         if (*middle < value)
  1839.         {
  1840.             first = middle + 1;
  1841.             len = len - half - 1;
  1842.         }
  1843.         else
  1844.             len = half;
  1845.     }
  1846.     return first;
  1847. }
  1848.  
  1849. template <class ForwardIterator, class T>
  1850. inline ForwardIterator lower_bound (ForwardIterator first,ForwardIterator last,
  1851.                                     const T& value)
  1852. {
  1853.     return __lower_bound(first, last, value, distance_type(first),
  1854. #ifndef RWSTD_NO_BASE_CLASS_MATCH
  1855.                          iterator_category(first));
  1856. #else
  1857.                          forward_iterator_tag());
  1858. #endif
  1859. }
  1860.  
  1861. template <class ForwardIterator, class T, class Compare, class Distance>
  1862. ForwardIterator __lower_bound (ForwardIterator first, ForwardIterator last,
  1863.                                const T& value, Compare comp, Distance*,
  1864.                                forward_iterator_tag)
  1865. {
  1866.     Distance len;
  1867.     __initialize(len, Distance(0));
  1868.     distance(first, last, len);
  1869.     Distance half;
  1870.     ForwardIterator middle;
  1871.  
  1872.     while (len > 0)
  1873.     {
  1874.         half = len / 2;
  1875.         middle = first;
  1876.         advance(middle, half);
  1877.         if (comp(*middle, value))
  1878.         {
  1879.             first = middle;
  1880.             ++first;
  1881.             len = len - half - 1;
  1882.         }
  1883.         else
  1884.             len = half;
  1885.     }
  1886.     return first;
  1887. }
  1888.  
  1889. template <class ForwardIterator, class T, class Compare, class Distance>
  1890. inline ForwardIterator __lower_bound (ForwardIterator first,
  1891.                                       ForwardIterator last,
  1892.                                       const T& value, Compare comp, Distance*,
  1893.                                       bidirectional_iterator_tag)
  1894. {
  1895.     return __lower_bound(first, last, value, comp, (Distance*) 0,
  1896.                          forward_iterator_tag());
  1897. }
  1898.  
  1899. template <class RandomAccessIterator, class T, class Compare, class Distance>
  1900. RandomAccessIterator __lower_bound (RandomAccessIterator first,
  1901.                                     RandomAccessIterator last,
  1902.                                     const T& value, Compare comp, Distance*,
  1903.                                     random_access_iterator_tag)
  1904. {
  1905.     Distance len = last - first;
  1906.     Distance half;
  1907.     RandomAccessIterator middle;
  1908.  
  1909.     while (len > 0)
  1910.     {
  1911.         half = len / 2;
  1912.         middle = first + half;
  1913.         if (comp(*middle, value))
  1914.         {
  1915.             first = middle + 1;
  1916.             len = len - half - 1;
  1917.         }
  1918.         else
  1919.             len = half;
  1920.     }
  1921.     return first;
  1922. }
  1923.  
  1924. template <class ForwardIterator, class T, class Compare>
  1925. inline ForwardIterator lower_bound (ForwardIterator first,ForwardIterator last,
  1926.                                     const T& value, Compare comp)
  1927. {
  1928.     return __lower_bound(first, last, value, comp, distance_type(first),
  1929. #ifndef RWSTD_NO_BASE_CLASS_MATCH
  1930.                          iterator_category(first));
  1931. #else
  1932.                          forward_iterator_tag());
  1933. #endif
  1934. }
  1935.  
  1936. template <class ForwardIterator, class T, class Distance>
  1937. ForwardIterator __upper_bound (ForwardIterator first, ForwardIterator last,
  1938.                                const T& value, Distance*,
  1939.                                forward_iterator_tag)
  1940. {
  1941.     Distance len;
  1942.     __initialize(len, Distance(0));
  1943.     distance(first, last, len);
  1944.     Distance half;
  1945.     ForwardIterator middle;
  1946.  
  1947.     while (len > 0)
  1948.     {
  1949.         half = len / 2;
  1950.         middle = first;
  1951.         advance(middle, half);
  1952.         if (value < *middle)
  1953.             len = half;
  1954.         else
  1955.         {
  1956.             first = middle;
  1957.             ++first;
  1958.             len = len - half - 1;
  1959.         }
  1960.     }
  1961.     return first;
  1962. }
  1963.  
  1964. template <class ForwardIterator, class T, class Distance>
  1965. inline ForwardIterator __upper_bound (ForwardIterator first,
  1966.                                       ForwardIterator last,
  1967.                                       const T& value, Distance*,
  1968.                                       bidirectional_iterator_tag)
  1969. {
  1970.     return __upper_bound(first, last, value, (Distance*)0,
  1971.                          forward_iterator_tag());
  1972. }
  1973.  
  1974. template <class RandomAccessIterator, class T, class Distance>
  1975. RandomAccessIterator __upper_bound (RandomAccessIterator first,
  1976.                                     RandomAccessIterator last, const T& value,
  1977.                                     Distance*, random_access_iterator_tag)
  1978. {
  1979.     Distance len = last - first;
  1980.     Distance half;
  1981.     RandomAccessIterator middle;
  1982.  
  1983.     while (len > 0)
  1984.     {
  1985.         half = len / 2;
  1986.         middle = first + half;
  1987.         if (value < *middle)
  1988.             len = half;
  1989.         else
  1990.         {
  1991.             first = middle + 1;
  1992.             len = len - half - 1;
  1993.         }
  1994.     }
  1995.     return first;
  1996. }
  1997.  
  1998. template <class ForwardIterator, class T>
  1999. inline ForwardIterator upper_bound (ForwardIterator first,ForwardIterator last,
  2000.                                     const T& value)
  2001. {
  2002.     return __upper_bound(first, last, value, distance_type(first),
  2003. #ifndef RWSTD_NO_BASE_CLASS_MATCH
  2004.                          iterator_category(first));
  2005. #else
  2006.                          forward_iterator_tag());
  2007. #endif
  2008. }
  2009.  
  2010. template <class ForwardIterator, class T, class Compare, class Distance>
  2011. ForwardIterator __upper_bound (ForwardIterator first, ForwardIterator last,
  2012.                                const T& value, Compare comp, Distance*,
  2013.                                forward_iterator_tag)
  2014. {
  2015.     Distance len;
  2016.     __initialize(len, Distance(0));
  2017.     distance(first, last, len);
  2018.     Distance half;
  2019.     ForwardIterator middle;
  2020.  
  2021.     while (len > 0)
  2022.     {
  2023.         half = len / 2;
  2024.         middle = first;
  2025.         advance(middle, half);
  2026.         if (comp(value, *middle))
  2027.             len = half;
  2028.         else {
  2029.             first = middle;
  2030.             ++first;
  2031.             len = len - half - 1;
  2032.         }
  2033.     }
  2034.     return first;
  2035. }
  2036.  
  2037. template <class ForwardIterator, class T, class Compare, class Distance>
  2038. inline ForwardIterator __upper_bound (ForwardIterator first,
  2039.                                       ForwardIterator last,
  2040.                                       const T& value, Compare comp, Distance*,
  2041.                                       bidirectional_iterator_tag)
  2042. {
  2043.     return __upper_bound(first, last, value, comp, (Distance*)0,
  2044.                          forward_iterator_tag());
  2045. }
  2046.  
  2047. template <class RandomAccessIterator, class T, class Compare, class Distance>
  2048. RandomAccessIterator __upper_bound (RandomAccessIterator first,
  2049.                                     RandomAccessIterator last,
  2050.                                     const T& value, Compare comp, Distance*,
  2051.                                     random_access_iterator_tag)
  2052. {
  2053.     Distance len = last - first;
  2054.     Distance half;
  2055.     RandomAccessIterator middle;
  2056.  
  2057.     while (len > 0)
  2058.     {
  2059.         half = len / 2;
  2060.         middle = first + half;
  2061.         if (comp(value, *middle))
  2062.             len = half;
  2063.         else {
  2064.             first = middle + 1;
  2065.             len = len - half - 1;
  2066.         }
  2067.     }
  2068.     return first;
  2069. }
  2070.  
  2071. template <class ForwardIterator, class T, class Compare>
  2072. inline ForwardIterator upper_bound (ForwardIterator first,ForwardIterator last,
  2073.                                     const T& value, Compare comp)
  2074. {
  2075.     return __upper_bound(first, last, value, comp, distance_type(first),
  2076. #ifndef RWSTD_NO_BASE_CLASS_MATCH
  2077.                          iterator_category(first));
  2078. #else
  2079.                          forward_iterator_tag());
  2080. #endif
  2081. }
  2082.  
  2083. template <class ForwardIterator, class T, class Distance>
  2084. pair<ForwardIterator, ForwardIterator>
  2085. __equal_range (ForwardIterator first, ForwardIterator last, const T& value,
  2086.                Distance*, forward_iterator_tag)
  2087. {
  2088.     Distance len;
  2089.     __initialize(len, Distance(0));
  2090.     distance(first, last, len);
  2091.     Distance half;
  2092.     ForwardIterator middle, left, right;
  2093.  
  2094.     while (len > 0)
  2095.     {
  2096.         half = len / 2;
  2097.         middle = first;
  2098.         advance(middle, half);
  2099.         if (*middle < value)
  2100.         {
  2101.             first = middle;
  2102.             ++first;
  2103.             len = len - half - 1;
  2104.         }
  2105.         else if (value < *middle)
  2106.             len = half;
  2107.         else
  2108.         {
  2109.             left = lower_bound(first, middle, value);
  2110.             advance(first, len);
  2111.             right = upper_bound(++middle, first, value);
  2112.             pair<ForwardIterator, ForwardIterator> tmp(left, right);
  2113.             return tmp;
  2114.         }
  2115.     }
  2116.     pair<ForwardIterator, ForwardIterator> tmp(first, first);
  2117.     return tmp;
  2118. }
  2119.  
  2120. template <class ForwardIterator, class T, class Distance>
  2121. inline pair<ForwardIterator, ForwardIterator>
  2122. __equal_range (ForwardIterator first, ForwardIterator last, const T& value,
  2123.                Distance*, bidirectional_iterator_tag)
  2124. {
  2125.     return __equal_range(first, last, value, (Distance*)0,
  2126.                          forward_iterator_tag());
  2127. }
  2128.  
  2129. template <class RandomAccessIterator, class T, class Distance>
  2130. pair<RandomAccessIterator, RandomAccessIterator>
  2131. __equal_range (RandomAccessIterator first, RandomAccessIterator last,
  2132.                const T& value, Distance*, random_access_iterator_tag)
  2133. {
  2134.     Distance len = last - first;
  2135.     Distance half;
  2136.     RandomAccessIterator middle, left, right;
  2137.  
  2138.     while (len > 0)
  2139.     {
  2140.         half = len / 2;
  2141.         middle = first + half;
  2142.         if (*middle < value)
  2143.         {
  2144.             first = middle + 1;
  2145.             len = len - half - 1;
  2146.         }
  2147.         else if (value < *middle)
  2148.             len = half;
  2149.         else
  2150.         {
  2151.             left = lower_bound(first, middle, value);
  2152.             right = upper_bound(++middle, first + len, value);
  2153.             pair<RandomAccessIterator,RandomAccessIterator> tmp(left,right);
  2154.             return tmp;
  2155.         }
  2156.     }
  2157.     pair<RandomAccessIterator, RandomAccessIterator> tmp(first, first);
  2158.     return tmp;
  2159. }
  2160.  
  2161. template <class ForwardIterator, class T>
  2162. inline pair<ForwardIterator, ForwardIterator>
  2163. equal_range (ForwardIterator first, ForwardIterator last, const T& value)
  2164. {
  2165.     return __equal_range(first, last, value, distance_type(first),
  2166. #ifndef RWSTD_NO_BASE_CLASS_MATCH
  2167.                          iterator_category(first));
  2168. #else
  2169.                          forward_iterator_tag());
  2170. #endif
  2171. }
  2172.  
  2173. template <class ForwardIterator, class T, class Compare, class Distance>
  2174. pair<ForwardIterator, ForwardIterator>
  2175. __equal_range (ForwardIterator first, ForwardIterator last, const T& value,
  2176.                Compare comp, Distance*, forward_iterator_tag)
  2177. {
  2178.     Distance len;
  2179.     __initialize(len, Distance(0));
  2180.     distance(first, last, len);
  2181.     Distance half;
  2182.     ForwardIterator middle, left, right;
  2183.  
  2184.     while (len > 0)
  2185.     {
  2186.         half = len / 2;
  2187.         middle = first;
  2188.         advance(middle, half);
  2189.         if (comp(*middle, value))
  2190.         {
  2191.             first = middle;
  2192.             ++first;
  2193.             len = len - half - 1;
  2194.         }
  2195.         else if (comp(value, *middle))
  2196.             len = half;
  2197.         else
  2198.         {
  2199.             left = lower_bound(first, middle, value, comp);
  2200.             advance(first, len);
  2201.             right = upper_bound(++middle, first, value, comp);
  2202.             pair<ForwardIterator, ForwardIterator> tmp(left, right);
  2203.             return tmp;
  2204.         }
  2205.     }
  2206.     pair<ForwardIterator, ForwardIterator> tmp(first, first);
  2207.     return tmp;
  2208. }
  2209.  
  2210. template <class ForwardIterator, class T, class Compare, class Distance>
  2211. inline pair<ForwardIterator, ForwardIterator>
  2212. __equal_range (ForwardIterator first, ForwardIterator last, const T& value,
  2213.                Compare comp, Distance*, bidirectional_iterator_tag)
  2214. {
  2215.     return __equal_range(first, last, value, comp, (Distance*)0,
  2216.                          forward_iterator_tag());
  2217. }
  2218.  
  2219. template <class RandomAccessIterator, class T, class Compare, class Distance>
  2220. pair<RandomAccessIterator, RandomAccessIterator>
  2221. __equal_range (RandomAccessIterator first, RandomAccessIterator last,
  2222.                const T& value, Compare comp, Distance*,
  2223.                random_access_iterator_tag)
  2224. {
  2225.     Distance len = last - first;
  2226.     Distance half;
  2227.     RandomAccessIterator middle, left, right;
  2228.  
  2229.     while (len > 0)
  2230.     {
  2231.         half = len / 2;
  2232.         middle = first + half;
  2233.         if (comp(*middle, value))
  2234.         {
  2235.             first = middle + 1;
  2236.             len = len - half - 1;
  2237.         }
  2238.         else if (comp(value, *middle))
  2239.             len = half;
  2240.         else
  2241.         {
  2242.             left = lower_bound(first, middle, value, comp);
  2243.             right = upper_bound(++middle, first + len, value, comp);
  2244.             pair<RandomAccessIterator,RandomAccessIterator> tmp(left, right);
  2245.             return tmp;
  2246.         }
  2247.     }
  2248.     pair<RandomAccessIterator, RandomAccessIterator> tmp(first, first);
  2249.     return tmp;
  2250. }
  2251.  
  2252. template <class ForwardIterator, class T, class Compare>
  2253. inline pair<ForwardIterator, ForwardIterator>
  2254. equal_range (ForwardIterator first, ForwardIterator last, const T& value,
  2255.              Compare comp)
  2256. {
  2257.     return __equal_range(first, last, value, comp, distance_type(first),
  2258. #ifndef RWSTD_NO_BASE_CLASS_MATCH
  2259.                          iterator_category(first));
  2260. #else
  2261.                          forward_iterator_tag());
  2262. #endif
  2263. }
  2264.  
  2265. template <class ForwardIterator, class T>
  2266. inline bool binary_search (ForwardIterator first, ForwardIterator last,
  2267.                            const T& value)
  2268. {
  2269.     ForwardIterator i = lower_bound(first, last, value);
  2270.     return i != last && !(value < *i);
  2271. }
  2272.  
  2273. template <class ForwardIterator, class T, class Compare>
  2274. inline bool binary_search (ForwardIterator first, ForwardIterator last,
  2275.                            const T& value, Compare comp)
  2276. {
  2277.     ForwardIterator i = lower_bound(first, last, value, comp);
  2278.     return i != last && !comp(value, *i);
  2279. }
  2280.  
  2281. //
  2282. // Merge
  2283. //
  2284.  
  2285. template <class InputIterator1, class InputIterator2, class OutputIterator>
  2286. OutputIterator merge (InputIterator1 first1, InputIterator1 last1,
  2287.                       InputIterator2 first2, InputIterator2 last2,
  2288.                       OutputIterator result)
  2289. {
  2290.     while (first1 != last1 && first2 != last2)
  2291.     {
  2292.         if (*first2 < *first1)
  2293.             *result++ = *first2++;
  2294.         else
  2295.             *result++ = *first1++;
  2296.     }
  2297.     return copy(first2, last2, copy(first1, last1, result));
  2298. }
  2299.  
  2300. template <class InputIterator1, class InputIterator2, class OutputIterator,
  2301.           class Compare>
  2302. OutputIterator merge (InputIterator1 first1, InputIterator1 last1,
  2303.                       InputIterator2 first2, InputIterator2 last2,
  2304.                       OutputIterator result, Compare comp)
  2305. {
  2306.     while (first1 != last1 && first2 != last2)
  2307.     {
  2308.         if (comp(*first2, *first1))
  2309.             *result++ = *first2++;
  2310.         else
  2311.             *result++ = *first1++;
  2312.     }
  2313.     return copy(first2, last2, copy(first1, last1, result));
  2314. }
  2315.  
  2316. template <class BidirectionalIterator, class Distance>
  2317. void __merge_without_buffer (BidirectionalIterator first,
  2318.                              BidirectionalIterator middle,
  2319.                              BidirectionalIterator last,
  2320.                              Distance len1, Distance len2)
  2321. {
  2322.     if (len1 == 0 || len2 == 0) return;
  2323.     if (len1 + len2 == 2)
  2324.     {
  2325.         if (*middle < *first) iter_swap(first, middle);
  2326.         return;
  2327.     }
  2328.     BidirectionalIterator first_cut = first;
  2329.     BidirectionalIterator second_cut = middle;
  2330.     Distance len11;
  2331.     __initialize(len11, Distance(0));
  2332.     Distance len22;
  2333.     __initialize(len22, Distance(0));
  2334.     if (len1 > len2)
  2335.     {
  2336.         len11 = len1 / 2;
  2337.         advance(first_cut, len11);
  2338.         second_cut = lower_bound(middle, last, *first_cut);
  2339.         distance(middle, second_cut, len22);
  2340.     }
  2341.     else
  2342.     {
  2343.         len22 = len2 / 2;
  2344.         advance(second_cut, len22);
  2345.         first_cut = upper_bound(first, middle, *second_cut);
  2346.         distance(first, first_cut, len11);
  2347.     }
  2348.     rotate(first_cut, middle, second_cut);
  2349.     BidirectionalIterator new_middle = first_cut;
  2350.     advance(new_middle, len22);
  2351.     __merge_without_buffer(first, first_cut, new_middle, len11, len22);
  2352.     __merge_without_buffer(new_middle, second_cut, last, len1 - len11,
  2353.                            len2 - len22);
  2354. }
  2355.  
  2356. template <class BidirectionalIterator, class Distance, class Compare>
  2357. void __merge_without_buffer (BidirectionalIterator first,
  2358.                              BidirectionalIterator middle,
  2359.                              BidirectionalIterator last,
  2360.                              Distance len1, Distance len2, Compare comp)
  2361. {
  2362.     if (len1 == 0 || len2 == 0) return;
  2363.     if (len1 + len2 == 2)
  2364.     {
  2365.         if (comp(*middle, *first)) iter_swap(first, middle);
  2366.         return;
  2367.     }
  2368.     BidirectionalIterator first_cut = first;
  2369.     BidirectionalIterator second_cut = middle;
  2370.     Distance len11;
  2371.     __initialize(len11, Distance(0));
  2372.     Distance len22;
  2373.     __initialize(len22, Distance(0));
  2374.     if (len1 > len2)
  2375.     {
  2376.         len11 = len1 / 2;
  2377.         advance(first_cut, len11);
  2378.         second_cut = lower_bound(middle, last, *first_cut, comp);
  2379.         distance(middle, second_cut, len22);
  2380.     }
  2381.     else
  2382.     {
  2383.         len22 = len2 / 2;
  2384.         advance(second_cut, len22);
  2385.         first_cut = upper_bound(first, middle, *second_cut, comp);
  2386.         distance(first, first_cut, len11);
  2387.     }
  2388.     rotate(first_cut, middle, second_cut);
  2389.     BidirectionalIterator new_middle = first_cut;
  2390.     advance(new_middle, len22);
  2391.     __merge_without_buffer(first, first_cut, new_middle, len11, len22, comp);
  2392.     __merge_without_buffer(new_middle, second_cut, last, len1 - len11,
  2393.                            len2 - len22, comp);
  2394. }
  2395.  
  2396. template <class BidirectionalIterator1, class BidirectionalIterator2,
  2397.           class Distance>
  2398. BidirectionalIterator1 __rotate_adaptive (BidirectionalIterator1 first,
  2399.                                           BidirectionalIterator1 middle,
  2400.                                           BidirectionalIterator1 last,
  2401.                                           Distance len1, Distance len2,
  2402.                                           BidirectionalIterator2 buffer,
  2403.                                           Distance buffer_size)
  2404. {
  2405.     BidirectionalIterator2 buffer_end;
  2406.     if (len1 > len2 && len2 <= buffer_size)
  2407.     {
  2408.         buffer_end = copy(middle, last, buffer);
  2409.         copy_backward(first, middle, last);
  2410.         return copy(buffer, buffer_end, first);
  2411.     }
  2412.     else if (len1 <= buffer_size)
  2413.     {
  2414.         buffer_end = copy(first, middle, buffer);
  2415.         copy(middle, last, first);
  2416.         return copy_backward(buffer, buffer_end, last);
  2417.     }
  2418.     else
  2419.     {
  2420.         rotate(first, middle, last);
  2421.         advance(first, len2);
  2422.         return first;
  2423.     }
  2424. }
  2425.  
  2426. template <class BidirectionalIterator1, class BidirectionalIterator2,
  2427.           class BidirectionalIterator3>
  2428. BidirectionalIterator3 __merge_backward (BidirectionalIterator1 first1,
  2429.                                          BidirectionalIterator1 last1,
  2430.                                          BidirectionalIterator2 first2,
  2431.                                          BidirectionalIterator2 last2,
  2432.                                          BidirectionalIterator3 result)
  2433. {
  2434.     if (first1 == last1) return copy_backward(first2, last2, result);
  2435.     if (first2 == last2) return copy_backward(first1, last1, result);
  2436.     --last1;
  2437.     --last2;
  2438.     while (true)
  2439.     {
  2440.         if (*last2 < *last1)
  2441.         {
  2442.             *--result = *last1;
  2443.             if (first1 == last1) return copy_backward(first2, ++last2, result);
  2444.             --last1;
  2445.         }
  2446.         else
  2447.         {
  2448.             *--result = *last2;
  2449.             if (first2 == last2) return copy_backward(first1, ++last1, result);
  2450.             --last2;
  2451.         }
  2452.     }
  2453. }
  2454.  
  2455. template <class BidirectionalIterator1, class BidirectionalIterator2,
  2456.           class BidirectionalIterator3, class Compare>
  2457. BidirectionalIterator3 __merge_backward (BidirectionalIterator1 first1,
  2458.                                          BidirectionalIterator1 last1,
  2459.                                          BidirectionalIterator2 first2,
  2460.                                          BidirectionalIterator2 last2,
  2461.                                          BidirectionalIterator3 result,
  2462.                                          Compare comp)
  2463. {
  2464.     if (first1 == last1) return copy_backward(first2, last2, result);
  2465.     if (first2 == last2) return copy_backward(first1, last1, result);
  2466.     --last1;
  2467.     --last2;
  2468.     while (true)
  2469.     {
  2470.         if (comp(*last2, *last1))
  2471.         {
  2472.             *--result = *last1;
  2473.             if (first1 == last1) return copy_backward(first2, ++last2, result);
  2474.             --last1;
  2475.         }
  2476.         else
  2477.         {
  2478.             *--result = *last2;
  2479.             if (first2 == last2) return copy_backward(first1, ++last1, result);
  2480.             --last2;
  2481.         }
  2482.     }
  2483. }
  2484.  
  2485. template <class BidirectionalIterator, class Distance, class Pointer, class T>
  2486. void __merge_adaptive (BidirectionalIterator first,
  2487.                        BidirectionalIterator middle,
  2488.                        BidirectionalIterator last, Distance len1,Distance len2,
  2489.                        Pointer buffer, Distance buffer_size, T*)
  2490. {
  2491.     if (len1 <= len2 && len1 <= buffer_size)
  2492.     {
  2493.         Pointer end_buffer = copy(first, middle, buffer);
  2494.         merge(buffer, end_buffer, middle, last, first);
  2495.     }
  2496.     else if (len2 <= buffer_size)
  2497.     {
  2498.         Pointer end_buffer = copy(middle, last, buffer);
  2499.         __merge_backward(first, middle, buffer, end_buffer, last);
  2500.     }
  2501.     else
  2502.     {
  2503.         BidirectionalIterator first_cut = first;
  2504.         BidirectionalIterator second_cut = middle;
  2505.         Distance len11;
  2506.         __initialize(len11, Distance(0));
  2507.         Distance len22;
  2508.         __initialize(len22, Distance(0));
  2509.         if (len1 > len2)
  2510.         {
  2511.             len11 = len1 / 2;
  2512.             advance(first_cut, len11);
  2513.             second_cut = lower_bound(middle, last, *first_cut);
  2514.             distance(middle, second_cut, len22);
  2515.         }
  2516.         else
  2517.         {
  2518.             len22 = len2 / 2;
  2519.             advance(second_cut, len22);
  2520.             first_cut = upper_bound(first, middle, *second_cut);
  2521.             distance(first, first_cut, len11);
  2522.         }
  2523.         BidirectionalIterator new_middle =
  2524.             __rotate_adaptive(first_cut, middle, second_cut, len1 - len11,
  2525.                               len22, buffer, buffer_size);
  2526.         __merge_adaptive(first, first_cut, new_middle, len11, len22, buffer,
  2527.                          buffer_size, (T*)0);
  2528.         __merge_adaptive(new_middle, second_cut, last, len1 - len11,
  2529.                          len2 - len22, buffer, buffer_size, (T*)0);
  2530.     }
  2531. }
  2532.  
  2533. template <class BidirectionalIterator, class Distance, class Pointer, class T,
  2534.           class Compare>
  2535. void __merge_adaptive (BidirectionalIterator first,
  2536.                        BidirectionalIterator middle,
  2537.                        BidirectionalIterator last, Distance len1,Distance len2,
  2538.                        Pointer buffer, Distance buffer_size, T*, Compare comp)
  2539. {
  2540.     if (len1 <= len2 && len1 <= buffer_size)
  2541.     {
  2542.         Pointer end_buffer = copy(first, middle, buffer);
  2543.         merge(buffer, end_buffer, middle, last, first, comp);
  2544.     }
  2545.     else if (len2 <= buffer_size)
  2546.     {
  2547.         Pointer end_buffer = copy(middle, last, buffer);
  2548.         __merge_backward(first, middle, buffer, end_buffer, last, comp);
  2549.     }
  2550.     else
  2551.     {
  2552.         BidirectionalIterator first_cut = first;
  2553.         BidirectionalIterator second_cut = middle;
  2554.         Distance len11;
  2555.         __initialize(len11, Distance(0));
  2556.         Distance len22;
  2557.         __initialize(len22, Distance(0));
  2558.         if (len1 > len2)
  2559.         {
  2560.             len11 = len1 / 2;
  2561.             advance(first_cut, len11);
  2562.             second_cut = lower_bound(middle, last, *first_cut, comp);
  2563.             distance(middle, second_cut, len22);
  2564.         }
  2565.         else
  2566.         {
  2567.             len22 = len2 / 2;
  2568.             advance(second_cut, len22);
  2569.             first_cut = upper_bound(first, middle, *second_cut, comp);
  2570.             distance(first, first_cut, len11);
  2571.         }
  2572.         BidirectionalIterator new_middle =
  2573.             __rotate_adaptive(first_cut, middle, second_cut, len1 - len11,
  2574.                               len22, buffer, buffer_size);
  2575.         __merge_adaptive(first, first_cut, new_middle, len11, len22, buffer,
  2576.                          buffer_size, (T*)0, comp);
  2577.         __merge_adaptive(new_middle, second_cut, last, len1 - len11,
  2578.                          len2 - len22, buffer, buffer_size, (T*)0, comp);
  2579.     }
  2580. }
  2581.  
  2582. template <class BidirectionalIterator, class Distance, class Pointer, class T>
  2583. void __inplace_merge (BidirectionalIterator first,
  2584.                       BidirectionalIterator middle,
  2585.                       BidirectionalIterator last, Distance len1,
  2586.                       Distance len2, pair<Pointer, Distance> p, T*)
  2587. {
  2588.     if (p.first == 0)
  2589.         __merge_without_buffer(first, middle, last, len1, len2);
  2590.     else
  2591.     {
  2592.         Distance len = min(p.second, len1 + len2);
  2593.         fill_n(raw_storage_iterator<Pointer, T>(p.first), len, *first);
  2594.         __merge_adaptive(first, middle, last, len1, len2, p.first,
  2595.                          p.second, (T*)0);
  2596.         destroy(p.first, p.first + len);
  2597.         return_temporary_buffer(p.first);
  2598.     }
  2599. }
  2600.  
  2601. template <class BidirectionalIterator, class Distance, class Pointer, class T,
  2602.       class Compare>
  2603. void __inplace_merge (BidirectionalIterator first,
  2604.                       BidirectionalIterator middle,
  2605.                       BidirectionalIterator last, Distance len1,
  2606.                       Distance len2, pair<Pointer, Distance> p, T*,
  2607.                       Compare comp)
  2608. {
  2609.     if (p.first == 0)
  2610.         __merge_without_buffer(first, middle, last, len1, len2, comp);
  2611.     else
  2612.     {
  2613.         Distance len = min(p.second, len1 + len2);
  2614.         fill_n(raw_storage_iterator<Pointer, T>(p.first), len, *first);
  2615.         __merge_adaptive(first, middle, last, len1, len2, p.first,
  2616.                          p.second, (T*)0, comp);
  2617.         destroy(p.first, p.first + len);
  2618.         return_temporary_buffer(p.first);
  2619.     }
  2620. }
  2621.  
  2622. template <class BidirectionalIterator, class T, class Distance>
  2623. inline void __inplace_merge_aux (BidirectionalIterator first,
  2624.                                  BidirectionalIterator middle,
  2625.                                  BidirectionalIterator last, T*, Distance*)
  2626. {
  2627.     Distance len1;
  2628.     __initialize(len1, Distance(0));
  2629.     distance(first, middle, len1);
  2630.     Distance len2;
  2631.     __initialize(len2, Distance(0));
  2632.     distance(middle, last, len2);
  2633.     __inplace_merge(first, middle, last, len1, len2,
  2634.                     get_temporary_buffer(len1 + len2, (T*)0), (T*)0);
  2635. }
  2636.  
  2637. template <class BidirectionalIterator, class T, class Distance, class Compare>
  2638. inline void __inplace_merge_aux (BidirectionalIterator first,
  2639.                                  BidirectionalIterator middle,
  2640.                                  BidirectionalIterator last, T*, Distance*,
  2641.                                  Compare comp)
  2642. {
  2643.     Distance len1;
  2644.     __initialize(len1, Distance(0));
  2645.     distance(first, middle, len1);
  2646.     Distance len2;
  2647.     __initialize(len2, Distance(0));
  2648.     distance(middle, last, len2);
  2649.     __inplace_merge(first, middle, last, len1, len2,
  2650.                     get_temporary_buffer(len1 + len2, (T*)0), (T*)0, comp);
  2651. }
  2652.  
  2653. template <class BidirectionalIterator>
  2654. inline void inplace_merge (BidirectionalIterator first,
  2655.                            BidirectionalIterator middle,
  2656.                            BidirectionalIterator last)
  2657. {
  2658.     if (!(first == middle || middle == last))
  2659.         __inplace_merge_aux(first, middle, last, RWSTD_VALUE_TYPE(first),
  2660.                             distance_type(first));
  2661. }
  2662.  
  2663. template <class BidirectionalIterator, class Compare>
  2664. inline void inplace_merge (BidirectionalIterator first,
  2665.                            BidirectionalIterator middle,
  2666.                            BidirectionalIterator last, Compare comp)
  2667. {
  2668.     if (!(first == middle || middle == last))
  2669.         __inplace_merge_aux(first, middle, last, RWSTD_VALUE_TYPE(first),
  2670.                             distance_type(first), comp);
  2671. }
  2672.  
  2673. //
  2674. // Set operations.
  2675. //
  2676.  
  2677. template <class InputIterator1, class InputIterator2>
  2678. bool includes (InputIterator1 first1, InputIterator1 last1,
  2679.                InputIterator2 first2, InputIterator2 last2)
  2680. {
  2681.     while (first1 != last1 && first2 != last2)
  2682.     {
  2683.         if (*first2 < *first1)
  2684.             return false;
  2685.         else if(*first1 < *first2)
  2686.             ++first1;
  2687.         else
  2688.             ++first1, ++first2;
  2689.     }
  2690.     return first2 == last2;
  2691. }
  2692.  
  2693. template <class InputIterator1, class InputIterator2, class Compare>
  2694. bool includes (InputIterator1 first1, InputIterator1 last1,
  2695.                InputIterator2 first2, InputIterator2 last2, Compare comp)
  2696. {
  2697.     while (first1 != last1 && first2 != last2)
  2698.     {
  2699.         if (comp(*first2, *first1))
  2700.             return false;
  2701.         else if(comp(*first1, *first2))
  2702.             ++first1;
  2703.         else
  2704.             ++first1, ++first2;
  2705.     }
  2706.     return first2 == last2;
  2707. }
  2708.  
  2709. template <class InputIterator1, class InputIterator2, class OutputIterator>
  2710. OutputIterator set_union (InputIterator1 first1, InputIterator1 last1,
  2711.                           InputIterator2 first2, InputIterator2 last2,
  2712.                           OutputIterator result)
  2713. {
  2714.     while (first1 != last1 && first2 != last2)
  2715.     {
  2716.         if (*first1 < *first2)
  2717.             *result++ = *first1++;
  2718.         else if (*first2 < *first1)
  2719.             *result++ = *first2++;
  2720.         else
  2721.         {
  2722.             *result++ = *first1++;
  2723.             first2++;
  2724.         }
  2725.     }
  2726.     return copy(first2, last2, copy(first1, last1, result));
  2727. }
  2728.  
  2729. template <class InputIterator1, class InputIterator2, class OutputIterator,
  2730.           class Compare>
  2731. OutputIterator set_union (InputIterator1 first1, InputIterator1 last1,
  2732.                           InputIterator2 first2, InputIterator2 last2,
  2733.                           OutputIterator result, Compare comp)
  2734. {
  2735.     while (first1 != last1 && first2 != last2)
  2736.     {
  2737.         if (comp(*first1, *first2))
  2738.             *result++ = *first1++;
  2739.         else if (comp(*first2, *first1))
  2740.             *result++ = *first2++;
  2741.         else
  2742.         {
  2743.             *result++ = *first1++;
  2744.             ++first2;
  2745.         }
  2746.     }
  2747.     return copy(first2, last2, copy(first1, last1, result));
  2748. }
  2749.  
  2750. template <class InputIterator1, class InputIterator2, class OutputIterator>
  2751. OutputIterator set_intersection (InputIterator1 first1, InputIterator1 last1,
  2752.                                  InputIterator2 first2, InputIterator2 last2,
  2753.                                  OutputIterator result)
  2754. {
  2755.     while (first1 != last1 && first2 != last2)
  2756.     {
  2757.         if (*first1 < *first2)
  2758.             ++first1;
  2759.         else if (*first2 < *first1)
  2760.             ++first2;
  2761.         else
  2762.         {
  2763.             *result++ = *first1++;
  2764.             ++first2;
  2765.         }
  2766.     }
  2767.     return result;
  2768. }
  2769.  
  2770. template <class InputIterator1, class InputIterator2, class OutputIterator,
  2771.           class Compare>
  2772. OutputIterator set_intersection (InputIterator1 first1, InputIterator1 last1,
  2773.                                  InputIterator2 first2, InputIterator2 last2,
  2774.                                  OutputIterator result, Compare comp)
  2775. {
  2776.     while (first1 != last1 && first2 != last2)
  2777.     {
  2778.         if (comp(*first1, *first2))
  2779.             ++first1;
  2780.         else if (comp(*first2, *first1))
  2781.             ++first2;
  2782.         else
  2783.         {
  2784.             *result++ = *first1++;
  2785.             ++first2;
  2786.         }
  2787.     }
  2788.     return result;
  2789. }
  2790.  
  2791. template <class InputIterator1, class InputIterator2, class OutputIterator>
  2792. OutputIterator set_difference (InputIterator1 first1, InputIterator1 last1,
  2793.                                InputIterator2 first2, InputIterator2 last2,
  2794.                                OutputIterator result)
  2795. {
  2796.     while (first1 != last1 && first2 != last2)
  2797.     {
  2798.         if (*first1 < *first2)
  2799.             *result++ = *first1++;
  2800.         else if (*first2 < *first1)
  2801.             ++first2;
  2802.         else
  2803.         {
  2804.             ++first1;
  2805.             ++first2;
  2806.         }
  2807.     }
  2808.     return copy(first1, last1, result);
  2809. }
  2810.  
  2811. template <class InputIterator1, class InputIterator2, class OutputIterator,
  2812.           class Compare>
  2813. OutputIterator set_difference (InputIterator1 first1, InputIterator1 last1,
  2814.                                InputIterator2 first2, InputIterator2 last2,
  2815.                                OutputIterator result, Compare comp)
  2816. {
  2817.     while (first1 != last1 && first2 != last2)
  2818.     {
  2819.         if (comp(*first1, *first2))
  2820.             *result++ = *first1++;
  2821.         else if (comp(*first2, *first1))
  2822.             ++first2;
  2823.         else
  2824.         {
  2825.             ++first1;
  2826.             ++first2;
  2827.         }
  2828.     }
  2829.     return copy(first1, last1, result);
  2830. }
  2831.  
  2832. template <class InputIterator1, class InputIterator2, class OutputIterator>
  2833. OutputIterator set_symmetric_difference (InputIterator1 first1,
  2834.                                          InputIterator1 last1,
  2835.                                          InputIterator2 first2,
  2836.                                          InputIterator2 last2,
  2837.                                          OutputIterator result)
  2838. {
  2839.     while (first1 != last1 && first2 != last2)
  2840.     {
  2841.         if (*first1 < *first2)
  2842.             *result++ = *first1++;
  2843.         else if (*first2 < *first1)
  2844.             *result++ = *first2++;
  2845.         else
  2846.         {
  2847.             ++first1;
  2848.             ++first2;
  2849.         }
  2850.     }
  2851.     return copy(first2, last2, copy(first1, last1, result));
  2852. }
  2853.  
  2854. template <class InputIterator1, class InputIterator2, class OutputIterator,
  2855.           class Compare>
  2856. OutputIterator set_symmetric_difference (InputIterator1 first1,
  2857.                                          InputIterator1 last1,
  2858.                                          InputIterator2 first2,
  2859.                                          InputIterator2 last2,
  2860.                                          OutputIterator result, Compare comp)
  2861. {
  2862.     while (first1 != last1 && first2 != last2)
  2863.     {
  2864.         if (comp(*first1, *first2))
  2865.             *result++ = *first1++;
  2866.         else if (comp(*first2, *first1))
  2867.             *result++ = *first2++;
  2868.         else
  2869.         {
  2870.             ++first1;
  2871.             ++first2;
  2872.         }
  2873.     }
  2874.     return copy(first2, last2, copy(first1, last1, result));
  2875. }
  2876.  
  2877. //
  2878. // Heap operations.
  2879. //
  2880.  
  2881. template <class RandomAccessIterator, class Distance, class T>
  2882. void __push_heap (RandomAccessIterator first, Distance holeIndex,
  2883.                   Distance topIndex, T value)
  2884. {
  2885.     Distance parent = (holeIndex - 1) / 2;
  2886.     while (holeIndex > topIndex && *(first + parent) < value)
  2887.     {
  2888.         *(first + holeIndex) = *(first + parent);
  2889.         holeIndex = parent;
  2890.         parent = (holeIndex - 1) / 2;
  2891.     }
  2892.     *(first + holeIndex) = value;
  2893. }
  2894.  
  2895. template <class RandomAccessIterator, class Distance, class T>
  2896. inline void __push_heap_aux (RandomAccessIterator first,
  2897.                              RandomAccessIterator last, Distance*, T*)
  2898. {
  2899.     __push_heap(first, Distance((last-first)-1), Distance(0), T(*(last-1)));
  2900. }
  2901.  
  2902. template <class RandomAccessIterator>
  2903. inline void push_heap (RandomAccessIterator first, RandomAccessIterator last)
  2904. {
  2905.    if (!(first == last))
  2906.        __push_heap_aux(first, last, distance_type(first),
  2907.                        RWSTD_VALUE_TYPE(first));
  2908. }
  2909.  
  2910. template <class RandomAccessIterator, class Distance, class T, class Compare>
  2911. void __push_heap (RandomAccessIterator first, Distance holeIndex,
  2912.                   Distance topIndex, T value, Compare comp)
  2913. {
  2914.     Distance parent = (holeIndex - 1) / 2;
  2915.     while (holeIndex > topIndex && comp(*(first + parent), value))
  2916.     {
  2917.         *(first + holeIndex) = *(first + parent);
  2918.         holeIndex = parent;
  2919.         parent = (holeIndex - 1) / 2;
  2920.     }
  2921.     *(first + holeIndex) = value;
  2922. }
  2923.  
  2924. template <class RandomAccessIterator, class Compare,  class Distance, class T>
  2925. inline void __push_heap_aux (RandomAccessIterator first,
  2926.                              RandomAccessIterator last, Compare comp,
  2927.                  Distance*, T*)
  2928. {
  2929.     __push_heap(first, Distance((last-first)-1), Distance(0),
  2930.         T(*(last - 1)), comp);
  2931. }
  2932.  
  2933. template <class RandomAccessIterator, class Compare>
  2934. inline void push_heap (RandomAccessIterator first, RandomAccessIterator last,
  2935.                        Compare comp)
  2936. {
  2937.    if (!(first == last))
  2938.         __push_heap_aux(first, last, comp, distance_type(first),
  2939.                         RWSTD_VALUE_TYPE(first));
  2940. }
  2941.  
  2942. template <class RandomAccessIterator, class Distance, class T>
  2943. void __adjust_heap (RandomAccessIterator first, Distance holeIndex,
  2944.                     Distance len, T value)
  2945. {
  2946.     Distance topIndex = holeIndex;
  2947.     Distance secondChild = 2 * holeIndex + 2;
  2948.     while (secondChild < len)
  2949.     {
  2950.         if (*(first + secondChild) < *(first + (secondChild - 1)))
  2951.             secondChild--;
  2952.         *(first + holeIndex) = *(first + secondChild);
  2953.         holeIndex = secondChild;
  2954.         secondChild = 2 * (secondChild + 1);
  2955.     }
  2956.     if (secondChild == len)
  2957.     {
  2958.         *(first + holeIndex) = *(first + (secondChild - 1));
  2959.         holeIndex = secondChild - 1;
  2960.     }
  2961.     __push_heap(first, holeIndex, topIndex, value);
  2962. }
  2963.  
  2964. template <class RandomAccessIterator, class T, class Distance>
  2965. inline void __pop_heap (RandomAccessIterator first, RandomAccessIterator last,
  2966.                         RandomAccessIterator result, T value, Distance*)
  2967. {
  2968.     *result = *first;
  2969.     __adjust_heap(first, Distance(0), Distance(last - first), value);
  2970. }
  2971.  
  2972. template <class RandomAccessIterator, class T>
  2973. inline void __pop_heap_aux (RandomAccessIterator first,
  2974.                             RandomAccessIterator last, T*)
  2975. {
  2976.     __pop_heap(first, last-1, last-1, T(*(last-1)), distance_type(first));
  2977. }
  2978.  
  2979. template <class RandomAccessIterator>
  2980. inline void pop_heap (RandomAccessIterator first, RandomAccessIterator last)
  2981. {
  2982.     if (!(first == last))
  2983.        __pop_heap_aux(first, last, RWSTD_VALUE_TYPE(first));
  2984. }
  2985.  
  2986. template <class RandomAccessIterator, class Distance, class T, class Compare>
  2987. void __adjust_heap (RandomAccessIterator first, Distance holeIndex,
  2988.                     Distance len, T value, Compare comp)
  2989. {
  2990.     Distance topIndex = holeIndex;
  2991.     Distance secondChild = 2 * holeIndex + 2;
  2992.     while (secondChild < len)
  2993.     {
  2994.         if (comp(*(first + secondChild), *(first + (secondChild - 1))))
  2995.             secondChild--;
  2996.         *(first + holeIndex) = *(first + secondChild);
  2997.         holeIndex = secondChild;
  2998.         secondChild = 2 * (secondChild + 1);
  2999.     }
  3000.     if (secondChild == len)
  3001.     {
  3002.         *(first + holeIndex) = *(first + (secondChild - 1));
  3003.         holeIndex = secondChild - 1;
  3004.     }
  3005.     __push_heap(first, holeIndex, topIndex, value, comp);
  3006. }
  3007.  
  3008. template <class RandomAccessIterator, class T, class Compare, class Distance>
  3009. inline void __pop_heap (RandomAccessIterator first, RandomAccessIterator last,
  3010.                         RandomAccessIterator result, T value, Compare comp,
  3011.                         Distance*)
  3012. {
  3013.     *result = *first;
  3014.     __adjust_heap(first, Distance(0), Distance(last - first), value, comp);
  3015. }
  3016.  
  3017. template <class RandomAccessIterator, class T, class Compare>
  3018. inline void __pop_heap_aux (RandomAccessIterator first,
  3019.                             RandomAccessIterator last, T*, Compare comp)
  3020. {
  3021.     __pop_heap(first, last - 1, last - 1, T(*(last - 1)), comp,
  3022.                distance_type(first));
  3023. }
  3024.  
  3025. template <class RandomAccessIterator, class Compare>
  3026. inline void pop_heap (RandomAccessIterator first, RandomAccessIterator last,
  3027.                       Compare comp)
  3028. {
  3029.     if (!(first == last))
  3030.        __pop_heap_aux(first, last, RWSTD_VALUE_TYPE(first), comp);
  3031. }
  3032.  
  3033. template <class RandomAccessIterator, class T, class Distance>
  3034. void __make_heap (RandomAccessIterator first, RandomAccessIterator last, T*,
  3035.                   Distance*)
  3036. {
  3037.     Distance len = last - first;
  3038.     Distance parent = (len - 2)/2;
  3039.     while (true)
  3040.     {
  3041.         __adjust_heap(first, parent, len, T(*(first + parent)));
  3042.         if (parent == 0) return;
  3043.         parent--;
  3044.     }
  3045. }
  3046.  
  3047. template <class RandomAccessIterator>
  3048. inline void make_heap (RandomAccessIterator first, RandomAccessIterator last)
  3049. {
  3050.     if (!(last - first < 2))
  3051.         __make_heap(first, last, RWSTD_VALUE_TYPE(first),
  3052.                     distance_type(first));
  3053. }
  3054.  
  3055. template <class RandomAccessIterator, class Compare, class T, class Distance>
  3056. void __make_heap (RandomAccessIterator first, RandomAccessIterator last,
  3057.                   Compare comp, T*, Distance*)
  3058. {
  3059.     Distance len = last - first;
  3060.     Distance parent = (len - 2)/2;
  3061.     while (true)
  3062.     {
  3063.         __adjust_heap(first, parent, len, T(*(first + parent)), comp);
  3064.         if (parent == 0)
  3065.             return;
  3066.         parent--;
  3067.     }
  3068. }
  3069.  
  3070. template <class RandomAccessIterator, class Compare>
  3071. inline void make_heap (RandomAccessIterator first, RandomAccessIterator last,
  3072.                        Compare comp)
  3073. {
  3074.     if (!(last - first < 2))
  3075.         __make_heap(first, last, comp, RWSTD_VALUE_TYPE(first),
  3076.                     distance_type(first));
  3077. }
  3078.  
  3079. template <class RandomAccessIterator>
  3080. void sort_heap (RandomAccessIterator first, RandomAccessIterator last)
  3081. {
  3082.     while (last - first > 1) pop_heap(first, last--);
  3083. }
  3084.  
  3085. template <class RandomAccessIterator, class Compare>
  3086. void sort_heap (RandomAccessIterator first, RandomAccessIterator last,
  3087.                 Compare comp)
  3088. {
  3089.     while (last - first > 1) pop_heap(first, last--, comp);
  3090. }
  3091.  
  3092. //
  3093. // Minimum and maximum.
  3094. //
  3095. #if !defined(RWSTD_NO_NAMESPACE)
  3096. using ::min;
  3097. #endif
  3098.  
  3099. template <class T, class Compare>
  3100. inline const T& min (const T& a, const T& b, Compare comp)
  3101. {
  3102.     return comp(b, a) ? b : a;
  3103. }
  3104.  
  3105. #if !defined(RWSTD_NO_NAMESPACE)
  3106. using ::max;
  3107. #endif
  3108.  
  3109. template <class T, class Compare>
  3110. inline const T& max (const T& a, const T& b, Compare comp)
  3111. {
  3112.     return comp(a, b) ? b : a;
  3113. }
  3114.  
  3115. template <class ForwardIterator>
  3116. ForwardIterator min_element (ForwardIterator first, ForwardIterator last)
  3117. {
  3118.     if (first == last) return first;
  3119.     ForwardIterator result = first;
  3120.     while (++first != last)
  3121.         if (*first < *result) result = first;
  3122.     return result;
  3123. }
  3124.  
  3125. template <class ForwardIterator, class Compare>
  3126. ForwardIterator min_element (ForwardIterator first, ForwardIterator last,
  3127.                              Compare comp)
  3128. {
  3129.     if (first == last) return first;
  3130.     ForwardIterator result = first;
  3131.     while (++first != last)
  3132.         if (comp(*first, *result)) result = first;
  3133.     return result;
  3134. }
  3135.  
  3136. template <class ForwardIterator>
  3137. ForwardIterator max_element (ForwardIterator first, ForwardIterator last)
  3138. {
  3139.     if (first == last) return first;
  3140.     ForwardIterator result = first;
  3141.     while (++first != last)
  3142.         if (*result < *first) result = first;
  3143.     return result;
  3144. }
  3145.  
  3146. template <class ForwardIterator, class Compare>
  3147. ForwardIterator max_element (ForwardIterator first, ForwardIterator last,
  3148.                              Compare comp)
  3149. {
  3150.     if (first == last) return first;
  3151.     ForwardIterator result = first;
  3152.     while (++first != last)
  3153.         if (comp(*result, *first)) result = first;
  3154.     return result;
  3155. }
  3156.  
  3157. template <class InputIterator1, class InputIterator2>
  3158. bool lexicographical_compare (InputIterator1 first1, InputIterator1 last1,
  3159.                               InputIterator2 first2, InputIterator2 last2)
  3160. {
  3161.     while (first1 != last1 && first2 != last2)
  3162.     {
  3163.         if (*first1 < *first2)     return true;
  3164.         if (*first2++ < *first1++) return false;
  3165.     }
  3166.     return first1 == last1 && first2 != last2;
  3167. }
  3168.  
  3169. template <class InputIterator1, class InputIterator2, class Compare>
  3170. bool lexicographical_compare(InputIterator1 first1, InputIterator1 last1,
  3171.                              InputIterator2 first2, InputIterator2 last2,
  3172.                              Compare comp)
  3173. {
  3174.     while (first1 != last1 && first2 != last2)
  3175.     {
  3176.         if (comp(*first1, *first2))     return true;
  3177.         if (comp(*first2++, *first1++)) return false;
  3178.     }
  3179.     return first1 == last1 && first2 != last2;
  3180. }
  3181.  
  3182. //
  3183. // Permutations.
  3184. //
  3185.  
  3186. template <class BidirectionalIterator>
  3187. bool next_permutation (BidirectionalIterator first,
  3188.                        BidirectionalIterator last)
  3189. {
  3190.     if (first == last) return false;
  3191.     BidirectionalIterator i = first;
  3192.     ++i;
  3193.     if (i == last) return false;
  3194.     i = last;
  3195.     --i;
  3196.  
  3197.     for (;;)
  3198.     {
  3199.         BidirectionalIterator ii = i--;
  3200.         if (*i < *ii)
  3201.         {
  3202.             BidirectionalIterator j = last;
  3203.             while (!(*i < *--j))
  3204.                 ;
  3205.             iter_swap(i, j);
  3206.             reverse(ii, last);
  3207.             return true;
  3208.         }
  3209.         if (i == first)
  3210.         {
  3211.             reverse(first, last);
  3212.             return false;
  3213.         }
  3214.     }
  3215. }
  3216.  
  3217. template <class BidirectionalIterator, class Compare>
  3218. bool next_permutation (BidirectionalIterator first, BidirectionalIterator last,
  3219.                        Compare comp)
  3220. {
  3221.     if (first == last) return false;
  3222.     BidirectionalIterator i = first;
  3223.     ++i;
  3224.     if (i == last) return false;
  3225.     i = last;
  3226.     --i;
  3227.  
  3228.     for (;;)
  3229.     {
  3230.         BidirectionalIterator ii = i--;
  3231.         if (comp(*i, *ii))
  3232.         {
  3233.             BidirectionalIterator j = last;
  3234.             while (!comp(*i, *--j))
  3235.                 ;
  3236.             iter_swap(i, j);
  3237.             reverse(ii, last);
  3238.             return true;
  3239.         }
  3240.         if (i == first)
  3241.         {
  3242.             reverse(first, last);
  3243.             return false;
  3244.         }
  3245.     }
  3246. }
  3247.  
  3248. template <class BidirectionalIterator>
  3249. bool prev_permutation (BidirectionalIterator first,
  3250.                        BidirectionalIterator last)
  3251. {
  3252.     if (first == last) return false;
  3253.     BidirectionalIterator i = first;
  3254.     ++i;
  3255.     if (i == last) return false;
  3256.     i = last;
  3257.     --i;
  3258.  
  3259.     for (;;)
  3260.     {
  3261.         BidirectionalIterator ii = i--;
  3262.         if (*ii < *i)
  3263.         {
  3264.             BidirectionalIterator j = last;
  3265.             while (!(*--j < *i))
  3266.                 ;
  3267.             iter_swap(i, j);
  3268.             reverse(ii, last);
  3269.             return true;
  3270.         }
  3271.         if (i == first)
  3272.         {
  3273.             reverse(first, last);
  3274.             return false;
  3275.         }
  3276.     }
  3277. }
  3278.  
  3279. template <class BidirectionalIterator, class Compare>
  3280. bool prev_permutation (BidirectionalIterator first, BidirectionalIterator last,
  3281.                        Compare comp)
  3282. {
  3283.     if (first == last) return false;
  3284.     BidirectionalIterator i = first;
  3285.     ++i;
  3286.     if (i == last) return false;
  3287.     i = last;
  3288.     --i;
  3289.  
  3290.     for(;;)
  3291.     {
  3292.         BidirectionalIterator ii = i--;
  3293.         if (comp(*ii, *i))
  3294.         {
  3295.             BidirectionalIterator j = last;
  3296.             while (!comp(*--j, *i))
  3297.                 ;
  3298.             iter_swap(i, j);
  3299.             reverse(ii, last);
  3300.             return true;
  3301.         }
  3302.         if (i == first)
  3303.         {
  3304.             reverse(first, last);
  3305.             return false;
  3306.         }
  3307.     }
  3308. }
  3309.  
  3310. #ifndef RWSTD_NO_NAMESPACE
  3311. }
  3312. #endif
  3313.  
  3314. #endif /*__STD_ALGORITHM*/
  3315.  
  3316.