• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/toolchains/hndtools-arm-linux-2.6.36-uclibc-4.5.3/arm-brcm-linux-uclibcgnueabi/include/c++/4.5.3/bits/
1// Heap implementation -*- C++ -*-
2
3// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
4// Free Software Foundation, Inc.
5//
6// This file is part of the GNU ISO C++ Library.  This library is free
7// software; you can redistribute it and/or modify it under the
8// terms of the GNU General Public License as published by the
9// Free Software Foundation; either version 3, or (at your option)
10// any later version.
11
12// This library is distributed in the hope that it will be useful,
13// but WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15// GNU General Public License for more details.
16
17// Under Section 7 of GPL version 3, you are granted additional
18// permissions described in the GCC Runtime Library Exception, version
19// 3.1, as published by the Free Software Foundation.
20
21// You should have received a copy of the GNU General Public License and
22// a copy of the GCC Runtime Library Exception along with this program;
23// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
24// <http://www.gnu.org/licenses/>.
25
26/*
27 *
28 * Copyright (c) 1994
29 * Hewlett-Packard Company
30 *
31 * Permission to use, copy, modify, distribute and sell this software
32 * and its documentation for any purpose is hereby granted without fee,
33 * provided that the above copyright notice appear in all copies and
34 * that both that copyright notice and this permission notice appear
35 * in supporting documentation.  Hewlett-Packard Company makes no
36 * representations about the suitability of this software for any
37 * purpose.  It is provided "as is" without express or implied warranty.
38 *
39 * Copyright (c) 1997
40 * Silicon Graphics Computer Systems, Inc.
41 *
42 * Permission to use, copy, modify, distribute and sell this software
43 * and its documentation for any purpose is hereby granted without fee,
44 * provided that the above copyright notice appear in all copies and
45 * that both that copyright notice and this permission notice appear
46 * in supporting documentation.  Silicon Graphics makes no
47 * representations about the suitability of this software for any
48 * purpose.  It is provided "as is" without express or implied warranty.
49 */
50
51/** @file stl_heap.h
52 *  This is an internal header file, included by other library headers.
53 *  You should not attempt to use it directly.
54 */
55
56#ifndef _STL_HEAP_H
57#define _STL_HEAP_H 1
58
59#include <debug/debug.h>
60#include <bits/move.h>
61
62_GLIBCXX_BEGIN_NAMESPACE(std)
63
64  /**
65   * @defgroup heap_algorithms Heap
66   * @ingroup sorting_algorithms
67   */
68
69  template<typename _RandomAccessIterator, typename _Distance>
70    _Distance
71    __is_heap_until(_RandomAccessIterator __first, _Distance __n)
72    {
73      _Distance __parent = 0;
74      for (_Distance __child = 1; __child < __n; ++__child)
75	{
76	  if (__first[__parent] < __first[__child])
77	    return __child;
78	  if ((__child & 1) == 0)
79	    ++__parent;
80	}
81      return __n;
82    }
83
84  template<typename _RandomAccessIterator, typename _Distance,
85	   typename _Compare>
86    _Distance
87    __is_heap_until(_RandomAccessIterator __first, _Distance __n,
88		    _Compare __comp)
89    {
90      _Distance __parent = 0;
91      for (_Distance __child = 1; __child < __n; ++__child)
92	{
93	  if (__comp(__first[__parent], __first[__child]))
94	    return __child;
95	  if ((__child & 1) == 0)
96	    ++__parent;
97	}
98      return __n;
99    }
100
101  // __is_heap, a predicate testing whether or not a range is a heap.
102  // This function is an extension, not part of the C++ standard.
103  template<typename _RandomAccessIterator, typename _Distance>
104    inline bool
105    __is_heap(_RandomAccessIterator __first, _Distance __n)
106    { return std::__is_heap_until(__first, __n) == __n; }
107
108  template<typename _RandomAccessIterator, typename _Compare,
109	   typename _Distance>
110    inline bool
111    __is_heap(_RandomAccessIterator __first, _Compare __comp, _Distance __n)
112    { return std::__is_heap_until(__first, __n, __comp) == __n; }
113
114  template<typename _RandomAccessIterator>
115    inline bool
116    __is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
117    { return std::__is_heap(__first, std::distance(__first, __last)); }
118
119  template<typename _RandomAccessIterator, typename _Compare>
120    inline bool
121    __is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
122	      _Compare __comp)
123    { return std::__is_heap(__first, __comp, std::distance(__first, __last)); }
124
125  // Heap-manipulation functions: push_heap, pop_heap, make_heap, sort_heap,
126  // + is_heap and is_heap_until in C++0x.
127
128  template<typename _RandomAccessIterator, typename _Distance, typename _Tp>
129    void
130    __push_heap(_RandomAccessIterator __first,
131		_Distance __holeIndex, _Distance __topIndex, _Tp __value)
132    {
133      _Distance __parent = (__holeIndex - 1) / 2;
134      while (__holeIndex > __topIndex && *(__first + __parent) < __value)
135	{
136	  *(__first + __holeIndex) = _GLIBCXX_MOVE(*(__first + __parent));
137	  __holeIndex = __parent;
138	  __parent = (__holeIndex - 1) / 2;
139	}
140      *(__first + __holeIndex) = _GLIBCXX_MOVE(__value);
141    }
142
143  /**
144   *  @brief  Push an element onto a heap.
145   *  @param  first  Start of heap.
146   *  @param  last   End of heap + element.
147   *  @ingroup heap_algorithms
148   *
149   *  This operation pushes the element at last-1 onto the valid heap over the
150   *  range [first,last-1).  After completion, [first,last) is a valid heap.
151  */
152  template<typename _RandomAccessIterator>
153    inline void
154    push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
155    {
156      typedef typename iterator_traits<_RandomAccessIterator>::value_type
157	  _ValueType;
158      typedef typename iterator_traits<_RandomAccessIterator>::difference_type
159	  _DistanceType;
160
161      // concept requirements
162      __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
163	    _RandomAccessIterator>)
164      __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>)
165      __glibcxx_requires_valid_range(__first, __last);
166      __glibcxx_requires_heap(__first, __last - 1);
167
168      _ValueType __value = _GLIBCXX_MOVE(*(__last - 1));
169      std::__push_heap(__first, _DistanceType((__last - __first) - 1),
170		       _DistanceType(0), _GLIBCXX_MOVE(__value));
171    }
172
173  template<typename _RandomAccessIterator, typename _Distance, typename _Tp,
174	   typename _Compare>
175    void
176    __push_heap(_RandomAccessIterator __first, _Distance __holeIndex,
177		_Distance __topIndex, _Tp __value, _Compare __comp)
178    {
179      _Distance __parent = (__holeIndex - 1) / 2;
180      while (__holeIndex > __topIndex
181	     && __comp(*(__first + __parent), __value))
182	{
183	  *(__first + __holeIndex) = _GLIBCXX_MOVE(*(__first + __parent));
184	  __holeIndex = __parent;
185	  __parent = (__holeIndex - 1) / 2;
186	}
187      *(__first + __holeIndex) = _GLIBCXX_MOVE(__value);
188    }
189
190  /**
191   *  @brief  Push an element onto a heap using comparison functor.
192   *  @param  first  Start of heap.
193   *  @param  last   End of heap + element.
194   *  @param  comp   Comparison functor.
195   *  @ingroup heap_algorithms
196   *
197   *  This operation pushes the element at last-1 onto the valid heap over the
198   *  range [first,last-1).  After completion, [first,last) is a valid heap.
199   *  Compare operations are performed using comp.
200  */
201  template<typename _RandomAccessIterator, typename _Compare>
202    inline void
203    push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
204	      _Compare __comp)
205    {
206      typedef typename iterator_traits<_RandomAccessIterator>::value_type
207	  _ValueType;
208      typedef typename iterator_traits<_RandomAccessIterator>::difference_type
209	  _DistanceType;
210
211      // concept requirements
212      __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
213	    _RandomAccessIterator>)
214      __glibcxx_requires_valid_range(__first, __last);
215      __glibcxx_requires_heap_pred(__first, __last - 1, __comp);
216
217      _ValueType __value = _GLIBCXX_MOVE(*(__last - 1));
218      std::__push_heap(__first, _DistanceType((__last - __first) - 1),
219		       _DistanceType(0), _GLIBCXX_MOVE(__value), __comp);
220    }
221
222  template<typename _RandomAccessIterator, typename _Distance, typename _Tp>
223    void
224    __adjust_heap(_RandomAccessIterator __first, _Distance __holeIndex,
225		  _Distance __len, _Tp __value)
226    {
227      const _Distance __topIndex = __holeIndex;
228      _Distance __secondChild = __holeIndex;
229      while (__secondChild < (__len - 1) / 2)
230	{
231	  __secondChild = 2 * (__secondChild + 1);
232	  if (*(__first + __secondChild) < *(__first + (__secondChild - 1)))
233	    __secondChild--;
234	  *(__first + __holeIndex) = _GLIBCXX_MOVE(*(__first + __secondChild));
235	  __holeIndex = __secondChild;
236	}
237      if ((__len & 1) == 0 && __secondChild == (__len - 2) / 2)
238	{
239	  __secondChild = 2 * (__secondChild + 1);
240	  *(__first + __holeIndex) = _GLIBCXX_MOVE(*(__first
241						     + (__secondChild - 1)));
242	  __holeIndex = __secondChild - 1;
243	}
244      std::__push_heap(__first, __holeIndex, __topIndex,
245		       _GLIBCXX_MOVE(__value));
246    }
247
248  template<typename _RandomAccessIterator>
249    inline void
250    __pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
251	       _RandomAccessIterator __result)
252    {
253      typedef typename iterator_traits<_RandomAccessIterator>::value_type
254	_ValueType;
255      typedef typename iterator_traits<_RandomAccessIterator>::difference_type
256	_DistanceType;
257
258      _ValueType __value = _GLIBCXX_MOVE(*__result);
259      *__result = _GLIBCXX_MOVE(*__first);
260      std::__adjust_heap(__first, _DistanceType(0),
261			 _DistanceType(__last - __first),
262			 _GLIBCXX_MOVE(__value));
263    }
264
265  /**
266   *  @brief  Pop an element off a heap.
267   *  @param  first  Start of heap.
268   *  @param  last   End of heap.
269   *  @ingroup heap_algorithms
270   *
271   *  This operation pops the top of the heap.  The elements first and last-1
272   *  are swapped and [first,last-1) is made into a heap.
273  */
274  template<typename _RandomAccessIterator>
275    inline void
276    pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
277    {
278      typedef typename iterator_traits<_RandomAccessIterator>::value_type
279	_ValueType;
280
281      // concept requirements
282      __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
283	    _RandomAccessIterator>)
284      __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>)
285      __glibcxx_requires_valid_range(__first, __last);
286      __glibcxx_requires_heap(__first, __last);
287
288      --__last;
289      std::__pop_heap(__first, __last, __last);
290    }
291
292  template<typename _RandomAccessIterator, typename _Distance,
293	   typename _Tp, typename _Compare>
294    void
295    __adjust_heap(_RandomAccessIterator __first, _Distance __holeIndex,
296		  _Distance __len, _Tp __value, _Compare __comp)
297    {
298      const _Distance __topIndex = __holeIndex;
299      _Distance __secondChild = __holeIndex;
300      while (__secondChild < (__len - 1) / 2)
301	{
302	  __secondChild = 2 * (__secondChild + 1);
303	  if (__comp(*(__first + __secondChild),
304		     *(__first + (__secondChild - 1))))
305	    __secondChild--;
306	  *(__first + __holeIndex) = _GLIBCXX_MOVE(*(__first + __secondChild));
307	  __holeIndex = __secondChild;
308	}
309      if ((__len & 1) == 0 && __secondChild == (__len - 2) / 2)
310	{
311	  __secondChild = 2 * (__secondChild + 1);
312	  *(__first + __holeIndex) = _GLIBCXX_MOVE(*(__first
313						     + (__secondChild - 1)));
314	  __holeIndex = __secondChild - 1;
315	}
316      std::__push_heap(__first, __holeIndex, __topIndex,
317		       _GLIBCXX_MOVE(__value), __comp);
318    }
319
320  template<typename _RandomAccessIterator, typename _Compare>
321    inline void
322    __pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
323	       _RandomAccessIterator __result, _Compare __comp)
324    {
325      typedef typename iterator_traits<_RandomAccessIterator>::value_type
326	_ValueType;
327      typedef typename iterator_traits<_RandomAccessIterator>::difference_type
328	_DistanceType;
329
330      _ValueType __value = _GLIBCXX_MOVE(*__result);
331      *__result = _GLIBCXX_MOVE(*__first);
332      std::__adjust_heap(__first, _DistanceType(0),
333			 _DistanceType(__last - __first),
334			 _GLIBCXX_MOVE(__value), __comp);
335    }
336
337  /**
338   *  @brief  Pop an element off a heap using comparison functor.
339   *  @param  first  Start of heap.
340   *  @param  last   End of heap.
341   *  @param  comp   Comparison functor to use.
342   *  @ingroup heap_algorithms
343   *
344   *  This operation pops the top of the heap.  The elements first and last-1
345   *  are swapped and [first,last-1) is made into a heap.  Comparisons are
346   *  made using comp.
347  */
348  template<typename _RandomAccessIterator, typename _Compare>
349    inline void
350    pop_heap(_RandomAccessIterator __first,
351	     _RandomAccessIterator __last, _Compare __comp)
352    {
353      // concept requirements
354      __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
355	    _RandomAccessIterator>)
356      __glibcxx_requires_valid_range(__first, __last);
357      __glibcxx_requires_heap_pred(__first, __last, __comp);
358
359      --__last;
360      std::__pop_heap(__first, __last, __last, __comp);
361    }
362
363  /**
364   *  @brief  Construct a heap over a range.
365   *  @param  first  Start of heap.
366   *  @param  last   End of heap.
367   *  @ingroup heap_algorithms
368   *
369   *  This operation makes the elements in [first,last) into a heap.
370  */
371  template<typename _RandomAccessIterator>
372    void
373    make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
374    {
375      typedef typename iterator_traits<_RandomAccessIterator>::value_type
376	  _ValueType;
377      typedef typename iterator_traits<_RandomAccessIterator>::difference_type
378	  _DistanceType;
379
380      // concept requirements
381      __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
382	    _RandomAccessIterator>)
383      __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>)
384      __glibcxx_requires_valid_range(__first, __last);
385
386      if (__last - __first < 2)
387	return;
388
389      const _DistanceType __len = __last - __first;
390      _DistanceType __parent = (__len - 2) / 2;
391      while (true)
392	{
393	  _ValueType __value = _GLIBCXX_MOVE(*(__first + __parent));
394	  std::__adjust_heap(__first, __parent, __len, _GLIBCXX_MOVE(__value));
395	  if (__parent == 0)
396	    return;
397	  __parent--;
398	}
399    }
400
401  /**
402   *  @brief  Construct a heap over a range using comparison functor.
403   *  @param  first  Start of heap.
404   *  @param  last   End of heap.
405   *  @param  comp   Comparison functor to use.
406   *  @ingroup heap_algorithms
407   *
408   *  This operation makes the elements in [first,last) into a heap.
409   *  Comparisons are made using comp.
410  */
411  template<typename _RandomAccessIterator, typename _Compare>
412    void
413    make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
414	      _Compare __comp)
415    {
416      typedef typename iterator_traits<_RandomAccessIterator>::value_type
417	  _ValueType;
418      typedef typename iterator_traits<_RandomAccessIterator>::difference_type
419	  _DistanceType;
420
421      // concept requirements
422      __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
423	    _RandomAccessIterator>)
424      __glibcxx_requires_valid_range(__first, __last);
425
426      if (__last - __first < 2)
427	return;
428
429      const _DistanceType __len = __last - __first;
430      _DistanceType __parent = (__len - 2) / 2;
431      while (true)
432	{
433	  _ValueType __value = _GLIBCXX_MOVE(*(__first + __parent));
434	  std::__adjust_heap(__first, __parent, __len, _GLIBCXX_MOVE(__value),
435			     __comp);
436	  if (__parent == 0)
437	    return;
438	  __parent--;
439	}
440    }
441
442  /**
443   *  @brief  Sort a heap.
444   *  @param  first  Start of heap.
445   *  @param  last   End of heap.
446   *  @ingroup heap_algorithms
447   *
448   *  This operation sorts the valid heap in the range [first,last).
449  */
450  template<typename _RandomAccessIterator>
451    void
452    sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
453    {
454      // concept requirements
455      __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
456	    _RandomAccessIterator>)
457      __glibcxx_function_requires(_LessThanComparableConcept<
458	    typename iterator_traits<_RandomAccessIterator>::value_type>)
459      __glibcxx_requires_valid_range(__first, __last);
460      __glibcxx_requires_heap(__first, __last);
461
462      while (__last - __first > 1)
463	{
464	  --__last;
465	  std::__pop_heap(__first, __last, __last);
466	}
467    }
468
469  /**
470   *  @brief  Sort a heap using comparison functor.
471   *  @param  first  Start of heap.
472   *  @param  last   End of heap.
473   *  @param  comp   Comparison functor to use.
474   *  @ingroup heap_algorithms
475   *
476   *  This operation sorts the valid heap in the range [first,last).
477   *  Comparisons are made using comp.
478  */
479  template<typename _RandomAccessIterator, typename _Compare>
480    void
481    sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
482	      _Compare __comp)
483    {
484      // concept requirements
485      __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
486	    _RandomAccessIterator>)
487      __glibcxx_requires_valid_range(__first, __last);
488      __glibcxx_requires_heap_pred(__first, __last, __comp);
489
490      while (__last - __first > 1)
491	{
492	  --__last;
493	  std::__pop_heap(__first, __last, __last, __comp);
494	}
495    }
496
497#ifdef __GXX_EXPERIMENTAL_CXX0X__
498  /**
499   *  @brief  Search the end of a heap.
500   *  @param  first  Start of range.
501   *  @param  last   End of range.
502   *  @return  An iterator pointing to the first element not in the heap.
503   *  @ingroup heap_algorithms
504   *
505   *  This operation returns the last iterator i in [first, last) for which
506   *  the range [first, i) is a heap.
507  */
508  template<typename _RandomAccessIterator>
509    inline _RandomAccessIterator
510    is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last)
511    {
512      // concept requirements
513      __glibcxx_function_requires(_RandomAccessIteratorConcept<
514	    _RandomAccessIterator>)
515      __glibcxx_function_requires(_LessThanComparableConcept<
516	    typename iterator_traits<_RandomAccessIterator>::value_type>)
517      __glibcxx_requires_valid_range(__first, __last);
518
519      return __first + std::__is_heap_until(__first, std::distance(__first,
520								   __last));
521    }
522
523  /**
524   *  @brief  Search the end of a heap using comparison functor.
525   *  @param  first  Start of range.
526   *  @param  last   End of range.
527   *  @param  comp   Comparison functor to use.
528   *  @return  An iterator pointing to the first element not in the heap.
529   *  @ingroup heap_algorithms
530   *
531   *  This operation returns the last iterator i in [first, last) for which
532   *  the range [first, i) is a heap.  Comparisons are made using comp.
533  */
534  template<typename _RandomAccessIterator, typename _Compare>
535    inline _RandomAccessIterator
536    is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last,
537		  _Compare __comp)
538    {
539      // concept requirements
540      __glibcxx_function_requires(_RandomAccessIteratorConcept<
541	    _RandomAccessIterator>)
542      __glibcxx_requires_valid_range(__first, __last);
543
544      return __first + std::__is_heap_until(__first, std::distance(__first,
545								   __last),
546					    __comp);
547    }
548
549  /**
550   *  @brief  Determines whether a range is a heap.
551   *  @param  first  Start of range.
552   *  @param  last   End of range.
553   *  @return  True if range is a heap, false otherwise.
554   *  @ingroup heap_algorithms
555  */
556  template<typename _RandomAccessIterator>
557    inline bool
558    is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
559    { return std::is_heap_until(__first, __last) == __last; }
560
561  /**
562   *  @brief  Determines whether a range is a heap using comparison functor.
563   *  @param  first  Start of range.
564   *  @param  last   End of range.
565   *  @param  comp   Comparison functor to use.
566   *  @return  True if range is a heap, false otherwise.
567   *  @ingroup heap_algorithms
568  */
569  template<typename _RandomAccessIterator, typename _Compare>
570    inline bool
571    is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
572	    _Compare __comp)
573    { return std::is_heap_until(__first, __last, __comp) == __last; }
574#endif
575
576_GLIBCXX_END_NAMESPACE
577
578#endif /* _STL_HEAP_H */
579