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