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

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [libstdc++-v3/] [include/] [bits/] [stl_heap.h] - Blame information for rev 17

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 17 jlechner
// Heap implementation -*- C++ -*-
2
 
3
// Copyright (C) 2001, 2004 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
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
 
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
 
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.
58
 */
59
 
60
#ifndef _STL_HEAP_H
61
#define _STL_HEAP_H 1
62
 
63
#include <debug/debug.h>
64
 
65
namespace std
66
{
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
        {
77
          if (__first[__parent] < __first[__child])
78
            return false;
79
          if ((__child & 1) == 0)
80
            ++__parent;
81
        }
82
      return true;
83
    }
84
 
85
  template<typename _RandomAccessIterator, typename _Distance,
86
           typename _StrictWeakOrdering>
87
    bool
88
    __is_heap(_RandomAccessIterator __first, _StrictWeakOrdering __comp,
89
              _Distance __n)
90
    {
91
      _Distance __parent = 0;
92
      for (_Distance __child = 1; __child < __n; ++__child)
93
        {
94
          if (__comp(__first[__parent], __first[__child]))
95
            return false;
96
          if ((__child & 1) == 0)
97
            ++__parent;
98
        }
99
      return true;
100
    }
101
 
102
  template<typename _RandomAccessIterator>
103
    bool
104
    __is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
105
    { return std::__is_heap(__first, std::distance(__first, __last)); }
106
 
107
  template<typename _RandomAccessIterator, typename _StrictWeakOrdering>
108
    bool
109
    __is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
110
            _StrictWeakOrdering __comp)
111
    { return std::__is_heap(__first, __comp, std::distance(__first, __last)); }
112
 
113
  // Heap-manipulation functions: push_heap, pop_heap, make_heap, sort_heap.
114
 
115
  template<typename _RandomAccessIterator, typename _Distance, typename _Tp>
116
    void
117
    __push_heap(_RandomAccessIterator __first,
118
                _Distance __holeIndex, _Distance __topIndex, _Tp __value)
119
    {
120
      _Distance __parent = (__holeIndex - 1) / 2;
121
      while (__holeIndex > __topIndex && *(__first + __parent) < __value)
122
        {
123
          *(__first + __holeIndex) = *(__first + __parent);
124
          __holeIndex = __parent;
125
          __parent = (__holeIndex - 1) / 2;
126
        }
127
      *(__first + __holeIndex) = __value;
128
    }
129
 
130
  /**
131
   *  @brief  Push an element onto a heap.
132
   *  @param  first  Start of heap.
133
   *  @param  last   End of heap + element.
134
   *  @ingroup heap
135
   *
136
   *  This operation pushes the element at last-1 onto the valid heap over the
137
   *  range [first,last-1).  After completion, [first,last) is a valid heap.
138
  */
139
  template<typename _RandomAccessIterator>
140
    inline void
141
    push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
142
    {
143
      typedef typename iterator_traits<_RandomAccessIterator>::value_type
144
          _ValueType;
145
      typedef typename iterator_traits<_RandomAccessIterator>::difference_type
146
          _DistanceType;
147
 
148
      // concept requirements
149
      __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
150
            _RandomAccessIterator>)
151
      __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>)
152
      __glibcxx_requires_valid_range(__first, __last);
153
      //      __glibcxx_requires_heap(__first, __last - 1);
154
 
155
      std::__push_heap(__first, _DistanceType((__last - __first) - 1),
156
                       _DistanceType(0), _ValueType(*(__last - 1)));
157
    }
158
 
159
  template<typename _RandomAccessIterator, typename _Distance, typename _Tp,
160
            typename _Compare>
161
    void
162
    __push_heap(_RandomAccessIterator __first, _Distance __holeIndex,
163
                _Distance __topIndex, _Tp __value, _Compare __comp)
164
    {
165
      _Distance __parent = (__holeIndex - 1) / 2;
166
      while (__holeIndex > __topIndex
167
             && __comp(*(__first + __parent), __value))
168
        {
169
          *(__first + __holeIndex) = *(__first + __parent);
170
          __holeIndex = __parent;
171
          __parent = (__holeIndex - 1) / 2;
172
        }
173
      *(__first + __holeIndex) = __value;
174
    }
175
 
176
  /**
177
   *  @brief  Push an element onto a heap using comparison functor.
178
   *  @param  first  Start of heap.
179
   *  @param  last   End of heap + element.
180
   *  @param  comp   Comparison functor.
181
   *  @ingroup heap
182
   *
183
   *  This operation pushes the element at last-1 onto the valid heap over the
184
   *  range [first,last-1).  After completion, [first,last) is a valid heap.
185
   *  Compare operations are performed using comp.
186
  */
187
  template<typename _RandomAccessIterator, typename _Compare>
188
    inline void
189
    push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
190
              _Compare __comp)
191
    {
192
      typedef typename iterator_traits<_RandomAccessIterator>::value_type
193
          _ValueType;
194
      typedef typename iterator_traits<_RandomAccessIterator>::difference_type
195
          _DistanceType;
196
 
197
      // concept requirements
198
      __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
199
            _RandomAccessIterator>)
200
      __glibcxx_requires_valid_range(__first, __last);
201
      __glibcxx_requires_heap_pred(__first, __last - 1, __comp);
202
 
203
      std::__push_heap(__first, _DistanceType((__last - __first) - 1),
204
                       _DistanceType(0), _ValueType(*(__last - 1)), __comp);
205
    }
206
 
207
  template<typename _RandomAccessIterator, typename _Distance, typename _Tp>
208
    void
209
    __adjust_heap(_RandomAccessIterator __first, _Distance __holeIndex,
210
                  _Distance __len, _Tp __value)
211
    {
212
      const _Distance __topIndex = __holeIndex;
213
      _Distance __secondChild = 2 * __holeIndex + 2;
214
      while (__secondChild < __len)
215
        {
216
          if (*(__first + __secondChild) < *(__first + (__secondChild - 1)))
217
            __secondChild--;
218
          *(__first + __holeIndex) = *(__first + __secondChild);
219
          __holeIndex = __secondChild;
220
          __secondChild = 2 * (__secondChild + 1);
221
        }
222
      if (__secondChild == __len)
223
        {
224
          *(__first + __holeIndex) = *(__first + (__secondChild - 1));
225
          __holeIndex = __secondChild - 1;
226
        }
227
      std::__push_heap(__first, __holeIndex, __topIndex, __value);
228
    }
229
 
230
  template<typename _RandomAccessIterator, typename _Tp>
231
    inline void
232
    __pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
233
               _RandomAccessIterator __result, _Tp __value)
234
    {
235
      typedef typename iterator_traits<_RandomAccessIterator>::difference_type
236
        _Distance;
237
      *__result = *__first;
238
      std::__adjust_heap(__first, _Distance(0), _Distance(__last - __first),
239
                         __value);
240
    }
241
 
242
  /**
243
   *  @brief  Pop an element off a heap.
244
   *  @param  first  Start of heap.
245
   *  @param  last   End of heap.
246
   *  @ingroup heap
247
   *
248
   *  This operation pops the top of the heap.  The elements first and last-1
249
   *  are swapped and [first,last-1) is made into a heap.
250
  */
251
  template<typename _RandomAccessIterator>
252
    inline void
253
    pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
254
    {
255
      typedef typename iterator_traits<_RandomAccessIterator>::value_type
256
        _ValueType;
257
 
258
      // concept requirements
259
      __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
260
            _RandomAccessIterator>)
261
      __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>)
262
      __glibcxx_requires_valid_range(__first, __last);
263
      __glibcxx_requires_heap(__first, __last);
264
 
265
      std::__pop_heap(__first, __last - 1, __last - 1,
266
                      _ValueType(*(__last - 1)));
267
    }
268
 
269
  template<typename _RandomAccessIterator, typename _Distance,
270
           typename _Tp, typename _Compare>
271
    void
272
    __adjust_heap(_RandomAccessIterator __first, _Distance __holeIndex,
273
                  _Distance __len, _Tp __value, _Compare __comp)
274
    {
275
      const _Distance __topIndex = __holeIndex;
276
      _Distance __secondChild = 2 * __holeIndex + 2;
277
      while (__secondChild < __len)
278
        {
279
          if (__comp(*(__first + __secondChild),
280
                     *(__first + (__secondChild - 1))))
281
            __secondChild--;
282
          *(__first + __holeIndex) = *(__first + __secondChild);
283
          __holeIndex = __secondChild;
284
          __secondChild = 2 * (__secondChild + 1);
285
        }
286
      if (__secondChild == __len)
287
        {
288
          *(__first + __holeIndex) = *(__first + (__secondChild - 1));
289
          __holeIndex = __secondChild - 1;
290
        }
291
      std::__push_heap(__first, __holeIndex, __topIndex, __value, __comp);
292
    }
293
 
294
  template<typename _RandomAccessIterator, typename _Tp, typename _Compare>
295
    inline void
296
    __pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
297
               _RandomAccessIterator __result, _Tp __value, _Compare __comp)
298
    {
299
      typedef typename iterator_traits<_RandomAccessIterator>::difference_type
300
        _Distance;
301
      *__result = *__first;
302
      std::__adjust_heap(__first, _Distance(0), _Distance(__last - __first),
303
                         __value, __comp);
304
    }
305
 
306
  /**
307
   *  @brief  Pop an element off a heap using comparison functor.
308
   *  @param  first  Start of heap.
309
   *  @param  last   End of heap.
310
   *  @param  comp   Comparison functor to use.
311
   *  @ingroup heap
312
   *
313
   *  This operation pops the top of the heap.  The elements first and last-1
314
   *  are swapped and [first,last-1) is made into a heap.  Comparisons are
315
   *  made using comp.
316
  */
317
  template<typename _RandomAccessIterator, typename _Compare>
318
    inline void
319
    pop_heap(_RandomAccessIterator __first,
320
             _RandomAccessIterator __last, _Compare __comp)
321
    {
322
      // concept requirements
323
      __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
324
            _RandomAccessIterator>)
325
      __glibcxx_requires_valid_range(__first, __last);
326
      __glibcxx_requires_heap_pred(__first, __last, __comp);
327
 
328
      typedef typename iterator_traits<_RandomAccessIterator>::value_type
329
        _ValueType;
330
      std::__pop_heap(__first, __last - 1, __last - 1,
331
                      _ValueType(*(__last - 1)), __comp);
332
    }
333
 
334
  /**
335
   *  @brief  Construct a heap over a range.
336
   *  @param  first  Start of heap.
337
   *  @param  last   End of heap.
338
   *  @ingroup heap
339
   *
340
   *  This operation makes the elements in [first,last) into a heap.
341
  */
342
  template<typename _RandomAccessIterator>
343
    void
344
    make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
345
    {
346
      typedef typename iterator_traits<_RandomAccessIterator>::value_type
347
          _ValueType;
348
      typedef typename iterator_traits<_RandomAccessIterator>::difference_type
349
          _DistanceType;
350
 
351
      // concept requirements
352
      __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
353
            _RandomAccessIterator>)
354
      __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>)
355
      __glibcxx_requires_valid_range(__first, __last);
356
 
357
      if (__last - __first < 2)
358
        return;
359
 
360
      const _DistanceType __len = __last - __first;
361
      _DistanceType __parent = (__len - 2) / 2;
362
      while (true)
363
        {
364
          std::__adjust_heap(__first, __parent, __len,
365
                             _ValueType(*(__first + __parent)));
366
          if (__parent == 0)
367
            return;
368
          __parent--;
369
        }
370
    }
371
 
372
  /**
373
   *  @brief  Construct a heap over a range using comparison functor.
374
   *  @param  first  Start of heap.
375
   *  @param  last   End of heap.
376
   *  @param  comp   Comparison functor to use.
377
   *  @ingroup heap
378
   *
379
   *  This operation makes the elements in [first,last) into a heap.
380
   *  Comparisons are made using comp.
381
  */
382
  template<typename _RandomAccessIterator, typename _Compare>
383
    inline void
384
    make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
385
              _Compare __comp)
386
    {
387
      typedef typename iterator_traits<_RandomAccessIterator>::value_type
388
          _ValueType;
389
      typedef typename iterator_traits<_RandomAccessIterator>::difference_type
390
          _DistanceType;
391
 
392
      // concept requirements
393
      __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
394
            _RandomAccessIterator>)
395
      __glibcxx_requires_valid_range(__first, __last);
396
 
397
      if (__last - __first < 2)
398
        return;
399
 
400
      const _DistanceType __len = __last - __first;
401
      _DistanceType __parent = (__len - 2) / 2;
402
      while (true)
403
        {
404
          std::__adjust_heap(__first, __parent, __len,
405
                             _ValueType(*(__first + __parent)), __comp);
406
          if (__parent == 0)
407
            return;
408
          __parent--;
409
        }
410
    }
411
 
412
  /**
413
   *  @brief  Sort a heap.
414
   *  @param  first  Start of heap.
415
   *  @param  last   End of heap.
416
   *  @ingroup heap
417
   *
418
   *  This operation sorts the valid heap in the range [first,last).
419
  */
420
  template<typename _RandomAccessIterator>
421
    void
422
    sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
423
    {
424
      // concept requirements
425
      __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
426
            _RandomAccessIterator>)
427
      __glibcxx_function_requires(_LessThanComparableConcept<
428
            typename iterator_traits<_RandomAccessIterator>::value_type>)
429
      __glibcxx_requires_valid_range(__first, __last);
430
      //      __glibcxx_requires_heap(__first, __last);
431
 
432
      while (__last - __first > 1)
433
        std::pop_heap(__first, __last--);
434
    }
435
 
436
  /**
437
   *  @brief  Sort a heap using comparison functor.
438
   *  @param  first  Start of heap.
439
   *  @param  last   End of heap.
440
   *  @param  comp   Comparison functor to use.
441
   *  @ingroup heap
442
   *
443
   *  This operation sorts the valid heap in the range [first,last).
444
   *  Comparisons are made using comp.
445
  */
446
  template<typename _RandomAccessIterator, typename _Compare>
447
    void
448
    sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
449
              _Compare __comp)
450
    {
451
      // concept requirements
452
      __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
453
            _RandomAccessIterator>)
454
      __glibcxx_requires_valid_range(__first, __last);
455
      __glibcxx_requires_heap_pred(__first, __last, __comp);
456
 
457
      while (__last - __first > 1)
458
        std::pop_heap(__first, __last--, __comp);
459
    }
460
 
461
} // namespace std
462
 
463
#endif /* _STL_HEAP_H */
464
 
465
// Local Variables:
466
// mode:C++
467
// End:

powered by: WebSVN 2.1.0

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