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