Update set (extra) foreach implementation
This commit is contained in:
+22
-4
@@ -70,7 +70,7 @@ _Bool libcdsb_vset_insert(set_t* x, const void* v, vtype t) {
|
||||
}
|
||||
|
||||
|
||||
int libcdsb_vset_foreach(const set_t* x, void* data, int (*callback)(const void* value, vtype type, void* data)) {
|
||||
int libcdsb_vset_foreach(set_t* x, void* data, vset_foreach_callback callback, _Bool flush) {
|
||||
stack_t z = { .prev = 0, .value = x->root };
|
||||
int r = 0;
|
||||
rbnode_t* c;
|
||||
@@ -78,14 +78,32 @@ int libcdsb_vset_foreach(const set_t* x, void* data, int (*callback)(const void*
|
||||
if (rbnode_is_empty(x->root)) return 0;
|
||||
|
||||
while ((c = stack_pop(&z))) {
|
||||
if ((r = callback(vnode_peek(&c->value, x->type), x->type, data))) {
|
||||
stack_flush(&z);
|
||||
if ((r = callback(vnode_peek(&c->value, x->type), x->type, data)))
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (!rbnode_is_empty(c->right)) stack_push(&z, c->right);
|
||||
if (!rbnode_is_empty(c->left)) stack_push(&z, c->left);
|
||||
|
||||
if (flush) {
|
||||
vnode_free(&c->value, x->type);
|
||||
free(c);
|
||||
}
|
||||
}
|
||||
|
||||
if (flush) {
|
||||
while (c) {
|
||||
if (!rbnode_is_empty(c->right)) stack_push(&z, c->right);
|
||||
if (!rbnode_is_empty(c->left)) stack_push(&z, c->left);
|
||||
|
||||
vnode_free(&c->value, x->type);
|
||||
free(c);
|
||||
|
||||
c = stack_pop(&z);
|
||||
}
|
||||
|
||||
memset(x, 0, sizeof(*x));
|
||||
} else stack_flush(&z);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user