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