Update set (extra) foreach implementation
This commit is contained in:
parent
659c329880
commit
2f0a3a3c8e
@ -6,11 +6,14 @@
|
|||||||
#ifndef LIBCDSB_EXTRA_SET_H
|
#ifndef LIBCDSB_EXTRA_SET_H
|
||||||
#define LIBCDSB_EXTRA_SET_H
|
#define LIBCDSB_EXTRA_SET_H
|
||||||
|
|
||||||
#define vset_foreach libcdsb_vset_foreach
|
typedef int (*vset_foreach_callback)(const void* value, vtype type, void* data);
|
||||||
|
|
||||||
extern _Bool libcdsb_vset_find (vtype_value* x, vtype_set* s, const void* value, vtype type, _Bool cut);
|
|
||||||
extern _Bool libcdsb_vset_insert(vtype_set* x, const void* value, vtype type);
|
|
||||||
|
|
||||||
extern int libcdsb_vset_foreach(const vtype_set* x, void* data, int (*callback)(const void* value, vtype type, void* data)) LIBCDSB_nt__ LIBCDSB_nn13__;
|
#define vset_foreach(x, data, callback) libcdsb_vset_foreach(x, data, callback, 0)
|
||||||
|
|
||||||
|
extern _Bool libcdsb_vset_find (vtype_value* x, vtype_set* s, const void* value, vtype type, _Bool cut) LIBCDSB_nt__ LIBCDSB_nn23__;
|
||||||
|
extern _Bool libcdsb_vset_insert(vtype_set* x, const void* value, vtype type) LIBCDSB_nt__ LIBCDSB_nn12__;
|
||||||
|
|
||||||
|
extern int libcdsb_vset_foreach(vtype_set* x, void* data, vset_foreach_callback, _Bool flush) LIBCDSB_nt__ LIBCDSB_nn13__;
|
||||||
|
|
||||||
#endif /* LIBCDSB_EXTRA_SET_H */
|
#endif /* LIBCDSB_EXTRA_SET_H */
|
||||||
|
@ -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 };
|
stack_t z = { .prev = 0, .value = x->root };
|
||||||
int r = 0;
|
int r = 0;
|
||||||
rbnode_t* c;
|
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;
|
if (rbnode_is_empty(x->root)) return 0;
|
||||||
|
|
||||||
while ((c = stack_pop(&z))) {
|
while ((c = stack_pop(&z))) {
|
||||||
if ((r = callback(vnode_peek(&c->value, x->type), x->type, data))) {
|
if ((r = callback(vnode_peek(&c->value, x->type), x->type, data)))
|
||||||
stack_flush(&z);
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
if (!rbnode_is_empty(c->right)) stack_push(&z, c->right);
|
if (!rbnode_is_empty(c->right)) stack_push(&z, c->right);
|
||||||
if (!rbnode_is_empty(c->left)) stack_push(&z, c->left);
|
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;
|
return r;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user