PeriDyno 1.0.0
Loading...
Searching...
No Matches
Heap.h
Go to the documentation of this file.
1/*
2BSD 3 - Clause License
3
4Copyright(c) 2019, Electronic Arts
5All rights reserved.
6*/
7
8//Modified implementation is based on C++ EASTL.
9
10#ifndef HEAP_H
11#define HEAP_H
12#include "functional_base.h"
13#include "Platform.h"
14#include "type_traits.h"
15
16namespace dyno
17{
18
19 /*The publicly usable functions we define are :
20 // push_heap -- Adds an entry to a heap.
21 // pop_heap -- Removes the top entry from a heap.
22 // make_heap -- Converts an array to a heap.
23 // sort_heap -- Sorts a heap in place (return reverse order of cmp, i.e. greater: descend, less: ascend).
24 // remove_heap -- Removes an arbitrary entry from a heap.
25 // change_heap -- Changes the priority of an entry in the heap.
26 // is_heap -- Returns true if an array appears is in heap format.
27 // is_heap_until -- Returns largest part of the range which is a heap.
28 //
29 // Please noted that, we do not implement heap for default cmp, so one have to add explicit cmp to heap, e.g. less<float> cmp.
30 // See functional_base.h for those internal cmp. You are also welcomed to make own cmp inherited binary_function.
31 */
32
33 /*============================================== promote heap ======================================================*/
35 template <typename RandomAccessIterator, typename Distance, typename T, typename Compare, typename ValueType>
36 DYN_FUNC inline void promote_heap_impl(RandomAccessIterator first, Distance topPosition, Distance position, T value, Compare compare)
37 {
38 for (Distance parentPosition = (position - 1) >> 1; // This formula assumes that (position > 0). // We use '>> 1' instead of '/ 2' because we have seen VC++ generate better code with >>.
39 (position > topPosition) && compare(*(first + parentPosition), value);
40 parentPosition = (position - 1) >> 1)
41 {
42 *(first + position) = dyno::forward<ValueType>(*(first + parentPosition)); // Swap the node with its parent.
43 position = parentPosition;
44 }
45
46 *(first + position) = dyno::forward<ValueType>(value);
47 }
48
55 template <typename RandomAccessIterator, typename Distance, typename T, typename Compare>
56 DYN_FUNC inline void promote_heap(RandomAccessIterator first, Distance topPosition, Distance position, const T& value, Compare compare)
57 {
58 typedef typename iterator_traits<RandomAccessIterator>::value_type value_type;
60 }
61
62
63 template <typename RandomAccessIterator, typename Distance, typename T, typename Compare>
64 DYN_FUNC inline void promote_heap(RandomAccessIterator first, Distance topPosition, Distance position, T&& value, Compare compare)
65 {
66 typedef typename iterator_traits<RandomAccessIterator>::value_type value_type;
68 }
69
70
71 /*============================================== adjust heap ======================================================*/
73 template <typename RandomAccessIterator, typename Distance, typename T, typename Compare, typename ValueType>
74 DYN_FUNC void adjust_heap_impl(RandomAccessIterator first, Distance topPosition, Distance heapSize, Distance position, T value, Compare compare)
75 {
76 // We do the conventional approach of moving the position down to the
77 // bottom then inserting the value at the back and moving it up.
78 Distance childPosition = (2 * position) + 2;
79
80 for (; childPosition < heapSize; childPosition = (2 * childPosition) + 2)
81 {
82 if (compare(*(first + childPosition), *(first + (childPosition - 1)))) // Choose the larger of the two children.
83 --childPosition;
84 *(first + position) = dyno::forward<ValueType>(*(first + childPosition)); // Swap positions with this child.
85 position = childPosition;
86 }
87
88 if (childPosition == heapSize) // If we are at the bottom...
89 {
90 *(first + position) = dyno::forward<ValueType>(*(first + (childPosition - 1)));
91 position = childPosition - 1;
92 }
93
95 }
96
102 template <typename RandomAccessIterator, typename Distance, typename T, typename Compare>
103 DYN_FUNC void adjust_heap(RandomAccessIterator first, Distance topPosition, Distance heapSize, Distance position, const T& value, Compare compare)
104 {
105 typedef typename iterator_traits<RandomAccessIterator>::value_type value_type;
107 }
108
109 template <typename RandomAccessIterator, typename Distance, typename T, typename Compare>
110 DYN_FUNC void adjust_heap(RandomAccessIterator first, Distance topPosition, Distance heapSize, Distance position, T&& value, Compare compare)
111 {
112 typedef typename iterator_traits<RandomAccessIterator>::value_type value_type;
113 dyno::adjust_heap_impl<RandomAccessIterator, Distance, T&&, Compare, value_type>(first, topPosition, heapSize, position, dyno::forward<T>(value), compare);
114 }
115
116 /*================================================ push heap ======================================================*/
121 template <typename RandomAccessIterator, typename Compare>
122 DYN_FUNC inline void push_heap(RandomAccessIterator first, RandomAccessIterator last, Compare compare)
123 {
126
127 const value_type tempBottom(*(last - 1));
128
130 (first, (difference_type)0, (difference_type)(last - first - 1), tempBottom, compare);
131 }
132
133 /*================================================= pop heap ======================================================*/
139 template <typename RandomAccessIterator, typename Compare>
140 DYN_FUNC inline void pop_heap(RandomAccessIterator first, RandomAccessIterator last, Compare compare)
141 {
144
145 value_type tempBottom(dyno::forward<value_type>(*(last - 1)));
146 *(last - 1) = dyno::forward<value_type>(*first);
148 (first, (difference_type)0, (difference_type)(last - first - 1), 0, dyno::forward<value_type>(tempBottom), compare);
149 }
150
151
152 /*================================================ make heap ======================================================*/
158
159 template <typename RandomAccessIterator, typename Compare>
160 DYN_FUNC void make_heap(RandomAccessIterator first, RandomAccessIterator last, Compare compare)
161 {
164
165 const difference_type heapSize = last - first;
166
167 if (heapSize >= 2) // If there is anything to do... (we need this check because otherwise the math fails below).
168 {
169 difference_type parentPosition = ((heapSize - 2) >> 1) + 1;
170
171 do {
172 --parentPosition;
173 value_type temp(dyno::forward<value_type>(*(first + parentPosition)));
175 (first, parentPosition, heapSize, parentPosition, dyno::forward<value_type>(temp), compare);
176 } while (parentPosition != 0);
177 }
178 }
179
180 /*================================================ sort heap ====================================================*/
189 template <typename RandomAccessIterator, typename Compare>
190 DYN_FUNC inline void sort_heap(RandomAccessIterator first, RandomAccessIterator last, Compare compare)
191 {
192 for (; (last - first) > 1; --last) // We simply use the heap to sort itself.
194 }
195
196 /*================================================ remove heap ====================================================*/
202
203 template <typename RandomAccessIterator, typename Distance, typename Compare>
204 DYN_FUNC inline void remove_heap(RandomAccessIterator first, Distance heapSize, Distance position, Compare compare)
205 {
208
209 const value_type tempBottom(*(first + heapSize - 1));
210 *(first + heapSize - 1) = *(first + position);
212 (first, (difference_type)0, (difference_type)(heapSize - 1), (difference_type)position, tempBottom, compare);
213 }
214
215 /*================================================ change heap ====================================================*/
220 template <typename RandomAccessIterator, typename Distance, typename Compare>
221 DYN_FUNC inline void change_heap(RandomAccessIterator first, Distance heapSize, Distance position, Compare compare)
222 {
225
226 dyno::remove_heap<RandomAccessIterator, Distance, Compare>(first, heapSize, position, compare);
227
228 value_type tempBottom(*(first + heapSize - 1));
229
231 (first, (difference_type)0, (difference_type)(heapSize - 1), tempBottom, compare);
232 }
233
234 /*================================================ is_heap_until ==================================================*/
236 template <typename RandomAccessIterator, typename Compare>
237 DYN_FUNC inline RandomAccessIterator is_heap_until(RandomAccessIterator first, RandomAccessIterator last, Compare compare)
238 {
239 int counter = 0;
240
241 for (RandomAccessIterator child = first + 1; child < last; ++child, counter ^= 1)
242 {
243 if (compare(*first, *child))
244 return child;
245 first += counter; // counter switches between 0 and 1 every time through.
246 }
247
248 return last;
249 }
250
251 /*================================================== is_heap ======================================================*/
254 template <typename RandomAccessIterator>
255 DYN_FUNC inline bool is_heap(RandomAccessIterator first, RandomAccessIterator last)
256 {
257 return (dyno::is_heap_until(first, last) == last);
258 }
259
260
261}
262
263#endif // HEAP_H
#define T(t)
This is an implementation of AdditiveCCD based on peridyno.
Definition Array.h:25
DYN_FUNC void pop_heap(RandomAccessIterator first, RandomAccessIterator last, Compare compare)
Definition Heap.h:140
DYN_FUNC bool is_heap(RandomAccessIterator first, RandomAccessIterator last)
Definition Heap.h:255
DYN_FUNC void sort_heap(RandomAccessIterator first, RandomAccessIterator last, Compare compare)
Definition Heap.h:190
DYN_FUNC constexpr T && forward(typename dyno::remove_reference< T >::type &x) noexcept
Definition type_traits.h:17
DYN_FUNC void change_heap(RandomAccessIterator first, Distance heapSize, Distance position, Compare compare)
Definition Heap.h:221
DYN_FUNC void promote_heap_impl(RandomAccessIterator first, Distance topPosition, Distance position, T value, Compare compare)
promote_heap_implementation
Definition Heap.h:36
DYN_FUNC RandomAccessIterator is_heap_until(RandomAccessIterator first, RandomAccessIterator last, Compare compare)
is_heap_until
Definition Heap.h:237
DYN_FUNC void promote_heap(RandomAccessIterator first, Distance topPosition, Distance position, const T &value, Compare compare)
Definition Heap.h:56
DYN_FUNC void make_heap(RandomAccessIterator first, RandomAccessIterator last, Compare compare)
Definition Heap.h:160
DYN_FUNC void adjust_heap(RandomAccessIterator first, Distance topPosition, Distance heapSize, Distance position, const T &value, Compare compare)
Definition Heap.h:103
DYN_FUNC void adjust_heap_impl(RandomAccessIterator first, Distance topPosition, Distance heapSize, Distance position, T value, Compare compare)
adjust heap implementation
Definition Heap.h:74
DYN_FUNC void push_heap(RandomAccessIterator first, RandomAccessIterator last, Compare compare)
Definition Heap.h:122
DYN_FUNC void remove_heap(RandomAccessIterator first, Distance heapSize, Distance position, Compare compare)
Definition Heap.h:204