89 lines
2.1 KiB
C
89 lines
2.1 KiB
C
|
/* 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;
|
||
|
}
|