/* This software is licensed by the MIT License, see LICENSE file */ /* Copyright © 2022 Gregory Lirent */ #include "../../include/set.h" #include "../__internal/rbtree.h" /*#####################################################################################################################*/ static int tree_compare(rbiter_t* s0, rbiter_t* s1, vtype t) { rbnode_t* p0; rbnode_t* p1; int cmp; for(;;) { p0 = rbiter_next(s0); p1 = rbiter_next(s1); if (rbnode_is_empty(p0) || rbnode_is_empty(p1)) { goto end_; } else cmp = vnode_compare(&p0->value, t, &p1->value, t); if (cmp != 0) break; } for(;;) { p0 = rbiter_next(s0); p1 = rbiter_next(s1); if (rbnode_is_empty(p0) || rbnode_is_empty(p1)) { end_: if (p0 == p1) return cmp; return (rbnode_is_empty(p0)) ? -1 : 1; } } } /*#####################################################################################################################*/ void vset_init(vtype_set* x, vtype t) { x->root = rbnode_empty; x->type = t; } void vset_free(vtype_set* x) { rbnode_t* t; rbnode_t* c; while (!rbnode_is_empty(x->root)) { if (!rbnode_is_empty(c->left)) { c = c->left; } else if (!rbnode_is_empty(c->right)) { c = c->right; } else if (!rbnode_is_root(c)) { vnode_free(&c->value, x->type); t = c; c = c->parent; if (t == c->left) c->left = rbnode_empty; else c->right = rbnode_empty; free(t); } else { vnode_free(&c->value, x->type); x->root = rbnode_empty; } } x->type = 0; } size_t vset_size(const vtype_set* x) { size_t n; rbiter_t i; n = 0; if (rbiter_init(&i, &x->root, 0)) { while (!rbnode_is_empty(rbiter_next(&i))) ++n; } return n; } int vset_compare(const vtype_set* s0, const vtype_set* s1) { rbiter_t iter[2]; if (s0 == s1) return 0; if (s0->type == s1->type) { rbiter_init(iter+0, &s0->root, RBI_INORDER); rbiter_init(iter+1, &s1->root, RBI_INORDER); return tree_compare(iter+0, iter+1, s0->type); } else return s0->type < s1->type ? -1 : 1; }