Refactor set, add attaching functional
This commit is contained in:
parent
925a8855ed
commit
b789b133e2
@ -3,7 +3,7 @@
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include "../include/extra/set.h"
|
||||
#include "../include/set.h"
|
||||
|
||||
typedef vtype_set vset_t;
|
||||
|
||||
@ -22,6 +22,7 @@ int print_value(const void* value, vtype type, void* data) {
|
||||
int main(int argc, char** argv) {
|
||||
|
||||
vset_t set;
|
||||
int a, b;
|
||||
|
||||
vset_init(&set, VTYPE_INT32);
|
||||
|
||||
@ -29,8 +30,11 @@ int main(int argc, char** argv) {
|
||||
vset_push(&set, i);
|
||||
}
|
||||
|
||||
vset_get(&set, 13, "Get value:", print_value);
|
||||
vset_pop(&set, 18, "Pop value:", print_value);
|
||||
a = 13;
|
||||
b = 18;
|
||||
|
||||
vset_get(&set, a, "Get value:", print_value);
|
||||
vset_pop(&set, b, "Pop value:", print_value);
|
||||
|
||||
vset_foreach(&set, "Foreach loop:", print_value);
|
||||
|
||||
|
@ -1,15 +0,0 @@
|
||||
/* This software is licensed by the MIT License, see LICENSE file */
|
||||
/* Copyright © 2022 Gregory Lirent */
|
||||
|
||||
#include "../set.h"
|
||||
|
||||
#ifndef LIBCDSB_EXTRA_SET_H
|
||||
#define LIBCDSB_EXTRA_SET_H
|
||||
|
||||
#define vset_foreach(x, data, callback) libcdsb_vset_foreach(x, data, callback, 0)
|
||||
|
||||
extern bool libcdsb_vset_insert (vtype_set* x, const void* value, vtype type) Nonnull__(1);
|
||||
extern int libcdsb_vset_find (vtype_set* x, const void* value, vtype type, void* data, vset_access_callback, bool cut) Nonnull__(1);
|
||||
extern int libcdsb_vset_foreach(vtype_set* x, void* data, vset_access_callback, bool flush) Nonnull__(1,3);
|
||||
|
||||
#endif /* LIBCDSB_EXTRA_SET_H */
|
@ -7,61 +7,28 @@
|
||||
#ifndef LIBCDSB_SET_H
|
||||
#define LIBCDSB_SET_H
|
||||
|
||||
/*#####################################################################################################################*/
|
||||
|
||||
typedef int (*vset_access_callback)(const void* value, vtype type, void* data);
|
||||
|
||||
/*#####################################################################################################################*/
|
||||
|
||||
extern void vset_init(vtype_set* x, vtype type) Nonnull__(1);
|
||||
|
||||
#define vset_pop(x, value, data, callback) _LIBCDSB_Generic (libcdsb_vset, find, value)(x, value, data, callback, 1)
|
||||
#define vset_get(x, value, data, callback) _LIBCDSB_Generic (libcdsb_vset, find, value)(x, value, data, callback, 0)
|
||||
#define vset_push(x, value) _LIBCDSB_Generic (libcdsb_vset, push, value)(x, value)
|
||||
#define vset_remove(x, value) vset_pop(x, value, 0, 0)
|
||||
/*#####################################################################################################################*/
|
||||
|
||||
#define in_vset(x, value) (vset_get(&x, value, 0, 0) == 0)
|
||||
#define vset_pop(x, value, data, callback) libcdsb_vset_find (x, _LIBCDSB_value_pointer(value), _LIBCDSB_vtypeof(value), data, callback, 1)
|
||||
#define vset_get(x, value, data, callback) libcdsb_vset_find (x, _LIBCDSB_value_pointer(value), _LIBCDSB_vtypeof(value), data, callback, 0)
|
||||
#define vset_push(x, value) libcdsb_vset_insert (x, _LIBCDSB_value_pointer(value), _LIBCDSB_vtypeof(value))
|
||||
#define vset_attach(x, value) libcdsb_vset_attach (x, _LIBCDSB_value_pointer(value), _LIBCDSB_vtypeof(value))
|
||||
#define vset_foreach(x, data, callback) libcdsb_vset_foreach(x, data, callback, 0)
|
||||
#define vset_remove(x, value) vset_pop (x, value, 0, 0)
|
||||
|
||||
#define in_vset(x, value) (vset_get(x, value, 0, 0) == 0)
|
||||
|
||||
/*#####################################################################################################################*/
|
||||
|
||||
extern bool libcdsb_vset_push_pointer(vtype_set* x, const void* value) Nonnull__(1);
|
||||
extern bool libcdsb_vset_push_cstring(vtype_set* x, const char* value) Nonnull__(1,2);
|
||||
extern bool libcdsb_vset_push_string (vtype_set* x, const vtype_string* value) Nonnull__(1,2);
|
||||
extern bool libcdsb_vset_push_array (vtype_set* x, const vtype_array* value) Nonnull__(1,2);
|
||||
extern bool libcdsb_vset_push_list (vtype_set* x, const vtype_list* value) Nonnull__(1,2);
|
||||
extern bool libcdsb_vset_push_map (vtype_set* x, const vtype_map* value) Nonnull__(1,2);
|
||||
extern bool libcdsb_vset_push_vset (vtype_set* x, const vtype_set* value) Nonnull__(1,2);
|
||||
extern bool libcdsb_vset_push_dict (vtype_set* x, const vtype_dict* value) Nonnull__(1,2);
|
||||
extern bool libcdsb_vset_push_boolean(vtype_set* x, vtype_bool value) Nonnull__(1);
|
||||
extern bool libcdsb_vset_push_uint8 (vtype_set* x, vtype_uint8 value) Nonnull__(1);
|
||||
extern bool libcdsb_vset_push_uint16 (vtype_set* x, vtype_uint16 value) Nonnull__(1);
|
||||
extern bool libcdsb_vset_push_uint32 (vtype_set* x, vtype_uint32 value) Nonnull__(1);
|
||||
extern bool libcdsb_vset_push_uint64 (vtype_set* x, vtype_uint64 value) Nonnull__(1);
|
||||
extern bool libcdsb_vset_push_int8 (vtype_set* x, vtype_int8 value) Nonnull__(1);
|
||||
extern bool libcdsb_vset_push_int16 (vtype_set* x, vtype_int16 value) Nonnull__(1);
|
||||
extern bool libcdsb_vset_push_int32 (vtype_set* x, vtype_int32 value) Nonnull__(1);
|
||||
extern bool libcdsb_vset_push_int64 (vtype_set* x, vtype_int64 value) Nonnull__(1);
|
||||
extern bool libcdsb_vset_push_float (vtype_set* x, vtype_float value) Nonnull__(1);
|
||||
extern bool libcdsb_vset_push_double (vtype_set* x, vtype_double value) Nonnull__(1);
|
||||
extern bool libcdsb_vset_push_ldouble(vtype_set* x, vtype_ldouble value) Nonnull__(1);
|
||||
|
||||
extern int libcdsb_vset_find_pointer(vtype_set* x, const void* value, void* data, vset_access_callback, bool cut) Nonnull__(1);
|
||||
extern int libcdsb_vset_find_cstring(vtype_set* x, const char* value, void* data, vset_access_callback, bool cut) Nonnull__(1,2);
|
||||
extern int libcdsb_vset_find_string (vtype_set* x, const vtype_string* value, void* data, vset_access_callback, bool cut) Nonnull__(1,2);
|
||||
extern int libcdsb_vset_find_array (vtype_set* x, const vtype_array* value, void* data, vset_access_callback, bool cut) Nonnull__(1,2);
|
||||
extern int libcdsb_vset_find_list (vtype_set* x, const vtype_list* value, void* data, vset_access_callback, bool cut) Nonnull__(1,2);
|
||||
extern int libcdsb_vset_find_map (vtype_set* x, const vtype_map* value, void* data, vset_access_callback, bool cut) Nonnull__(1,2);
|
||||
extern int libcdsb_vset_find_vset (vtype_set* x, const vtype_set* value, void* data, vset_access_callback, bool cut) Nonnull__(1,2);
|
||||
extern int libcdsb_vset_find_dict (vtype_set* x, const vtype_dict* value, void* data, vset_access_callback, bool cut) Nonnull__(1,2);
|
||||
extern int libcdsb_vset_find_boolean(vtype_set* x, vtype_bool value, void* data, vset_access_callback, bool cut) Nonnull__(1);
|
||||
extern int libcdsb_vset_find_uint8 (vtype_set* x, vtype_uint8 value, void* data, vset_access_callback, bool cut) Nonnull__(1);
|
||||
extern int libcdsb_vset_find_uint16 (vtype_set* x, vtype_uint16 value, void* data, vset_access_callback, bool cut) Nonnull__(1);
|
||||
extern int libcdsb_vset_find_uint32 (vtype_set* x, vtype_uint32 value, void* data, vset_access_callback, bool cut) Nonnull__(1);
|
||||
extern int libcdsb_vset_find_uint64 (vtype_set* x, vtype_uint64 value, void* data, vset_access_callback, bool cut) Nonnull__(1);
|
||||
extern int libcdsb_vset_find_int8 (vtype_set* x, vtype_int8 value, void* data, vset_access_callback, bool cut) Nonnull__(1);
|
||||
extern int libcdsb_vset_find_int16 (vtype_set* x, vtype_int16 value, void* data, vset_access_callback, bool cut) Nonnull__(1);
|
||||
extern int libcdsb_vset_find_int32 (vtype_set* x, vtype_int32 value, void* data, vset_access_callback, bool cut) Nonnull__(1);
|
||||
extern int libcdsb_vset_find_int64 (vtype_set* x, vtype_int64 value, void* data, vset_access_callback, bool cut) Nonnull__(1);
|
||||
extern int libcdsb_vset_find_float (vtype_set* x, vtype_float value, void* data, vset_access_callback, bool cut) Nonnull__(1);
|
||||
extern int libcdsb_vset_find_double (vtype_set* x, vtype_double value, void* data, vset_access_callback, bool cut) Nonnull__(1);
|
||||
extern int libcdsb_vset_find_ldouble(vtype_set* x, vtype_ldouble value, void* data, vset_access_callback, bool cut) Nonnull__(1);
|
||||
extern bool libcdsb_vset_insert (vtype_set* x, const void* value, vtype type) Nonnull__(1);
|
||||
extern bool libcdsb_vset_attach (vtype_set* x, const void* value, vtype type) Nonnull__(1);
|
||||
extern int libcdsb_vset_find (vtype_set* x, const void* value, vtype type, void* data, vset_access_callback, bool cut) Nonnull__(1);
|
||||
extern int libcdsb_vset_foreach(vtype_set* x, void* data, vset_access_callback, bool flush) Nonnull__(1,3);
|
||||
|
||||
#endif /* LIBCDSB_SET_H */
|
||||
|
@ -17,7 +17,7 @@ typedef struct libcdsb_rbtree_node {
|
||||
|
||||
extern rbnode_t LIBCDSB_RBTREE_NODE_EMPTY[1];
|
||||
|
||||
extern void* libcdsb_rbtree_node_create(void* value, rbnode_t* parent, int colored, int size) Nonnull__(1,2);
|
||||
extern void* libcdsb_rbtree_node_create(void* value, rbnode_t* parent, int colored, int size) Nonnull__( 2);
|
||||
extern void libcdsb_rbtree_node_fixup (rbnode_t** root, rbnode_t* node) Nonnull__(1,2);
|
||||
extern rbnode_t* libcdsb_rbtree_node_delete(rbnode_t** root, rbnode_t* node) Nonnull__(1,2);
|
||||
|
||||
|
@ -1,47 +1,9 @@
|
||||
/* This software is licensed by the MIT License, see LICENSE file */
|
||||
/* Copyright © 2022 Gregory Lirent */
|
||||
|
||||
#include "../../include/extra/set.h"
|
||||
#include "../../include/set.h"
|
||||
#include "../__internal/rbtree.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;
|
||||
}
|
||||
|
||||
|
||||
int libcdsb_vset_find(vtype_set* x, const void* v, vtype t, void* _, vset_access_callback callback, bool cut) {
|
||||
rbnode_t* c;
|
||||
void *val;
|
161
src/set/base.c
161
src/set/base.c
@ -1,161 +0,0 @@
|
||||
/* This software is licensed by the MIT License, see LICENSE file */
|
||||
/* Copyright © 2022 Gregory Lirent */
|
||||
|
||||
#include "../../include/set.h"
|
||||
#include "../__internal/rbtree.h"
|
||||
|
||||
/*#####################################################################################################################*/
|
||||
|
||||
static inline int rbnode_compare(const rbnode_t* s0, const rbnode_t* s1, vtype t) {
|
||||
return vnode_compare(s0->value, t, s1->value, t);
|
||||
}
|
||||
|
||||
static inline hash_t rbnode_hash(const rbnode_t* s, vtype t) {
|
||||
return vnode_hash(&s->value, t);
|
||||
}
|
||||
|
||||
/*#####################################################################################################################*/
|
||||
|
||||
hash_t vset_hash(const set_t* s) {
|
||||
|
||||
stack_t z;
|
||||
rbnode_t *c0, *c1;
|
||||
hash_t hash, v;
|
||||
|
||||
if (rbnode_is_empty(s->root))
|
||||
return 0;
|
||||
|
||||
stack_init(&z);
|
||||
stack_push(&z, s->root->left);
|
||||
|
||||
hash = 1;
|
||||
|
||||
if (!rbnode_is_empty(c0 = stack_pop(&z))) {
|
||||
do {
|
||||
++hash;
|
||||
if (!rbnode_is_empty(c0->right)) stack_push(&z, c0->right);
|
||||
if (!rbnode_is_empty(c0->left)) stack_push(&z, c1 = c0->left);
|
||||
} while (!is_null(c0 = stack_pop(&z)));
|
||||
}
|
||||
|
||||
v = rbnode_hash(c1, s->type);
|
||||
stack_push(&z, s->root->right);
|
||||
|
||||
if (!rbnode_is_empty(c0 = stack_pop(&z))) {
|
||||
do {
|
||||
++hash;
|
||||
if (!rbnode_is_empty(c0->right)) stack_push(&z, c1 = c0->right);
|
||||
if (!rbnode_is_empty(c0->left)) stack_push(&z, c0->left);
|
||||
} while (!is_null(c0 = stack_pop(&z)));
|
||||
}
|
||||
|
||||
v += rbnode_hash(c1, s->type);
|
||||
|
||||
return (hash ^ v) + VTYPE_SET;
|
||||
}
|
||||
|
||||
/*#####################################################################################################################*/
|
||||
|
||||
void vset_init(set_t* x, vtype t) {
|
||||
x->root = rbnode_empty;
|
||||
x->type = t;
|
||||
}
|
||||
|
||||
|
||||
void vset_free(set_t* x) {
|
||||
rbnode_t *t, *c;
|
||||
|
||||
c = x->root;
|
||||
|
||||
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 set_t* x) {
|
||||
stack_t z;
|
||||
size_t n;
|
||||
rbnode_t* c;
|
||||
|
||||
stack_init(&z);
|
||||
stack_push(&z, x->root);
|
||||
|
||||
n = 0;
|
||||
|
||||
if (!rbnode_is_empty(x->root)) {
|
||||
while ((c = stack_pop(&z))) {
|
||||
++n;
|
||||
if (!rbnode_is_empty(c->right)) stack_push(&z, c->right);
|
||||
if (!rbnode_is_empty(c->left)) stack_push(&z, c->left);
|
||||
}
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
/*#####################################################################################################################*/
|
||||
|
||||
int vset_compare(const set_t* s0, const set_t* s1) {
|
||||
stack_t z;
|
||||
rbnode_t *c0, *c1;
|
||||
int cmp;
|
||||
|
||||
if (s0 == s1 || s0->root == s1->root)
|
||||
return 0;
|
||||
if (s0->type != s1->type)
|
||||
return s0->type - s1->type;
|
||||
|
||||
stack_init(&z);
|
||||
stack_push_many(&z, 2, (void*)s1, (void*)s0);
|
||||
|
||||
cmp = 0;
|
||||
|
||||
do {
|
||||
c0 = stack_pop(&z);
|
||||
c1 = stack_pop(&z);
|
||||
|
||||
if (rbnode_is_empty(c0) || rbnode_is_empty(c1)) {
|
||||
if (c0 != c1) {
|
||||
stack_flush(&z);
|
||||
return rbnode_is_empty(c0) ? -1 : 1;
|
||||
}
|
||||
} else if ((cmp = rbnode_compare(c0, c1, s0->type))) {
|
||||
if (c0->left == c1->right) { // == rbnode_empty
|
||||
cmp = rbnode_compare(c0->right, c1, s0->type);
|
||||
if (!cmp) cmp = rbnode_compare(c0, c1->left, s0->type);
|
||||
} else if (c0->right == c1->left) { // == rbnode_empty
|
||||
cmp = rbnode_compare(c0, c1->right, s0->type);
|
||||
if (!cmp) cmp = rbnode_compare(c0->left, c1, s0->type);
|
||||
}
|
||||
|
||||
if (cmp) {
|
||||
stack_flush(&z);
|
||||
return cmp;
|
||||
}
|
||||
} else stack_push_many(&z, 4, c1->right, c0->right, c1->left, c0->left);
|
||||
|
||||
} while (!is_null(z.value));
|
||||
|
||||
return 0;
|
||||
}
|
55
src/set/comparison.c
Normal file
55
src/set/comparison.c
Normal file
@ -0,0 +1,55 @@
|
||||
/* This software is licensed by the MIT License, see LICENSE file */
|
||||
/* Copyright © 2022 Gregory Lirent */
|
||||
|
||||
#include "../../include/set.h"
|
||||
#include "../__internal/rbtree.h"
|
||||
|
||||
static inline int rbnode_compare(const rbnode_t* s0, const rbnode_t* s1, vtype t) {
|
||||
return vnode_compare(s0->value, t, s1->value, t);
|
||||
}
|
||||
|
||||
/*#####################################################################################################################*/
|
||||
|
||||
int vset_compare(const set_t* s0, const set_t* s1) {
|
||||
stack_t z;
|
||||
rbnode_t *c0, *c1;
|
||||
int cmp;
|
||||
|
||||
if (s0 == s1 || s0->root == s1->root)
|
||||
return 0;
|
||||
if (s0->type != s1->type)
|
||||
return s0->type - s1->type;
|
||||
|
||||
stack_init(&z);
|
||||
stack_push_many(&z, 2, (void*)s1, (void*)s0);
|
||||
|
||||
cmp = 0;
|
||||
|
||||
do {
|
||||
c0 = stack_pop(&z);
|
||||
c1 = stack_pop(&z);
|
||||
|
||||
if (rbnode_is_empty(c0) || rbnode_is_empty(c1)) {
|
||||
if (c0 != c1) {
|
||||
stack_flush(&z);
|
||||
return rbnode_is_empty(c0) ? -1 : 1;
|
||||
}
|
||||
} else if ((cmp = rbnode_compare(c0, c1, s0->type))) {
|
||||
if (c0->left == c1->right) { // == rbnode_empty
|
||||
cmp = rbnode_compare(c0->right, c1, s0->type);
|
||||
if (!cmp) cmp = rbnode_compare(c0, c1->left, s0->type);
|
||||
} else if (c0->right == c1->left) { // == rbnode_empty
|
||||
cmp = rbnode_compare(c0, c1->right, s0->type);
|
||||
if (!cmp) cmp = rbnode_compare(c0->left, c1, s0->type);
|
||||
}
|
||||
|
||||
if (cmp) {
|
||||
stack_flush(&z);
|
||||
return cmp;
|
||||
}
|
||||
} else stack_push_many(&z, 4, c1->right, c0->right, c1->left, c0->left);
|
||||
|
||||
} while (!is_null(z.value));
|
||||
|
||||
return 0;
|
||||
}
|
71
src/set/compute.c
Normal file
71
src/set/compute.c
Normal file
@ -0,0 +1,71 @@
|
||||
/* This software is licensed by the MIT License, see LICENSE file */
|
||||
/* Copyright © 2022 Gregory Lirent */
|
||||
|
||||
#include "../../include/set.h"
|
||||
#include "../__internal/rbtree.h"
|
||||
|
||||
static inline hash_t rbnode_hash(const rbnode_t* s, vtype t) {
|
||||
return vnode_hash(&s->value, t);
|
||||
}
|
||||
|
||||
/*#####################################################################################################################*/
|
||||
|
||||
size_t vset_size(const set_t* x) {
|
||||
stack_t z;
|
||||
size_t n;
|
||||
rbnode_t* c;
|
||||
|
||||
stack_init(&z);
|
||||
stack_push(&z, x->root);
|
||||
|
||||
n = 0;
|
||||
|
||||
if (!rbnode_is_empty(x->root)) {
|
||||
while ((c = stack_pop(&z))) {
|
||||
++n;
|
||||
if (!rbnode_is_empty(c->right)) stack_push(&z, c->right);
|
||||
if (!rbnode_is_empty(c->left)) stack_push(&z, c->left);
|
||||
}
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
hash_t vset_hash(const set_t* s) {
|
||||
|
||||
stack_t z;
|
||||
rbnode_t *c0, *c1;
|
||||
hash_t hash, v;
|
||||
|
||||
if (rbnode_is_empty(s->root))
|
||||
return 0;
|
||||
|
||||
stack_init(&z);
|
||||
stack_push(&z, s->root->left);
|
||||
|
||||
hash = 1;
|
||||
|
||||
if (!rbnode_is_empty(c0 = stack_pop(&z))) {
|
||||
do {
|
||||
++hash;
|
||||
if (!rbnode_is_empty(c0->right)) stack_push(&z, c0->right);
|
||||
if (!rbnode_is_empty(c0->left)) stack_push(&z, c1 = c0->left);
|
||||
} while (!is_null(c0 = stack_pop(&z)));
|
||||
}
|
||||
|
||||
v = rbnode_hash(c1, s->type);
|
||||
stack_push(&z, s->root->right);
|
||||
|
||||
if (!rbnode_is_empty(c0 = stack_pop(&z))) {
|
||||
do {
|
||||
++hash;
|
||||
if (!rbnode_is_empty(c0->right)) stack_push(&z, c1 = c0->right);
|
||||
if (!rbnode_is_empty(c0->left)) stack_push(&z, c0->left);
|
||||
} while (!is_null(c0 = stack_pop(&z)));
|
||||
}
|
||||
|
||||
v += rbnode_hash(c1, s->type);
|
||||
|
||||
return (hash ^ v) + VTYPE_SET;
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
/* This software is licensed by the MIT License, see LICENSE file */
|
||||
/* Copyright © 2022 Gregory Lirent */
|
||||
|
||||
#include "../../include/extra/set.h"
|
||||
#include "../__internal/include.h"
|
||||
|
||||
int libcdsb_vset_find_pointer(set_t* x, const void* v, void* _, vset_access_callback cb, bool cut) { return libcdsb_vset_find(x, &v, vtypeof(&v), _, cb, cut); }
|
||||
int libcdsb_vset_find_cstring(set_t* x, const char* v, void* _, vset_access_callback cb, bool cut) { return libcdsb_vset_find(x, &v, vtypeof(&v), _, cb, cut); }
|
||||
int libcdsb_vset_find_string (set_t* x, const str_t* v, void* _, vset_access_callback cb, bool cut) { return libcdsb_vset_find(x, v, vtypeof( v), _, cb, cut); }
|
||||
int libcdsb_vset_find_array (set_t* x, const arr_t* v, void* _, vset_access_callback cb, bool cut) { return libcdsb_vset_find(x, v, vtypeof( v), _, cb, cut); }
|
||||
int libcdsb_vset_find_list (set_t* x, const list_t* v, void* _, vset_access_callback cb, bool cut) { return libcdsb_vset_find(x, v, vtypeof( v), _, cb, cut); }
|
||||
int libcdsb_vset_find_map (set_t* x, const map_t* v, void* _, vset_access_callback cb, bool cut) { return libcdsb_vset_find(x, v, vtypeof( v), _, cb, cut); }
|
||||
int libcdsb_vset_find_vset (set_t* x, const set_t* v, void* _, vset_access_callback cb, bool cut) { return libcdsb_vset_find(x, v, vtypeof( v), _, cb, cut); }
|
||||
int libcdsb_vset_find_dict (set_t* x, const dict_t* v, void* _, vset_access_callback cb, bool cut) { return libcdsb_vset_find(x, v, vtypeof( v), _, cb, cut); }
|
||||
int libcdsb_vset_find_boolean(set_t* x, bool v, void* _, vset_access_callback cb, bool cut) { return libcdsb_vset_find(x, &v, vtypeof(&v), _, cb, cut); }
|
||||
int libcdsb_vset_find_int8 (set_t* x, s8_t v, void* _, vset_access_callback cb, bool cut) { return libcdsb_vset_find(x, &v, vtypeof(&v), _, cb, cut); }
|
||||
int libcdsb_vset_find_int16 (set_t* x, s16_t v, void* _, vset_access_callback cb, bool cut) { return libcdsb_vset_find(x, &v, vtypeof(&v), _, cb, cut); }
|
||||
int libcdsb_vset_find_int32 (set_t* x, s32_t v, void* _, vset_access_callback cb, bool cut) { return libcdsb_vset_find(x, &v, vtypeof(&v), _, cb, cut); }
|
||||
int libcdsb_vset_find_int64 (set_t* x, s64_t v, void* _, vset_access_callback cb, bool cut) { return libcdsb_vset_find(x, &v, vtypeof(&v), _, cb, cut); }
|
||||
int libcdsb_vset_find_uint8 (set_t* x, u8_t v, void* _, vset_access_callback cb, bool cut) { return libcdsb_vset_find(x, &v, vtypeof(&v), _, cb, cut); }
|
||||
int libcdsb_vset_find_uint16 (set_t* x, u16_t v, void* _, vset_access_callback cb, bool cut) { return libcdsb_vset_find(x, &v, vtypeof(&v), _, cb, cut); }
|
||||
int libcdsb_vset_find_uint32 (set_t* x, u32_t v, void* _, vset_access_callback cb, bool cut) { return libcdsb_vset_find(x, &v, vtypeof(&v), _, cb, cut); }
|
||||
int libcdsb_vset_find_uint64 (set_t* x, u64_t v, void* _, vset_access_callback cb, bool cut) { return libcdsb_vset_find(x, &v, vtypeof(&v), _, cb, cut); }
|
||||
int libcdsb_vset_find_float (set_t* x, fl_t v, void* _, vset_access_callback cb, bool cut) { return libcdsb_vset_find(x, &v, vtypeof(&v), _, cb, cut); }
|
||||
int libcdsb_vset_find_double (set_t* x, dbl_t v, void* _, vset_access_callback cb, bool cut) { return libcdsb_vset_find(x, &v, vtypeof(&v), _, cb, cut); }
|
||||
int libcdsb_vset_find_ldouble(set_t* x, ldbl_t v, void* _, vset_access_callback cb, bool cut) { return libcdsb_vset_find(x, &v, vtypeof(&v), _, cb, cut); }
|
||||
|
||||
bool libcdsb_vset_push_pointer(set_t* x, const void* v) { return libcdsb_vset_insert(x, &v, vtypeof(&v)); }
|
||||
bool libcdsb_vset_push_cstring(set_t* x, const char* v) { return libcdsb_vset_insert(x, &v, vtypeof(&v)); }
|
||||
bool libcdsb_vset_push_string (set_t* x, const str_t* v) { return libcdsb_vset_insert(x, v, vtypeof( v)); }
|
||||
bool libcdsb_vset_push_array (set_t* x, const arr_t* v) { return libcdsb_vset_insert(x, v, vtypeof( v)); }
|
||||
bool libcdsb_vset_push_list (set_t* x, const list_t* v) { return libcdsb_vset_insert(x, v, vtypeof( v)); }
|
||||
bool libcdsb_vset_push_map (set_t* x, const map_t* v) { return libcdsb_vset_insert(x, v, vtypeof( v)); }
|
||||
bool libcdsb_vset_push_vset (set_t* x, const set_t* v) { return libcdsb_vset_insert(x, v, vtypeof( v)); }
|
||||
bool libcdsb_vset_push_dict (set_t* x, const dict_t* v) { return libcdsb_vset_insert(x, v, vtypeof( v)); }
|
||||
bool libcdsb_vset_push_boolean(set_t* x, bool v) { return libcdsb_vset_insert(x, &v, vtypeof(&v)); }
|
||||
bool libcdsb_vset_push_int8 (set_t* x, s8_t v) { return libcdsb_vset_insert(x, &v, vtypeof(&v)); }
|
||||
bool libcdsb_vset_push_int16 (set_t* x, s16_t v) { return libcdsb_vset_insert(x, &v, vtypeof(&v)); }
|
||||
bool libcdsb_vset_push_int32 (set_t* x, s32_t v) { return libcdsb_vset_insert(x, &v, vtypeof(&v)); }
|
||||
bool libcdsb_vset_push_int64 (set_t* x, s64_t v) { return libcdsb_vset_insert(x, &v, vtypeof(&v)); }
|
||||
bool libcdsb_vset_push_uint8 (set_t* x, u8_t v) { return libcdsb_vset_insert(x, &v, vtypeof(&v)); }
|
||||
bool libcdsb_vset_push_uint16 (set_t* x, u16_t v) { return libcdsb_vset_insert(x, &v, vtypeof(&v)); }
|
||||
bool libcdsb_vset_push_uint32 (set_t* x, u32_t v) { return libcdsb_vset_insert(x, &v, vtypeof(&v)); }
|
||||
bool libcdsb_vset_push_uint64 (set_t* x, u64_t v) { return libcdsb_vset_insert(x, &v, vtypeof(&v)); }
|
||||
bool libcdsb_vset_push_float (set_t* x, fl_t v) { return libcdsb_vset_insert(x, &v, vtypeof(&v)); }
|
||||
bool libcdsb_vset_push_double (set_t* x, dbl_t v) { return libcdsb_vset_insert(x, &v, vtypeof(&v)); }
|
||||
bool libcdsb_vset_push_ldouble(set_t* x, ldbl_t v) { return libcdsb_vset_insert(x, &v, vtypeof(&v)); }
|
39
src/set/memory.c
Normal file
39
src/set/memory.c
Normal file
@ -0,0 +1,39 @@
|
||||
/* This software is licensed by the MIT License, see LICENSE file */
|
||||
/* Copyright © 2022 Gregory Lirent */
|
||||
|
||||
#include "../../include/set.h"
|
||||
#include "../__internal/rbtree.h"
|
||||
|
||||
void vset_init(set_t* x, vtype t) {
|
||||
x->root = rbnode_empty;
|
||||
x->type = t;
|
||||
}
|
||||
|
||||
void vset_free(set_t* x) {
|
||||
rbnode_t *t, *c;
|
||||
|
||||
c = x->root;
|
||||
|
||||
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;
|
||||
}
|
88
src/set/modify.c
Normal file
88
src/set/modify.c
Normal file
@ -0,0 +1,88 @@
|
||||
/* 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;
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
/* This software is licensed by the MIT License, see LICENSE file */
|
||||
/* Copyright © 2022 Gregory Lirent */
|
||||
|
||||
#include "../../../include/extra/set.h"
|
||||
#include "../../../include/set.h"
|
||||
#include "../../../src/__internal/rbtree.h"
|
||||
|
||||
#include "../../include/random.h"
|
||||
|
Loading…
Reference in New Issue
Block a user