91 if (comparator(left, right)) {
94 right->next = left->subheaps;
96 left->subheaps = right;
100 if (right->subheaps) {
101 left->next = right->subheaps;
103 right->subheaps = left;
122 }
else if (list->next == NULL) {
130 PHeap * next = list->next;
132 PHeap * rest = next->next;
134 return pheap_meld(pheap_meld(list, next, comparator), pheap_merge_pairs(rest, comparator), comparator);
149 PHeap * subs = heap->subheaps;
150 return pheap_merge_pairs(subs, comparator);
162 static void pheap_visit_heap(
PHeap * heap,
void (*func)(
PHeap *,
void*),
void* extra) {
165 pheap_visit_heap(heap->subheaps, func, extra);
166 pheap_visit_heap(heap->next, func, extra);
179 static void pheap_visit_heap_after(
PHeap * heap,
void (*func)(
PHeap *,
void*),
void* extra) {
181 pheap_visit_heap_after(heap->subheaps, func, extra);
182 pheap_visit_heap_after(heap->next, func, extra);
193 #define IS_PHeap(o) (krk_isInstanceOf(o,PHeapClass))
194 #define AS_PHeap(o) ((struct PHeap_Obj*)AS_OBJECT(o))
195 #define CURRENT_CTYPE struct PHeap_Obj *
196 #define CURRENT_NAME self
198 KRK_Method(
PHeap,__init__) {
200 if (!
krk_parseArgs(
".V:PHeap", (
const char*[]){
"comp"}, &comparator))
return NONE_VAL();
201 self->comparator = comparator;
205 static int run_comparator(
PHeap * left,
PHeap * right) {
206 assert(left->owner == right->owner);
211 if (!IS_BOOLEAN(result))
return 0;
212 return AS_BOOLEAN(result);
215 KRK_Method(
PHeap,insert) {
217 if (!
krk_parseArgs(
".V",(
const char*[]){
"value"}, &value))
return NONE_VAL();
218 struct PHeap * node = calloc(
sizeof(
struct PHeap), 1);
221 self->heap = pheap_meld(self->heap, node, run_comparator);
226 KRK_Method(
PHeap,peek) {
227 if (self->heap)
return self->heap->value;
231 KRK_Method(
PHeap,pop) {
232 PHeap * old =
self->heap;
234 self->heap = pheap_delete_min(self->heap, run_comparator);
241 KRK_Method(
PHeap,__bool__) {
242 return BOOLEAN_VAL(self->heap != NULL);
245 KRK_Method(
PHeap,__len__) {
246 return INTEGER_VAL(self->count);
249 static void run_visitor(
PHeap * heap,
void * visitor) {
255 KRK_Method(
PHeap,visit) {
259 &func, &after))
return NONE_VAL();
261 (after ? pheap_visit_heap_after : pheap_visit_heap)(self->heap, run_visitor, &func);
266 static void _scan_one(
PHeap * heap,
void * unused) {
273 pheap_visit_heap(self->heap, _scan_one, NULL);
276 static void _free_one(
PHeap * heap,
void * unused) {
282 pheap_visit_heap_after(self->heap,_free_one, NULL);
285 KRK_Method(
PHeap,comp) {
286 return self->comparator;
290 KRK_DOC(module,
"Pairing heap with simple insert and pop-min operations.");
293 KRK_DOC(
PHeap,
"Pairing heap with simple insert and pop-min operations.");
295 PHeap->_ongcscan = _pheap_scan;
296 PHeap->_ongcsweep = _pheap_sweep;
299 "@arguments comp\n\n"
300 "Create a new pairing heap governed by the given comparator function.");
302 "@arguments value\n\n"
303 "Insert a new element into the heap.");
305 "Retrieve the root (smallest) element of the heap, or None if it is empty.");
307 "Remove and return the root (smallest) element of the heap. If the heap is empty, IndexError is raised.");
308 BIND_METHOD(
PHeap,__bool__);
309 BIND_METHOD(
PHeap,__len__);
311 "@arguments func,after=False\n\n"
312 "Call a function for each element of the heap.");
313 BIND_PROP(
PHeap,comp);
KrkValue krk_runtimeError(KrkClass *type, const char *fmt,...)
Produce and raise an exception with a formatted message.
void krk_markValue(KrkValue value)
During a GC scan cycle, mark a value as used.
int(* pheap_comparator_func)(PHeap *, PHeap *)
Heap comparator function.
KrkClass * krk_makeClass(KrkInstance *module, KrkClass **_class, const char *name, KrkClass *base)
Convenience function for creating new types.
void krk_finalizeClass(KrkClass *_class)
Finalize a class by collecting pointers to core methods.
Stack reference or primative value.
Utilities for creating native bindings.
#define krk_parseArgs(f, n,...)
Parse arguments to a function while accepting keyword arguments.
#define KRK_DOC(thing, text)
Attach documentation to a thing of various types.
Core API for the bytecode virtual machine.
KrkValue krk_callStack(int argCount)
Call a callable on the stack with argCount arguments.
#define vm
Convenience macro for namespacing.
void krk_push(KrkValue value)
Push a stack value.