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