OSDN Git Service

c19195aad39a4dab6e04c8f79d90586d50dc6d68
[pf3gnuchains/gcc-fork.git] / libstdc++-v3 / include / bits / stl_heap.h
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
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 _CPP_BITS_STL_HEAP_H
61 #define _CPP_BITS_STL_HEAP_H 1
62
63 namespace std
64 {
65
66   // Heap-manipulation functions: push_heap, pop_heap, make_heap, sort_heap.
67
68   template<typename _RandomAccessIterator, typename _Distance, typename _Tp>
69     void 
70     __push_heap(_RandomAccessIterator __first,
71                 _Distance __holeIndex, _Distance __topIndex, _Tp __value)
72     {
73       _Distance __parent = (__holeIndex - 1) / 2;
74       while (__holeIndex > __topIndex && *(__first + __parent) < __value) {
75         *(__first + __holeIndex) = *(__first + __parent);
76         __holeIndex = __parent;
77         __parent = (__holeIndex - 1) / 2;
78       }    
79       *(__first + __holeIndex) = __value;
80     }
81
82   template<typename _RandomAccessIterator>
83     inline void 
84     push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
85     {
86       typedef typename iterator_traits<_RandomAccessIterator>::value_type
87           _ValueType;
88       typedef typename iterator_traits<_RandomAccessIterator>::difference_type
89           _DistanceType;
90
91       // concept requirements
92       __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept<
93             _RandomAccessIterator>)
94       __glibcpp_function_requires(_LessThanComparableConcept<_ValueType>)
95
96       __push_heap(__first, _DistanceType((__last - __first) - 1), _DistanceType(0), 
97                   _ValueType(*(__last - 1)));
98     }
99
100   template<typename _RandomAccessIterator, typename _Distance, typename _Tp, 
101             typename _Compare>
102     void
103     __push_heap(_RandomAccessIterator __first, _Distance __holeIndex,
104                 _Distance __topIndex, _Tp __value, _Compare __comp)
105     {
106       _Distance __parent = (__holeIndex - 1) / 2;
107       while (__holeIndex > __topIndex && __comp(*(__first + __parent), __value)) {
108         *(__first + __holeIndex) = *(__first + __parent);
109         __holeIndex = __parent;
110         __parent = (__holeIndex - 1) / 2;
111       }
112       *(__first + __holeIndex) = __value;
113     }
114
115   template<typename _RandomAccessIterator, typename _Compare>
116     inline void 
117     push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
118               _Compare __comp)
119     {
120       typedef typename iterator_traits<_RandomAccessIterator>::value_type
121           _ValueType;
122       typedef typename iterator_traits<_RandomAccessIterator>::difference_type
123           _DistanceType;
124
125       // concept requirements
126       __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept<
127             _RandomAccessIterator>)
128
129       __push_heap(__first, _DistanceType((__last - __first) - 1), _DistanceType(0), 
130                   _ValueType(*(__last - 1)), __comp);
131     }
132
133   template<typename _RandomAccessIterator, typename _Distance, typename _Tp>
134     void 
135     __adjust_heap(_RandomAccessIterator __first, _Distance __holeIndex,
136                   _Distance __len, _Tp __value)
137     {
138       _Distance __topIndex = __holeIndex;
139       _Distance __secondChild = 2 * __holeIndex + 2;
140       while (__secondChild < __len) {
141         if (*(__first + __secondChild) < *(__first + (__secondChild - 1)))
142           __secondChild--;
143         *(__first + __holeIndex) = *(__first + __secondChild);
144         __holeIndex = __secondChild;
145         __secondChild = 2 * (__secondChild + 1);
146       }
147       if (__secondChild == __len) {
148         *(__first + __holeIndex) = *(__first + (__secondChild - 1));
149         __holeIndex = __secondChild - 1;
150       }
151       __push_heap(__first, __holeIndex, __topIndex, __value);
152     }
153
154   template<typename _RandomAccessIterator, typename _Tp>
155     inline void 
156     __pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
157                _RandomAccessIterator __result, _Tp __value)
158     {
159       typedef typename iterator_traits<_RandomAccessIterator>::difference_type _Distance;
160       *__result = *__first;
161       __adjust_heap(__first, _Distance(0), _Distance(__last - __first), __value);
162     }
163
164   template<typename _RandomAccessIterator>
165     inline void
166     pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
167     {
168       typedef typename iterator_traits<_RandomAccessIterator>::value_type _ValueType;
169
170       // concept requirements
171       __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept<
172             _RandomAccessIterator>)
173       __glibcpp_function_requires(_LessThanComparableConcept<_ValueType>)
174
175       __pop_heap(__first, __last - 1, __last - 1, _ValueType(*(__last - 1)));
176     }
177
178   template<typename _RandomAccessIterator, typename _Distance,
179            typename _Tp, typename _Compare>
180     void
181     __adjust_heap(_RandomAccessIterator __first, _Distance __holeIndex,
182                   _Distance __len, _Tp __value, _Compare __comp)
183     {
184       _Distance __topIndex = __holeIndex;
185       _Distance __secondChild = 2 * __holeIndex + 2;
186       while (__secondChild < __len) {
187         if (__comp(*(__first + __secondChild), *(__first + (__secondChild - 1))))
188           __secondChild--;
189         *(__first + __holeIndex) = *(__first + __secondChild);
190         __holeIndex = __secondChild;
191         __secondChild = 2 * (__secondChild + 1);
192       }
193       if (__secondChild == __len) {
194         *(__first + __holeIndex) = *(__first + (__secondChild - 1));
195         __holeIndex = __secondChild - 1;
196       }
197       __push_heap(__first, __holeIndex, __topIndex, __value, __comp);
198     }
199
200   template<typename _RandomAccessIterator, typename _Tp, typename _Compare>
201     inline void 
202     __pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
203                _RandomAccessIterator __result, _Tp __value, _Compare __comp)
204     {
205       typedef typename iterator_traits<_RandomAccessIterator>::difference_type _Distance;
206       *__result = *__first;
207       __adjust_heap(__first, _Distance(0), _Distance(__last - __first), 
208                     __value, __comp);
209     }
210
211   template<typename _RandomAccessIterator, typename _Compare>
212     inline void 
213     pop_heap(_RandomAccessIterator __first,
214              _RandomAccessIterator __last, _Compare __comp)
215     {
216       // concept requirements
217       __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept<
218             _RandomAccessIterator>)
219
220       typedef typename iterator_traits<_RandomAccessIterator>::value_type _ValueType;
221       __pop_heap(__first, __last - 1, __last - 1, _ValueType(*(__last - 1)), __comp);
222     }
223
224   template<typename _RandomAccessIterator>
225     void 
226     make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
227     {
228       typedef typename iterator_traits<_RandomAccessIterator>::value_type
229           _ValueType;
230       typedef typename iterator_traits<_RandomAccessIterator>::difference_type
231           _DistanceType;
232
233       // concept requirements
234       __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept<
235             _RandomAccessIterator>)
236       __glibcpp_function_requires(_LessThanComparableConcept<_ValueType>)
237
238       if (__last - __first < 2) return;
239       _DistanceType __len = __last - __first;
240       _DistanceType __parent = (__len - 2)/2;
241         
242       while (true) {
243         __adjust_heap(__first, __parent, __len, _ValueType(*(__first + __parent)));
244         if (__parent == 0) return;
245         __parent--;
246       }
247     }
248
249   template<typename _RandomAccessIterator, typename _Compare>
250     inline void 
251     make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
252               _Compare __comp)
253     {
254       typedef typename iterator_traits<_RandomAccessIterator>::value_type
255           _ValueType;
256       typedef typename iterator_traits<_RandomAccessIterator>::difference_type
257           _DistanceType;
258
259       // concept requirements
260       __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept<
261             _RandomAccessIterator>)
262
263       if (__last - __first < 2) return;
264       _DistanceType __len = __last - __first;
265       _DistanceType __parent = (__len - 2)/2;
266         
267       while (true) {
268         __adjust_heap(__first, __parent, __len,
269                       _ValueType(*(__first + __parent)), __comp);
270         if (__parent == 0) return;
271         __parent--;
272       }
273     }
274
275   template<typename _RandomAccessIterator>
276     void
277     sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
278     {
279       // concept requirements
280       __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept<
281             _RandomAccessIterator>)
282       __glibcpp_function_requires(_LessThanComparableConcept<
283             typename iterator_traits<_RandomAccessIterator>::value_type>)
284
285       while (__last - __first > 1)
286         pop_heap(__first, __last--);
287     }
288
289   template<typename _RandomAccessIterator, typename _Compare>
290     void 
291     sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
292               _Compare __comp)
293     {
294       // concept requirements
295       __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept<
296             _RandomAccessIterator>)
297
298       while (__last - __first > 1)
299         pop_heap(__first, __last--, __comp);
300     }
301
302 } // namespace std
303
304 #endif /* _CPP_BITS_STL_HEAP_H */
305
306 // Local Variables:
307 // mode:C++
308 // End: