OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gcc-4.5.1/] [libstdc++-v3/] [include/] [bits/] [stl_heap.h] - Blame information for rev 816

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 424 jeremybenn
// 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 Algorithms
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 */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.