21template <
typename T,
typename I,
typename P = std::less<T>>
32 Heap( P pred = {} ) : pred_( pred ) {}
41 size_t size()
const {
return heap_.size(); }
66 bool less_(
size_t posA,
size_t posB )
const;
69 void lift_(
size_t pos,
I elemId );
72 std::vector<Element> heap_;
77template <
typename T,
typename I,
typename P>
79 : heap_(
size, {
I(), def } )
80 , id2PosInHeap_(
size )
84 for (
I i{ size_t( 0 ) }; i <
size; ++i )
91template <
typename T,
typename I,
typename P>
93 : heap_( std::move( elms ) )
94 , id2PosInHeap_( heap_.
size() )
98 std::make_heap( heap_.begin(), heap_.end(), [
this](
const Element & a,
const Element & b )
100 if ( pred_( a.val, b.val ) )
102 if ( pred_( b.val, a.val ) )
107 for (
size_t i = 0; i < heap_.size(); ++i )
108 id2PosInHeap_[heap_[i].
id] = i;
111template <
typename T,
typename I,
typename P>
115 assert ( heap_.size() == id2PosInHeap_.size() );
116 while ( heap_.size() <
size )
119 heap_.push_back( { i, def } );
120 id2PosInHeap_.push_back( i );
123 assert ( heap_.size() == id2PosInHeap_.size() );
126template <
typename T,
typename I,
typename P>
129 size_t pos = id2PosInHeap_[ elemId ];
130 assert( heap_[pos].
id == elemId );
131 if ( pred_( newVal, heap_[pos].val ) )
133 else if ( pred_( heap_[pos].val, newVal ) )
137template <
typename T,
typename I,
typename P>
140 size_t pos = id2PosInHeap_[ elemId ];
141 assert( heap_[pos].
id == elemId );
142 assert( !( pred_( newVal, heap_[pos].val ) ) );
143 heap_[pos].val = newVal;
144 lift_( pos, elemId );
147template <
typename T,
typename I,
typename P>
148void Heap<T, I, P>::lift_(
size_t pos,
I elemId )
152 size_t parentPos = ( pos - 1 ) / 2;
153 if ( !( less_( parentPos, pos ) ) )
155 auto parentId = heap_[parentPos].id;
156 assert( id2PosInHeap_[parentId] == parentPos );
157 std::swap( heap_[parentPos], heap_[pos] );
158 std::swap( parentPos, pos );
159 id2PosInHeap_[parentId] = parentPos;
161 id2PosInHeap_[elemId] = pos;
164template <
typename T,
typename I,
typename P>
167 size_t pos = id2PosInHeap_[ elemId ];
168 assert( heap_[pos].
id == elemId );
169 assert( !( pred_( heap_[pos].val, newVal ) ) );
170 heap_[pos].val = newVal;
173 size_t child1Pos = 2 * pos + 1;
174 if ( child1Pos >= heap_.size() )
176 auto child1Id = heap_[child1Pos].id;
177 size_t child2Pos = 2 * pos + 2;
178 if ( child2Pos >= heap_.size() )
180 assert( id2PosInHeap_[child1Id] == child1Pos );
181 if ( !( less_( child1Pos, pos ) ) )
183 std::swap( heap_[child1Pos], heap_[pos] );
184 std::swap( child1Pos, pos );
185 id2PosInHeap_[child1Id] = child1Pos;
189 auto child2Id = heap_[child2Pos].id;
190 if ( !( less_( child1Pos, pos ) ) && !( less_( child1Pos, child2Pos ) ) )
192 std::swap( heap_[child1Pos], heap_[pos] );
193 std::swap( child1Pos, pos );
194 id2PosInHeap_[child1Id] = child1Pos;
196 else if ( !( less_( child2Pos, pos ) ) )
198 assert( !( less_( child2Pos, child1Pos ) ) );
199 std::swap( heap_[child2Pos], heap_[pos] );
200 std::swap( child2Pos, pos );
201 id2PosInHeap_[child2Id] = child2Pos;
205 assert( !( less_( pos, child1Pos ) ) );
206 assert( !( less_( pos, child2Pos ) ) );
210 id2PosInHeap_[elemId] = pos;
213template <
typename T,
typename I,
typename P>
214inline bool Heap<T, I, P>::less_(
size_t posA,
size_t posB )
const
216 const auto & a = heap_[posA];
217 const auto & b = heap_[posB];
218 if ( pred_( a.val, b.val ) )
220 if ( pred_( b.val, a.val ) )
#define MR_LIFETIMEBOUND
Definition MRMacros.h:81
#define MR_LIFETIME_CAPTURE_BY_NESTED(x)
Definition MRMacros.h:86
#define MR_LIFETIMEBOUND_NESTED
Definition MRMacros.h:84
#define MR_TIMER
FUNCTION in GCC/Clang returns only short function name without class name and template parameters
Definition MRTimer.h:56
const Element & top() const MR_LIFETIMEBOUND
returns the element with the largest value
Definition MRHeap.h:50
size_t size() const
returns the size of the heap
Definition MRHeap.h:41
Heap(P pred={})
constructs an empty heap
Definition MRHeap.h:32
const T & value(I elemId) const MR_LIFETIMEBOUND
returns the value associated with given element
Definition MRHeap.h:47
Element setTopValue(const T &newVal MR_LIFETIME_CAPTURE_BY_NESTED(this))
sets new value to the current top element, returning its previous value
Definition MRHeap.h:62
void increaseValue(I elemId, const U &inc)
Definition MRHeap.h:59
std::vector<T>-like container that requires specific indexing type,
Definition MRVector.h:23
void setValue(I elemId, const T &newVal MR_LIFETIME_CAPTURE_BY_NESTED(this))
sets new value to given element
Definition MRHeap.h:127
void resize(size_t size, T def MR_LIFETIME_CAPTURE_BY_NESTED(this)={})
increases the size of the heap by adding elements at the end
Definition MRHeap.h:112
void setSmallerValue(I elemId, const T &newVal MR_LIFETIME_CAPTURE_BY_NESTED(this))
Definition MRHeap.h:165
void setLargerValue(I elemId, const T &newVal MR_LIFETIME_CAPTURE_BY_NESTED(this))
sets new value to given element, which shall be larger/smaller than the current value
Definition MRHeap.h:138
ImVec2 size(const ViewportRectangle &rect)
Definition MRViewport.h:32
class MRMESH_CLASS I
Definition MRMeshFwd.h:139
only for bindings generation
Definition MRCameraOrientationPlugin.h:8
T val
Definition MRHeap.h:28
I id
Definition MRHeap.h:27