/* This software is licensed by the MIT License, see LICENSE file */ /* Copyright © 2022 Gregory Lirent */ #include "../../include/set.h" #include "../__internal/rbtree.h" #include "../__internal/assert.h" bool libcdsb_vset_insert(set_t* x, const void* v, vtype t) { int cmp; rbnode_t* n; rbnode_t* p; vnode_t vn; n = x->root; vn = vnode_tcreate(x->type, v, t); t = x->type; v = vnode_peek(&vn, t); if (!rbnode_is_empty(n)) { do { p = n; cmp = vtype_compare(v, t, vnode_peek(&n->value, t), t); if (cmp == 0) { vnode_free(&vn, t); return false; } n = (cmp < 0) ? n->left : n->right; } while (!rbnode_is_empty(n)); n = rbnode_create(vn, p, 1); if (cmp < 0) p->left = n; else p->right = n; if (!rbnode_is_root(p)) rbnode_fixup(&x->root, n); } else n = x->root = rbnode_create(vn, rbnode_empty, 0); return true; } bool libcdsb_vset_attach(set_t* x, const void* v, vtype t) { int cmp; rbnode_t* n; rbnode_t* p; n = x->root; t = x->type; if (!rbnode_is_empty(n)) { do { p = n; cmp = vtype_compare(v, t, vnode_peek(&n->value, t), t); if (cmp == 0) return false; n = (cmp < 0) ? n->left : n->right; } while (!rbnode_is_empty(n)); n = rbnode_create(nullptr, p, 1); if (cmp < 0) p->left = n; else p->right = n; if (!rbnode_is_root(p)) rbnode_fixup(&x->root, n); } else n = x->root = rbnode_create(nullptr, rbnode_empty, 0); if (t < VTYPE_STRING) { n->value = vnode_tcreate(x->type, v, t); } else { type_assert(x->type, t); if (sizeof(str_t) == sizeof(void*) && t == VTYPE_STRING) { n->value = *(char**)v; } else { n->value = malloc(vtype_size(t)); memcpy(n->value, v, vtype_size(t)); } } return true; }