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