1*404b540aSrobert // Heap implementation -*- C++ -*-
2*404b540aSrobert
3*404b540aSrobert // Copyright (C) 2001, 2004, 2005, 2006 Free Software Foundation, Inc.
4*404b540aSrobert //
5*404b540aSrobert // This file is part of the GNU ISO C++ Library. This library is free
6*404b540aSrobert // software; you can redistribute it and/or modify it under the
7*404b540aSrobert // terms of the GNU General Public License as published by the
8*404b540aSrobert // Free Software Foundation; either version 2, or (at your option)
9*404b540aSrobert // any later version.
10*404b540aSrobert
11*404b540aSrobert // This library is distributed in the hope that it will be useful,
12*404b540aSrobert // but WITHOUT ANY WARRANTY; without even the implied warranty of
13*404b540aSrobert // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14*404b540aSrobert // GNU General Public License for more details.
15*404b540aSrobert
16*404b540aSrobert // You should have received a copy of the GNU General Public License along
17*404b540aSrobert // with this library; see the file COPYING. If not, write to the Free
18*404b540aSrobert // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
19*404b540aSrobert // USA.
20*404b540aSrobert
21*404b540aSrobert // As a special exception, you may use this file as part of a free software
22*404b540aSrobert // library without restriction. Specifically, if other files instantiate
23*404b540aSrobert // templates or use macros or inline functions from this file, or you compile
24*404b540aSrobert // this file and link it with other files to produce an executable, this
25*404b540aSrobert // file does not by itself cause the resulting executable to be covered by
26*404b540aSrobert // the GNU General Public License. This exception does not however
27*404b540aSrobert // invalidate any other reasons why the executable file might be covered by
28*404b540aSrobert // the GNU General Public License.
29*404b540aSrobert
30*404b540aSrobert /*
31*404b540aSrobert *
32*404b540aSrobert * Copyright (c) 1994
33*404b540aSrobert * Hewlett-Packard Company
34*404b540aSrobert *
35*404b540aSrobert * Permission to use, copy, modify, distribute and sell this software
36*404b540aSrobert * and its documentation for any purpose is hereby granted without fee,
37*404b540aSrobert * provided that the above copyright notice appear in all copies and
38*404b540aSrobert * that both that copyright notice and this permission notice appear
39*404b540aSrobert * in supporting documentation. Hewlett-Packard Company makes no
40*404b540aSrobert * representations about the suitability of this software for any
41*404b540aSrobert * purpose. It is provided "as is" without express or implied warranty.
42*404b540aSrobert *
43*404b540aSrobert * Copyright (c) 1997
44*404b540aSrobert * Silicon Graphics Computer Systems, Inc.
45*404b540aSrobert *
46*404b540aSrobert * Permission to use, copy, modify, distribute and sell this software
47*404b540aSrobert * and its documentation for any purpose is hereby granted without fee,
48*404b540aSrobert * provided that the above copyright notice appear in all copies and
49*404b540aSrobert * that both that copyright notice and this permission notice appear
50*404b540aSrobert * in supporting documentation. Silicon Graphics makes no
51*404b540aSrobert * representations about the suitability of this software for any
52*404b540aSrobert * purpose. It is provided "as is" without express or implied warranty.
53*404b540aSrobert */
54*404b540aSrobert
55*404b540aSrobert /** @file stl_heap.h
56*404b540aSrobert * This is an internal header file, included by other library headers.
57*404b540aSrobert * You should not attempt to use it directly.
58*404b540aSrobert */
59*404b540aSrobert
60*404b540aSrobert #ifndef _STL_HEAP_H
61*404b540aSrobert #define _STL_HEAP_H 1
62*404b540aSrobert
63*404b540aSrobert #include <debug/debug.h>
64*404b540aSrobert
_GLIBCXX_BEGIN_NAMESPACE(std)65*404b540aSrobert _GLIBCXX_BEGIN_NAMESPACE(std)
66*404b540aSrobert
67*404b540aSrobert // is_heap, a predicate testing whether or not a range is
68*404b540aSrobert // a heap. This function is an extension, not part of the C++
69*404b540aSrobert // standard.
70*404b540aSrobert template<typename _RandomAccessIterator, typename _Distance>
71*404b540aSrobert bool
72*404b540aSrobert __is_heap(_RandomAccessIterator __first, _Distance __n)
73*404b540aSrobert {
74*404b540aSrobert _Distance __parent = 0;
75*404b540aSrobert for (_Distance __child = 1; __child < __n; ++__child)
76*404b540aSrobert {
77*404b540aSrobert if (__first[__parent] < __first[__child])
78*404b540aSrobert return false;
79*404b540aSrobert if ((__child & 1) == 0)
80*404b540aSrobert ++__parent;
81*404b540aSrobert }
82*404b540aSrobert return true;
83*404b540aSrobert }
84*404b540aSrobert
85*404b540aSrobert template<typename _RandomAccessIterator, typename _Distance,
86*404b540aSrobert typename _StrictWeakOrdering>
87*404b540aSrobert bool
__is_heap(_RandomAccessIterator __first,_StrictWeakOrdering __comp,_Distance __n)88*404b540aSrobert __is_heap(_RandomAccessIterator __first, _StrictWeakOrdering __comp,
89*404b540aSrobert _Distance __n)
90*404b540aSrobert {
91*404b540aSrobert _Distance __parent = 0;
92*404b540aSrobert for (_Distance __child = 1; __child < __n; ++__child)
93*404b540aSrobert {
94*404b540aSrobert if (__comp(__first[__parent], __first[__child]))
95*404b540aSrobert return false;
96*404b540aSrobert if ((__child & 1) == 0)
97*404b540aSrobert ++__parent;
98*404b540aSrobert }
99*404b540aSrobert return true;
100*404b540aSrobert }
101*404b540aSrobert
102*404b540aSrobert template<typename _RandomAccessIterator>
103*404b540aSrobert bool
__is_heap(_RandomAccessIterator __first,_RandomAccessIterator __last)104*404b540aSrobert __is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
105*404b540aSrobert { return std::__is_heap(__first, std::distance(__first, __last)); }
106*404b540aSrobert
107*404b540aSrobert template<typename _RandomAccessIterator, typename _StrictWeakOrdering>
108*404b540aSrobert bool
__is_heap(_RandomAccessIterator __first,_RandomAccessIterator __last,_StrictWeakOrdering __comp)109*404b540aSrobert __is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
110*404b540aSrobert _StrictWeakOrdering __comp)
111*404b540aSrobert { return std::__is_heap(__first, __comp, std::distance(__first, __last)); }
112*404b540aSrobert
113*404b540aSrobert // Heap-manipulation functions: push_heap, pop_heap, make_heap, sort_heap.
114*404b540aSrobert
115*404b540aSrobert template<typename _RandomAccessIterator, typename _Distance, typename _Tp>
116*404b540aSrobert void
__push_heap(_RandomAccessIterator __first,_Distance __holeIndex,_Distance __topIndex,_Tp __value)117*404b540aSrobert __push_heap(_RandomAccessIterator __first,
118*404b540aSrobert _Distance __holeIndex, _Distance __topIndex, _Tp __value)
119*404b540aSrobert {
120*404b540aSrobert _Distance __parent = (__holeIndex - 1) / 2;
121*404b540aSrobert while (__holeIndex > __topIndex && *(__first + __parent) < __value)
122*404b540aSrobert {
123*404b540aSrobert *(__first + __holeIndex) = *(__first + __parent);
124*404b540aSrobert __holeIndex = __parent;
125*404b540aSrobert __parent = (__holeIndex - 1) / 2;
126*404b540aSrobert }
127*404b540aSrobert *(__first + __holeIndex) = __value;
128*404b540aSrobert }
129*404b540aSrobert
130*404b540aSrobert /**
131*404b540aSrobert * @brief Push an element onto a heap.
132*404b540aSrobert * @param first Start of heap.
133*404b540aSrobert * @param last End of heap + element.
134*404b540aSrobert * @ingroup heap
135*404b540aSrobert *
136*404b540aSrobert * This operation pushes the element at last-1 onto the valid heap over the
137*404b540aSrobert * range [first,last-1). After completion, [first,last) is a valid heap.
138*404b540aSrobert */
139*404b540aSrobert template<typename _RandomAccessIterator>
140*404b540aSrobert inline void
push_heap(_RandomAccessIterator __first,_RandomAccessIterator __last)141*404b540aSrobert push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
142*404b540aSrobert {
143*404b540aSrobert typedef typename iterator_traits<_RandomAccessIterator>::value_type
144*404b540aSrobert _ValueType;
145*404b540aSrobert typedef typename iterator_traits<_RandomAccessIterator>::difference_type
146*404b540aSrobert _DistanceType;
147*404b540aSrobert
148*404b540aSrobert // concept requirements
149*404b540aSrobert __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
150*404b540aSrobert _RandomAccessIterator>)
151*404b540aSrobert __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>)
152*404b540aSrobert __glibcxx_requires_valid_range(__first, __last);
153*404b540aSrobert // __glibcxx_requires_heap(__first, __last - 1);
154*404b540aSrobert
155*404b540aSrobert std::__push_heap(__first, _DistanceType((__last - __first) - 1),
156*404b540aSrobert _DistanceType(0), _ValueType(*(__last - 1)));
157*404b540aSrobert }
158*404b540aSrobert
159*404b540aSrobert template<typename _RandomAccessIterator, typename _Distance, typename _Tp,
160*404b540aSrobert typename _Compare>
161*404b540aSrobert void
__push_heap(_RandomAccessIterator __first,_Distance __holeIndex,_Distance __topIndex,_Tp __value,_Compare __comp)162*404b540aSrobert __push_heap(_RandomAccessIterator __first, _Distance __holeIndex,
163*404b540aSrobert _Distance __topIndex, _Tp __value, _Compare __comp)
164*404b540aSrobert {
165*404b540aSrobert _Distance __parent = (__holeIndex - 1) / 2;
166*404b540aSrobert while (__holeIndex > __topIndex
167*404b540aSrobert && __comp(*(__first + __parent), __value))
168*404b540aSrobert {
169*404b540aSrobert *(__first + __holeIndex) = *(__first + __parent);
170*404b540aSrobert __holeIndex = __parent;
171*404b540aSrobert __parent = (__holeIndex - 1) / 2;
172*404b540aSrobert }
173*404b540aSrobert *(__first + __holeIndex) = __value;
174*404b540aSrobert }
175*404b540aSrobert
176*404b540aSrobert /**
177*404b540aSrobert * @brief Push an element onto a heap using comparison functor.
178*404b540aSrobert * @param first Start of heap.
179*404b540aSrobert * @param last End of heap + element.
180*404b540aSrobert * @param comp Comparison functor.
181*404b540aSrobert * @ingroup heap
182*404b540aSrobert *
183*404b540aSrobert * This operation pushes the element at last-1 onto the valid heap over the
184*404b540aSrobert * range [first,last-1). After completion, [first,last) is a valid heap.
185*404b540aSrobert * Compare operations are performed using comp.
186*404b540aSrobert */
187*404b540aSrobert template<typename _RandomAccessIterator, typename _Compare>
188*404b540aSrobert inline void
push_heap(_RandomAccessIterator __first,_RandomAccessIterator __last,_Compare __comp)189*404b540aSrobert push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
190*404b540aSrobert _Compare __comp)
191*404b540aSrobert {
192*404b540aSrobert typedef typename iterator_traits<_RandomAccessIterator>::value_type
193*404b540aSrobert _ValueType;
194*404b540aSrobert typedef typename iterator_traits<_RandomAccessIterator>::difference_type
195*404b540aSrobert _DistanceType;
196*404b540aSrobert
197*404b540aSrobert // concept requirements
198*404b540aSrobert __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
199*404b540aSrobert _RandomAccessIterator>)
200*404b540aSrobert __glibcxx_requires_valid_range(__first, __last);
201*404b540aSrobert __glibcxx_requires_heap_pred(__first, __last - 1, __comp);
202*404b540aSrobert
203*404b540aSrobert std::__push_heap(__first, _DistanceType((__last - __first) - 1),
204*404b540aSrobert _DistanceType(0), _ValueType(*(__last - 1)), __comp);
205*404b540aSrobert }
206*404b540aSrobert
207*404b540aSrobert template<typename _RandomAccessIterator, typename _Distance, typename _Tp>
208*404b540aSrobert void
__adjust_heap(_RandomAccessIterator __first,_Distance __holeIndex,_Distance __len,_Tp __value)209*404b540aSrobert __adjust_heap(_RandomAccessIterator __first, _Distance __holeIndex,
210*404b540aSrobert _Distance __len, _Tp __value)
211*404b540aSrobert {
212*404b540aSrobert const _Distance __topIndex = __holeIndex;
213*404b540aSrobert _Distance __secondChild = 2 * __holeIndex + 2;
214*404b540aSrobert while (__secondChild < __len)
215*404b540aSrobert {
216*404b540aSrobert if (*(__first + __secondChild) < *(__first + (__secondChild - 1)))
217*404b540aSrobert __secondChild--;
218*404b540aSrobert *(__first + __holeIndex) = *(__first + __secondChild);
219*404b540aSrobert __holeIndex = __secondChild;
220*404b540aSrobert __secondChild = 2 * (__secondChild + 1);
221*404b540aSrobert }
222*404b540aSrobert if (__secondChild == __len)
223*404b540aSrobert {
224*404b540aSrobert *(__first + __holeIndex) = *(__first + (__secondChild - 1));
225*404b540aSrobert __holeIndex = __secondChild - 1;
226*404b540aSrobert }
227*404b540aSrobert std::__push_heap(__first, __holeIndex, __topIndex, __value);
228*404b540aSrobert }
229*404b540aSrobert
230*404b540aSrobert template<typename _RandomAccessIterator, typename _Tp>
231*404b540aSrobert inline void
__pop_heap(_RandomAccessIterator __first,_RandomAccessIterator __last,_RandomAccessIterator __result,_Tp __value)232*404b540aSrobert __pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
233*404b540aSrobert _RandomAccessIterator __result, _Tp __value)
234*404b540aSrobert {
235*404b540aSrobert typedef typename iterator_traits<_RandomAccessIterator>::difference_type
236*404b540aSrobert _Distance;
237*404b540aSrobert *__result = *__first;
238*404b540aSrobert std::__adjust_heap(__first, _Distance(0), _Distance(__last - __first),
239*404b540aSrobert __value);
240*404b540aSrobert }
241*404b540aSrobert
242*404b540aSrobert /**
243*404b540aSrobert * @brief Pop an element off a heap.
244*404b540aSrobert * @param first Start of heap.
245*404b540aSrobert * @param last End of heap.
246*404b540aSrobert * @ingroup heap
247*404b540aSrobert *
248*404b540aSrobert * This operation pops the top of the heap. The elements first and last-1
249*404b540aSrobert * are swapped and [first,last-1) is made into a heap.
250*404b540aSrobert */
251*404b540aSrobert template<typename _RandomAccessIterator>
252*404b540aSrobert inline void
pop_heap(_RandomAccessIterator __first,_RandomAccessIterator __last)253*404b540aSrobert pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
254*404b540aSrobert {
255*404b540aSrobert typedef typename iterator_traits<_RandomAccessIterator>::value_type
256*404b540aSrobert _ValueType;
257*404b540aSrobert
258*404b540aSrobert // concept requirements
259*404b540aSrobert __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
260*404b540aSrobert _RandomAccessIterator>)
261*404b540aSrobert __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>)
262*404b540aSrobert __glibcxx_requires_valid_range(__first, __last);
263*404b540aSrobert __glibcxx_requires_heap(__first, __last);
264*404b540aSrobert
265*404b540aSrobert std::__pop_heap(__first, __last - 1, __last - 1,
266*404b540aSrobert _ValueType(*(__last - 1)));
267*404b540aSrobert }
268*404b540aSrobert
269*404b540aSrobert template<typename _RandomAccessIterator, typename _Distance,
270*404b540aSrobert typename _Tp, typename _Compare>
271*404b540aSrobert void
__adjust_heap(_RandomAccessIterator __first,_Distance __holeIndex,_Distance __len,_Tp __value,_Compare __comp)272*404b540aSrobert __adjust_heap(_RandomAccessIterator __first, _Distance __holeIndex,
273*404b540aSrobert _Distance __len, _Tp __value, _Compare __comp)
274*404b540aSrobert {
275*404b540aSrobert const _Distance __topIndex = __holeIndex;
276*404b540aSrobert _Distance __secondChild = 2 * __holeIndex + 2;
277*404b540aSrobert while (__secondChild < __len)
278*404b540aSrobert {
279*404b540aSrobert if (__comp(*(__first + __secondChild),
280*404b540aSrobert *(__first + (__secondChild - 1))))
281*404b540aSrobert __secondChild--;
282*404b540aSrobert *(__first + __holeIndex) = *(__first + __secondChild);
283*404b540aSrobert __holeIndex = __secondChild;
284*404b540aSrobert __secondChild = 2 * (__secondChild + 1);
285*404b540aSrobert }
286*404b540aSrobert if (__secondChild == __len)
287*404b540aSrobert {
288*404b540aSrobert *(__first + __holeIndex) = *(__first + (__secondChild - 1));
289*404b540aSrobert __holeIndex = __secondChild - 1;
290*404b540aSrobert }
291*404b540aSrobert std::__push_heap(__first, __holeIndex, __topIndex, __value, __comp);
292*404b540aSrobert }
293*404b540aSrobert
294*404b540aSrobert template<typename _RandomAccessIterator, typename _Tp, typename _Compare>
295*404b540aSrobert inline void
__pop_heap(_RandomAccessIterator __first,_RandomAccessIterator __last,_RandomAccessIterator __result,_Tp __value,_Compare __comp)296*404b540aSrobert __pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
297*404b540aSrobert _RandomAccessIterator __result, _Tp __value, _Compare __comp)
298*404b540aSrobert {
299*404b540aSrobert typedef typename iterator_traits<_RandomAccessIterator>::difference_type
300*404b540aSrobert _Distance;
301*404b540aSrobert *__result = *__first;
302*404b540aSrobert std::__adjust_heap(__first, _Distance(0), _Distance(__last - __first),
303*404b540aSrobert __value, __comp);
304*404b540aSrobert }
305*404b540aSrobert
306*404b540aSrobert /**
307*404b540aSrobert * @brief Pop an element off a heap using comparison functor.
308*404b540aSrobert * @param first Start of heap.
309*404b540aSrobert * @param last End of heap.
310*404b540aSrobert * @param comp Comparison functor to use.
311*404b540aSrobert * @ingroup heap
312*404b540aSrobert *
313*404b540aSrobert * This operation pops the top of the heap. The elements first and last-1
314*404b540aSrobert * are swapped and [first,last-1) is made into a heap. Comparisons are
315*404b540aSrobert * made using comp.
316*404b540aSrobert */
317*404b540aSrobert template<typename _RandomAccessIterator, typename _Compare>
318*404b540aSrobert inline void
pop_heap(_RandomAccessIterator __first,_RandomAccessIterator __last,_Compare __comp)319*404b540aSrobert pop_heap(_RandomAccessIterator __first,
320*404b540aSrobert _RandomAccessIterator __last, _Compare __comp)
321*404b540aSrobert {
322*404b540aSrobert // concept requirements
323*404b540aSrobert __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
324*404b540aSrobert _RandomAccessIterator>)
325*404b540aSrobert __glibcxx_requires_valid_range(__first, __last);
326*404b540aSrobert __glibcxx_requires_heap_pred(__first, __last, __comp);
327*404b540aSrobert
328*404b540aSrobert typedef typename iterator_traits<_RandomAccessIterator>::value_type
329*404b540aSrobert _ValueType;
330*404b540aSrobert std::__pop_heap(__first, __last - 1, __last - 1,
331*404b540aSrobert _ValueType(*(__last - 1)), __comp);
332*404b540aSrobert }
333*404b540aSrobert
334*404b540aSrobert /**
335*404b540aSrobert * @brief Construct a heap over a range.
336*404b540aSrobert * @param first Start of heap.
337*404b540aSrobert * @param last End of heap.
338*404b540aSrobert * @ingroup heap
339*404b540aSrobert *
340*404b540aSrobert * This operation makes the elements in [first,last) into a heap.
341*404b540aSrobert */
342*404b540aSrobert template<typename _RandomAccessIterator>
343*404b540aSrobert void
make_heap(_RandomAccessIterator __first,_RandomAccessIterator __last)344*404b540aSrobert make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
345*404b540aSrobert {
346*404b540aSrobert typedef typename iterator_traits<_RandomAccessIterator>::value_type
347*404b540aSrobert _ValueType;
348*404b540aSrobert typedef typename iterator_traits<_RandomAccessIterator>::difference_type
349*404b540aSrobert _DistanceType;
350*404b540aSrobert
351*404b540aSrobert // concept requirements
352*404b540aSrobert __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
353*404b540aSrobert _RandomAccessIterator>)
354*404b540aSrobert __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>)
355*404b540aSrobert __glibcxx_requires_valid_range(__first, __last);
356*404b540aSrobert
357*404b540aSrobert if (__last - __first < 2)
358*404b540aSrobert return;
359*404b540aSrobert
360*404b540aSrobert const _DistanceType __len = __last - __first;
361*404b540aSrobert _DistanceType __parent = (__len - 2) / 2;
362*404b540aSrobert while (true)
363*404b540aSrobert {
364*404b540aSrobert std::__adjust_heap(__first, __parent, __len,
365*404b540aSrobert _ValueType(*(__first + __parent)));
366*404b540aSrobert if (__parent == 0)
367*404b540aSrobert return;
368*404b540aSrobert __parent--;
369*404b540aSrobert }
370*404b540aSrobert }
371*404b540aSrobert
372*404b540aSrobert /**
373*404b540aSrobert * @brief Construct a heap over a range using comparison functor.
374*404b540aSrobert * @param first Start of heap.
375*404b540aSrobert * @param last End of heap.
376*404b540aSrobert * @param comp Comparison functor to use.
377*404b540aSrobert * @ingroup heap
378*404b540aSrobert *
379*404b540aSrobert * This operation makes the elements in [first,last) into a heap.
380*404b540aSrobert * Comparisons are made using comp.
381*404b540aSrobert */
382*404b540aSrobert template<typename _RandomAccessIterator, typename _Compare>
383*404b540aSrobert inline void
make_heap(_RandomAccessIterator __first,_RandomAccessIterator __last,_Compare __comp)384*404b540aSrobert make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
385*404b540aSrobert _Compare __comp)
386*404b540aSrobert {
387*404b540aSrobert typedef typename iterator_traits<_RandomAccessIterator>::value_type
388*404b540aSrobert _ValueType;
389*404b540aSrobert typedef typename iterator_traits<_RandomAccessIterator>::difference_type
390*404b540aSrobert _DistanceType;
391*404b540aSrobert
392*404b540aSrobert // concept requirements
393*404b540aSrobert __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
394*404b540aSrobert _RandomAccessIterator>)
395*404b540aSrobert __glibcxx_requires_valid_range(__first, __last);
396*404b540aSrobert
397*404b540aSrobert if (__last - __first < 2)
398*404b540aSrobert return;
399*404b540aSrobert
400*404b540aSrobert const _DistanceType __len = __last - __first;
401*404b540aSrobert _DistanceType __parent = (__len - 2) / 2;
402*404b540aSrobert while (true)
403*404b540aSrobert {
404*404b540aSrobert std::__adjust_heap(__first, __parent, __len,
405*404b540aSrobert _ValueType(*(__first + __parent)), __comp);
406*404b540aSrobert if (__parent == 0)
407*404b540aSrobert return;
408*404b540aSrobert __parent--;
409*404b540aSrobert }
410*404b540aSrobert }
411*404b540aSrobert
412*404b540aSrobert /**
413*404b540aSrobert * @brief Sort a heap.
414*404b540aSrobert * @param first Start of heap.
415*404b540aSrobert * @param last End of heap.
416*404b540aSrobert * @ingroup heap
417*404b540aSrobert *
418*404b540aSrobert * This operation sorts the valid heap in the range [first,last).
419*404b540aSrobert */
420*404b540aSrobert template<typename _RandomAccessIterator>
421*404b540aSrobert void
sort_heap(_RandomAccessIterator __first,_RandomAccessIterator __last)422*404b540aSrobert sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
423*404b540aSrobert {
424*404b540aSrobert // concept requirements
425*404b540aSrobert __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
426*404b540aSrobert _RandomAccessIterator>)
427*404b540aSrobert __glibcxx_function_requires(_LessThanComparableConcept<
428*404b540aSrobert typename iterator_traits<_RandomAccessIterator>::value_type>)
429*404b540aSrobert __glibcxx_requires_valid_range(__first, __last);
430*404b540aSrobert // __glibcxx_requires_heap(__first, __last);
431*404b540aSrobert
432*404b540aSrobert while (__last - __first > 1)
433*404b540aSrobert std::pop_heap(__first, _RandomAccessIterator(__last--));
434*404b540aSrobert }
435*404b540aSrobert
436*404b540aSrobert /**
437*404b540aSrobert * @brief Sort a heap using comparison functor.
438*404b540aSrobert * @param first Start of heap.
439*404b540aSrobert * @param last End of heap.
440*404b540aSrobert * @param comp Comparison functor to use.
441*404b540aSrobert * @ingroup heap
442*404b540aSrobert *
443*404b540aSrobert * This operation sorts the valid heap in the range [first,last).
444*404b540aSrobert * Comparisons are made using comp.
445*404b540aSrobert */
446*404b540aSrobert template<typename _RandomAccessIterator, typename _Compare>
447*404b540aSrobert void
sort_heap(_RandomAccessIterator __first,_RandomAccessIterator __last,_Compare __comp)448*404b540aSrobert sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
449*404b540aSrobert _Compare __comp)
450*404b540aSrobert {
451*404b540aSrobert // concept requirements
452*404b540aSrobert __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
453*404b540aSrobert _RandomAccessIterator>)
454*404b540aSrobert __glibcxx_requires_valid_range(__first, __last);
455*404b540aSrobert __glibcxx_requires_heap_pred(__first, __last, __comp);
456*404b540aSrobert
457*404b540aSrobert while (__last - __first > 1)
458*404b540aSrobert std::pop_heap(__first, _RandomAccessIterator(__last--), __comp);
459*404b540aSrobert }
460*404b540aSrobert
461*404b540aSrobert _GLIBCXX_END_NAMESPACE
462*404b540aSrobert
463*404b540aSrobert #endif /* _STL_HEAP_H */
464