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 
00056 
00057 
00058 
00059 
00060 #ifndef _STL_HEAP_H
00061 #define _STL_HEAP_H 1
00062 
00063 #include <debug/debug.h>
00064 
00065 namespace std
00066 {
00067   
00068   
00069   
00070   template<typename _RandomAccessIterator, typename _Distance>
00071     bool
00072     __is_heap(_RandomAccessIterator __first, _Distance __n)
00073     {
00074       _Distance __parent = 0;
00075       for (_Distance __child = 1; __child < __n; ++__child)
00076     {
00077       if (__first[__parent] < __first[__child])
00078         return false;
00079       if ((__child & 1) == 0)
00080         ++__parent;
00081     }
00082       return true;
00083     }
00084 
00085   template<typename _RandomAccessIterator, typename _Distance,
00086            typename _StrictWeakOrdering>
00087     bool
00088     __is_heap(_RandomAccessIterator __first, _StrictWeakOrdering __comp,
00089           _Distance __n)
00090     {
00091       _Distance __parent = 0;
00092       for (_Distance __child = 1; __child < __n; ++__child)
00093     {
00094       if (__comp(__first[__parent], __first[__child]))
00095         return false;
00096       if ((__child & 1) == 0)
00097         ++__parent;
00098     }
00099       return true;
00100     }
00101 
00102   template<typename _RandomAccessIterator>
00103     bool
00104     __is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
00105     { return std::__is_heap(__first, std::distance(__first, __last)); }
00106 
00107   template<typename _RandomAccessIterator, typename _StrictWeakOrdering>
00108     bool
00109     __is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
00110         _StrictWeakOrdering __comp)
00111     { return std::__is_heap(__first, __comp, std::distance(__first, __last)); }
00112 
00113   
00114 
00115   template<typename _RandomAccessIterator, typename _Distance, typename _Tp>
00116     void
00117     __push_heap(_RandomAccessIterator __first,
00118         _Distance __holeIndex, _Distance __topIndex, _Tp __value)
00119     {
00120       _Distance __parent = (__holeIndex - 1) / 2;
00121       while (__holeIndex > __topIndex && *(__first + __parent) < __value)
00122     {
00123       *(__first + __holeIndex) = *(__first + __parent);
00124       __holeIndex = __parent;
00125       __parent = (__holeIndex - 1) / 2;
00126     }
00127       *(__first + __holeIndex) = __value;
00128     }
00129 
00130 
00131 
00132 
00133 
00134 
00135 
00136 
00137 
00138 
00139   template<typename _RandomAccessIterator>
00140     inline void
00141     push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
00142     {
00143       typedef typename iterator_traits<_RandomAccessIterator>::value_type
00144       _ValueType;
00145       typedef typename iterator_traits<_RandomAccessIterator>::difference_type
00146       _DistanceType;
00147 
00148       
00149       __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
00150         _RandomAccessIterator>)
00151       __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>)
00152       __glibcxx_requires_valid_range(__first, __last);
00153       
00154 
00155       std::__push_heap(__first, _DistanceType((__last - __first) - 1),
00156                _DistanceType(0), _ValueType(*(__last - 1)));
00157     }
00158 
00159   template<typename _RandomAccessIterator, typename _Distance, typename _Tp,
00160         typename _Compare>
00161     void
00162     __push_heap(_RandomAccessIterator __first, _Distance __holeIndex,
00163         _Distance __topIndex, _Tp __value, _Compare __comp)
00164     {
00165       _Distance __parent = (__holeIndex - 1) / 2;
00166       while (__holeIndex > __topIndex
00167          && __comp(*(__first + __parent), __value))
00168     {
00169       *(__first + __holeIndex) = *(__first + __parent);
00170       __holeIndex = __parent;
00171       __parent = (__holeIndex - 1) / 2;
00172     }
00173       *(__first + __holeIndex) = __value;
00174     }
00175 
00176 
00177 
00178 
00179 
00180 
00181 
00182 
00183 
00184 
00185 
00186 
00187   template<typename _RandomAccessIterator, typename _Compare>
00188     inline void
00189     push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
00190           _Compare __comp)
00191     {
00192       typedef typename iterator_traits<_RandomAccessIterator>::value_type
00193       _ValueType;
00194       typedef typename iterator_traits<_RandomAccessIterator>::difference_type
00195       _DistanceType;
00196 
00197       
00198       __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
00199         _RandomAccessIterator>)
00200       __glibcxx_requires_valid_range(__first, __last);
00201       __glibcxx_requires_heap_pred(__first, __last - 1, __comp);
00202 
00203       std::__push_heap(__first, _DistanceType((__last - __first) - 1),
00204                _DistanceType(0), _ValueType(*(__last - 1)), __comp);
00205     }
00206 
00207   template<typename _RandomAccessIterator, typename _Distance, typename _Tp>
00208     void
00209     __adjust_heap(_RandomAccessIterator __first, _Distance __holeIndex,
00210           _Distance __len, _Tp __value)
00211     {
00212       const _Distance __topIndex = __holeIndex;
00213       _Distance __secondChild = 2 * __holeIndex + 2;
00214       while (__secondChild < __len)
00215     {
00216       if (*(__first + __secondChild) < *(__first + (__secondChild - 1)))
00217         __secondChild--;
00218       *(__first + __holeIndex) = *(__first + __secondChild);
00219       __holeIndex = __secondChild;
00220       __secondChild = 2 * (__secondChild + 1);
00221     }
00222       if (__secondChild == __len)
00223     {
00224       *(__first + __holeIndex) = *(__first + (__secondChild - 1));
00225       __holeIndex = __secondChild - 1;
00226     }
00227       std::__push_heap(__first, __holeIndex, __topIndex, __value);
00228     }
00229 
00230   template<typename _RandomAccessIterator, typename _Tp>
00231     inline void
00232     __pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
00233            _RandomAccessIterator __result, _Tp __value)
00234     {
00235       typedef typename iterator_traits<_RandomAccessIterator>::difference_type
00236     _Distance;
00237       *__result = *__first;
00238       std::__adjust_heap(__first, _Distance(0), _Distance(__last - __first),
00239              __value);
00240     }
00241 
00242 
00243 
00244 
00245 
00246 
00247 
00248 
00249 
00250 
00251   template<typename _RandomAccessIterator>
00252     inline void
00253     pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
00254     {
00255       typedef typename iterator_traits<_RandomAccessIterator>::value_type
00256     _ValueType;
00257 
00258       
00259       __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
00260         _RandomAccessIterator>)
00261       __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>)
00262       __glibcxx_requires_valid_range(__first, __last);
00263       __glibcxx_requires_heap(__first, __last);
00264 
00265       std::__pop_heap(__first, __last - 1, __last - 1,
00266               _ValueType(*(__last - 1)));
00267     }
00268 
00269   template<typename _RandomAccessIterator, typename _Distance,
00270        typename _Tp, typename _Compare>
00271     void
00272     __adjust_heap(_RandomAccessIterator __first, _Distance __holeIndex,
00273           _Distance __len, _Tp __value, _Compare __comp)
00274     {
00275       const _Distance __topIndex = __holeIndex;
00276       _Distance __secondChild = 2 * __holeIndex + 2;
00277       while (__secondChild < __len)
00278     {
00279       if (__comp(*(__first + __secondChild),
00280              *(__first + (__secondChild - 1))))
00281         __secondChild--;
00282       *(__first + __holeIndex) = *(__first + __secondChild);
00283       __holeIndex = __secondChild;
00284       __secondChild = 2 * (__secondChild + 1);
00285     }
00286       if (__secondChild == __len)
00287     {
00288       *(__first + __holeIndex) = *(__first + (__secondChild - 1));
00289       __holeIndex = __secondChild - 1;
00290     }
00291       std::__push_heap(__first, __holeIndex, __topIndex, __value, __comp);
00292     }
00293 
00294   template<typename _RandomAccessIterator, typename _Tp, typename _Compare>
00295     inline void
00296     __pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
00297            _RandomAccessIterator __result, _Tp __value, _Compare __comp)
00298     {
00299       typedef typename iterator_traits<_RandomAccessIterator>::difference_type
00300     _Distance;
00301       *__result = *__first;
00302       std::__adjust_heap(__first, _Distance(0), _Distance(__last - __first),
00303              __value, __comp);
00304     }
00305 
00306 
00307 
00308 
00309 
00310 
00311 
00312 
00313 
00314 
00315 
00316 
00317   template<typename _RandomAccessIterator, typename _Compare>
00318     inline void
00319     pop_heap(_RandomAccessIterator __first,
00320          _RandomAccessIterator __last, _Compare __comp)
00321     {
00322       
00323       __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
00324         _RandomAccessIterator>)
00325       __glibcxx_requires_valid_range(__first, __last);
00326       __glibcxx_requires_heap_pred(__first, __last, __comp);
00327 
00328       typedef typename iterator_traits<_RandomAccessIterator>::value_type
00329     _ValueType;
00330       std::__pop_heap(__first, __last - 1, __last - 1,
00331               _ValueType(*(__last - 1)), __comp);
00332     }
00333 
00334 
00335 
00336 
00337 
00338 
00339 
00340 
00341 
00342   template<typename _RandomAccessIterator>
00343     void
00344     make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
00345     {
00346       typedef typename iterator_traits<_RandomAccessIterator>::value_type
00347       _ValueType;
00348       typedef typename iterator_traits<_RandomAccessIterator>::difference_type
00349       _DistanceType;
00350 
00351       
00352       __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
00353         _RandomAccessIterator>)
00354       __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>)
00355       __glibcxx_requires_valid_range(__first, __last);
00356 
00357       if (__last - __first < 2)
00358     return;
00359 
00360       const _DistanceType __len = __last - __first;
00361       _DistanceType __parent = (__len - 2) / 2;
00362       while (true)
00363     {
00364       std::__adjust_heap(__first, __parent, __len,
00365                  _ValueType(*(__first + __parent)));
00366       if (__parent == 0)
00367         return;
00368       __parent--;
00369     }
00370     }
00371 
00372 
00373 
00374 
00375 
00376 
00377 
00378 
00379 
00380 
00381 
00382   template<typename _RandomAccessIterator, typename _Compare>
00383     inline void
00384     make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
00385           _Compare __comp)
00386     {
00387       typedef typename iterator_traits<_RandomAccessIterator>::value_type
00388       _ValueType;
00389       typedef typename iterator_traits<_RandomAccessIterator>::difference_type
00390       _DistanceType;
00391 
00392       
00393       __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
00394         _RandomAccessIterator>)
00395       __glibcxx_requires_valid_range(__first, __last);
00396 
00397       if (__last - __first < 2)
00398     return;
00399 
00400       const _DistanceType __len = __last - __first;
00401       _DistanceType __parent = (__len - 2) / 2;
00402       while (true)
00403     {
00404       std::__adjust_heap(__first, __parent, __len,
00405                  _ValueType(*(__first + __parent)), __comp);
00406       if (__parent == 0)
00407         return;
00408       __parent--;
00409     }
00410     }
00411 
00412 
00413 
00414 
00415 
00416 
00417 
00418 
00419 
00420   template<typename _RandomAccessIterator>
00421     void
00422     sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
00423     {
00424       
00425       __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
00426         _RandomAccessIterator>)
00427       __glibcxx_function_requires(_LessThanComparableConcept<
00428         typename iterator_traits<_RandomAccessIterator>::value_type>)
00429       __glibcxx_requires_valid_range(__first, __last);
00430       
00431 
00432       while (__last - __first > 1)
00433     std::pop_heap(__first, __last--);
00434     }
00435 
00436 
00437 
00438 
00439 
00440 
00441 
00442 
00443 
00444 
00445 
00446   template<typename _RandomAccessIterator, typename _Compare>
00447     void
00448     sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
00449           _Compare __comp)
00450     {
00451       
00452       __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
00453         _RandomAccessIterator>)
00454       __glibcxx_requires_valid_range(__first, __last);
00455       __glibcxx_requires_heap_pred(__first, __last, __comp);
00456 
00457       while (__last - __first > 1)
00458     std::pop_heap(__first, __last--, __comp);
00459     }
00460 
00461 } 
00462 
00463 #endif 
00464 
00465 
00466 
00467