00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00062 #ifndef _EXT_ALGORITHM
00063 #define _EXT_ALGORITHM
00064
00065 #pragma GCC system_header
00066 #include <algorithm>
00067
00068 namespace __gnu_cxx
00069 {
00070 using std::ptrdiff_t;
00071 using std::min;
00072 using std::pair;
00073 using std::input_iterator_tag;
00074 using std::random_access_iterator_tag;
00075 using std::iterator_traits;
00076
00077
00078
00079
00080 template<typename _InputIter, typename _Size, typename _OutputIter>
00081 pair<_InputIter, _OutputIter>
00082 __copy_n(_InputIter __first, _Size __count,
00083 _OutputIter __result,
00084 input_iterator_tag)
00085 {
00086 for ( ; __count > 0; --__count) {
00087 *__result = *__first;
00088 ++__first;
00089 ++__result;
00090 }
00091 return pair<_InputIter, _OutputIter>(__first, __result);
00092 }
00093
00094 template<typename _RAIter, typename _Size, typename _OutputIter>
00095 inline pair<_RAIter, _OutputIter>
00096 __copy_n(_RAIter __first, _Size __count,
00097 _OutputIter __result,
00098 random_access_iterator_tag)
00099 {
00100 _RAIter __last = __first + __count;
00101 return pair<_RAIter, _OutputIter>(__last,
00102 std::copy(__first, __last, __result));
00103 }
00104
00119 template<typename _InputIter, typename _Size, typename _OutputIter>
00120 inline pair<_InputIter, _OutputIter>
00121 copy_n(_InputIter __first, _Size __count, _OutputIter __result)
00122 {
00123
00124 __glibcpp_function_requires(_InputIteratorConcept<_InputIter>)
00125 __glibcpp_function_requires(_OutputIteratorConcept<_OutputIter,
00126 typename iterator_traits<_InputIter>::value_type>)
00127
00128 return __copy_n(__first, __count, __result,
00129 std::__iterator_category(__first));
00130 }
00131
00132 template<typename _InputIter1, typename _InputIter2>
00133 int
00134 __lexicographical_compare_3way(_InputIter1 __first1, _InputIter1 __last1,
00135 _InputIter2 __first2, _InputIter2 __last2)
00136 {
00137 while (__first1 != __last1 && __first2 != __last2) {
00138 if (*__first1 < *__first2)
00139 return -1;
00140 if (*__first2 < *__first1)
00141 return 1;
00142 ++__first1;
00143 ++__first2;
00144 }
00145 if (__first2 == __last2) {
00146 return !(__first1 == __last1);
00147 }
00148 else {
00149 return -1;
00150 }
00151 }
00152
00153 inline int
00154 __lexicographical_compare_3way(const unsigned char* __first1,
00155 const unsigned char* __last1,
00156 const unsigned char* __first2,
00157 const unsigned char* __last2)
00158 {
00159 const ptrdiff_t __len1 = __last1 - __first1;
00160 const ptrdiff_t __len2 = __last2 - __first2;
00161 const int __result = std::memcmp(__first1, __first2, min(__len1, __len2));
00162 return __result != 0 ? __result
00163 : (__len1 == __len2 ? 0 : (__len1 < __len2 ? -1 : 1));
00164 }
00165
00166 inline int
00167 __lexicographical_compare_3way(const char* __first1, const char* __last1,
00168 const char* __first2, const char* __last2)
00169 {
00170 #if CHAR_MAX == SCHAR_MAX
00171 return __lexicographical_compare_3way(
00172 (const signed char*) __first1,
00173 (const signed char*) __last1,
00174 (const signed char*) __first2,
00175 (const signed char*) __last2);
00176 #else
00177 return __lexicographical_compare_3way((const unsigned char*) __first1,
00178 (const unsigned char*) __last1,
00179 (const unsigned char*) __first2,
00180 (const unsigned char*) __last2);
00181 #endif
00182 }
00183
00198 template<typename _InputIter1, typename _InputIter2>
00199 int
00200 lexicographical_compare_3way(_InputIter1 __first1, _InputIter1 __last1,
00201 _InputIter2 __first2, _InputIter2 __last2)
00202 {
00203
00204 __glibcpp_function_requires(_InputIteratorConcept<_InputIter1>)
00205 __glibcpp_function_requires(_InputIteratorConcept<_InputIter2>)
00206 __glibcpp_function_requires(_LessThanComparableConcept<
00207 typename iterator_traits<_InputIter1>::value_type>)
00208 __glibcpp_function_requires(_LessThanComparableConcept<
00209 typename iterator_traits<_InputIter2>::value_type>)
00210
00211 return __lexicographical_compare_3way(__first1, __last1, __first2, __last2);
00212 }
00213
00214
00215
00216
00217 template<typename _InputIter, typename _Tp, typename _Size>
00218 void
00219 count(_InputIter __first, _InputIter __last,
00220 const _Tp& __value,
00221 _Size& __n)
00222 {
00223
00224 __glibcpp_function_requires(_InputIteratorConcept<_InputIter>)
00225 __glibcpp_function_requires(_EqualityComparableConcept<
00226 typename iterator_traits<_InputIter>::value_type >)
00227 __glibcpp_function_requires(_EqualityComparableConcept<_Tp>)
00228 for ( ; __first != __last; ++__first)
00229 if (*__first == __value)
00230 ++__n;
00231 }
00232
00233 template<typename _InputIter, typename _Predicate, typename _Size>
00234 void
00235 count_if(_InputIter __first, _InputIter __last,
00236 _Predicate __pred,
00237 _Size& __n)
00238 {
00239
00240 __glibcpp_function_requires(_InputIteratorConcept<_InputIter>)
00241 __glibcpp_function_requires(_UnaryPredicateConcept<_Predicate,
00242 typename iterator_traits<_InputIter>::value_type>)
00243 for ( ; __first != __last; ++__first)
00244 if (__pred(*__first))
00245 ++__n;
00246 }
00247
00248
00249
00250 template<typename _ForwardIter, typename _OutputIter, typename _Distance>
00251 _OutputIter
00252 random_sample_n(_ForwardIter __first, _ForwardIter __last,
00253 _OutputIter __out, const _Distance __n)
00254 {
00255
00256 __glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>)
00257 __glibcpp_function_requires(_OutputIteratorConcept<_OutputIter,
00258 typename iterator_traits<_ForwardIter>::value_type>)
00259
00260 _Distance __remaining = std::distance(__first, __last);
00261 _Distance __m = min(__n, __remaining);
00262
00263 while (__m > 0) {
00264 if (std::__random_number(__remaining) < __m) {
00265 *__out = *__first;
00266 ++__out;
00267 --__m;
00268 }
00269
00270 --__remaining;
00271 ++__first;
00272 }
00273 return __out;
00274 }
00275
00276 template<typename _ForwardIter, typename _OutputIter, typename _Distance,
00277 typename _RandomNumberGenerator>
00278 _OutputIter
00279 random_sample_n(_ForwardIter __first, _ForwardIter __last,
00280 _OutputIter __out, const _Distance __n,
00281 _RandomNumberGenerator& __rand)
00282 {
00283
00284 __glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>)
00285 __glibcpp_function_requires(_OutputIteratorConcept<_OutputIter,
00286 typename iterator_traits<_ForwardIter>::value_type>)
00287 __glibcpp_function_requires(_UnaryFunctionConcept<
00288 _RandomNumberGenerator, _Distance, _Distance>)
00289
00290 _Distance __remaining = std::distance(__first, __last);
00291 _Distance __m = min(__n, __remaining);
00292
00293 while (__m > 0) {
00294 if (__rand(__remaining) < __m) {
00295 *__out = *__first;
00296 ++__out;
00297 --__m;
00298 }
00299
00300 --__remaining;
00301 ++__first;
00302 }
00303 return __out;
00304 }
00305
00306 template<typename _InputIter, typename _RandomAccessIter, typename _Distance>
00307 _RandomAccessIter
00308 __random_sample(_InputIter __first, _InputIter __last,
00309 _RandomAccessIter __out,
00310 const _Distance __n)
00311 {
00312 _Distance __m = 0;
00313 _Distance __t = __n;
00314 for ( ; __first != __last && __m < __n; ++__m, ++__first)
00315 __out[__m] = *__first;
00316
00317 while (__first != __last) {
00318 ++__t;
00319 _Distance __M = std::__random_number(__t);
00320 if (__M < __n)
00321 __out[__M] = *__first;
00322 ++__first;
00323 }
00324
00325 return __out + __m;
00326 }
00327
00328 template<typename _InputIter, typename _RandomAccessIter,
00329 typename _RandomNumberGenerator, typename _Distance>
00330 _RandomAccessIter
00331 __random_sample(_InputIter __first, _InputIter __last,
00332 _RandomAccessIter __out,
00333 _RandomNumberGenerator& __rand,
00334 const _Distance __n)
00335 {
00336
00337 __glibcpp_function_requires(_UnaryFunctionConcept<
00338 _RandomNumberGenerator, _Distance, _Distance>)
00339
00340 _Distance __m = 0;
00341 _Distance __t = __n;
00342 for ( ; __first != __last && __m < __n; ++__m, ++__first)
00343 __out[__m] = *__first;
00344
00345 while (__first != __last) {
00346 ++__t;
00347 _Distance __M = __rand(__t);
00348 if (__M < __n)
00349 __out[__M] = *__first;
00350 ++__first;
00351 }
00352
00353 return __out + __m;
00354 }
00355
00356 template<typename _InputIter, typename _RandomAccessIter>
00357 inline _RandomAccessIter
00358 random_sample(_InputIter __first, _InputIter __last,
00359 _RandomAccessIter __out_first, _RandomAccessIter __out_last)
00360 {
00361
00362 __glibcpp_function_requires(_InputIteratorConcept<_InputIter>)
00363 __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept<
00364 _RandomAccessIter>)
00365
00366 return __random_sample(__first, __last,
00367 __out_first, __out_last - __out_first);
00368 }
00369
00370 template<typename _InputIter, typename _RandomAccessIter,
00371 typename _RandomNumberGenerator>
00372 inline _RandomAccessIter
00373 random_sample(_InputIter __first, _InputIter __last,
00374 _RandomAccessIter __out_first, _RandomAccessIter __out_last,
00375 _RandomNumberGenerator& __rand)
00376 {
00377
00378 __glibcpp_function_requires(_InputIteratorConcept<_InputIter>)
00379 __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept<
00380 _RandomAccessIter>)
00381
00382 return __random_sample(__first, __last,
00383 __out_first, __rand,
00384 __out_last - __out_first);
00385 }
00386
00387
00388
00389
00390
00391 template<typename _RandomAccessIter, typename _Distance>
00392 bool
00393 __is_heap(_RandomAccessIter __first, _Distance __n)
00394 {
00395 _Distance __parent = 0;
00396 for (_Distance __child = 1; __child < __n; ++__child) {
00397 if (__first[__parent] < __first[__child])
00398 return false;
00399 if ((__child & 1) == 0)
00400 ++__parent;
00401 }
00402 return true;
00403 }
00404
00405 template<typename _RandomAccessIter, typename _Distance,
00406 typename _StrictWeakOrdering>
00407 bool
00408 __is_heap(_RandomAccessIter __first, _StrictWeakOrdering __comp,
00409 _Distance __n)
00410 {
00411 _Distance __parent = 0;
00412 for (_Distance __child = 1; __child < __n; ++__child) {
00413 if (__comp(__first[__parent], __first[__child]))
00414 return false;
00415 if ((__child & 1) == 0)
00416 ++__parent;
00417 }
00418 return true;
00419 }
00420
00421 template<typename _RandomAccessIter>
00422 inline bool
00423 is_heap(_RandomAccessIter __first, _RandomAccessIter __last)
00424 {
00425
00426 __glibcpp_function_requires(_RandomAccessIteratorConcept<_RandomAccessIter>)
00427 __glibcpp_function_requires(_LessThanComparableConcept<
00428 typename iterator_traits<_RandomAccessIter>::value_type>)
00429
00430 return __is_heap(__first, __last - __first);
00431 }
00432
00433 template<typename _RandomAccessIter, typename _StrictWeakOrdering>
00434 inline bool
00435 is_heap(_RandomAccessIter __first, _RandomAccessIter __last,
00436 _StrictWeakOrdering __comp)
00437 {
00438
00439 __glibcpp_function_requires(_RandomAccessIteratorConcept<_RandomAccessIter>)
00440 __glibcpp_function_requires(_BinaryPredicateConcept<_StrictWeakOrdering,
00441 typename iterator_traits<_RandomAccessIter>::value_type,
00442 typename iterator_traits<_RandomAccessIter>::value_type>)
00443
00444 return __is_heap(__first, __comp, __last - __first);
00445 }
00446
00447
00448
00449
00450
00451 template<typename _ForwardIter>
00452 bool
00453 is_sorted(_ForwardIter __first, _ForwardIter __last)
00454 {
00455
00456 __glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>)
00457 __glibcpp_function_requires(_LessThanComparableConcept<
00458 typename iterator_traits<_ForwardIter>::value_type>)
00459
00460 if (__first == __last)
00461 return true;
00462
00463 _ForwardIter __next = __first;
00464 for (++__next; __next != __last; __first = __next, ++__next) {
00465 if (*__next < *__first)
00466 return false;
00467 }
00468
00469 return true;
00470 }
00471
00472 template<typename _ForwardIter, typename _StrictWeakOrdering>
00473 bool
00474 is_sorted(_ForwardIter __first, _ForwardIter __last, _StrictWeakOrdering __comp)
00475 {
00476
00477 __glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>)
00478 __glibcpp_function_requires(_BinaryPredicateConcept<_StrictWeakOrdering,
00479 typename iterator_traits<_ForwardIter>::value_type,
00480 typename iterator_traits<_ForwardIter>::value_type>)
00481
00482 if (__first == __last)
00483 return true;
00484
00485 _ForwardIter __next = __first;
00486 for (++__next; __next != __last; __first = __next, ++__next) {
00487 if (__comp(*__next, *__first))
00488 return false;
00489 }
00490
00491 return true;
00492 }
00493
00494 }
00495
00496 #endif