00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #ifndef __SGI_STL_INTERNAL_ALGO_H
00032 #define __SGI_STL_INTERNAL_ALGO_H
00033
00034 #include <stl_heap.h>
00035
00036
00037
00038
00039
00040 __STL_BEGIN_NAMESPACE
00041
00042 #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
00043 #pragma set woff 1209
00044 #endif
00045
00046
00047
00048 template <class _Tp>
00049 inline const _Tp& __median(const _Tp& __a, const _Tp& __b, const _Tp& __c) {
00050 __STL_REQUIRES(_Tp, _LessThanComparable);
00051 if (__a < __b)
00052 if (__b < __c)
00053 return __b;
00054 else if (__a < __c)
00055 return __c;
00056 else
00057 return __a;
00058 else if (__a < __c)
00059 return __a;
00060 else if (__b < __c)
00061 return __c;
00062 else
00063 return __b;
00064 }
00065
00066 template <class _Tp, class _Compare>
00067 inline const _Tp&
00068 __median(const _Tp& __a, const _Tp& __b, const _Tp& __c, _Compare __comp) {
00069 __STL_BINARY_FUNCTION_CHECK(_Compare, bool, _Tp, _Tp);
00070 if (__comp(__a, __b))
00071 if (__comp(__b, __c))
00072 return __b;
00073 else if (__comp(__a, __c))
00074 return __c;
00075 else
00076 return __a;
00077 else if (__comp(__a, __c))
00078 return __a;
00079 else if (__comp(__b, __c))
00080 return __c;
00081 else
00082 return __b;
00083 }
00084
00085
00086 template <class _InputIter, class _Function>
00087 _Function for_each(_InputIter __first, _InputIter __last, _Function __f) {
00088 __STL_REQUIRES(_InputIter, _InputIterator);
00089 for ( ; __first != __last; ++__first)
00090 __f(*__first);
00091 return __f;
00092 }
00093
00094
00095
00096 template <class _InputIter, class _Tp>
00097 inline _InputIter find(_InputIter __first, _InputIter __last,
00098 const _Tp& __val,
00099 input_iterator_tag)
00100 {
00101 while (__first != __last && !(*__first == __val))
00102 ++__first;
00103 return __first;
00104 }
00105
00106 template <class _InputIter, class _Predicate>
00107 inline _InputIter find_if(_InputIter __first, _InputIter __last,
00108 _Predicate __pred,
00109 input_iterator_tag)
00110 {
00111 while (__first != __last && !__pred(*__first))
00112 ++__first;
00113 return __first;
00114 }
00115
00116 #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
00117
00118 template <class _RandomAccessIter, class _Tp>
00119 _RandomAccessIter find(_RandomAccessIter __first, _RandomAccessIter __last,
00120 const _Tp& __val,
00121 random_access_iterator_tag)
00122 {
00123 typename iterator_traits<_RandomAccessIter>::difference_type __trip_count
00124 = (__last - __first) >> 2;
00125
00126 for ( ; __trip_count > 0 ; --__trip_count) {
00127 if (*__first == __val) return __first;
00128 ++__first;
00129
00130 if (*__first == __val) return __first;
00131 ++__first;
00132
00133 if (*__first == __val) return __first;
00134 ++__first;
00135
00136 if (*__first == __val) return __first;
00137 ++__first;
00138 }
00139
00140 switch(__last - __first) {
00141 case 3:
00142 if (*__first == __val) return __first;
00143 ++__first;
00144 case 2:
00145 if (*__first == __val) return __first;
00146 ++__first;
00147 case 1:
00148 if (*__first == __val) return __first;
00149 ++__first;
00150 case 0:
00151 default:
00152 return __last;
00153 }
00154 }
00155
00156 template <class _RandomAccessIter, class _Predicate>
00157 _RandomAccessIter find_if(_RandomAccessIter __first, _RandomAccessIter __last,
00158 _Predicate __pred,
00159 random_access_iterator_tag)
00160 {
00161 typename iterator_traits<_RandomAccessIter>::difference_type __trip_count
00162 = (__last - __first) >> 2;
00163
00164 for ( ; __trip_count > 0 ; --__trip_count) {
00165 if (__pred(*__first)) return __first;
00166 ++__first;
00167
00168 if (__pred(*__first)) return __first;
00169 ++__first;
00170
00171 if (__pred(*__first)) return __first;
00172 ++__first;
00173
00174 if (__pred(*__first)) return __first;
00175 ++__first;
00176 }
00177
00178 switch(__last - __first) {
00179 case 3:
00180 if (__pred(*__first)) return __first;
00181 ++__first;
00182 case 2:
00183 if (__pred(*__first)) return __first;
00184 ++__first;
00185 case 1:
00186 if (__pred(*__first)) return __first;
00187 ++__first;
00188 case 0:
00189 default:
00190 return __last;
00191 }
00192 }
00193
00194 #endif
00195
00196 template <class _InputIter, class _Tp>
00197 inline _InputIter find(_InputIter __first, _InputIter __last,
00198 const _Tp& __val)
00199 {
00200 __STL_REQUIRES(_InputIter, _InputIterator);
00201 __STL_REQUIRES_BINARY_OP(_OP_EQUAL, bool,
00202 typename iterator_traits<_InputIter>::value_type, _Tp);
00203 return find(__first, __last, __val, __ITERATOR_CATEGORY(__first));
00204 }
00205
00206 template <class _InputIter, class _Predicate>
00207 inline _InputIter find_if(_InputIter __first, _InputIter __last,
00208 _Predicate __pred) {
00209 __STL_REQUIRES(_InputIter, _InputIterator);
00210 __STL_UNARY_FUNCTION_CHECK(_Predicate, bool,
00211 typename iterator_traits<_InputIter>::value_type);
00212 return find_if(__first, __last, __pred, __ITERATOR_CATEGORY(__first));
00213 }
00214
00215
00216
00217 template <class _ForwardIter>
00218 _ForwardIter adjacent_find(_ForwardIter __first, _ForwardIter __last) {
00219 __STL_REQUIRES(_ForwardIter, _ForwardIterator);
00220 __STL_REQUIRES(typename iterator_traits<_ForwardIter>::value_type,
00221 _EqualityComparable);
00222 if (__first == __last)
00223 return __last;
00224 _ForwardIter __next = __first;
00225 while(++__next != __last) {
00226 if (*__first == *__next)
00227 return __first;
00228 __first = __next;
00229 }
00230 return __last;
00231 }
00232
00233 template <class _ForwardIter, class _BinaryPredicate>
00234 _ForwardIter adjacent_find(_ForwardIter __first, _ForwardIter __last,
00235 _BinaryPredicate __binary_pred) {
00236 __STL_REQUIRES(_ForwardIter, _ForwardIterator);
00237 __STL_BINARY_FUNCTION_CHECK(_BinaryPredicate, bool,
00238 typename iterator_traits<_ForwardIter>::value_type,
00239 typename iterator_traits<_ForwardIter>::value_type);
00240 if (__first == __last)
00241 return __last;
00242 _ForwardIter __next = __first;
00243 while(++__next != __last) {
00244 if (__binary_pred(*__first, *__next))
00245 return __first;
00246 __first = __next;
00247 }
00248 return __last;
00249 }
00250
00251
00252
00253
00254
00255
00256
00257 template <class _InputIter, class _Tp, class _Size>
00258 void count(_InputIter __first, _InputIter __last, const _Tp& __value,
00259 _Size& __n) {
00260 __STL_REQUIRES(_InputIter, _InputIterator);
00261 __STL_REQUIRES(typename iterator_traits<_InputIter>::value_type,
00262 _EqualityComparable);
00263 __STL_REQUIRES(_Tp, _EqualityComparable);
00264 for ( ; __first != __last; ++__first)
00265 if (*__first == __value)
00266 ++__n;
00267 }
00268
00269 template <class _InputIter, class _Predicate, class _Size>
00270 void count_if(_InputIter __first, _InputIter __last, _Predicate __pred,
00271 _Size& __n) {
00272 __STL_REQUIRES(_InputIter, _InputIterator);
00273 __STL_UNARY_FUNCTION_CHECK(_Predicate, bool,
00274 typename iterator_traits<_InputIter>::value_type);
00275 for ( ; __first != __last; ++__first)
00276 if (__pred(*__first))
00277 ++__n;
00278 }
00279
00280 #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
00281
00282 template <class _InputIter, class _Tp>
00283 typename iterator_traits<_InputIter>::difference_type
00284 count(_InputIter __first, _InputIter __last, const _Tp& __value) {
00285 __STL_REQUIRES(_InputIter, _InputIterator);
00286 __STL_REQUIRES(typename iterator_traits<_InputIter>::value_type,
00287 _EqualityComparable);
00288 __STL_REQUIRES(_Tp, _EqualityComparable);
00289 typename iterator_traits<_InputIter>::difference_type __n = 0;
00290 for ( ; __first != __last; ++__first)
00291 if (*__first == __value)
00292 ++__n;
00293 return __n;
00294 }
00295
00296 template <class _InputIter, class _Predicate>
00297 typename iterator_traits<_InputIter>::difference_type
00298 count_if(_InputIter __first, _InputIter __last, _Predicate __pred) {
00299 __STL_REQUIRES(_InputIter, _InputIterator);
00300 __STL_UNARY_FUNCTION_CHECK(_Predicate, bool,
00301 typename iterator_traits<_InputIter>::value_type);
00302 typename iterator_traits<_InputIter>::difference_type __n = 0;
00303 for ( ; __first != __last; ++__first)
00304 if (__pred(*__first))
00305 ++__n;
00306 return __n;
00307 }
00308
00309
00310 #endif
00311
00312
00313
00314 template <class _ForwardIter1, class _ForwardIter2>
00315 _ForwardIter1 search(_ForwardIter1 __first1, _ForwardIter1 __last1,
00316 _ForwardIter2 __first2, _ForwardIter2 __last2)
00317 {
00318 __STL_REQUIRES(_ForwardIter1, _ForwardIterator);
00319 __STL_REQUIRES(_ForwardIter2, _ForwardIterator);
00320 __STL_REQUIRES_BINARY_OP(_OP_EQUAL, bool,
00321 typename iterator_traits<_ForwardIter1>::value_type,
00322 typename iterator_traits<_ForwardIter2>::value_type);
00323
00324
00325 if (__first1 == __last1 || __first2 == __last2)
00326 return __first1;
00327
00328
00329 _ForwardIter2 __tmp(__first2);
00330 ++__tmp;
00331 if (__tmp == __last2)
00332 return find(__first1, __last1, *__first2);
00333
00334
00335
00336 _ForwardIter2 __p1, __p;
00337
00338 __p1 = __first2; ++__p1;
00339
00340 _ForwardIter1 __current = __first1;
00341
00342 while (__first1 != __last1) {
00343 __first1 = find(__first1, __last1, *__first2);
00344 if (__first1 == __last1)
00345 return __last1;
00346
00347 __p = __p1;
00348 __current = __first1;
00349 if (++__current == __last1)
00350 return __last1;
00351
00352 while (*__current == *__p) {
00353 if (++__p == __last2)
00354 return __first1;
00355 if (++__current == __last1)
00356 return __last1;
00357 }
00358
00359 ++__first1;
00360 }
00361 return __first1;
00362 }
00363
00364 template <class _ForwardIter1, class _ForwardIter2, class _BinaryPred>
00365 _ForwardIter1 search(_ForwardIter1 __first1, _ForwardIter1 __last1,
00366 _ForwardIter2 __first2, _ForwardIter2 __last2,
00367 _BinaryPred __predicate)
00368 {
00369 __STL_REQUIRES(_ForwardIter1, _ForwardIterator);
00370 __STL_REQUIRES(_ForwardIter2, _ForwardIterator);
00371 __STL_BINARY_FUNCTION_CHECK(_BinaryPred, bool,
00372 typename iterator_traits<_ForwardIter1>::value_type,
00373 typename iterator_traits<_ForwardIter2>::value_type);
00374
00375
00376 if (__first1 == __last1 || __first2 == __last2)
00377 return __first1;
00378
00379
00380 _ForwardIter2 __tmp(__first2);
00381 ++__tmp;
00382 if (__tmp == __last2) {
00383 while (__first1 != __last1 && !__predicate(*__first1, *__first2))
00384 ++__first1;
00385 return __first1;
00386 }
00387
00388
00389
00390 _ForwardIter2 __p1, __p;
00391
00392 __p1 = __first2; ++__p1;
00393
00394 _ForwardIter1 __current = __first1;
00395
00396 while (__first1 != __last1) {
00397 while (__first1 != __last1) {
00398 if (__predicate(*__first1, *__first2))
00399 break;
00400 ++__first1;
00401 }
00402 while (__first1 != __last1 && !__predicate(*__first1, *__first2))
00403 ++__first1;
00404 if (__first1 == __last1)
00405 return __last1;
00406
00407 __p = __p1;
00408 __current = __first1;
00409 if (++__current == __last1) return __last1;
00410
00411 while (__predicate(*__current, *__p)) {
00412 if (++__p == __last2)
00413 return __first1;
00414 if (++__current == __last1)
00415 return __last1;
00416 }
00417
00418 ++__first1;
00419 }
00420 return __first1;
00421 }
00422
00423
00424
00425 template <class _ForwardIter, class _Integer, class _Tp>
00426 _ForwardIter search_n(_ForwardIter __first, _ForwardIter __last,
00427 _Integer __count, const _Tp& __val) {
00428 __STL_REQUIRES(_ForwardIter, _ForwardIterator);
00429 __STL_REQUIRES(typename iterator_traits<_ForwardIter>::value_type,
00430 _EqualityComparable);
00431 __STL_REQUIRES(_Tp, _EqualityComparable);
00432
00433 if (__count <= 0)
00434 return __first;
00435 else {
00436 __first = find(__first, __last, __val);
00437 while (__first != __last) {
00438 _Integer __n = __count - 1;
00439 _ForwardIter __i = __first;
00440 ++__i;
00441 while (__i != __last && __n != 0 && *__i == __val) {
00442 ++__i;
00443 --__n;
00444 }
00445 if (__n == 0)
00446 return __first;
00447 else
00448 __first = find(__i, __last, __val);
00449 }
00450 return __last;
00451 }
00452 }
00453
00454 template <class _ForwardIter, class _Integer, class _Tp, class _BinaryPred>
00455 _ForwardIter search_n(_ForwardIter __first, _ForwardIter __last,
00456 _Integer __count, const _Tp& __val,
00457 _BinaryPred __binary_pred) {
00458 __STL_REQUIRES(_ForwardIter, _ForwardIterator);
00459 __STL_BINARY_FUNCTION_CHECK(_BinaryPred, bool,
00460 typename iterator_traits<_ForwardIter>::value_type, _Tp);
00461 if (__count <= 0)
00462 return __first;
00463 else {
00464 while (__first != __last) {
00465 if (__binary_pred(*__first, __val))
00466 break;
00467 ++__first;
00468 }
00469 while (__first != __last) {
00470 _Integer __n = __count - 1;
00471 _ForwardIter __i = __first;
00472 ++__i;
00473 while (__i != __last && __n != 0 && __binary_pred(*__i, __val)) {
00474 ++__i;
00475 --__n;
00476 }
00477 if (__n == 0)
00478 return __first;
00479 else {
00480 while (__i != __last) {
00481 if (__binary_pred(*__i, __val))
00482 break;
00483 ++__i;
00484 }
00485 __first = __i;
00486 }
00487 }
00488 return __last;
00489 }
00490 }
00491
00492
00493
00494 template <class _ForwardIter1, class _ForwardIter2>
00495 _ForwardIter2 swap_ranges(_ForwardIter1 __first1, _ForwardIter1 __last1,
00496 _ForwardIter2 __first2) {
00497 __STL_REQUIRES(_ForwardIter1, _Mutable_ForwardIterator);
00498 __STL_REQUIRES(_ForwardIter2, _Mutable_ForwardIterator);
00499 __STL_CONVERTIBLE(typename iterator_traits<_ForwardIter1>::value_type,
00500 typename iterator_traits<_ForwardIter2>::value_type);
00501 __STL_CONVERTIBLE(typename iterator_traits<_ForwardIter2>::value_type,
00502 typename iterator_traits<_ForwardIter1>::value_type);
00503 for ( ; __first1 != __last1; ++__first1, ++__first2)
00504 iter_swap(__first1, __first2);
00505 return __first2;
00506 }
00507
00508
00509
00510 template <class _InputIter, class _OutputIter, class _UnaryOperation>
00511 _OutputIter transform(_InputIter __first, _InputIter __last,
00512 _OutputIter __result, _UnaryOperation __opr) {
00513 __STL_REQUIRES(_InputIter, _InputIterator);
00514 __STL_REQUIRES(_OutputIter, _OutputIterator);
00515
00516 for ( ; __first != __last; ++__first, ++__result)
00517 *__result = __opr(*__first);
00518 return __result;
00519 }
00520
00521 template <class _InputIter1, class _InputIter2, class _OutputIter,
00522 class _BinaryOperation>
00523 _OutputIter transform(_InputIter1 __first1, _InputIter1 __last1,
00524 _InputIter2 __first2, _OutputIter __result,
00525 _BinaryOperation __binary_op) {
00526 __STL_REQUIRES(_InputIter1, _InputIterator);
00527 __STL_REQUIRES(_InputIter2, _InputIterator);
00528 __STL_REQUIRES(_OutputIter, _OutputIterator);
00529 for ( ; __first1 != __last1; ++__first1, ++__first2, ++__result)
00530 *__result = __binary_op(*__first1, *__first2);
00531 return __result;
00532 }
00533
00534
00535
00536 template <class _ForwardIter, class _Tp>
00537 void replace(_ForwardIter __first, _ForwardIter __last,
00538 const _Tp& __old_value, const _Tp& __new_value) {
00539 __STL_REQUIRES(_ForwardIter, _Mutable_ForwardIterator);
00540 __STL_REQUIRES_BINARY_OP(_OP_EQUAL, bool,
00541 typename iterator_traits<_ForwardIter>::value_type, _Tp);
00542 __STL_CONVERTIBLE(_Tp, typename iterator_traits<_ForwardIter>::value_type);
00543 for ( ; __first != __last; ++__first)
00544 if (*__first == __old_value)
00545 *__first = __new_value;
00546 }
00547
00548 template <class _ForwardIter, class _Predicate, class _Tp>
00549 void replace_if(_ForwardIter __first, _ForwardIter __last,
00550 _Predicate __pred, const _Tp& __new_value) {
00551 __STL_REQUIRES(_ForwardIter, _Mutable_ForwardIterator);
00552 __STL_CONVERTIBLE(_Tp, typename iterator_traits<_ForwardIter>::value_type);
00553 __STL_UNARY_FUNCTION_CHECK(_Predicate, bool,
00554 typename iterator_traits<_ForwardIter>::value_type);
00555 for ( ; __first != __last; ++__first)
00556 if (__pred(*__first))
00557 *__first = __new_value;
00558 }
00559
00560 template <class _InputIter, class _OutputIter, class _Tp>
00561 _OutputIter replace_copy(_InputIter __first, _InputIter __last,
00562 _OutputIter __result,
00563 const _Tp& __old_value, const _Tp& __new_value) {
00564 __STL_REQUIRES(_InputIter, _InputIterator);
00565 __STL_REQUIRES(_OutputIter, _OutputIterator);
00566 __STL_REQUIRES_BINARY_OP(_OP_EQUAL, bool,
00567 typename iterator_traits<_InputIter>::value_type, _Tp);
00568 for ( ; __first != __last; ++__first, ++__result)
00569 *__result = *__first == __old_value ? __new_value : *__first;
00570 return __result;
00571 }
00572
00573 template <class _InputIter, class _OutputIter, class _Predicate, class _Tp>
00574 _OutputIter replace_copy_if(_InputIter __first, _InputIter __last,
00575 _OutputIter __result,
00576 _Predicate __pred, const _Tp& __new_value) {
00577 __STL_REQUIRES(_InputIter, _InputIterator);
00578 __STL_REQUIRES(_OutputIter, _OutputIterator);
00579 __STL_UNARY_FUNCTION_CHECK(_Predicate, bool,
00580 typename iterator_traits<_InputIter>::value_type);
00581 for ( ; __first != __last; ++__first, ++__result)
00582 *__result = __pred(*__first) ? __new_value : *__first;
00583 return __result;
00584 }
00585
00586
00587
00588 template <class _ForwardIter, class _Generator>
00589 void generate(_ForwardIter __first, _ForwardIter __last, _Generator __gen) {
00590 __STL_REQUIRES(_ForwardIter, _ForwardIterator);
00591 __STL_GENERATOR_CHECK(_Generator,
00592 typename iterator_traits<_ForwardIter>::value_type);
00593 for ( ; __first != __last; ++__first)
00594 *__first = __gen();
00595 }
00596
00597 template <class _OutputIter, class _Size, class _Generator>
00598 _OutputIter generate_n(_OutputIter __first, _Size __n, _Generator __gen) {
00599 __STL_REQUIRES(_OutputIter, _OutputIterator);
00600 for ( ; __n > 0; --__n, ++__first)
00601 *__first = __gen();
00602 return __first;
00603 }
00604
00605
00606
00607 template <class _InputIter, class _OutputIter, class _Tp>
00608 _OutputIter remove_copy(_InputIter __first, _InputIter __last,
00609 _OutputIter __result, const _Tp& __value) {
00610 __STL_REQUIRES(_InputIter, _InputIterator);
00611 __STL_REQUIRES(_OutputIter, _OutputIterator);
00612 __STL_REQUIRES_BINARY_OP(_OP_EQUAL, bool,
00613 typename iterator_traits<_InputIter>::value_type, _Tp);
00614 for ( ; __first != __last; ++__first)
00615 if (!(*__first == __value)) {
00616 *__result = *__first;
00617 ++__result;
00618 }
00619 return __result;
00620 }
00621
00622 template <class _InputIter, class _OutputIter, class _Predicate>
00623 _OutputIter remove_copy_if(_InputIter __first, _InputIter __last,
00624 _OutputIter __result, _Predicate __pred) {
00625 __STL_REQUIRES(_InputIter, _InputIterator);
00626 __STL_REQUIRES(_OutputIter, _OutputIterator);
00627 __STL_UNARY_FUNCTION_CHECK(_Predicate, bool,
00628 typename iterator_traits<_InputIter>::value_type);
00629 for ( ; __first != __last; ++__first)
00630 if (!__pred(*__first)) {
00631 *__result = *__first;
00632 ++__result;
00633 }
00634 return __result;
00635 }
00636
00637 template <class _ForwardIter, class _Tp>
00638 _ForwardIter remove(_ForwardIter __first, _ForwardIter __last,
00639 const _Tp& __value) {
00640 __STL_REQUIRES(_ForwardIter, _Mutable_ForwardIterator);
00641 __STL_REQUIRES_BINARY_OP(_OP_EQUAL, bool,
00642 typename iterator_traits<_ForwardIter>::value_type, _Tp);
00643 __STL_CONVERTIBLE(_Tp, typename iterator_traits<_ForwardIter>::value_type);
00644 __first = find(__first, __last, __value);
00645 _ForwardIter __i = __first;
00646 return __first == __last ? __first
00647 : remove_copy(++__i, __last, __first, __value);
00648 }
00649
00650 template <class _ForwardIter, class _Predicate>
00651 _ForwardIter remove_if(_ForwardIter __first, _ForwardIter __last,
00652 _Predicate __pred) {
00653 __STL_REQUIRES(_ForwardIter, _Mutable_ForwardIterator);
00654 __STL_UNARY_FUNCTION_CHECK(_Predicate, bool,
00655 typename iterator_traits<_ForwardIter>::value_type);
00656 __first = find_if(__first, __last, __pred);
00657 _ForwardIter __i = __first;
00658 return __first == __last ? __first
00659 : remove_copy_if(++__i, __last, __first, __pred);
00660 }
00661
00662
00663
00664 template <class _InputIter, class _OutputIter, class _Tp>
00665 _OutputIter __unique_copy(_InputIter __first, _InputIter __last,
00666 _OutputIter __result, _Tp*) {
00667 _Tp __value = *__first;
00668 *__result = __value;
00669 while (++__first != __last)
00670 if (!(__value == *__first)) {
00671 __value = *__first;
00672 *++__result = __value;
00673 }
00674 return ++__result;
00675 }
00676
00677 template <class _InputIter, class _OutputIter>
00678 inline _OutputIter __unique_copy(_InputIter __first, _InputIter __last,
00679 _OutputIter __result,
00680 output_iterator_tag) {
00681 return __unique_copy(__first, __last, __result, __VALUE_TYPE(__first));
00682 }
00683
00684 template <class _InputIter, class _ForwardIter>
00685 _ForwardIter __unique_copy(_InputIter __first, _InputIter __last,
00686 _ForwardIter __result, forward_iterator_tag) {
00687 *__result = *__first;
00688 while (++__first != __last)
00689 if (!(*__result == *__first))
00690 *++__result = *__first;
00691 return ++__result;
00692 }
00693
00694 template <class _InputIter, class _OutputIter>
00695 inline _OutputIter unique_copy(_InputIter __first, _InputIter __last,
00696 _OutputIter __result) {
00697 __STL_REQUIRES(_InputIter, _InputIterator);
00698 __STL_REQUIRES(_OutputIter, _OutputIterator);
00699 __STL_REQUIRES(typename iterator_traits<_InputIter>::value_type,
00700 _EqualityComparable);
00701 if (__first == __last) return __result;
00702 return __unique_copy(__first, __last, __result,
00703 __ITERATOR_CATEGORY(__result));
00704 }
00705
00706 template <class _InputIter, class _OutputIter, class _BinaryPredicate,
00707 class _Tp>
00708 _OutputIter __unique_copy(_InputIter __first, _InputIter __last,
00709 _OutputIter __result,
00710 _BinaryPredicate __binary_pred, _Tp*) {
00711 __STL_BINARY_FUNCTION_CHECK(_BinaryPredicate, bool, _Tp, _Tp);
00712 _Tp __value = *__first;
00713 *__result = __value;
00714 while (++__first != __last)
00715 if (!__binary_pred(__value, *__first)) {
00716 __value = *__first;
00717 *++__result = __value;
00718 }
00719 return ++__result;
00720 }
00721
00722 template <class _InputIter, class _OutputIter, class _BinaryPredicate>
00723 inline _OutputIter __unique_copy(_InputIter __first, _InputIter __last,
00724 _OutputIter __result,
00725 _BinaryPredicate __binary_pred,
00726 output_iterator_tag) {
00727 return __unique_copy(__first, __last, __result, __binary_pred,
00728 __VALUE_TYPE(__first));
00729 }
00730
00731 template <class _InputIter, class _ForwardIter, class _BinaryPredicate>
00732 _ForwardIter __unique_copy(_InputIter __first, _InputIter __last,
00733 _ForwardIter __result,
00734 _BinaryPredicate __binary_pred,
00735 forward_iterator_tag) {
00736 __STL_BINARY_FUNCTION_CHECK(_BinaryPredicate, bool,
00737 typename iterator_traits<_ForwardIter>::value_type,
00738 typename iterator_traits<_InputIter>::value_type);
00739 *__result = *__first;
00740 while (++__first != __last)
00741 if (!__binary_pred(*__result, *__first)) *++__result = *__first;
00742 return ++__result;
00743 }
00744
00745 template <class _InputIter, class _OutputIter, class _BinaryPredicate>
00746 inline _OutputIter unique_copy(_InputIter __first, _InputIter __last,
00747 _OutputIter __result,
00748 _BinaryPredicate __binary_pred) {
00749 __STL_REQUIRES(_InputIter, _InputIterator);
00750 __STL_REQUIRES(_OutputIter, _OutputIterator);
00751 if (__first == __last) return __result;
00752 return __unique_copy(__first, __last, __result, __binary_pred,
00753 __ITERATOR_CATEGORY(__result));
00754 }
00755
00756 template <class _ForwardIter>
00757 _ForwardIter unique(_ForwardIter __first, _ForwardIter __last) {
00758 __STL_REQUIRES(_ForwardIter, _Mutable_ForwardIterator);
00759 __STL_REQUIRES(typename iterator_traits<_ForwardIter>::value_type,
00760 _EqualityComparable);
00761 __first = adjacent_find(__first, __last);
00762 return unique_copy(__first, __last, __first);
00763 }
00764
00765 template <class _ForwardIter, class _BinaryPredicate>
00766 _ForwardIter unique(_ForwardIter __first, _ForwardIter __last,
00767 _BinaryPredicate __binary_pred) {
00768 __STL_REQUIRES(_ForwardIter, _Mutable_ForwardIterator);
00769 __STL_BINARY_FUNCTION_CHECK(_BinaryPredicate, bool,
00770 typename iterator_traits<_ForwardIter>::value_type,
00771 typename iterator_traits<_ForwardIter>::value_type);
00772 __first = adjacent_find(__first, __last, __binary_pred);
00773 return unique_copy(__first, __last, __first, __binary_pred);
00774 }
00775
00776
00777
00778 template <class _BidirectionalIter>
00779 void __reverse(_BidirectionalIter __first, _BidirectionalIter __last,
00780 bidirectional_iterator_tag) {
00781 while (true)
00782 if (__first == __last || __first == --__last)
00783 return;
00784 else
00785 iter_swap(__first++, __last);
00786 }
00787
00788 template <class _RandomAccessIter>
00789 void __reverse(_RandomAccessIter __first, _RandomAccessIter __last,
00790 random_access_iterator_tag) {
00791 while (__first < __last)
00792 iter_swap(__first++, --__last);
00793 }
00794
00795 template <class _BidirectionalIter>
00796 inline void reverse(_BidirectionalIter __first, _BidirectionalIter __last) {
00797 __STL_REQUIRES(_BidirectionalIter, _Mutable_BidirectionalIterator);
00798 __reverse(__first, __last, __ITERATOR_CATEGORY(__first));
00799 }
00800
00801 template <class _BidirectionalIter, class _OutputIter>
00802 _OutputIter reverse_copy(_BidirectionalIter __first,
00803 _BidirectionalIter __last,
00804 _OutputIter __result) {
00805 __STL_REQUIRES(_BidirectionalIter, _BidirectionalIterator);
00806 __STL_REQUIRES(_OutputIter, _OutputIterator);
00807 while (__first != __last) {
00808 --__last;
00809 *__result = *__last;
00810 ++__result;
00811 }
00812 return __result;
00813 }
00814
00815
00816
00817 template <class _EuclideanRingElement>
00818 _EuclideanRingElement __gcd(_EuclideanRingElement __m,
00819 _EuclideanRingElement __n)
00820 {
00821 while (__n != 0) {
00822 _EuclideanRingElement __t = __m % __n;
00823 __m = __n;
00824 __n = __t;
00825 }
00826 return __m;
00827 }
00828
00829 template <class _ForwardIter, class _Distance>
00830 _ForwardIter __rotate(_ForwardIter __first,
00831 _ForwardIter __middle,
00832 _ForwardIter __last,
00833 _Distance*,
00834 forward_iterator_tag) {
00835 if (__first == __middle)
00836 return __last;
00837 if (__last == __middle)
00838 return __first;
00839
00840 _ForwardIter __first2 = __middle;
00841 do {
00842 swap(*__first++, *__first2++);
00843 if (__first == __middle)
00844 __middle = __first2;
00845 } while (__first2 != __last);
00846
00847 _ForwardIter __new_middle = __first;
00848
00849 __first2 = __middle;
00850
00851 while (__first2 != __last) {
00852 swap (*__first++, *__first2++);
00853 if (__first == __middle)
00854 __middle = __first2;
00855 else if (__first2 == __last)
00856 __first2 = __middle;
00857 }
00858
00859 return __new_middle;
00860 }
00861
00862
00863 template <class _BidirectionalIter, class _Distance>
00864 _BidirectionalIter __rotate(_BidirectionalIter __first,
00865 _BidirectionalIter __middle,
00866 _BidirectionalIter __last,
00867 _Distance*,
00868 bidirectional_iterator_tag) {
00869 __STL_REQUIRES(_BidirectionalIter, _Mutable_BidirectionalIterator);
00870 if (__first == __middle)
00871 return __last;
00872 if (__last == __middle)
00873 return __first;
00874
00875 __reverse(__first, __middle, bidirectional_iterator_tag());
00876 __reverse(__middle, __last, bidirectional_iterator_tag());
00877
00878 while (__first != __middle && __middle != __last)
00879 swap (*__first++, *--__last);
00880
00881 if (__first == __middle) {
00882 __reverse(__middle, __last, bidirectional_iterator_tag());
00883 return __last;
00884 }
00885 else {
00886 __reverse(__first, __middle, bidirectional_iterator_tag());
00887 return __first;
00888 }
00889 }
00890
00891 template <class _RandomAccessIter, class _Distance, class _Tp>
00892 _RandomAccessIter __rotate(_RandomAccessIter __first,
00893 _RandomAccessIter __middle,
00894 _RandomAccessIter __last,
00895 _Distance *, _Tp *) {
00896 __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator);
00897 _Distance __n = __last - __first;
00898 _Distance __k = __middle - __first;
00899 _Distance __l = __n - __k;
00900 _RandomAccessIter __result = __first + (__last - __middle);
00901
00902 if (__k == 0)
00903 return __last;
00904
00905 else if (__k == __l) {
00906 swap_ranges(__first, __middle, __middle);
00907 return __result;
00908 }
00909
00910 _Distance __d = __gcd(__n, __k);
00911
00912 for (_Distance __i = 0; __i < __d; __i++) {
00913 _Tp __tmp = *__first;
00914 _RandomAccessIter __p = __first;
00915
00916 if (__k < __l) {
00917 for (_Distance __j = 0; __j < __l/__d; __j++) {
00918 if (__p > __first + __l) {
00919 *__p = *(__p - __l);
00920 __p -= __l;
00921 }
00922
00923 *__p = *(__p + __k);
00924 __p += __k;
00925 }
00926 }
00927
00928 else {
00929 for (_Distance __j = 0; __j < __k/__d - 1; __j ++) {
00930 if (__p < __last - __k) {
00931 *__p = *(__p + __k);
00932 __p += __k;
00933 }
00934
00935 *__p = * (__p - __l);
00936 __p -= __l;
00937 }
00938 }
00939
00940 *__p = __tmp;
00941 ++__first;
00942 }
00943
00944 return __result;
00945 }
00946
00947 template <class _ForwardIter>
00948 inline _ForwardIter rotate(_ForwardIter __first, _ForwardIter __middle,
00949 _ForwardIter __last) {
00950 __STL_REQUIRES(_ForwardIter, _Mutable_ForwardIterator);
00951 return __rotate(__first, __middle, __last,
00952 __DISTANCE_TYPE(__first),
00953 __ITERATOR_CATEGORY(__first));
00954 }
00955
00956 template <class _ForwardIter, class _OutputIter>
00957 _OutputIter rotate_copy(_ForwardIter __first, _ForwardIter __middle,
00958 _ForwardIter __last, _OutputIter __result) {
00959 __STL_REQUIRES(_ForwardIter, _ForwardIterator);
00960 __STL_REQUIRES(_OutputIter, _OutputIterator);
00961 return copy(__first, __middle, copy(__middle, __last, __result));
00962 }
00963
00964
00965
00966
00967
00968 template <class _Distance>
00969 inline _Distance __random_number(_Distance __n) {
00970 #ifdef __STL_NO_DRAND48
00971 return rand() % __n;
00972 #else
00973 return lrand48() % __n;
00974 #endif
00975 }
00976
00977
00978
00979 template <class _RandomAccessIter>
00980 inline void random_shuffle(_RandomAccessIter __first,
00981 _RandomAccessIter __last) {
00982 __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator);
00983 if (__first == __last) return;
00984 for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i)
00985 iter_swap(__i, __first + __random_number((__i - __first) + 1));
00986 }
00987
00988 template <class _RandomAccessIter, class _RandomNumberGenerator>
00989 void random_shuffle(_RandomAccessIter __first, _RandomAccessIter __last,
00990 _RandomNumberGenerator& __rand) {
00991 __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator);
00992 if (__first == __last) return;
00993 for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i)
00994 iter_swap(__i, __first + __rand((__i - __first) + 1));
00995 }
00996
00997
00998
00999 template <class _ForwardIter, class _OutputIter, class _Distance>
01000 _OutputIter random_sample_n(_ForwardIter __first, _ForwardIter __last,
01001 _OutputIter __out, const _Distance __n)
01002 {
01003 __STL_REQUIRES(_ForwardIter, _ForwardIterator);
01004 __STL_REQUIRES(_OutputIter, _OutputIterator);
01005 _Distance __remaining = 0;
01006 distance(__first, __last, __remaining);
01007 _Distance __m = min(__n, __remaining);
01008
01009 while (__m > 0) {
01010 if (__random_number(__remaining) < __m) {
01011 *__out = *__first;
01012 ++__out;
01013 --__m;
01014 }
01015
01016 --__remaining;
01017 ++__first;
01018 }
01019 return __out;
01020 }
01021
01022 template <class _ForwardIter, class _OutputIter, class _Distance,
01023 class _RandomNumberGenerator>
01024 _OutputIter random_sample_n(_ForwardIter __first, _ForwardIter __last,
01025 _OutputIter __out, const _Distance __n,
01026 _RandomNumberGenerator& __rand)
01027 {
01028 __STL_REQUIRES(_ForwardIter, _ForwardIterator);
01029 __STL_REQUIRES(_OutputIter, _OutputIterator);
01030 __STL_UNARY_FUNCTION_CHECK(_RandomNumberGenerator, _Distance, _Distance);
01031 _Distance __remaining = 0;
01032 distance(__first, __last, __remaining);
01033 _Distance __m = min(__n, __remaining);
01034
01035 while (__m > 0) {
01036 if (__rand(__remaining) < __m) {
01037 *__out = *__first;
01038 ++__out;
01039 --__m;
01040 }
01041
01042 --__remaining;
01043 ++__first;
01044 }
01045 return __out;
01046 }
01047
01048 template <class _InputIter, class _RandomAccessIter, class _Distance>
01049 _RandomAccessIter __random_sample(_InputIter __first, _InputIter __last,
01050 _RandomAccessIter __out,
01051 const _Distance __n)
01052 {
01053 _Distance __m = 0;
01054 _Distance __t = __n;
01055 for ( ; __first != __last && __m < __n; ++__m, ++__first)
01056 __out[__m] = *__first;
01057
01058 while (__first != __last) {
01059 ++__t;
01060 _Distance __M = __random_number(__t);
01061 if (__M < __n)
01062 __out[__M] = *__first;
01063 ++__first;
01064 }
01065
01066 return __out + __m;
01067 }
01068
01069 template <class _InputIter, class _RandomAccessIter,
01070 class _RandomNumberGenerator, class _Distance>
01071 _RandomAccessIter __random_sample(_InputIter __first, _InputIter __last,
01072 _RandomAccessIter __out,
01073 _RandomNumberGenerator& __rand,
01074 const _Distance __n)
01075 {
01076 __STL_UNARY_FUNCTION_CHECK(_RandomNumberGenerator, _Distance, _Distance);
01077 _Distance __m = 0;
01078 _Distance __t = __n;
01079 for ( ; __first != __last && __m < __n; ++__m, ++__first)
01080 __out[__m] = *__first;
01081
01082 while (__first != __last) {
01083 ++__t;
01084 _Distance __M = __rand(__t);
01085 if (__M < __n)
01086 __out[__M] = *__first;
01087 ++__first;
01088 }
01089
01090 return __out + __m;
01091 }
01092
01093 template <class _InputIter, class _RandomAccessIter>
01094 inline _RandomAccessIter
01095 random_sample(_InputIter __first, _InputIter __last,
01096 _RandomAccessIter __out_first, _RandomAccessIter __out_last)
01097 {
01098 __STL_REQUIRES(_InputIter, _InputIterator);
01099 __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator);
01100 return __random_sample(__first, __last,
01101 __out_first, __out_last - __out_first);
01102 }
01103
01104
01105 template <class _InputIter, class _RandomAccessIter,
01106 class _RandomNumberGenerator>
01107 inline _RandomAccessIter
01108 random_sample(_InputIter __first, _InputIter __last,
01109 _RandomAccessIter __out_first, _RandomAccessIter __out_last,
01110 _RandomNumberGenerator& __rand)
01111 {
01112 __STL_REQUIRES(_InputIter, _InputIterator);
01113 __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator);
01114 return __random_sample(__first, __last,
01115 __out_first, __rand,
01116 __out_last - __out_first);
01117 }
01118
01119
01120
01121 template <class _ForwardIter, class _Predicate>
01122 _ForwardIter __partition(_ForwardIter __first,
01123 _ForwardIter __last,
01124 _Predicate __pred,
01125 forward_iterator_tag) {
01126 if (__first == __last) return __first;
01127
01128 while (__pred(*__first))
01129 if (++__first == __last) return __first;
01130
01131 _ForwardIter __next = __first;
01132
01133 while (++__next != __last)
01134 if (__pred(*__next)) {
01135 swap(*__first, *__next);
01136 ++__first;
01137 }
01138
01139 return __first;
01140 }
01141
01142 template <class _BidirectionalIter, class _Predicate>
01143 _BidirectionalIter __partition(_BidirectionalIter __first,
01144 _BidirectionalIter __last,
01145 _Predicate __pred,
01146 bidirectional_iterator_tag) {
01147 while (true) {
01148 while (true)
01149 if (__first == __last)
01150 return __first;
01151 else if (__pred(*__first))
01152 ++__first;
01153 else
01154 break;
01155 --__last;
01156 while (true)
01157 if (__first == __last)
01158 return __first;
01159 else if (!__pred(*__last))
01160 --__last;
01161 else
01162 break;
01163 iter_swap(__first, __last);
01164 ++__first;
01165 }
01166 }
01167
01168 template <class _ForwardIter, class _Predicate>
01169 inline _ForwardIter partition(_ForwardIter __first,
01170 _ForwardIter __last,
01171 _Predicate __pred) {
01172 __STL_REQUIRES(_ForwardIter, _Mutable_ForwardIterator);
01173 __STL_UNARY_FUNCTION_CHECK(_Predicate, bool,
01174 typename iterator_traits<_ForwardIter>::value_type);
01175 return __partition(__first, __last, __pred, __ITERATOR_CATEGORY(__first));
01176 }
01177
01178
01179 template <class _ForwardIter, class _Predicate, class _Distance>
01180 _ForwardIter __inplace_stable_partition(_ForwardIter __first,
01181 _ForwardIter __last,
01182 _Predicate __pred, _Distance __len) {
01183 if (__len == 1)
01184 return __pred(*__first) ? __last : __first;
01185 _ForwardIter __middle = __first;
01186 advance(__middle, __len / 2);
01187 return rotate(__inplace_stable_partition(__first, __middle, __pred,
01188 __len / 2),
01189 __middle,
01190 __inplace_stable_partition(__middle, __last, __pred,
01191 __len - __len / 2));
01192 }
01193
01194 template <class _ForwardIter, class _Pointer, class _Predicate,
01195 class _Distance>
01196 _ForwardIter __stable_partition_adaptive(_ForwardIter __first,
01197 _ForwardIter __last,
01198 _Predicate __pred, _Distance __len,
01199 _Pointer __buffer,
01200 _Distance __buffer_size)
01201 {
01202 if (__len <= __buffer_size) {
01203 _ForwardIter __result1 = __first;
01204 _Pointer __result2 = __buffer;
01205 for ( ; __first != __last ; ++__first)
01206 if (__pred(*__first)) {
01207 *__result1 = *__first;
01208 ++__result1;
01209 }
01210 else {
01211 *__result2 = *__first;
01212 ++__result2;
01213 }
01214 copy(__buffer, __result2, __result1);
01215 return __result1;
01216 }
01217 else {
01218 _ForwardIter __middle = __first;
01219 advance(__middle, __len / 2);
01220 return rotate(__stable_partition_adaptive(
01221 __first, __middle, __pred,
01222 __len / 2, __buffer, __buffer_size),
01223 __middle,
01224 __stable_partition_adaptive(
01225 __middle, __last, __pred,
01226 __len - __len / 2, __buffer, __buffer_size));
01227 }
01228 }
01229
01230 template <class _ForwardIter, class _Predicate, class _Tp, class _Distance>
01231 inline _ForwardIter
01232 __stable_partition_aux(_ForwardIter __first, _ForwardIter __last,
01233 _Predicate __pred, _Tp*, _Distance*)
01234 {
01235 _Temporary_buffer<_ForwardIter, _Tp> __buf(__first, __last);
01236 if (__buf.size() > 0)
01237 return __stable_partition_adaptive(__first, __last, __pred,
01238 _Distance(__buf.requested_size()),
01239 __buf.begin(), __buf.size());
01240 else
01241 return __inplace_stable_partition(__first, __last, __pred,
01242 _Distance(__buf.requested_size()));
01243 }
01244
01245 template <class _ForwardIter, class _Predicate>
01246 inline _ForwardIter stable_partition(_ForwardIter __first,
01247 _ForwardIter __last,
01248 _Predicate __pred) {
01249 __STL_REQUIRES(_ForwardIter, _Mutable_ForwardIterator);
01250 __STL_UNARY_FUNCTION_CHECK(_Predicate, bool,
01251 typename iterator_traits<_ForwardIter>::value_type);
01252 if (__first == __last)
01253 return __first;
01254 else
01255 return __stable_partition_aux(__first, __last, __pred,
01256 __VALUE_TYPE(__first),
01257 __DISTANCE_TYPE(__first));
01258 }
01259
01260 template <class _RandomAccessIter, class _Tp>
01261 _RandomAccessIter __unguarded_partition(_RandomAccessIter __first,
01262 _RandomAccessIter __last,
01263 _Tp __pivot)
01264 {
01265 while (true) {
01266 while (*__first < __pivot)
01267 ++__first;
01268 --__last;
01269 while (__pivot < *__last)
01270 --__last;
01271 if (!(__first < __last))
01272 return __first;
01273 iter_swap(__first, __last);
01274 ++__first;
01275 }
01276 }
01277
01278 template <class _RandomAccessIter, class _Tp, class _Compare>
01279 _RandomAccessIter __unguarded_partition(_RandomAccessIter __first,
01280 _RandomAccessIter __last,
01281 _Tp __pivot, _Compare __comp)
01282 {
01283 while (true) {
01284 while (__comp(*__first, __pivot))
01285 ++__first;
01286 --__last;
01287 while (__comp(__pivot, *__last))
01288 --__last;
01289 if (!(__first < __last))
01290 return __first;
01291 iter_swap(__first, __last);
01292 ++__first;
01293 }
01294 }
01295
01296 const int __stl_threshold = 16;
01297
01298
01299
01300 template <class _RandomAccessIter, class _Tp>
01301 void __unguarded_linear_insert(_RandomAccessIter __last, _Tp __val) {
01302 _RandomAccessIter __next = __last;
01303 --__next;
01304 while (__val < *__next) {
01305 *__last = *__next;
01306 __last = __next;
01307 --__next;
01308 }
01309 *__last = __val;
01310 }
01311
01312 template <class _RandomAccessIter, class _Tp, class _Compare>
01313 void __unguarded_linear_insert(_RandomAccessIter __last, _Tp __val,
01314 _Compare __comp) {
01315 _RandomAccessIter __next = __last;
01316 --__next;
01317 while (__comp(__val, *__next)) {
01318 *__last = *__next;
01319 __last = __next;
01320 --__next;
01321 }
01322 *__last = __val;
01323 }
01324
01325 template <class _RandomAccessIter, class _Tp>
01326 inline void __linear_insert(_RandomAccessIter __first,
01327 _RandomAccessIter __last, _Tp*) {
01328 _Tp __val = *__last;
01329 if (__val < *__first) {
01330 copy_backward(__first, __last, __last + 1);
01331 *__first = __val;
01332 }
01333 else
01334 __unguarded_linear_insert(__last, __val);
01335 }
01336
01337 template <class _RandomAccessIter, class _Tp, class _Compare>
01338 inline void __linear_insert(_RandomAccessIter __first,
01339 _RandomAccessIter __last, _Tp*, _Compare __comp) {
01340 _Tp __val = *__last;
01341 if (__comp(__val, *__first)) {
01342 copy_backward(__first, __last, __last + 1);
01343 *__first = __val;
01344 }
01345 else
01346 __unguarded_linear_insert(__last, __val, __comp);
01347 }
01348
01349 template <class _RandomAccessIter>
01350 void __insertion_sort(_RandomAccessIter __first, _RandomAccessIter __last) {
01351 if (__first == __last) return;
01352 for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i)
01353 __linear_insert(__first, __i, __VALUE_TYPE(__first));
01354 }
01355
01356 template <class _RandomAccessIter, class _Compare>
01357 void __insertion_sort(_RandomAccessIter __first,
01358 _RandomAccessIter __last, _Compare __comp) {
01359 if (__first == __last) return;
01360 for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i)
01361 __linear_insert(__first, __i, __VALUE_TYPE(__first), __comp);
01362 }
01363
01364 template <class _RandomAccessIter, class _Tp>
01365 void __unguarded_insertion_sort_aux(_RandomAccessIter __first,
01366 _RandomAccessIter __last, _Tp*) {
01367 for (_RandomAccessIter __i = __first; __i != __last; ++__i)
01368 __unguarded_linear_insert(__i, _Tp(*__i));
01369 }
01370
01371 template <class _RandomAccessIter>
01372 inline void __unguarded_insertion_sort(_RandomAccessIter __first,
01373 _RandomAccessIter __last) {
01374 __unguarded_insertion_sort_aux(__first, __last, __VALUE_TYPE(__first));
01375 }
01376
01377 template <class _RandomAccessIter, class _Tp, class _Compare>
01378 void __unguarded_insertion_sort_aux(_RandomAccessIter __first,
01379 _RandomAccessIter __last,
01380 _Tp*, _Compare __comp) {
01381 for (_RandomAccessIter __i = __first; __i != __last; ++__i)
01382 __unguarded_linear_insert(__i, _Tp(*__i), __comp);
01383 }
01384
01385 template <class _RandomAccessIter, class _Compare>
01386 inline void __unguarded_insertion_sort(_RandomAccessIter __first,
01387 _RandomAccessIter __last,
01388 _Compare __comp) {
01389 __unguarded_insertion_sort_aux(__first, __last, __VALUE_TYPE(__first),
01390 __comp);
01391 }
01392
01393 template <class _RandomAccessIter>
01394 void __final_insertion_sort(_RandomAccessIter __first,
01395 _RandomAccessIter __last) {
01396 if (__last - __first > __stl_threshold) {
01397 __insertion_sort(__first, __first + __stl_threshold);
01398 __unguarded_insertion_sort(__first + __stl_threshold, __last);
01399 }
01400 else
01401 __insertion_sort(__first, __last);
01402 }
01403
01404 template <class _RandomAccessIter, class _Compare>
01405 void __final_insertion_sort(_RandomAccessIter __first,
01406 _RandomAccessIter __last, _Compare __comp) {
01407 if (__last - __first > __stl_threshold) {
01408 __insertion_sort(__first, __first + __stl_threshold, __comp);
01409 __unguarded_insertion_sort(__first + __stl_threshold, __last, __comp);
01410 }
01411 else
01412 __insertion_sort(__first, __last, __comp);
01413 }
01414
01415 template <class _Size>
01416 inline _Size __lg(_Size __n) {
01417 _Size __k;
01418 for (__k = 0; __n != 1; __n >>= 1) ++__k;
01419 return __k;
01420 }
01421
01422 template <class _RandomAccessIter, class _Tp, class _Size>
01423 void __introsort_loop(_RandomAccessIter __first,
01424 _RandomAccessIter __last, _Tp*,
01425 _Size __depth_limit)
01426 {
01427 while (__last - __first > __stl_threshold) {
01428 if (__depth_limit == 0) {
01429 partial_sort(__first, __last, __last);
01430 return;
01431 }
01432 --__depth_limit;
01433 _RandomAccessIter __cut =
01434 __unguarded_partition(__first, __last,
01435 _Tp(__median(*__first,
01436 *(__first + (__last - __first)/2),
01437 *(__last - 1))));
01438 __introsort_loop(__cut, __last, (_Tp*) 0, __depth_limit);
01439 __last = __cut;
01440 }
01441 }
01442
01443 template <class _RandomAccessIter, class _Tp, class _Size, class _Compare>
01444 void __introsort_loop(_RandomAccessIter __first,
01445 _RandomAccessIter __last, _Tp*,
01446 _Size __depth_limit, _Compare __comp)
01447 {
01448 while (__last - __first > __stl_threshold) {
01449 if (__depth_limit == 0) {
01450 partial_sort(__first, __last, __last, __comp);
01451 return;
01452 }
01453 --__depth_limit;
01454 _RandomAccessIter __cut =
01455 __unguarded_partition(__first, __last,
01456 _Tp(__median(*__first,
01457 *(__first + (__last - __first)/2),
01458 *(__last - 1), __comp)),
01459 __comp);
01460 __introsort_loop(__cut, __last, (_Tp*) 0, __depth_limit, __comp);
01461 __last = __cut;
01462 }
01463 }
01464
01465 template <class _RandomAccessIter>
01466 inline void sort(_RandomAccessIter __first, _RandomAccessIter __last) {
01467 __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator);
01468 __STL_REQUIRES(typename iterator_traits<_RandomAccessIter>::value_type,
01469 _LessThanComparable);
01470 if (__first != __last) {
01471 __introsort_loop(__first, __last,
01472 __VALUE_TYPE(__first),
01473 __lg(__last - __first) * 2);
01474 __final_insertion_sort(__first, __last);
01475 }
01476 }
01477
01478 template <class _RandomAccessIter, class _Compare>
01479 inline void sort(_RandomAccessIter __first, _RandomAccessIter __last,
01480 _Compare __comp) {
01481 __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator);
01482 __STL_BINARY_FUNCTION_CHECK(_Compare, bool,
01483 typename iterator_traits<_RandomAccessIter>::value_type,
01484 typename iterator_traits<_RandomAccessIter>::value_type);
01485 if (__first != __last) {
01486 __introsort_loop(__first, __last,
01487 __VALUE_TYPE(__first),
01488 __lg(__last - __first) * 2,
01489 __comp);
01490 __final_insertion_sort(__first, __last, __comp);
01491 }
01492 }
01493
01494
01495
01496 template <class _RandomAccessIter>
01497 void __inplace_stable_sort(_RandomAccessIter __first,
01498 _RandomAccessIter __last) {
01499 if (__last - __first < 15) {
01500 __insertion_sort(__first, __last);
01501 return;
01502 }
01503 _RandomAccessIter __middle = __first + (__last - __first) / 2;
01504 __inplace_stable_sort(__first, __middle);
01505 __inplace_stable_sort(__middle, __last);
01506 __merge_without_buffer(__first, __middle, __last,
01507 __middle - __first,
01508 __last - __middle);
01509 }
01510
01511 template <class _RandomAccessIter, class _Compare>
01512 void __inplace_stable_sort(_RandomAccessIter __first,
01513 _RandomAccessIter __last, _Compare __comp) {
01514 if (__last - __first < 15) {
01515 __insertion_sort(__first, __last, __comp);
01516 return;
01517 }
01518 _RandomAccessIter __middle = __first + (__last - __first) / 2;
01519 __inplace_stable_sort(__first, __middle, __comp);
01520 __inplace_stable_sort(__middle, __last, __comp);
01521 __merge_without_buffer(__first, __middle, __last,
01522 __middle - __first,
01523 __last - __middle,
01524 __comp);
01525 }
01526
01527 template <class _RandomAccessIter1, class _RandomAccessIter2,
01528 class _Distance>
01529 void __merge_sort_loop(_RandomAccessIter1 __first,
01530 _RandomAccessIter1 __last,
01531 _RandomAccessIter2 __result, _Distance __step_size) {
01532 _Distance __two_step = 2 * __step_size;
01533
01534 while (__last - __first >= __two_step) {
01535 __result = merge(__first, __first + __step_size,
01536 __first + __step_size, __first + __two_step,
01537 __result);
01538 __first += __two_step;
01539 }
01540
01541 __step_size = min(_Distance(__last - __first), __step_size);
01542 merge(__first, __first + __step_size, __first + __step_size, __last,
01543 __result);
01544 }
01545
01546 template <class _RandomAccessIter1, class _RandomAccessIter2,
01547 class _Distance, class _Compare>
01548 void __merge_sort_loop(_RandomAccessIter1 __first,
01549 _RandomAccessIter1 __last,
01550 _RandomAccessIter2 __result, _Distance __step_size,
01551 _Compare __comp) {
01552 _Distance __two_step = 2 * __step_size;
01553
01554 while (__last - __first >= __two_step) {
01555 __result = merge(__first, __first + __step_size,
01556 __first + __step_size, __first + __two_step,
01557 __result,
01558 __comp);
01559 __first += __two_step;
01560 }
01561 __step_size = min(_Distance(__last - __first), __step_size);
01562
01563 merge(__first, __first + __step_size,
01564 __first + __step_size, __last,
01565 __result,
01566 __comp);
01567 }
01568
01569 const int __stl_chunk_size = 7;
01570
01571 template <class _RandomAccessIter, class _Distance>
01572 void __chunk_insertion_sort(_RandomAccessIter __first,
01573 _RandomAccessIter __last, _Distance __chunk_size)
01574 {
01575 while (__last - __first >= __chunk_size) {
01576 __insertion_sort(__first, __first + __chunk_size);
01577 __first += __chunk_size;
01578 }
01579 __insertion_sort(__first, __last);
01580 }
01581
01582 template <class _RandomAccessIter, class _Distance, class _Compare>
01583 void __chunk_insertion_sort(_RandomAccessIter __first,
01584 _RandomAccessIter __last,
01585 _Distance __chunk_size, _Compare __comp)
01586 {
01587 while (__last - __first >= __chunk_size) {
01588 __insertion_sort(__first, __first + __chunk_size, __comp);
01589 __first += __chunk_size;
01590 }
01591 __insertion_sort(__first, __last, __comp);
01592 }
01593
01594 template <class _RandomAccessIter, class _Pointer, class _Distance>
01595 void __merge_sort_with_buffer(_RandomAccessIter __first,
01596 _RandomAccessIter __last,
01597 _Pointer __buffer, _Distance*) {
01598 _Distance __len = __last - __first;
01599 _Pointer __buffer_last = __buffer + __len;
01600
01601 _Distance __step_size = __stl_chunk_size;
01602 __chunk_insertion_sort(__first, __last, __step_size);
01603
01604 while (__step_size < __len) {
01605 __merge_sort_loop(__first, __last, __buffer, __step_size);
01606 __step_size *= 2;
01607 __merge_sort_loop(__buffer, __buffer_last, __first, __step_size);
01608 __step_size *= 2;
01609 }
01610 }
01611
01612 template <class _RandomAccessIter, class _Pointer, class _Distance,
01613 class _Compare>
01614 void __merge_sort_with_buffer(_RandomAccessIter __first,
01615 _RandomAccessIter __last, _Pointer __buffer,
01616 _Distance*, _Compare __comp) {
01617 _Distance __len = __last - __first;
01618 _Pointer __buffer_last = __buffer + __len;
01619
01620 _Distance __step_size = __stl_chunk_size;
01621 __chunk_insertion_sort(__first, __last, __step_size, __comp);
01622
01623 while (__step_size < __len) {
01624 __merge_sort_loop(__first, __last, __buffer, __step_size, __comp);
01625 __step_size *= 2;
01626 __merge_sort_loop(__buffer, __buffer_last, __first, __step_size, __comp);
01627 __step_size *= 2;
01628 }
01629 }
01630
01631 template <class _RandomAccessIter, class _Pointer, class _Distance>
01632 void __stable_sort_adaptive(_RandomAccessIter __first,
01633 _RandomAccessIter __last, _Pointer __buffer,
01634 _Distance __buffer_size) {
01635 _Distance __len = (__last - __first + 1) / 2;
01636 _RandomAccessIter __middle = __first + __len;
01637 if (__len > __buffer_size) {
01638 __stable_sort_adaptive(__first, __middle, __buffer, __buffer_size);
01639 __stable_sort_adaptive(__middle, __last, __buffer, __buffer_size);
01640 }
01641 else {
01642 __merge_sort_with_buffer(__first, __middle, __buffer, (_Distance*)0);
01643 __merge_sort_with_buffer(__middle, __last, __buffer, (_Distance*)0);
01644 }
01645 __merge_adaptive(__first, __middle, __last, _Distance(__middle - __first),
01646 _Distance(__last - __middle), __buffer, __buffer_size);
01647 }
01648
01649 template <class _RandomAccessIter, class _Pointer, class _Distance,
01650 class _Compare>
01651 void __stable_sort_adaptive(_RandomAccessIter __first,
01652 _RandomAccessIter __last, _Pointer __buffer,
01653 _Distance __buffer_size, _Compare __comp) {
01654 _Distance __len = (__last - __first + 1) / 2;
01655 _RandomAccessIter __middle = __first + __len;
01656 if (__len > __buffer_size) {
01657 __stable_sort_adaptive(__first, __middle, __buffer, __buffer_size,
01658 __comp);
01659 __stable_sort_adaptive(__middle, __last, __buffer, __buffer_size,
01660 __comp);
01661 }
01662 else {
01663 __merge_sort_with_buffer(__first, __middle, __buffer, (_Distance*)0,
01664 __comp);
01665 __merge_sort_with_buffer(__middle, __last, __buffer, (_Distance*)0,
01666 __comp);
01667 }
01668 __merge_adaptive(__first, __middle, __last, _Distance(__middle - __first),
01669 _Distance(__last - __middle), __buffer, __buffer_size,
01670 __comp);
01671 }
01672
01673 template <class _RandomAccessIter, class _Tp, class _Distance>
01674 inline void __stable_sort_aux(_RandomAccessIter __first,
01675 _RandomAccessIter __last, _Tp*, _Distance*) {
01676 _Temporary_buffer<_RandomAccessIter, _Tp> buf(__first, __last);
01677 if (buf.begin() == 0)
01678 __inplace_stable_sort(__first, __last);
01679 else
01680 __stable_sort_adaptive(__first, __last, buf.begin(),
01681 _Distance(buf.size()));
01682 }
01683
01684 template <class _RandomAccessIter, class _Tp, class _Distance, class _Compare>
01685 inline void __stable_sort_aux(_RandomAccessIter __first,
01686 _RandomAccessIter __last, _Tp*, _Distance*,
01687 _Compare __comp) {
01688 _Temporary_buffer<_RandomAccessIter, _Tp> buf(__first, __last);
01689 if (buf.begin() == 0)
01690 __inplace_stable_sort(__first, __last, __comp);
01691 else
01692 __stable_sort_adaptive(__first, __last, buf.begin(),
01693 _Distance(buf.size()),
01694 __comp);
01695 }
01696
01697 template <class _RandomAccessIter>
01698 inline void stable_sort(_RandomAccessIter __first,
01699 _RandomAccessIter __last) {
01700 __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator);
01701 __STL_REQUIRES(typename iterator_traits<_RandomAccessIter>::value_type,
01702 _LessThanComparable);
01703 __stable_sort_aux(__first, __last,
01704 __VALUE_TYPE(__first),
01705 __DISTANCE_TYPE(__first));
01706 }
01707
01708 template <class _RandomAccessIter, class _Compare>
01709 inline void stable_sort(_RandomAccessIter __first,
01710 _RandomAccessIter __last, _Compare __comp) {
01711 __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator);
01712 __STL_BINARY_FUNCTION_CHECK(_Compare, bool,
01713 typename iterator_traits<_RandomAccessIter>::value_type,
01714 typename iterator_traits<_RandomAccessIter>::value_type);
01715 __stable_sort_aux(__first, __last,
01716 __VALUE_TYPE(__first),
01717 __DISTANCE_TYPE(__first),
01718 __comp);
01719 }
01720
01721
01722
01723 template <class _RandomAccessIter, class _Tp>
01724 void __partial_sort(_RandomAccessIter __first, _RandomAccessIter __middle,
01725 _RandomAccessIter __last, _Tp*) {
01726 make_heap(__first, __middle);
01727 for (_RandomAccessIter __i = __middle; __i < __last; ++__i)
01728 if (*__i < *__first)
01729 __pop_heap(__first, __middle, __i, _Tp(*__i),
01730 __DISTANCE_TYPE(__first));
01731 sort_heap(__first, __middle);
01732 }
01733
01734 template <class _RandomAccessIter>
01735 inline void partial_sort(_RandomAccessIter __first,
01736 _RandomAccessIter __middle,
01737 _RandomAccessIter __last) {
01738 __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator);
01739 __STL_REQUIRES(typename iterator_traits<_RandomAccessIter>::value_type,
01740 _LessThanComparable);
01741 __partial_sort(__first, __middle, __last, __VALUE_TYPE(__first));
01742 }
01743
01744 template <class _RandomAccessIter, class _Tp, class _Compare>
01745 void __partial_sort(_RandomAccessIter __first, _RandomAccessIter __middle,
01746 _RandomAccessIter __last, _Tp*, _Compare __comp) {
01747 make_heap(__first, __middle, __comp);
01748 for (_RandomAccessIter __i = __middle; __i < __last; ++__i)
01749 if (__comp(*__i, *__first))
01750 __pop_heap(__first, __middle, __i, _Tp(*__i), __comp,
01751 __DISTANCE_TYPE(__first));
01752 sort_heap(__first, __middle, __comp);
01753 }
01754
01755 template <class _RandomAccessIter, class _Compare>
01756 inline void partial_sort(_RandomAccessIter __first,
01757 _RandomAccessIter __middle,
01758 _RandomAccessIter __last, _Compare __comp) {
01759 __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator);
01760 __STL_BINARY_FUNCTION_CHECK(_Compare, bool,
01761 typename iterator_traits<_RandomAccessIter>::value_type,
01762 typename iterator_traits<_RandomAccessIter>::value_type);
01763 __partial_sort(__first, __middle, __last, __VALUE_TYPE(__first), __comp);
01764 }
01765
01766 template <class _InputIter, class _RandomAccessIter, class _Distance,
01767 class _Tp>
01768 _RandomAccessIter __partial_sort_copy(_InputIter __first,
01769 _InputIter __last,
01770 _RandomAccessIter __result_first,
01771 _RandomAccessIter __result_last,
01772 _Distance*, _Tp*) {
01773 if (__result_first == __result_last) return __result_last;
01774 _RandomAccessIter __result_real_last = __result_first;
01775 while(__first != __last && __result_real_last != __result_last) {
01776 *__result_real_last = *__first;
01777 ++__result_real_last;
01778 ++__first;
01779 }
01780 make_heap(__result_first, __result_real_last);
01781 while (__first != __last) {
01782 if (*__first < *__result_first)
01783 __adjust_heap(__result_first, _Distance(0),
01784 _Distance(__result_real_last - __result_first),
01785 _Tp(*__first));
01786 ++__first;
01787 }
01788 sort_heap(__result_first, __result_real_last);
01789 return __result_real_last;
01790 }
01791
01792 template <class _InputIter, class _RandomAccessIter>
01793 inline _RandomAccessIter
01794 partial_sort_copy(_InputIter __first, _InputIter __last,
01795 _RandomAccessIter __result_first,
01796 _RandomAccessIter __result_last) {
01797 __STL_REQUIRES(_InputIter, _InputIterator);
01798 __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator);
01799 __STL_CONVERTIBLE(typename iterator_traits<_InputIter>::value_type,
01800 typename iterator_traits<_RandomAccessIter>::value_type);
01801 __STL_REQUIRES(typename iterator_traits<_RandomAccessIter>::value_type,
01802 _LessThanComparable);
01803 __STL_REQUIRES(typename iterator_traits<_InputIter>::value_type,
01804 _LessThanComparable);
01805 return __partial_sort_copy(__first, __last, __result_first, __result_last,
01806 __DISTANCE_TYPE(__result_first),
01807 __VALUE_TYPE(__first));
01808 }
01809
01810 template <class _InputIter, class _RandomAccessIter, class _Compare,
01811 class _Distance, class _Tp>
01812 _RandomAccessIter __partial_sort_copy(_InputIter __first,
01813 _InputIter __last,
01814 _RandomAccessIter __result_first,
01815 _RandomAccessIter __result_last,
01816 _Compare __comp, _Distance*, _Tp*) {
01817 if (__result_first == __result_last) return __result_last;
01818 _RandomAccessIter __result_real_last = __result_first;
01819 while(__first != __last && __result_real_last != __result_last) {
01820 *__result_real_last = *__first;
01821 ++__result_real_last;
01822 ++__first;
01823 }
01824 make_heap(__result_first, __result_real_last, __comp);
01825 while (__first != __last) {
01826 if (__comp(*__first, *__result_first))
01827 __adjust_heap(__result_first, _Distance(0),
01828 _Distance(__result_real_last - __result_first),
01829 _Tp(*__first),
01830 __comp);
01831 ++__first;
01832 }
01833 sort_heap(__result_first, __result_real_last, __comp);
01834 return __result_real_last;
01835 }
01836
01837 template <class _InputIter, class _RandomAccessIter, class _Compare>
01838 inline _RandomAccessIter
01839 partial_sort_copy(_InputIter __first, _InputIter __last,
01840 _RandomAccessIter __result_first,
01841 _RandomAccessIter __result_last, _Compare __comp) {
01842 __STL_REQUIRES(_InputIter, _InputIterator);
01843 __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator);
01844 __STL_CONVERTIBLE(typename iterator_traits<_InputIter>::value_type,
01845 typename iterator_traits<_RandomAccessIter>::value_type);
01846 __STL_BINARY_FUNCTION_CHECK(_Compare, bool,
01847 typename iterator_traits<_RandomAccessIter>::value_type,
01848 typename iterator_traits<_RandomAccessIter>::value_type);
01849 return __partial_sort_copy(__first, __last, __result_first, __result_last,
01850 __comp,
01851 __DISTANCE_TYPE(__result_first),
01852 __VALUE_TYPE(__first));
01853 }
01854
01855
01856
01857 template <class _RandomAccessIter, class _Tp>
01858 void __nth_element(_RandomAccessIter __first, _RandomAccessIter __nth,
01859 _RandomAccessIter __last, _Tp*) {
01860 while (__last - __first > 3) {
01861 _RandomAccessIter __cut =
01862 __unguarded_partition(__first, __last,
01863 _Tp(__median(*__first,
01864 *(__first + (__last - __first)/2),
01865 *(__last - 1))));
01866 if (__cut <= __nth)
01867 __first = __cut;
01868 else
01869 __last = __cut;
01870 }
01871 __insertion_sort(__first, __last);
01872 }
01873
01874 template <class _RandomAccessIter>
01875 inline void nth_element(_RandomAccessIter __first, _RandomAccessIter __nth,
01876 _RandomAccessIter __last) {
01877 __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator);
01878 __STL_REQUIRES(typename iterator_traits<_RandomAccessIter>::value_type,
01879 _LessThanComparable);
01880 __nth_element(__first, __nth, __last, __VALUE_TYPE(__first));
01881 }
01882
01883 template <class _RandomAccessIter, class _Tp, class _Compare>
01884 void __nth_element(_RandomAccessIter __first, _RandomAccessIter __nth,
01885 _RandomAccessIter __last, _Tp*, _Compare __comp) {
01886 while (__last - __first > 3) {
01887 _RandomAccessIter __cut =
01888 __unguarded_partition(__first, __last,
01889 _Tp(__median(*__first,
01890 *(__first + (__last - __first)/2),
01891 *(__last - 1),
01892 __comp)),
01893 __comp);
01894 if (__cut <= __nth)
01895 __first = __cut;
01896 else
01897 __last = __cut;
01898 }
01899 __insertion_sort(__first, __last, __comp);
01900 }
01901
01902 template <class _RandomAccessIter, class _Compare>
01903 inline void nth_element(_RandomAccessIter __first, _RandomAccessIter __nth,
01904 _RandomAccessIter __last, _Compare __comp) {
01905 __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator);
01906 __STL_BINARY_FUNCTION_CHECK(_Compare, bool,
01907 typename iterator_traits<_RandomAccessIter>::value_type,
01908 typename iterator_traits<_RandomAccessIter>::value_type);
01909 __nth_element(__first, __nth, __last, __VALUE_TYPE(__first), __comp);
01910 }
01911
01912
01913
01914
01915 template <class _ForwardIter, class _Tp, class _Distance>
01916 _ForwardIter __lower_bound(_ForwardIter __first, _ForwardIter __last,
01917 const _Tp& __val, _Distance*)
01918 {
01919 _Distance __len = 0;
01920 distance(__first, __last, __len);
01921 _Distance __half;
01922 _ForwardIter __middle;
01923
01924 while (__len > 0) {
01925 __half = __len >> 1;
01926 __middle = __first;
01927 advance(__middle, __half);
01928 if (*__middle < __val) {
01929 __first = __middle;
01930 ++__first;
01931 __len = __len - __half - 1;
01932 }
01933 else
01934 __len = __half;
01935 }
01936 return __first;
01937 }
01938
01939 template <class _ForwardIter, class _Tp>
01940 inline _ForwardIter lower_bound(_ForwardIter __first, _ForwardIter __last,
01941 const _Tp& __val) {
01942 __STL_REQUIRES(_ForwardIter, _ForwardIterator);
01943 __STL_REQUIRES_SAME_TYPE(_Tp,
01944 typename iterator_traits<_ForwardIter>::value_type);
01945 __STL_REQUIRES(_Tp, _LessThanComparable);
01946 return __lower_bound(__first, __last, __val,
01947 __DISTANCE_TYPE(__first));
01948 }
01949
01950 template <class _ForwardIter, class _Tp, class _Compare, class _Distance>
01951 _ForwardIter __lower_bound(_ForwardIter __first, _ForwardIter __last,
01952 const _Tp& __val, _Compare __comp, _Distance*)
01953 {
01954 _Distance __len = 0;
01955 distance(__first, __last, __len);
01956 _Distance __half;
01957 _ForwardIter __middle;
01958
01959 while (__len > 0) {
01960 __half = __len >> 1;
01961 __middle = __first;
01962 advance(__middle, __half);
01963 if (__comp(*__middle, __val)) {
01964 __first = __middle;
01965 ++__first;
01966 __len = __len - __half - 1;
01967 }
01968 else
01969 __len = __half;
01970 }
01971 return __first;
01972 }
01973
01974 template <class _ForwardIter, class _Tp, class _Compare>
01975 inline _ForwardIter lower_bound(_ForwardIter __first, _ForwardIter __last,
01976 const _Tp& __val, _Compare __comp) {
01977 __STL_REQUIRES(_ForwardIter, _ForwardIterator);
01978 __STL_REQUIRES_SAME_TYPE(_Tp,
01979 typename iterator_traits<_ForwardIter>::value_type);
01980 __STL_BINARY_FUNCTION_CHECK(_Compare, bool, _Tp, _Tp);
01981 return __lower_bound(__first, __last, __val, __comp,
01982 __DISTANCE_TYPE(__first));
01983 }
01984
01985 template <class _ForwardIter, class _Tp, class _Distance>
01986 _ForwardIter __upper_bound(_ForwardIter __first, _ForwardIter __last,
01987 const _Tp& __val, _Distance*)
01988 {
01989 _Distance __len = 0;
01990 distance(__first, __last, __len);
01991 _Distance __half;
01992 _ForwardIter __middle;
01993
01994 while (__len > 0) {
01995 __half = __len >> 1;
01996 __middle = __first;
01997 advance(__middle, __half);
01998 if (__val < *__middle)
01999 __len = __half;
02000 else {
02001 __first = __middle;
02002 ++__first;
02003 __len = __len - __half - 1;
02004 }
02005 }
02006 return __first;
02007 }
02008
02009 template <class _ForwardIter, class _Tp>
02010 inline _ForwardIter upper_bound(_ForwardIter __first, _ForwardIter __last,
02011 const _Tp& __val) {
02012 __STL_REQUIRES(_ForwardIter, _ForwardIterator);
02013 __STL_REQUIRES_SAME_TYPE(_Tp,
02014 typename iterator_traits<_ForwardIter>::value_type);
02015 __STL_REQUIRES(_Tp, _LessThanComparable);
02016 return __upper_bound(__first, __last, __val,
02017 __DISTANCE_TYPE(__first));
02018 }
02019
02020 template <class _ForwardIter, class _Tp, class _Compare, class _Distance>
02021 _ForwardIter __upper_bound(_ForwardIter __first, _ForwardIter __last,
02022 const _Tp& __val, _Compare __comp, _Distance*)
02023 {
02024 _Distance __len = 0;
02025 distance(__first, __last, __len);
02026 _Distance __half;
02027 _ForwardIter __middle;
02028
02029 while (__len > 0) {
02030 __half = __len >> 1;
02031 __middle = __first;
02032 advance(__middle, __half);
02033 if (__comp(__val, *__middle))
02034 __len = __half;
02035 else {
02036 __first = __middle;
02037 ++__first;
02038 __len = __len - __half - 1;
02039 }
02040 }
02041 return __first;
02042 }
02043
02044 template <class _ForwardIter, class _Tp, class _Compare>
02045 inline _ForwardIter upper_bound(_ForwardIter __first, _ForwardIter __last,
02046 const _Tp& __val, _Compare __comp) {
02047 __STL_REQUIRES(_ForwardIter, _ForwardIterator);
02048 __STL_REQUIRES_SAME_TYPE(_Tp,
02049 typename iterator_traits<_ForwardIter>::value_type);
02050 __STL_BINARY_FUNCTION_CHECK(_Compare, bool, _Tp, _Tp);
02051 return __upper_bound(__first, __last, __val, __comp,
02052 __DISTANCE_TYPE(__first));
02053 }
02054
02055 template <class _ForwardIter, class _Tp, class _Distance>
02056 pair<_ForwardIter, _ForwardIter>
02057 __equal_range(_ForwardIter __first, _ForwardIter __last, const _Tp& __val,
02058 _Distance*)
02059 {
02060 _Distance __len = 0;
02061 distance(__first, __last, __len);
02062 _Distance __half;
02063 _ForwardIter __middle, __left, __right;
02064
02065 while (__len > 0) {
02066 __half = __len >> 1;
02067 __middle = __first;
02068 advance(__middle, __half);
02069 if (*__middle < __val) {
02070 __first = __middle;
02071 ++__first;
02072 __len = __len - __half - 1;
02073 }
02074 else if (__val < *__middle)
02075 __len = __half;
02076 else {
02077 __left = lower_bound(__first, __middle, __val);
02078 advance(__first, __len);
02079 __right = upper_bound(++__middle, __first, __val);
02080 return pair<_ForwardIter, _ForwardIter>(__left, __right);
02081 }
02082 }
02083 return pair<_ForwardIter, _ForwardIter>(__first, __first);
02084 }
02085
02086 template <class _ForwardIter, class _Tp>
02087 inline pair<_ForwardIter, _ForwardIter>
02088 equal_range(_ForwardIter __first, _ForwardIter __last, const _Tp& __val) {
02089 __STL_REQUIRES(_ForwardIter, _ForwardIterator);
02090 __STL_REQUIRES_SAME_TYPE(_Tp,
02091 typename iterator_traits<_ForwardIter>::value_type);
02092 __STL_REQUIRES(_Tp, _LessThanComparable);
02093 return __equal_range(__first, __last, __val,
02094 __DISTANCE_TYPE(__first));
02095 }
02096
02097 template <class _ForwardIter, class _Tp, class _Compare, class _Distance>
02098 pair<_ForwardIter, _ForwardIter>
02099 __equal_range(_ForwardIter __first, _ForwardIter __last, const _Tp& __val,
02100 _Compare __comp, _Distance*)
02101 {
02102 _Distance __len = 0;
02103 distance(__first, __last, __len);
02104 _Distance __half;
02105 _ForwardIter __middle, __left, __right;
02106
02107 while (__len > 0) {
02108 __half = __len >> 1;
02109 __middle = __first;
02110 advance(__middle, __half);
02111 if (__comp(*__middle, __val)) {
02112 __first = __middle;
02113 ++__first;
02114 __len = __len - __half - 1;
02115 }
02116 else if (__comp(__val, *__middle))
02117 __len = __half;
02118 else {
02119 __left = lower_bound(__first, __middle, __val, __comp);
02120 advance(__first, __len);
02121 __right = upper_bound(++__middle, __first, __val, __comp);
02122 return pair<_ForwardIter, _ForwardIter>(__left, __right);
02123 }
02124 }
02125 return pair<_ForwardIter, _ForwardIter>(__first, __first);
02126 }
02127
02128 template <class _ForwardIter, class _Tp, class _Compare>
02129 inline pair<_ForwardIter, _ForwardIter>
02130 equal_range(_ForwardIter __first, _ForwardIter __last, const _Tp& __val,
02131 _Compare __comp) {
02132 __STL_REQUIRES(_ForwardIter, _ForwardIterator);
02133 __STL_REQUIRES_SAME_TYPE(_Tp,
02134 typename iterator_traits<_ForwardIter>::value_type);
02135 __STL_BINARY_FUNCTION_CHECK(_Compare, bool, _Tp, _Tp);
02136 return __equal_range(__first, __last, __val, __comp,
02137 __DISTANCE_TYPE(__first));
02138 }
02139
02140 template <class _ForwardIter, class _Tp>
02141 bool binary_search(_ForwardIter __first, _ForwardIter __last,
02142 const _Tp& __val) {
02143 __STL_REQUIRES(_ForwardIter, _ForwardIterator);
02144 __STL_REQUIRES_SAME_TYPE(_Tp,
02145 typename iterator_traits<_ForwardIter>::value_type);
02146 __STL_REQUIRES(_Tp, _LessThanComparable);
02147 _ForwardIter __i = lower_bound(__first, __last, __val);
02148 return __i != __last && !(__val < *__i);
02149 }
02150
02151 template <class _ForwardIter, class _Tp, class _Compare>
02152 bool binary_search(_ForwardIter __first, _ForwardIter __last,
02153 const _Tp& __val,
02154 _Compare __comp) {
02155 __STL_REQUIRES(_ForwardIter, _ForwardIterator);
02156 __STL_REQUIRES_SAME_TYPE(_Tp,
02157 typename iterator_traits<_ForwardIter>::value_type);
02158 __STL_BINARY_FUNCTION_CHECK(_Compare, bool, _Tp, _Tp);
02159 _ForwardIter __i = lower_bound(__first, __last, __val, __comp);
02160 return __i != __last && !__comp(__val, *__i);
02161 }
02162
02163
02164
02165 template <class _InputIter1, class _InputIter2, class _OutputIter>
02166 _OutputIter merge(_InputIter1 __first1, _InputIter1 __last1,
02167 _InputIter2 __first2, _InputIter2 __last2,
02168 _OutputIter __result) {
02169 __STL_REQUIRES(_InputIter1, _InputIterator);
02170 __STL_REQUIRES(_InputIter2, _InputIterator);
02171 __STL_REQUIRES(_OutputIter, _OutputIterator);
02172 __STL_REQUIRES_SAME_TYPE(
02173 typename iterator_traits<_InputIter1>::value_type,
02174 typename iterator_traits<_InputIter2>::value_type);
02175 __STL_REQUIRES(typename iterator_traits<_InputIter1>::value_type,
02176 _LessThanComparable);
02177 while (__first1 != __last1 && __first2 != __last2) {
02178 if (*__first2 < *__first1) {
02179 *__result = *__first2;
02180 ++__first2;
02181 }
02182 else {
02183 *__result = *__first1;
02184 ++__first1;
02185 }
02186 ++__result;
02187 }
02188 return copy(__first2, __last2, copy(__first1, __last1, __result));
02189 }
02190
02191 template <class _InputIter1, class _InputIter2, class _OutputIter,
02192 class _Compare>
02193 _OutputIter merge(_InputIter1 __first1, _InputIter1 __last1,
02194 _InputIter2 __first2, _InputIter2 __last2,
02195 _OutputIter __result, _Compare __comp) {
02196 __STL_REQUIRES(_InputIter1, _InputIterator);
02197 __STL_REQUIRES(_InputIter2, _InputIterator);
02198 __STL_REQUIRES_SAME_TYPE(
02199 typename iterator_traits<_InputIter1>::value_type,
02200 typename iterator_traits<_InputIter2>::value_type);
02201 __STL_REQUIRES(_OutputIter, _OutputIterator);
02202 __STL_BINARY_FUNCTION_CHECK(_Compare, bool,
02203 typename iterator_traits<_InputIter1>::value_type,
02204 typename iterator_traits<_InputIter1>::value_type);
02205 while (__first1 != __last1 && __first2 != __last2) {
02206 if (__comp(*__first2, *__first1)) {
02207 *__result = *__first2;
02208 ++__first2;
02209 }
02210 else {
02211 *__result = *__first1;
02212 ++__first1;
02213 }
02214 ++__result;
02215 }
02216 return copy(__first2, __last2, copy(__first1, __last1, __result));
02217 }
02218
02219
02220
02221 template <class _BidirectionalIter, class _Distance>
02222 void __merge_without_buffer(_BidirectionalIter __first,
02223 _BidirectionalIter __middle,
02224 _BidirectionalIter __last,
02225 _Distance __len1, _Distance __len2) {
02226 if (__len1 == 0 || __len2 == 0)
02227 return;
02228 if (__len1 + __len2 == 2) {
02229 if (*__middle < *__first)
02230 iter_swap(__first, __middle);
02231 return;
02232 }
02233 _BidirectionalIter __first_cut = __first;
02234 _BidirectionalIter __second_cut = __middle;
02235 _Distance __len11 = 0;
02236 _Distance __len22 = 0;
02237 if (__len1 > __len2) {
02238 __len11 = __len1 / 2;
02239 advance(__first_cut, __len11);
02240 __second_cut = lower_bound(__middle, __last, *__first_cut);
02241 distance(__middle, __second_cut, __len22);
02242 }
02243 else {
02244 __len22 = __len2 / 2;
02245 advance(__second_cut, __len22);
02246 __first_cut = upper_bound(__first, __middle, *__second_cut);
02247 distance(__first, __first_cut, __len11);
02248 }
02249 _BidirectionalIter __new_middle
02250 = rotate(__first_cut, __middle, __second_cut);
02251 __merge_without_buffer(__first, __first_cut, __new_middle,
02252 __len11, __len22);
02253 __merge_without_buffer(__new_middle, __second_cut, __last, __len1 - __len11,
02254 __len2 - __len22);
02255 }
02256
02257 template <class _BidirectionalIter, class _Distance, class _Compare>
02258 void __merge_without_buffer(_BidirectionalIter __first,
02259 _BidirectionalIter __middle,
02260 _BidirectionalIter __last,
02261 _Distance __len1, _Distance __len2,
02262 _Compare __comp) {
02263 if (__len1 == 0 || __len2 == 0)
02264 return;
02265 if (__len1 + __len2 == 2) {
02266 if (__comp(*__middle, *__first))
02267 iter_swap(__first, __middle);
02268 return;
02269 }
02270 _BidirectionalIter __first_cut = __first;
02271 _BidirectionalIter __second_cut = __middle;
02272 _Distance __len11 = 0;
02273 _Distance __len22 = 0;
02274 if (__len1 > __len2) {
02275 __len11 = __len1 / 2;
02276 advance(__first_cut, __len11);
02277 __second_cut = lower_bound(__middle, __last, *__first_cut, __comp);
02278 distance(__middle, __second_cut, __len22);
02279 }
02280 else {
02281 __len22 = __len2 / 2;
02282 advance(__second_cut, __len22);
02283 __first_cut = upper_bound(__first, __middle, *__second_cut, __comp);
02284 distance(__first, __first_cut, __len11);
02285 }
02286 _BidirectionalIter __new_middle
02287 = rotate(__first_cut, __middle, __second_cut);
02288 __merge_without_buffer(__first, __first_cut, __new_middle, __len11, __len22,
02289 __comp);
02290 __merge_without_buffer(__new_middle, __second_cut, __last, __len1 - __len11,
02291 __len2 - __len22, __comp);
02292 }
02293
02294 template <class _BidirectionalIter1, class _BidirectionalIter2,
02295 class _Distance>
02296 _BidirectionalIter1 __rotate_adaptive(_BidirectionalIter1 __first,
02297 _BidirectionalIter1 __middle,
02298 _BidirectionalIter1 __last,
02299 _Distance __len1, _Distance __len2,
02300 _BidirectionalIter2 __buffer,
02301 _Distance __buffer_size) {
02302 _BidirectionalIter2 __buffer_end;
02303 if (__len1 > __len2 && __len2 <= __buffer_size) {
02304 __buffer_end = copy(__middle, __last, __buffer);
02305 copy_backward(__first, __middle, __last);
02306 return copy(__buffer, __buffer_end, __first);
02307 }
02308 else if (__len1 <= __buffer_size) {
02309 __buffer_end = copy(__first, __middle, __buffer);
02310 copy(__middle, __last, __first);
02311 return copy_backward(__buffer, __buffer_end, __last);
02312 }
02313 else
02314 return rotate(__first, __middle, __last);
02315 }
02316
02317 template <class _BidirectionalIter1, class _BidirectionalIter2,
02318 class _BidirectionalIter3>
02319 _BidirectionalIter3 __merge_backward(_BidirectionalIter1 __first1,
02320 _BidirectionalIter1 __last1,
02321 _BidirectionalIter2 __first2,
02322 _BidirectionalIter2 __last2,
02323 _BidirectionalIter3 __result) {
02324 if (__first1 == __last1)
02325 return copy_backward(__first2, __last2, __result);
02326 if (__first2 == __last2)
02327 return copy_backward(__first1, __last1, __result);
02328 --__last1;
02329 --__last2;
02330 while (true) {
02331 if (*__last2 < *__last1) {
02332 *--__result = *__last1;
02333 if (__first1 == __last1)
02334 return copy_backward(__first2, ++__last2, __result);
02335 --__last1;
02336 }
02337 else {
02338 *--__result = *__last2;
02339 if (__first2 == __last2)
02340 return copy_backward(__first1, ++__last1, __result);
02341 --__last2;
02342 }
02343 }
02344 }
02345
02346 template <class _BidirectionalIter1, class _BidirectionalIter2,
02347 class _BidirectionalIter3, class _Compare>
02348 _BidirectionalIter3 __merge_backward(_BidirectionalIter1 __first1,
02349 _BidirectionalIter1 __last1,
02350 _BidirectionalIter2 __first2,
02351 _BidirectionalIter2 __last2,
02352 _BidirectionalIter3 __result,
02353 _Compare __comp) {
02354 if (__first1 == __last1)
02355 return copy_backward(__first2, __last2, __result);
02356 if (__first2 == __last2)
02357 return copy_backward(__first1, __last1, __result);
02358 --__last1;
02359 --__last2;
02360 while (true) {
02361 if (__comp(*__last2, *__last1)) {
02362 *--__result = *__last1;
02363 if (__first1 == __last1)
02364 return copy_backward(__first2, ++__last2, __result);
02365 --__last1;
02366 }
02367 else {
02368 *--__result = *__last2;
02369 if (__first2 == __last2)
02370 return copy_backward(__first1, ++__last1, __result);
02371 --__last2;
02372 }
02373 }
02374 }
02375
02376 template <class _BidirectionalIter, class _Distance, class _Pointer>
02377 void __merge_adaptive(_BidirectionalIter __first,
02378 _BidirectionalIter __middle,
02379 _BidirectionalIter __last,
02380 _Distance __len1, _Distance __len2,
02381 _Pointer __buffer, _Distance __buffer_size) {
02382 if (__len1 <= __len2 && __len1 <= __buffer_size) {
02383 _Pointer __buffer_end = copy(__first, __middle, __buffer);
02384 merge(__buffer, __buffer_end, __middle, __last, __first);
02385 }
02386 else if (__len2 <= __buffer_size) {
02387 _Pointer __buffer_end = copy(__middle, __last, __buffer);
02388 __merge_backward(__first, __middle, __buffer, __buffer_end, __last);
02389 }
02390 else {
02391 _BidirectionalIter __first_cut = __first;
02392 _BidirectionalIter __second_cut = __middle;
02393 _Distance __len11 = 0;
02394 _Distance __len22 = 0;
02395 if (__len1 > __len2) {
02396 __len11 = __len1 / 2;
02397 advance(__first_cut, __len11);
02398 __second_cut = lower_bound(__middle, __last, *__first_cut);
02399 distance(__middle, __second_cut, __len22);
02400 }
02401 else {
02402 __len22 = __len2 / 2;
02403 advance(__second_cut, __len22);
02404 __first_cut = upper_bound(__first, __middle, *__second_cut);
02405 distance(__first, __first_cut, __len11);
02406 }
02407 _BidirectionalIter __new_middle =
02408 __rotate_adaptive(__first_cut, __middle, __second_cut, __len1 - __len11,
02409 __len22, __buffer, __buffer_size);
02410 __merge_adaptive(__first, __first_cut, __new_middle, __len11,
02411 __len22, __buffer, __buffer_size);
02412 __merge_adaptive(__new_middle, __second_cut, __last, __len1 - __len11,
02413 __len2 - __len22, __buffer, __buffer_size);
02414 }
02415 }
02416
02417 template <class _BidirectionalIter, class _Distance, class _Pointer,
02418 class _Compare>
02419 void __merge_adaptive(_BidirectionalIter __first,
02420 _BidirectionalIter __middle,
02421 _BidirectionalIter __last,
02422 _Distance __len1, _Distance __len2,
02423 _Pointer __buffer, _Distance __buffer_size,
02424 _Compare __comp) {
02425 if (__len1 <= __len2 && __len1 <= __buffer_size) {
02426 _Pointer __buffer_end = copy(__first, __middle, __buffer);
02427 merge(__buffer, __buffer_end, __middle, __last, __first, __comp);
02428 }
02429 else if (__len2 <= __buffer_size) {
02430 _Pointer __buffer_end = copy(__middle, __last, __buffer);
02431 __merge_backward(__first, __middle, __buffer, __buffer_end, __last,
02432 __comp);
02433 }
02434 else {
02435 _BidirectionalIter __first_cut = __first;
02436 _BidirectionalIter __second_cut = __middle;
02437 _Distance __len11 = 0;
02438 _Distance __len22 = 0;
02439 if (__len1 > __len2) {
02440 __len11 = __len1 / 2;
02441 advance(__first_cut, __len11);
02442 __second_cut = lower_bound(__middle, __last, *__first_cut, __comp);
02443 distance(__middle, __second_cut, __len22);
02444 }
02445 else {
02446 __len22 = __len2 / 2;
02447 advance(__second_cut, __len22);
02448 __first_cut = upper_bound(__first, __middle, *__second_cut, __comp);
02449 distance(__first, __first_cut, __len11);
02450 }
02451 _BidirectionalIter __new_middle =
02452 __rotate_adaptive(__first_cut, __middle, __second_cut, __len1 - __len11,
02453 __len22, __buffer, __buffer_size);
02454 __merge_adaptive(__first, __first_cut, __new_middle, __len11,
02455 __len22, __buffer, __buffer_size, __comp);
02456 __merge_adaptive(__new_middle, __second_cut, __last, __len1 - __len11,
02457 __len2 - __len22, __buffer, __buffer_size, __comp);
02458 }
02459 }
02460
02461 template <class _BidirectionalIter, class _Tp, class _Distance>
02462 inline void __inplace_merge_aux(_BidirectionalIter __first,
02463 _BidirectionalIter __middle,
02464 _BidirectionalIter __last, _Tp*, _Distance*) {
02465 _Distance __len1 = 0;
02466 distance(__first, __middle, __len1);
02467 _Distance __len2 = 0;
02468 distance(__middle, __last, __len2);
02469
02470 _Temporary_buffer<_BidirectionalIter, _Tp> __buf(__first, __last);
02471 if (__buf.begin() == 0)
02472 __merge_without_buffer(__first, __middle, __last, __len1, __len2);
02473 else
02474 __merge_adaptive(__first, __middle, __last, __len1, __len2,
02475 __buf.begin(), _Distance(__buf.size()));
02476 }
02477
02478 template <class _BidirectionalIter, class _Tp,
02479 class _Distance, class _Compare>
02480 inline void __inplace_merge_aux(_BidirectionalIter __first,
02481 _BidirectionalIter __middle,
02482 _BidirectionalIter __last, _Tp*, _Distance*,
02483 _Compare __comp) {
02484 _Distance __len1 = 0;
02485 distance(__first, __middle, __len1);
02486 _Distance __len2 = 0;
02487 distance(__middle, __last, __len2);
02488
02489 _Temporary_buffer<_BidirectionalIter, _Tp> __buf(__first, __last);
02490 if (__buf.begin() == 0)
02491 __merge_without_buffer(__first, __middle, __last, __len1, __len2, __comp);
02492 else
02493 __merge_adaptive(__first, __middle, __last, __len1, __len2,
02494 __buf.begin(), _Distance(__buf.size()),
02495 __comp);
02496 }
02497
02498 template <class _BidirectionalIter>
02499 inline void inplace_merge(_BidirectionalIter __first,
02500 _BidirectionalIter __middle,
02501 _BidirectionalIter __last) {
02502 __STL_REQUIRES(_BidirectionalIter, _Mutable_BidirectionalIterator);
02503 __STL_REQUIRES(typename iterator_traits<_BidirectionalIter>::value_type,
02504 _LessThanComparable);
02505 if (__first == __middle || __middle == __last)
02506 return;
02507 __inplace_merge_aux(__first, __middle, __last,
02508 __VALUE_TYPE(__first), __DISTANCE_TYPE(__first));
02509 }
02510
02511 template <class _BidirectionalIter, class _Compare>
02512 inline void inplace_merge(_BidirectionalIter __first,
02513 _BidirectionalIter __middle,
02514 _BidirectionalIter __last, _Compare __comp) {
02515 __STL_REQUIRES(_BidirectionalIter, _Mutable_BidirectionalIterator);
02516 __STL_BINARY_FUNCTION_CHECK(_Compare, bool,
02517 typename iterator_traits<_BidirectionalIter>::value_type,
02518 typename iterator_traits<_BidirectionalIter>::value_type);
02519 if (__first == __middle || __middle == __last)
02520 return;
02521 __inplace_merge_aux(__first, __middle, __last,
02522 __VALUE_TYPE(__first), __DISTANCE_TYPE(__first),
02523 __comp);
02524 }
02525
02526
02527
02528
02529
02530
02531 template <class _InputIter1, class _InputIter2>
02532 bool includes(_InputIter1 __first1, _InputIter1 __last1,
02533 _InputIter2 __first2, _InputIter2 __last2) {
02534 __STL_REQUIRES(_InputIter1, _InputIterator);
02535 __STL_REQUIRES(_InputIter2, _InputIterator);
02536 __STL_REQUIRES_SAME_TYPE(
02537 typename iterator_traits<_InputIter1>::value_type,
02538 typename iterator_traits<_InputIter2>::value_type);
02539 __STL_REQUIRES(typename iterator_traits<_InputIter1>::value_type,
02540 _LessThanComparable);
02541 while (__first1 != __last1 && __first2 != __last2)
02542 if (*__first2 < *__first1)
02543 return false;
02544 else if(*__first1 < *__first2)
02545 ++__first1;
02546 else
02547 ++__first1, ++__first2;
02548
02549 return __first2 == __last2;
02550 }
02551
02552 template <class _InputIter1, class _InputIter2, class _Compare>
02553 bool includes(_InputIter1 __first1, _InputIter1 __last1,
02554 _InputIter2 __first2, _InputIter2 __last2, _Compare __comp) {
02555 __STL_REQUIRES(_InputIter1, _InputIterator);
02556 __STL_REQUIRES(_InputIter2, _InputIterator);
02557 __STL_REQUIRES_SAME_TYPE(
02558 typename iterator_traits<_InputIter1>::value_type,
02559 typename iterator_traits<_InputIter2>::value_type);
02560 __STL_BINARY_FUNCTION_CHECK(_Compare, bool,
02561 typename iterator_traits<_InputIter1>::value_type,
02562 typename iterator_traits<_InputIter2>::value_type);
02563 while (__first1 != __last1 && __first2 != __last2)
02564 if (__comp(*__first2, *__first1))
02565 return false;
02566 else if(__comp(*__first1, *__first2))
02567 ++__first1;
02568 else
02569 ++__first1, ++__first2;
02570
02571 return __first2 == __last2;
02572 }
02573
02574 template <class _InputIter1, class _InputIter2, class _OutputIter>
02575 _OutputIter set_union(_InputIter1 __first1, _InputIter1 __last1,
02576 _InputIter2 __first2, _InputIter2 __last2,
02577 _OutputIter __result) {
02578 __STL_REQUIRES(_InputIter1, _InputIterator);
02579 __STL_REQUIRES(_InputIter2, _InputIterator);
02580 __STL_REQUIRES(_OutputIter, _OutputIterator);
02581 __STL_REQUIRES_SAME_TYPE(
02582 typename iterator_traits<_InputIter1>::value_type,
02583 typename iterator_traits<_InputIter2>::value_type);
02584 __STL_REQUIRES(typename iterator_traits<_InputIter1>::value_type,
02585 _LessThanComparable);
02586 while (__first1 != __last1 && __first2 != __last2) {
02587 if (*__first1 < *__first2) {
02588 *__result = *__first1;
02589 ++__first1;
02590 }
02591 else if (*__first2 < *__first1) {
02592 *__result = *__first2;
02593 ++__first2;
02594 }
02595 else {
02596 *__result = *__first1;
02597 ++__first1;
02598 ++__first2;
02599 }
02600 ++__result;
02601 }
02602 return copy(__first2, __last2, copy(__first1, __last1, __result));
02603 }
02604
02605 template <class _InputIter1, class _InputIter2, class _OutputIter,
02606 class _Compare>
02607 _OutputIter set_union(_InputIter1 __first1, _InputIter1 __last1,
02608 _InputIter2 __first2, _InputIter2 __last2,
02609 _OutputIter __result, _Compare __comp) {
02610 __STL_REQUIRES(_InputIter1, _InputIterator);
02611 __STL_REQUIRES(_InputIter2, _InputIterator);
02612 __STL_REQUIRES(_OutputIter, _OutputIterator);
02613 __STL_REQUIRES_SAME_TYPE(
02614 typename iterator_traits<_InputIter1>::value_type,
02615 typename iterator_traits<_InputIter2>::value_type);
02616 __STL_BINARY_FUNCTION_CHECK(_Compare, bool,
02617 typename iterator_traits<_InputIter1>::value_type,
02618 typename iterator_traits<_InputIter2>::value_type);
02619 while (__first1 != __last1 && __first2 != __last2) {
02620 if (__comp(*__first1, *__first2)) {
02621 *__result = *__first1;
02622 ++__first1;
02623 }
02624 else if (__comp(*__first2, *__first1)) {
02625 *__result = *__first2;
02626 ++__first2;
02627 }
02628 else {
02629 *__result = *__first1;
02630 ++__first1;
02631 ++__first2;
02632 }
02633 ++__result;
02634 }
02635 return copy(__first2, __last2, copy(__first1, __last1, __result));
02636 }
02637
02638 template <class _InputIter1, class _InputIter2, class _OutputIter>
02639 _OutputIter set_intersection(_InputIter1 __first1, _InputIter1 __last1,
02640 _InputIter2 __first2, _InputIter2 __last2,
02641 _OutputIter __result) {
02642 __STL_REQUIRES(_InputIter1, _InputIterator);
02643 __STL_REQUIRES(_InputIter2, _InputIterator);
02644 __STL_REQUIRES(_OutputIter, _OutputIterator);
02645 __STL_REQUIRES_SAME_TYPE(
02646 typename iterator_traits<_InputIter1>::value_type,
02647 typename iterator_traits<_InputIter2>::value_type);
02648 __STL_REQUIRES(typename iterator_traits<_InputIter1>::value_type,
02649 _LessThanComparable);
02650 while (__first1 != __last1 && __first2 != __last2)
02651 if (*__first1 < *__first2)
02652 ++__first1;
02653 else if (*__first2 < *__first1)
02654 ++__first2;
02655 else {
02656 *__result = *__first1;
02657 ++__first1;
02658 ++__first2;
02659 ++__result;
02660 }
02661 return __result;
02662 }
02663
02664 template <class _InputIter1, class _InputIter2, class _OutputIter,
02665 class _Compare>
02666 _OutputIter set_intersection(_InputIter1 __first1, _InputIter1 __last1,
02667 _InputIter2 __first2, _InputIter2 __last2,
02668 _OutputIter __result, _Compare __comp) {
02669 __STL_REQUIRES(_InputIter1, _InputIterator);
02670 __STL_REQUIRES(_InputIter2, _InputIterator);
02671 __STL_REQUIRES(_OutputIter, _OutputIterator);
02672 __STL_REQUIRES_SAME_TYPE(
02673 typename iterator_traits<_InputIter1>::value_type,
02674 typename iterator_traits<_InputIter2>::value_type);
02675 __STL_BINARY_FUNCTION_CHECK(_Compare, bool,
02676 typename iterator_traits<_InputIter1>::value_type,
02677 typename iterator_traits<_InputIter2>::value_type);
02678
02679 while (__first1 != __last1 && __first2 != __last2)
02680 if (__comp(*__first1, *__first2))
02681 ++__first1;
02682 else if (__comp(*__first2, *__first1))
02683 ++__first2;
02684 else {
02685 *__result = *__first1;
02686 ++__first1;
02687 ++__first2;
02688 ++__result;
02689 }
02690 return __result;
02691 }
02692
02693 template <class _InputIter1, class _InputIter2, class _OutputIter>
02694 _OutputIter set_difference(_InputIter1 __first1, _InputIter1 __last1,
02695 _InputIter2 __first2, _InputIter2 __last2,
02696 _OutputIter __result) {
02697 __STL_REQUIRES(_InputIter1, _InputIterator);
02698 __STL_REQUIRES(_InputIter2, _InputIterator);
02699 __STL_REQUIRES(_OutputIter, _OutputIterator);
02700 __STL_REQUIRES_SAME_TYPE(
02701 typename iterator_traits<_InputIter1>::value_type,
02702 typename iterator_traits<_InputIter2>::value_type);
02703 __STL_REQUIRES(typename iterator_traits<_InputIter1>::value_type,
02704 _LessThanComparable);
02705 while (__first1 != __last1 && __first2 != __last2)
02706 if (*__first1 < *__first2) {
02707 *__result = *__first1;
02708 ++__first1;
02709 ++__result;
02710 }
02711 else if (*__first2 < *__first1)
02712 ++__first2;
02713 else {
02714 ++__first1;
02715 ++__first2;
02716 }
02717 return copy(__first1, __last1, __result);
02718 }
02719
02720 template <class _InputIter1, class _InputIter2, class _OutputIter,
02721 class _Compare>
02722 _OutputIter set_difference(_InputIter1 __first1, _InputIter1 __last1,
02723 _InputIter2 __first2, _InputIter2 __last2,
02724 _OutputIter __result, _Compare __comp) {
02725 __STL_REQUIRES(_InputIter1, _InputIterator);
02726 __STL_REQUIRES(_InputIter2, _InputIterator);
02727 __STL_REQUIRES(_OutputIter, _OutputIterator);
02728 __STL_REQUIRES_SAME_TYPE(
02729 typename iterator_traits<_InputIter1>::value_type,
02730 typename iterator_traits<_InputIter2>::value_type);
02731 __STL_BINARY_FUNCTION_CHECK(_Compare, bool,
02732 typename iterator_traits<_InputIter1>::value_type,
02733 typename iterator_traits<_InputIter2>::value_type);
02734
02735 while (__first1 != __last1 && __first2 != __last2)
02736 if (__comp(*__first1, *__first2)) {
02737 *__result = *__first1;
02738 ++__first1;
02739 ++__result;
02740 }
02741 else if (__comp(*__first2, *__first1))
02742 ++__first2;
02743 else {
02744 ++__first1;
02745 ++__first2;
02746 }
02747 return copy(__first1, __last1, __result);
02748 }
02749
02750 template <class _InputIter1, class _InputIter2, class _OutputIter>
02751 _OutputIter
02752 set_symmetric_difference(_InputIter1 __first1, _InputIter1 __last1,
02753 _InputIter2 __first2, _InputIter2 __last2,
02754 _OutputIter __result) {
02755 __STL_REQUIRES(_InputIter1, _InputIterator);
02756 __STL_REQUIRES(_InputIter2, _InputIterator);
02757 __STL_REQUIRES(_OutputIter, _OutputIterator);
02758 __STL_REQUIRES_SAME_TYPE(
02759 typename iterator_traits<_InputIter1>::value_type,
02760 typename iterator_traits<_InputIter2>::value_type);
02761 __STL_REQUIRES(typename iterator_traits<_InputIter1>::value_type,
02762 _LessThanComparable);
02763 while (__first1 != __last1 && __first2 != __last2)
02764 if (*__first1 < *__first2) {
02765 *__result = *__first1;
02766 ++__first1;
02767 ++__result;
02768 }
02769 else if (*__first2 < *__first1) {
02770 *__result = *__first2;
02771 ++__first2;
02772 ++__result;
02773 }
02774 else {
02775 ++__first1;
02776 ++__first2;
02777 }
02778 return copy(__first2, __last2, copy(__first1, __last1, __result));
02779 }
02780
02781 template <class _InputIter1, class _InputIter2, class _OutputIter,
02782 class _Compare>
02783 _OutputIter
02784 set_symmetric_difference(_InputIter1 __first1, _InputIter1 __last1,
02785 _InputIter2 __first2, _InputIter2 __last2,
02786 _OutputIter __result,
02787 _Compare __comp) {
02788 __STL_REQUIRES(_InputIter1, _InputIterator);
02789 __STL_REQUIRES(_InputIter2, _InputIterator);
02790 __STL_REQUIRES(_OutputIter, _OutputIterator);
02791 __STL_REQUIRES_SAME_TYPE(
02792 typename iterator_traits<_InputIter1>::value_type,
02793 typename iterator_traits<_InputIter2>::value_type);
02794 __STL_BINARY_FUNCTION_CHECK(_Compare, bool,
02795 typename iterator_traits<_InputIter1>::value_type,
02796 typename iterator_traits<_InputIter2>::value_type);
02797 while (__first1 != __last1 && __first2 != __last2)
02798 if (__comp(*__first1, *__first2)) {
02799 *__result = *__first1;
02800 ++__first1;
02801 ++__result;
02802 }
02803 else if (__comp(*__first2, *__first1)) {
02804 *__result = *__first2;
02805 ++__first2;
02806 ++__result;
02807 }
02808 else {
02809 ++__first1;
02810 ++__first2;
02811 }
02812 return copy(__first2, __last2, copy(__first1, __last1, __result));
02813 }
02814
02815
02816
02817
02818 template <class _ForwardIter>
02819 _ForwardIter max_element(_ForwardIter __first, _ForwardIter __last) {
02820 __STL_REQUIRES(_ForwardIter, _ForwardIterator);
02821 __STL_REQUIRES(typename iterator_traits<_ForwardIter>::value_type,
02822 _LessThanComparable);
02823 if (__first == __last) return __first;
02824 _ForwardIter __result = __first;
02825 while (++__first != __last)
02826 if (*__result < *__first)
02827 __result = __first;
02828 return __result;
02829 }
02830
02831 template <class _ForwardIter, class _Compare>
02832 _ForwardIter max_element(_ForwardIter __first, _ForwardIter __last,
02833 _Compare __comp) {
02834 __STL_REQUIRES(_ForwardIter, _ForwardIterator);
02835 __STL_BINARY_FUNCTION_CHECK(_Compare, bool,
02836 typename iterator_traits<_ForwardIter>::value_type,
02837 typename iterator_traits<_ForwardIter>::value_type);
02838 if (__first == __last) return __first;
02839 _ForwardIter __result = __first;
02840 while (++__first != __last)
02841 if (__comp(*__result, *__first)) __result = __first;
02842 return __result;
02843 }
02844
02845 template <class _ForwardIter>
02846 _ForwardIter min_element(_ForwardIter __first, _ForwardIter __last) {
02847 __STL_REQUIRES(_ForwardIter, _ForwardIterator);
02848 __STL_REQUIRES(typename iterator_traits<_ForwardIter>::value_type,
02849 _LessThanComparable);
02850 if (__first == __last) return __first;
02851 _ForwardIter __result = __first;
02852 while (++__first != __last)
02853 if (*__first < *__result)
02854 __result = __first;
02855 return __result;
02856 }
02857
02858 template <class _ForwardIter, class _Compare>
02859 _ForwardIter min_element(_ForwardIter __first, _ForwardIter __last,
02860 _Compare __comp) {
02861 __STL_REQUIRES(_ForwardIter, _ForwardIterator);
02862 __STL_BINARY_FUNCTION_CHECK(_Compare, bool,
02863 typename iterator_traits<_ForwardIter>::value_type,
02864 typename iterator_traits<_ForwardIter>::value_type);
02865 if (__first == __last) return __first;
02866 _ForwardIter __result = __first;
02867 while (++__first != __last)
02868 if (__comp(*__first, *__result))
02869 __result = __first;
02870 return __result;
02871 }
02872
02873
02874
02875
02876 template <class _BidirectionalIter>
02877 bool next_permutation(_BidirectionalIter __first, _BidirectionalIter __last) {
02878 __STL_REQUIRES(_BidirectionalIter, _BidirectionalIterator);
02879 __STL_REQUIRES(typename iterator_traits<_BidirectionalIter>::value_type,
02880 _LessThanComparable);
02881 if (__first == __last)
02882 return false;
02883 _BidirectionalIter __i = __first;
02884 ++__i;
02885 if (__i == __last)
02886 return false;
02887 __i = __last;
02888 --__i;
02889
02890 for(;;) {
02891 _BidirectionalIter __ii = __i;
02892 --__i;
02893 if (*__i < *__ii) {
02894 _BidirectionalIter __j = __last;
02895 while (!(*__i < *--__j))
02896 {}
02897 iter_swap(__i, __j);
02898 reverse(__ii, __last);
02899 return true;
02900 }
02901 if (__i == __first) {
02902 reverse(__first, __last);
02903 return false;
02904 }
02905 }
02906 }
02907
02908 template <class _BidirectionalIter, class _Compare>
02909 bool next_permutation(_BidirectionalIter __first, _BidirectionalIter __last,
02910 _Compare __comp) {
02911 __STL_REQUIRES(_BidirectionalIter, _BidirectionalIterator);
02912 __STL_BINARY_FUNCTION_CHECK(_Compare, bool,
02913 typename iterator_traits<_BidirectionalIter>::value_type,
02914 typename iterator_traits<_BidirectionalIter>::value_type);
02915 if (__first == __last)
02916 return false;
02917 _BidirectionalIter __i = __first;
02918 ++__i;
02919 if (__i == __last)
02920 return false;
02921 __i = __last;
02922 --__i;
02923
02924 for(;;) {
02925 _BidirectionalIter __ii = __i;
02926 --__i;
02927 if (__comp(*__i, *__ii)) {
02928 _BidirectionalIter __j = __last;
02929 while (!__comp(*__i, *--__j))
02930 {}
02931 iter_swap(__i, __j);
02932 reverse(__ii, __last);
02933 return true;
02934 }
02935 if (__i == __first) {
02936 reverse(__first, __last);
02937 return false;
02938 }
02939 }
02940 }
02941
02942 template <class _BidirectionalIter>
02943 bool prev_permutation(_BidirectionalIter __first, _BidirectionalIter __last) {
02944 __STL_REQUIRES(_BidirectionalIter, _BidirectionalIterator);
02945 __STL_REQUIRES(typename iterator_traits<_BidirectionalIter>::value_type,
02946 _LessThanComparable);
02947 if (__first == __last)
02948 return false;
02949 _BidirectionalIter __i = __first;
02950 ++__i;
02951 if (__i == __last)
02952 return false;
02953 __i = __last;
02954 --__i;
02955
02956 for(;;) {
02957 _BidirectionalIter __ii = __i;
02958 --__i;
02959 if (*__ii < *__i) {
02960 _BidirectionalIter __j = __last;
02961 while (!(*--__j < *__i))
02962 {}
02963 iter_swap(__i, __j);
02964 reverse(__ii, __last);
02965 return true;
02966 }
02967 if (__i == __first) {
02968 reverse(__first, __last);
02969 return false;
02970 }
02971 }
02972 }
02973
02974 template <class _BidirectionalIter, class _Compare>
02975 bool prev_permutation(_BidirectionalIter __first, _BidirectionalIter __last,
02976 _Compare __comp) {
02977 __STL_REQUIRES(_BidirectionalIter, _BidirectionalIterator);
02978 __STL_BINARY_FUNCTION_CHECK(_Compare, bool,
02979 typename iterator_traits<_BidirectionalIter>::value_type,
02980 typename iterator_traits<_BidirectionalIter>::value_type);
02981 if (__first == __last)
02982 return false;
02983 _BidirectionalIter __i = __first;
02984 ++__i;
02985 if (__i == __last)
02986 return false;
02987 __i = __last;
02988 --__i;
02989
02990 for(;;) {
02991 _BidirectionalIter __ii = __i;
02992 --__i;
02993 if (__comp(*__ii, *__i)) {
02994 _BidirectionalIter __j = __last;
02995 while (!__comp(*--__j, *__i))
02996 {}
02997 iter_swap(__i, __j);
02998 reverse(__ii, __last);
02999 return true;
03000 }
03001 if (__i == __first) {
03002 reverse(__first, __last);
03003 return false;
03004 }
03005 }
03006 }
03007
03008
03009
03010 template <class _InputIter, class _ForwardIter>
03011 _InputIter find_first_of(_InputIter __first1, _InputIter __last1,
03012 _ForwardIter __first2, _ForwardIter __last2)
03013 {
03014 __STL_REQUIRES(_InputIter, _InputIterator);
03015 __STL_REQUIRES(_ForwardIter, _ForwardIterator);
03016 __STL_REQUIRES_BINARY_OP(_OP_EQUAL, bool,
03017 typename iterator_traits<_InputIter>::value_type,
03018 typename iterator_traits<_ForwardIter>::value_type);
03019
03020 for ( ; __first1 != __last1; ++__first1)
03021 for (_ForwardIter __iter = __first2; __iter != __last2; ++__iter)
03022 if (*__first1 == *__iter)
03023 return __first1;
03024 return __last1;
03025 }
03026
03027 template <class _InputIter, class _ForwardIter, class _BinaryPredicate>
03028 _InputIter find_first_of(_InputIter __first1, _InputIter __last1,
03029 _ForwardIter __first2, _ForwardIter __last2,
03030 _BinaryPredicate __comp)
03031 {
03032 __STL_REQUIRES(_InputIter, _InputIterator);
03033 __STL_REQUIRES(_ForwardIter, _ForwardIterator);
03034 __STL_BINARY_FUNCTION_CHECK(_BinaryPredicate, bool,
03035 typename iterator_traits<_InputIter>::value_type,
03036 typename iterator_traits<_ForwardIter>::value_type);
03037
03038 for ( ; __first1 != __last1; ++__first1)
03039 for (_ForwardIter __iter = __first2; __iter != __last2; ++__iter)
03040 if (__comp(*__first1, *__iter))
03041 return __first1;
03042 return __last1;
03043 }
03044
03045
03046
03047
03048
03049
03050
03051
03052 template <class _ForwardIter1, class _ForwardIter2>
03053 _ForwardIter1 __find_end(_ForwardIter1 __first1, _ForwardIter1 __last1,
03054 _ForwardIter2 __first2, _ForwardIter2 __last2,
03055 forward_iterator_tag, forward_iterator_tag)
03056 {
03057 if (__first2 == __last2)
03058 return __last1;
03059 else {
03060 _ForwardIter1 __result = __last1;
03061 while (1) {
03062 _ForwardIter1 __new_result
03063 = search(__first1, __last1, __first2, __last2);
03064 if (__new_result == __last1)
03065 return __result;
03066 else {
03067 __result = __new_result;
03068 __first1 = __new_result;
03069 ++__first1;
03070 }
03071 }
03072 }
03073 }
03074
03075 template <class _ForwardIter1, class _ForwardIter2,
03076 class _BinaryPredicate>
03077 _ForwardIter1 __find_end(_ForwardIter1 __first1, _ForwardIter1 __last1,
03078 _ForwardIter2 __first2, _ForwardIter2 __last2,
03079 forward_iterator_tag, forward_iterator_tag,
03080 _BinaryPredicate __comp)
03081 {
03082 if (__first2 == __last2)
03083 return __last1;
03084 else {
03085 _ForwardIter1 __result = __last1;
03086 while (1) {
03087 _ForwardIter1 __new_result
03088 = search(__first1, __last1, __first2, __last2, __comp);
03089 if (__new_result == __last1)
03090 return __result;
03091 else {
03092 __result = __new_result;
03093 __first1 = __new_result;
03094 ++__first1;
03095 }
03096 }
03097 }
03098 }
03099
03100
03101 #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
03102
03103 template <class _BidirectionalIter1, class _BidirectionalIter2>
03104 _BidirectionalIter1
03105 __find_end(_BidirectionalIter1 __first1, _BidirectionalIter1 __last1,
03106 _BidirectionalIter2 __first2, _BidirectionalIter2 __last2,
03107 bidirectional_iterator_tag, bidirectional_iterator_tag)
03108 {
03109 __STL_REQUIRES(_BidirectionalIter1, _BidirectionalIterator);
03110 __STL_REQUIRES(_BidirectionalIter2, _BidirectionalIterator);
03111 typedef reverse_iterator<_BidirectionalIter1> _RevIter1;
03112 typedef reverse_iterator<_BidirectionalIter2> _RevIter2;
03113
03114 _RevIter1 __rlast1(__first1);
03115 _RevIter2 __rlast2(__first2);
03116 _RevIter1 __rresult = search(_RevIter1(__last1), __rlast1,
03117 _RevIter2(__last2), __rlast2);
03118
03119 if (__rresult == __rlast1)
03120 return __last1;
03121 else {
03122 _BidirectionalIter1 __result = __rresult.base();
03123 advance(__result, -distance(__first2, __last2));
03124 return __result;
03125 }
03126 }
03127
03128 template <class _BidirectionalIter1, class _BidirectionalIter2,
03129 class _BinaryPredicate>
03130 _BidirectionalIter1
03131 __find_end(_BidirectionalIter1 __first1, _BidirectionalIter1 __last1,
03132 _BidirectionalIter2 __first2, _BidirectionalIter2 __last2,
03133 bidirectional_iterator_tag, bidirectional_iterator_tag,
03134 _BinaryPredicate __comp)
03135 {
03136 __STL_REQUIRES(_BidirectionalIter1, _BidirectionalIterator);
03137 __STL_REQUIRES(_BidirectionalIter2, _BidirectionalIterator);
03138 typedef reverse_iterator<_BidirectionalIter1> _RevIter1;
03139 typedef reverse_iterator<_BidirectionalIter2> _RevIter2;
03140
03141 _RevIter1 __rlast1(__first1);
03142 _RevIter2 __rlast2(__first2);
03143 _RevIter1 __rresult = search(_RevIter1(__last1), __rlast1,
03144 _RevIter2(__last2), __rlast2,
03145 __comp);
03146
03147 if (__rresult == __rlast1)
03148 return __last1;
03149 else {
03150 _BidirectionalIter1 __result = __rresult.base();
03151 advance(__result, -distance(__first2, __last2));
03152 return __result;
03153 }
03154 }
03155 #endif
03156
03157
03158
03159 template <class _ForwardIter1, class _ForwardIter2>
03160 inline _ForwardIter1
03161 find_end(_ForwardIter1 __first1, _ForwardIter1 __last1,
03162 _ForwardIter2 __first2, _ForwardIter2 __last2)
03163 {
03164 __STL_REQUIRES(_ForwardIter1, _ForwardIterator);
03165 __STL_REQUIRES(_ForwardIter2, _ForwardIterator);
03166 __STL_REQUIRES_BINARY_OP(_OP_EQUAL, bool,
03167 typename iterator_traits<_ForwardIter1>::value_type,
03168 typename iterator_traits<_ForwardIter2>::value_type);
03169 return __find_end(__first1, __last1, __first2, __last2,
03170 __ITERATOR_CATEGORY(__first1),
03171 __ITERATOR_CATEGORY(__first2));
03172 }
03173
03174 template <class _ForwardIter1, class _ForwardIter2,
03175 class _BinaryPredicate>
03176 inline _ForwardIter1
03177 find_end(_ForwardIter1 __first1, _ForwardIter1 __last1,
03178 _ForwardIter2 __first2, _ForwardIter2 __last2,
03179 _BinaryPredicate __comp)
03180 {
03181 __STL_REQUIRES(_ForwardIter1, _ForwardIterator);
03182 __STL_REQUIRES(_ForwardIter2, _ForwardIterator);
03183 __STL_BINARY_FUNCTION_CHECK(_BinaryPredicate, bool,
03184 typename iterator_traits<_ForwardIter1>::value_type,
03185 typename iterator_traits<_ForwardIter2>::value_type);
03186
03187 return __find_end(__first1, __last1, __first2, __last2,
03188 __ITERATOR_CATEGORY(__first1),
03189 __ITERATOR_CATEGORY(__first2),
03190 __comp);
03191 }
03192
03193
03194
03195
03196
03197 template <class _RandomAccessIter, class _Distance>
03198 bool __is_heap(_RandomAccessIter __first, _Distance __n)
03199 {
03200 _Distance __parent = 0;
03201 for (_Distance __child = 1; __child < __n; ++__child) {
03202 if (__first[__parent] < __first[__child])
03203 return false;
03204 if ((__child & 1) == 0)
03205 ++__parent;
03206 }
03207 return true;
03208 }
03209
03210 template <class _RandomAccessIter, class _Distance, class _StrictWeakOrdering>
03211 bool __is_heap(_RandomAccessIter __first, _StrictWeakOrdering __comp,
03212 _Distance __n)
03213 {
03214 _Distance __parent = 0;
03215 for (_Distance __child = 1; __child < __n; ++__child) {
03216 if (__comp(__first[__parent], __first[__child]))
03217 return false;
03218 if ((__child & 1) == 0)
03219 ++__parent;
03220 }
03221 return true;
03222 }
03223
03224 template <class _RandomAccessIter>
03225 inline bool is_heap(_RandomAccessIter __first, _RandomAccessIter __last)
03226 {
03227 __STL_REQUIRES(_RandomAccessIter, _RandomAccessIterator);
03228 __STL_REQUIRES(typename iterator_traits<_RandomAccessIter>::value_type,
03229 _LessThanComparable);
03230 return __is_heap(__first, __last - __first);
03231 }
03232
03233
03234 template <class _RandomAccessIter, class _StrictWeakOrdering>
03235 inline bool is_heap(_RandomAccessIter __first, _RandomAccessIter __last,
03236 _StrictWeakOrdering __comp)
03237 {
03238 __STL_REQUIRES(_RandomAccessIter, _RandomAccessIterator);
03239 __STL_BINARY_FUNCTION_CHECK(_StrictWeakOrdering, bool,
03240 typename iterator_traits<_RandomAccessIter>::value_type,
03241 typename iterator_traits<_RandomAccessIter>::value_type);
03242 return __is_heap(__first, __comp, __last - __first);
03243 }
03244
03245
03246
03247
03248
03249 template <class _ForwardIter>
03250 bool is_sorted(_ForwardIter __first, _ForwardIter __last)
03251 {
03252 __STL_REQUIRES(_ForwardIter, _ForwardIterator);
03253 __STL_REQUIRES(typename iterator_traits<_ForwardIter>::value_type,
03254 _LessThanComparable);
03255 if (__first == __last)
03256 return true;
03257
03258 _ForwardIter __next = __first;
03259 for (++__next; __next != __last; __first = __next, ++__next) {
03260 if (*__next < *__first)
03261 return false;
03262 }
03263
03264 return true;
03265 }
03266
03267 template <class _ForwardIter, class _StrictWeakOrdering>
03268 bool is_sorted(_ForwardIter __first, _ForwardIter __last,
03269 _StrictWeakOrdering __comp)
03270 {
03271 __STL_REQUIRES(_ForwardIter, _ForwardIterator);
03272 __STL_BINARY_FUNCTION_CHECK(_StrictWeakOrdering, bool,
03273 typename iterator_traits<_ForwardIter>::value_type,
03274 typename iterator_traits<_ForwardIter>::value_type);
03275 if (__first == __last)
03276 return true;
03277
03278 _ForwardIter __next = __first;
03279 for (++__next; __next != __last; __first = __next, ++__next) {
03280 if (__comp(*__next, *__first))
03281 return false;
03282 }
03283
03284 return true;
03285 }
03286
03287 #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
03288 #pragma reset woff 1209
03289 #endif
03290
03291 __STL_END_NAMESPACE
03292
03293 #endif
03294
03295
03296
03297