Update vnode comparison interface (vtype_variable)
This commit is contained in:
parent
3e860c26d3
commit
2b1bccb7e8
@ -80,8 +80,8 @@ typedef struct libcdsb_string vtype_string;
|
||||
typedef struct libcdsb_variable vtype_variable;
|
||||
|
||||
|
||||
extern const char* libcdsb_vtype_name (vtype t) Warn_unused_result__;
|
||||
extern const char* libcdsb_vtype_stringify(const void* value, vtype t) Warn_unused_result__;
|
||||
extern const char* libcdsb_vtype_name (vtype t) Warn_unused_result__;
|
||||
extern const char* libcdsb_vtype_stringify(vtype_variable value) Warn_unused_result__;
|
||||
|
||||
inline vtype_variable libcdsb_variable_build(void* value, vtype t) Always_inline__;
|
||||
|
||||
|
@ -60,9 +60,8 @@ typedef vtype_hash hash_t;
|
||||
|
||||
extern const size_t LIBCDSB_BUILTIN_VTYPE_SIZES[19];
|
||||
|
||||
extern int libcdsb_builtin_vtype_compare_values (const void* s0, vtype t0, const void* s1, vtype t1) pure__ wur__;
|
||||
extern int libcdsb_builtin_vtype_compare_values_eq(const void* s0, const void* s1, vtype t) pure__ wur__;
|
||||
extern hash_t libcdsb_builtin_vtype_hash (const void* value, vtype type) pure__ wur__;
|
||||
extern int libcdsb_builtin_variable_compare(vtype_variable s0, vtype_variable s1) pure__ wur__;
|
||||
extern hash_t libcdsb_builtin_vtype_hash (const void* value, vtype type) pure__ wur__;
|
||||
|
||||
ainline(stack_t* libcdsb_builtin_stack_insert(stack_t* x, void* v)) {
|
||||
stack_t* p = x->prev;
|
||||
@ -95,9 +94,9 @@ ainline(stack_t* libcdsb_builtin_stack_insert(stack_t* x, void* v)) {
|
||||
|
||||
#define vtype_stringify libcdsb_vtype_stringify
|
||||
#define vtype_name libcdsb_vtype_name
|
||||
#define vtype_compare libcdsb_builtin_vtype_compare_values
|
||||
#define vtype_compare_eq libcdsb_builtin_vtype_compare_values_eq
|
||||
#define vtype_hash libcdsb_builtin_vtype_hash
|
||||
#define vtype_size(type) (LIBCDSB_BUILTIN_VTYPE_SIZES[type])
|
||||
|
||||
#define variable_compare libcdsb_builtin_variable_compare
|
||||
|
||||
#endif /* LIBCDSB_SRC_INTERNAL_INCLUDE */
|
||||
|
@ -23,7 +23,9 @@ extern vnode_t libcdsb_builtin_vnode_create (const void* value, vtype type
|
||||
extern vnode_t libcdsb_builtin_vnode_create_target(vtype target_type, const void* value, vtype type) wur__;
|
||||
|
||||
extern void libcdsb_builtin_vnode_free(vnode_t* x, vtype type) Nonnull__(1);
|
||||
extern void* libcdsb_builtin_vnode_peek(const vnode_t* x, vtype type) pure__ wur__ Nonnull__(1);
|
||||
|
||||
extern vtype_variable libcdsb_builtin_vnode_peek(const vnode_t* x, vtype type) pure__ wur__ Nonnull__(1);
|
||||
|
||||
|
||||
ainline(void libcdsb_builtin_vnode_attach(vnode_t* node, const void* value, vtype type)) {
|
||||
if (type < VTYPE_STRING) {
|
||||
@ -58,12 +60,12 @@ ainline(void libcdsb_builtin_vnode_tattach(vnode_t* node, vtype target_type, con
|
||||
#define vnode_peek libcdsb_builtin_vnode_peek
|
||||
#define vnode_free libcdsb_builtin_vnode_free
|
||||
|
||||
#define vnode_hash(vnode, type) vtype_hash(vnode_peek(vnode, type), type)
|
||||
#define vnode_compare(s0, t0, s1, t1) vtype_compare(vnode_peek(s0, t0), t0, vnode_peek(s1, t1), t1)
|
||||
#define vnode_compare_eq(s0, s1, t) vtype_compare_eq(vnode_peek(s0, t), vnode_peek(s1, t), t)
|
||||
#define vnode_duplicate(vnode, type) vnode_create(vnode_peek(vnode, type), type)
|
||||
#define vnode_hash(vnode, type) vtype_hash(vnode_peek(vnode, type).pointer, type)
|
||||
#define vnode_compare(s0, t0, s1, t1) variable_compare(vnode_peek(s0, t0), vnode_peek(s1, t1))
|
||||
#define vnode_compare_eq(s0, s1, t) variable_compare(vnode_peek(s0, t ), vnode_peek(s1, t ))
|
||||
#define vnode_duplicate(vnode, type) vnode_create(vnode_peek(vnode, type).pointer, type)
|
||||
#define vnode_tduplicate(target_type, vnode, type) vnode_tcreate(target_type, vnode_peek(vnode, type), type)
|
||||
|
||||
#define vnode_stringify(n, t) vtype_stringify(vnode_peek(n, t), t)
|
||||
#define vnode_stringify(n, t) vtype_stringify(vnode_peek(n, t))
|
||||
|
||||
#endif /* LIBCDSB_SRC_INTERNAL_VNODE_H */
|
||||
|
@ -35,7 +35,7 @@ int libcdsb_array_find(arr_t* x, vtype_variable var, void* _, array_access_callb
|
||||
i = 0;
|
||||
|
||||
do {
|
||||
cmp = vtype_compare(p, x->type, var.pointer, var.type);
|
||||
cmp = variable_compare(libcdsb_variable_build(p, x->type), var);
|
||||
|
||||
if (cmp == 0) break;
|
||||
|
||||
@ -50,7 +50,7 @@ int libcdsb_array_find(arr_t* x, vtype_variable var, void* _, array_access_callb
|
||||
|
||||
while (i--) {
|
||||
p -= vtype_size(x->type);
|
||||
cmp = vtype_compare(p, x->type, var.pointer, var.type);
|
||||
cmp = variable_compare(libcdsb_variable_build(p, x->type), var);
|
||||
|
||||
if (cmp == 0) break;
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ int array_compare(const arr_t* s0, const arr_t* s1) {
|
||||
e = array_end(s0);
|
||||
|
||||
do {
|
||||
cmp = vtype_compare_eq(p0, p1, s0->type);
|
||||
cmp = variable_compare(libcdsb_variable_build(p0, s0->type), libcdsb_variable_build(p1, s0->type));
|
||||
|
||||
if (cmp == 0) {
|
||||
p0 += vtype_size(s0->type);
|
||||
|
@ -35,7 +35,7 @@ size_t libcdsb_array_count(const arr_t* s, vtype_variable var) {
|
||||
n = 0;
|
||||
|
||||
do {
|
||||
cmp = vtype_compare(p, s->type, var.pointer, var.type);
|
||||
cmp = variable_compare(libcdsb_variable_build(p, s->type), var);
|
||||
|
||||
if (cmp == 0) ++n;
|
||||
|
||||
|
@ -15,7 +15,7 @@ ssize_t libcdsb_array_insert(arr_t* x, vtype_variable var) {
|
||||
|
||||
if (var.type < VTYPE_STRING) {
|
||||
n = vnode_tcreate(x->type, var.pointer, var.type);
|
||||
memcpy(array_internal_at(x, i), vnode_peek(&n, x->type), vtype_size(x->type));
|
||||
memcpy(array_internal_at(x, i), vnode_peek(&n, x->type).pointer, vtype_size(x->type));
|
||||
|
||||
if (vtype_size(x->type) > sizeof(vnode_t))
|
||||
vnode_free(&n, x->type);
|
||||
@ -38,7 +38,7 @@ ssize_t libcdsb_array_attach(arr_t* x, vtype_variable var) {
|
||||
|
||||
if (var.type < VTYPE_STRING) {
|
||||
n = vnode_tcreate(x->type, var.pointer, var.type);
|
||||
memcpy(array_internal_at(x, i), vnode_peek(&n, x->type), vtype_size(x->type));
|
||||
memcpy(array_internal_at(x, i), vnode_peek(&n, x->type).pointer, vtype_size(x->type));
|
||||
|
||||
if (vtype_size(x->type) > sizeof(vnode_t))
|
||||
vnode_free(&n, x->type);
|
||||
|
@ -4,18 +4,19 @@
|
||||
#include "include.h"
|
||||
|
||||
int libcdsb_dict_find(dict_t* x, vtype_variable kvar, void* dt, dict_access_callback callback, bool cut) {
|
||||
dnode_t *c, **p;
|
||||
int r;
|
||||
void* key;
|
||||
dnode_t *c, **p;
|
||||
int r;
|
||||
vtype_variable k, v;
|
||||
|
||||
if (x->capacity) {
|
||||
c = *(p = x->nodes + (vtype_hash(kvar.pointer, kvar.type) % x->capacity));
|
||||
|
||||
while (!is_null(c)) {
|
||||
key = vnode_peek(&c->key, c->key_type);
|
||||
if (vtype_compare(kvar.pointer, kvar.type, key, c->key_type) == 0) {
|
||||
r = (callback) ? callback(libcdsb_variable_build(key, c->key_type),
|
||||
libcdsb_variable_build(vnode_peek(&c->value, c->value_type), c->value_type), dt) : 0;
|
||||
k = vnode_peek(&c->key, c->key_type);
|
||||
v = vnode_peek(&c->value, c->value_type);
|
||||
|
||||
if (variable_compare(k, kvar) == 0) {
|
||||
r = (callback) ? callback(k, v, dt) : 0;
|
||||
|
||||
if (cut) {
|
||||
*p = c->prev;
|
||||
@ -38,6 +39,7 @@ int libcdsb_dict_foreach(dict_t* x, void* dt, dict_access_callback callback, boo
|
||||
dnode_t *c;
|
||||
ssize_t i;
|
||||
int r;
|
||||
vtype_variable k, v;
|
||||
|
||||
r = 0;
|
||||
i = x->capacity;
|
||||
@ -46,9 +48,10 @@ int libcdsb_dict_foreach(dict_t* x, void* dt, dict_access_callback callback, boo
|
||||
c = x->nodes[--i];
|
||||
|
||||
while (!is_null(c)) {
|
||||
r = callback(libcdsb_variable_build(vnode_peek(&c->key, c->key_type), c->key_type),
|
||||
libcdsb_variable_build(vnode_peek(&c->value, c->value_type), c->value_type), dt);
|
||||
k = vnode_peek(&c->key, c->key_type);
|
||||
v = vnode_peek(&c->value, c->value_type);
|
||||
|
||||
r = callback(k, v, dt);
|
||||
c = c->prev;
|
||||
|
||||
if (r) {
|
||||
|
@ -51,7 +51,8 @@ bool libcdsb_dict_shrink_to_fit(dict_t* s) {
|
||||
|
||||
|
||||
bool libcdsb_dict_update(dict_t* x, vtype_variable key, vtype_variable value, void* dt, dict_access_callback callback) {
|
||||
dnode_t *c, **p;
|
||||
dnode_t *c, **p;
|
||||
vtype_variable k;
|
||||
|
||||
if (!x->capacity || (double)x->size / x->capacity > REBUILD_POINT_MAX)
|
||||
libcdsb_builtin_rehash(x, x->capacity + CAPACITY_BLOCK);
|
||||
@ -59,9 +60,10 @@ bool libcdsb_dict_update(dict_t* x, vtype_variable key, vtype_variable value, vo
|
||||
c = *(p = x->nodes + (vtype_hash(key.pointer, key.type) % x->capacity));
|
||||
|
||||
while (!is_null(c)) {
|
||||
if (vtype_compare(key.pointer, key.type, vnode_peek(&c->key, c->key_type), c->key_type) == 0) {
|
||||
if (callback) callback(libcdsb_variable_build(vnode_peek(&c->key, c->key_type), c->key_type),
|
||||
libcdsb_variable_build(vnode_peek(&c->value, c->value_type), c->value_type), dt);
|
||||
k = vnode_peek(&c->key, c->key_type);
|
||||
|
||||
if (variable_compare(k, key) == 0) {
|
||||
if (callback) callback(k, vnode_peek(&c->value, c->value_type), dt);
|
||||
|
||||
vnode_free(&c->value, c->value_type);
|
||||
|
||||
@ -85,7 +87,8 @@ bool libcdsb_dict_update(dict_t* x, vtype_variable key, vtype_variable value, vo
|
||||
|
||||
|
||||
bool libcdsb_dict_inject(dict_t* x, vtype_variable key, vtype_variable value, void* dt, dict_access_callback callback) {
|
||||
dnode_t *c, **p;
|
||||
dnode_t *c, **p;
|
||||
vtype_variable k;
|
||||
|
||||
if (!x->capacity || (double)x->size / x->capacity > REBUILD_POINT_MAX)
|
||||
libcdsb_builtin_rehash(x, x->capacity + CAPACITY_BLOCK);
|
||||
@ -93,9 +96,10 @@ bool libcdsb_dict_inject(dict_t* x, vtype_variable key, vtype_variable value, vo
|
||||
c = *(p = x->nodes + (vtype_hash(key.pointer, key.type) % x->capacity));
|
||||
|
||||
while (!is_null(c)) {
|
||||
if (vtype_compare(key.pointer, key.type, vnode_peek(&c->key, c->key_type), c->key_type) == 0) {
|
||||
if (callback) callback(libcdsb_variable_build(vnode_peek(&c->key, c->key_type), c->key_type),
|
||||
libcdsb_variable_build(vnode_peek(&c->value, c->value_type), c->value_type), dt);
|
||||
k = vnode_peek(&c->key, c->key_type);
|
||||
|
||||
if (variable_compare(k, key) == 0) {
|
||||
if (callback) callback(k, vnode_peek(&c->value, c->value_type), dt);
|
||||
|
||||
vnode_free(&c->key, c->key_type);
|
||||
vnode_free(&c->value, c->value_type);
|
||||
|
@ -21,7 +21,6 @@ static void libcdsb_builtin_cut(list_t* s, lnode_t* cur) {
|
||||
/*#####################################################################################################################*/
|
||||
|
||||
int libcdsb_list_get(vtype_list* x, ssize_t i, void* _, list_access_callback callback, bool cut) {
|
||||
|
||||
ldir_t dir;
|
||||
lnode_t* c;
|
||||
size_t n;
|
||||
@ -43,7 +42,7 @@ int libcdsb_list_get(vtype_list* x, ssize_t i, void* _, list_access_callback cal
|
||||
|
||||
if (n || is_null(c)) return -1;
|
||||
|
||||
i = (callback) ? callback(libcdsb_variable_build(vnode_peek(&c->node, c->type), c->type), i, _) : 0;
|
||||
i = (callback) ? callback(vnode_peek(&c->node, c->type), i, _) : 0;
|
||||
|
||||
if (cut) libcdsb_builtin_cut(x, c);
|
||||
|
||||
@ -56,16 +55,18 @@ int libcdsb_list_find(vtype_list* x, vtype_variable value, void* _, list_access_
|
||||
lnode_t* c;
|
||||
ssize_t i;
|
||||
int cmp;
|
||||
vtype_variable v;
|
||||
|
||||
dir = r ? LD_PREV : LD_NEXT;
|
||||
c = ldir_dir((lnode_t*)x, dir);
|
||||
i = 0;
|
||||
|
||||
while (!is_null(c)) {
|
||||
cmp = vtype_compare(vnode_peek(&c->node, c->type), c->type, value.pointer, value.type);
|
||||
v = vnode_peek(&c->node, c->type);
|
||||
cmp = variable_compare(v, value);
|
||||
|
||||
if (cmp == 0) {
|
||||
i = (callback) ? callback(libcdsb_variable_build(vnode_peek(&c->node, c->type), c->type), (r)?~i:i, _) : 0;
|
||||
i = (callback) ? callback(v, (r)?~i:i, _) : 0;
|
||||
|
||||
if (cut) libcdsb_builtin_cut(x, c);
|
||||
|
||||
@ -81,7 +82,6 @@ int libcdsb_list_find(vtype_list* x, vtype_variable value, void* _, list_access_
|
||||
|
||||
|
||||
int libcdsb_list_foreach(vtype_list* x, void* data, list_access_callback callback, bool flush) {
|
||||
|
||||
lnode_t* n;
|
||||
lnode_t* c;
|
||||
size_t i;
|
||||
@ -91,7 +91,7 @@ int libcdsb_list_foreach(vtype_list* x, void* data, list_access_callback callbac
|
||||
i = 0;
|
||||
|
||||
while (!is_null(c)) {
|
||||
if ((r = callback(libcdsb_variable_build(vnode_peek(&c->node, c->type), c->type), i, data)) != 0)
|
||||
if ((r = callback(vnode_peek(&c->node, c->type), i, data)) != 0)
|
||||
break;
|
||||
|
||||
n = c->next;
|
||||
|
@ -37,7 +37,6 @@ hash_t list_hash(const list_t* s) {
|
||||
|
||||
|
||||
size_t libcdsb_list_count(const list_t* s, vtype_variable value) {
|
||||
|
||||
lnode_t* c;
|
||||
size_t n;
|
||||
int cmp;
|
||||
@ -46,7 +45,7 @@ size_t libcdsb_list_count(const list_t* s, vtype_variable value) {
|
||||
n = 0;
|
||||
|
||||
while (!is_null(c)) {
|
||||
cmp = vtype_compare(vnode_peek(&c->node, c->type), c->type, value.pointer, value.type);
|
||||
cmp = variable_compare(vnode_peek(&c->node, c->type), value);
|
||||
|
||||
if (cmp == 0) ++n;
|
||||
|
||||
|
@ -4,7 +4,6 @@
|
||||
#include "include.h"
|
||||
|
||||
bool libcdsb_list_insert(list_t* x, ssize_t i, vtype_variable value, int ins, void* dt, list_access_callback callback) {
|
||||
|
||||
ldir_t dir;
|
||||
lnode_t* c;
|
||||
|
||||
@ -42,7 +41,7 @@ bool libcdsb_list_insert(list_t* x, ssize_t i, vtype_variable value, int ins, vo
|
||||
|
||||
ldir_dir(ldir_inv(c, dir), dir) = c;
|
||||
} else {
|
||||
if (callback) callback(libcdsb_variable_build(vnode_peek(&c->node, c->type), c->type), -1, dt);
|
||||
if (callback) callback(vnode_peek(&c->node, c->type), -1, dt);
|
||||
vnode_free(&c->node, c->type);
|
||||
}
|
||||
|
||||
@ -53,7 +52,6 @@ bool libcdsb_list_insert(list_t* x, ssize_t i, vtype_variable value, int ins, vo
|
||||
|
||||
|
||||
bool libcdsb_list_attach(list_t* x, ssize_t i, vtype_variable value, int ins, void* dt, list_access_callback callback) {
|
||||
|
||||
ldir_t dir;
|
||||
lnode_t* c;
|
||||
|
||||
@ -91,7 +89,7 @@ bool libcdsb_list_attach(list_t* x, ssize_t i, vtype_variable value, int ins, vo
|
||||
|
||||
ldir_dir(ldir_inv(c, dir), dir) = c;
|
||||
} else {
|
||||
if (callback) callback(libcdsb_variable_build(vnode_peek(&c->node, c->type), c->type), -1, dt);
|
||||
if (callback) callback(vnode_peek(&c->node, c->type), -1, dt);
|
||||
vnode_free(&c->node, c->type);
|
||||
}
|
||||
|
||||
|
@ -22,8 +22,7 @@ static int libcdsb_builtin_foreach(map_t* x, void* data, map_access_callback cal
|
||||
if (!mnode_is_empty(n->right)) cur = stack_insert(cur, n->right);
|
||||
|
||||
if (!r) {
|
||||
r = callback(libcdsb_variable_build(vnode_peek(&n->key, x->type), x->type),
|
||||
libcdsb_variable_build(vnode_peek(&n->value, n->type), n->type), data);
|
||||
r = callback(vnode_peek(&n->key, x->type), vnode_peek(&n->value, n->type), data);
|
||||
} else {
|
||||
stack_flush(&z);
|
||||
return r;
|
||||
@ -46,20 +45,19 @@ static int libcdsb_builtin_foreach(map_t* x, void* data, map_access_callback cal
|
||||
|
||||
/*#####################################################################################################################*/
|
||||
|
||||
int libcdsb_map_find(map_t* x, vtype_variable kvar, void* _, map_access_callback callback, bool cut) {
|
||||
int libcdsb_map_find(map_t* x, vtype_variable key, void* _, map_access_callback callback, bool cut) {
|
||||
mnode_t* c;
|
||||
void *key;
|
||||
int cmp;
|
||||
vtype_variable k;
|
||||
|
||||
c = x->root;
|
||||
|
||||
while (!mnode_is_empty(c)) {
|
||||
key = vnode_peek(&c->key, x->type);
|
||||
cmp = vtype_compare(kvar.pointer, kvar.type, key, x->type);
|
||||
k = vnode_peek(&c->key, x->type);
|
||||
cmp = variable_compare(key, k);
|
||||
|
||||
if (cmp == 0) {
|
||||
cmp = (callback) ? callback(libcdsb_variable_build(key, x->type),
|
||||
libcdsb_variable_build(vnode_peek(&c->value, c->type), c->type), _) : 0;
|
||||
cmp = (callback) ? callback(k, vnode_peek(&c->value, c->type), _) : 0;
|
||||
|
||||
if (cut) {
|
||||
c = mnode_delete(&x->root, c);
|
||||
@ -98,8 +96,7 @@ int libcdsb_map_foreach(map_t* x, void* data, map_access_callback callback, rbfo
|
||||
|
||||
while ((n = stack_pop(&iter))) {
|
||||
if (!r) {
|
||||
r = callback(libcdsb_variable_build(vnode_peek(&n->key, x->type), x->type),
|
||||
libcdsb_variable_build(vnode_peek(&n->value, n->type), n->type), data);
|
||||
r = callback(vnode_peek(&n->key, x->type), vnode_peek(&n->value, n->type), data);
|
||||
} else if (!flush) {
|
||||
stack_flush(&iter);
|
||||
return r;
|
||||
|
@ -7,15 +7,16 @@ bool libcdsb_map_update(map_t* x, vtype_variable key, vtype_variable value, void
|
||||
int cmp;
|
||||
mnode_t* n;
|
||||
mnode_t* p;
|
||||
vtype_variable k;
|
||||
|
||||
if (!mnode_is_empty(n = x->root)) {
|
||||
do {
|
||||
p = n;
|
||||
cmp = vtype_compare(key.pointer, key.type, vnode_peek(&n->key, x->type), x->type);
|
||||
p = n;
|
||||
k = vnode_peek(&n->key, x->type);
|
||||
cmp = variable_compare(key, k);
|
||||
|
||||
if (cmp == 0) {
|
||||
if (callback) callback(libcdsb_variable_build(vnode_peek(&n->key, x->type), x->type),
|
||||
libcdsb_variable_build(vnode_peek(&n->value, n->type), n->type), dt);
|
||||
if (callback) callback(k, vnode_peek(&n->value, n->type), dt);
|
||||
|
||||
vnode_free(&n->value, n->type);
|
||||
|
||||
@ -49,20 +50,21 @@ bool libcdsb_map_inject(map_t* x, vtype_variable key, vtype_variable value, void
|
||||
mnode_t* n;
|
||||
mnode_t* p;
|
||||
vnode_t kn;
|
||||
vtype_variable k;
|
||||
|
||||
vnode_tattach(&kn, x->type, key.pointer, key.type);
|
||||
n = x->root;
|
||||
key.type = x->type;
|
||||
key.pointer = vnode_peek(&kn, key.type);
|
||||
key.pointer = vnode_peek(&kn, key.type).pointer;
|
||||
|
||||
if (!mnode_is_empty(n)) {
|
||||
do {
|
||||
k = vnode_peek(&n->key, x->type);
|
||||
p = n;
|
||||
cmp = vtype_compare(key.pointer, key.type, vnode_peek(&n->key, x->type), x->type);
|
||||
cmp = variable_compare(key, k);
|
||||
|
||||
if (cmp == 0) {
|
||||
if (callback) callback(libcdsb_variable_build(vnode_peek(&n->key, x->type), x->type),
|
||||
libcdsb_variable_build(vnode_peek(&n->value, n->type), n->type), dt);
|
||||
if (callback) callback(k, vnode_peek(&n->value, n->type), dt);
|
||||
|
||||
vnode_free(&n->key, x->type);
|
||||
vnode_free(&n->value, n->type);
|
||||
|
@ -23,7 +23,7 @@ static int libcdsb_builtin_foreach(set_t* x, void* data, vset_access_callback ca
|
||||
if (!rbnode_is_empty(n->right)) cur = stack_insert(cur, n->right);
|
||||
|
||||
if (!r) {
|
||||
r = callback(libcdsb_variable_build(vnode_peek(&n->value, x->type), x->type), data);
|
||||
r = callback(vnode_peek(&n->value, x->type), data);
|
||||
} else {
|
||||
stack_flush(&z);
|
||||
return r;
|
||||
@ -48,17 +48,17 @@ static int libcdsb_builtin_foreach(set_t* x, void* data, vset_access_callback ca
|
||||
|
||||
int libcdsb_vset_find(vtype_set* x, vtype_variable value, void* _, vset_access_callback callback, bool cut) {
|
||||
rbnode_t* c;
|
||||
void *val;
|
||||
int cmp;
|
||||
vtype_variable v;
|
||||
|
||||
c = x->root;
|
||||
|
||||
while (!rbnode_is_empty(c)) {
|
||||
val = vnode_peek(&c->value, x->type);
|
||||
cmp = vtype_compare(value.pointer, value.type, val, x->type);
|
||||
v = vnode_peek(&c->value, x->type);
|
||||
cmp = variable_compare(value, v);
|
||||
|
||||
if (cmp == 0) {
|
||||
cmp = (callback) ? callback(libcdsb_variable_build(val, x->type), _) : 0;
|
||||
cmp = (callback) ? callback(v, _) : 0;
|
||||
|
||||
if (cut) {
|
||||
c = rbnode_delete(&x->root, c);
|
||||
@ -96,7 +96,7 @@ int libcdsb_vset_foreach(set_t* x, void* data, vset_access_callback callback, rb
|
||||
|
||||
while ((n = stack_pop(&iter))) {
|
||||
if (!r) {
|
||||
r = callback(libcdsb_variable_build(vnode_peek(&n->value, x->type), x->type), data);
|
||||
r = callback(vnode_peek(&n->value, x->type), data);
|
||||
} else if (!flush) {
|
||||
stack_flush(&iter);
|
||||
return r;
|
||||
|
@ -13,7 +13,7 @@ bool libcdsb_vset_insert(set_t* x, vtype_variable value) {
|
||||
if (!rbnode_is_empty(n = x->root)) {
|
||||
do {
|
||||
p = n;
|
||||
cmp = vtype_compare(value.pointer, value.type, vnode_peek(&n->value, x->type), x->type);
|
||||
cmp = variable_compare(value, vnode_peek(&n->value, x->type));
|
||||
|
||||
if (cmp == 0) return false;
|
||||
|
||||
@ -45,12 +45,12 @@ bool libcdsb_vset_attach(set_t* x, vtype_variable value) {
|
||||
vnode_tattach(&vn, x->type, value.pointer, value.type);
|
||||
n = x->root;
|
||||
value.type = x->type;
|
||||
value.pointer = vnode_peek(&vn, value.type);
|
||||
value.pointer = vnode_peek(&vn, value.type).pointer;
|
||||
|
||||
if (!rbnode_is_empty(n)) {
|
||||
do {
|
||||
p = n;
|
||||
cmp = vtype_compare(value.pointer, value.type, vnode_peek(&n->value, x->type), x->type);
|
||||
cmp = variable_compare(value, vnode_peek(&n->value, x->type));
|
||||
|
||||
if (cmp == 0) {
|
||||
vnode_free(&vn, value.type);
|
||||
|
@ -62,41 +62,41 @@ const char* libcdsb_vtype_name(vtype t) {
|
||||
}
|
||||
|
||||
|
||||
const char* libcdsb_vtype_stringify(const void* v, vtype t) {
|
||||
if (is_null(v) || (t == VTYPE_POINTER && is_null(*(void**)v))) return "null";
|
||||
if (t == VTYPE_BOOLEAN) return (*(vtype_bool*)v) ? "true" : "false";
|
||||
if (t == VTYPE_STRING) return *(char**)v;
|
||||
const char* libcdsb_vtype_stringify(vtype_variable value) {
|
||||
if (is_null(value.pointer) || (value.type == VTYPE_POINTER && is_null(*(void**)value.pointer))) return "null";
|
||||
if (value.type == VTYPE_BOOLEAN) return (*(vtype_bool*)value.pointer) ? "true" : "false";
|
||||
if (value.type == VTYPE_STRING) return *(char**)value.pointer;
|
||||
|
||||
if (LIBCDSB_BUILTIN_COUNTER > 15)
|
||||
LIBCDSB_BUILTIN_COUNTER = 0;
|
||||
|
||||
switch (t) {
|
||||
case VTYPE_INT8: stringify(*( s8_t*)v); break;
|
||||
case VTYPE_INT16: stringify(*( s16_t*)v); break;
|
||||
case VTYPE_INT32: stringify(*( s32_t*)v); break;
|
||||
case VTYPE_INT64: stringify(*( s64_t*)v); break;
|
||||
case VTYPE_UINT8: stringify(*( u8_t*)v); break;
|
||||
case VTYPE_UINT16: stringify(*( u16_t*)v); break;
|
||||
case VTYPE_UINT32: stringify(*( u32_t*)v); break;
|
||||
case VTYPE_UINT64: stringify(*( u64_t*)v); break;
|
||||
case VTYPE_FLOAT: if (abs(*(fl_t*)v) <= FLT_EPSILON) {
|
||||
switch (value.type) {
|
||||
case VTYPE_INT8: stringify(*( s8_t*)value.pointer); break;
|
||||
case VTYPE_INT16: stringify(*( s16_t*)value.pointer); break;
|
||||
case VTYPE_INT32: stringify(*( s32_t*)value.pointer); break;
|
||||
case VTYPE_INT64: stringify(*( s64_t*)value.pointer); break;
|
||||
case VTYPE_UINT8: stringify(*( u8_t*)value.pointer); break;
|
||||
case VTYPE_UINT16: stringify(*( u16_t*)value.pointer); break;
|
||||
case VTYPE_UINT32: stringify(*( u32_t*)value.pointer); break;
|
||||
case VTYPE_UINT64: stringify(*( u64_t*)value.pointer); break;
|
||||
case VTYPE_FLOAT: if (abs(*(fl_t*)value.pointer) <= FLT_EPSILON) {
|
||||
LIBCDSB_BUILTIN_BUFFER[LIBCDSB_BUILTIN_COUNTER][0] = 0x30;
|
||||
LIBCDSB_BUILTIN_BUFFER[LIBCDSB_BUILTIN_COUNTER][1] = 0x00;
|
||||
} else stringify(*(fl_t*)v);
|
||||
} else stringify(*(fl_t*)value.pointer);
|
||||
break;
|
||||
case VTYPE_DOUBLE: if (abs(*(dbl_t*)v) <= DBL_EPSILON) {
|
||||
case VTYPE_DOUBLE: if (abs(*(dbl_t*)value.pointer) <= DBL_EPSILON) {
|
||||
LIBCDSB_BUILTIN_BUFFER[LIBCDSB_BUILTIN_COUNTER][0] = 0x30;
|
||||
LIBCDSB_BUILTIN_BUFFER[LIBCDSB_BUILTIN_COUNTER][1] = 0x00;
|
||||
} else stringify(*(dbl_t*)v);
|
||||
} else stringify(*(dbl_t*)value.pointer);
|
||||
break;
|
||||
case VTYPE_LDOUBLE: if (abs(*(ldbl_t*)v) <= LDBL_EPSILON) {
|
||||
case VTYPE_LDOUBLE: if (abs(*(ldbl_t*)value.pointer) <= LDBL_EPSILON) {
|
||||
LIBCDSB_BUILTIN_BUFFER[LIBCDSB_BUILTIN_COUNTER][0] = 0x30;
|
||||
LIBCDSB_BUILTIN_BUFFER[LIBCDSB_BUILTIN_COUNTER][1] = 0x00;
|
||||
} else stringify(*(ldbl_t*)v);
|
||||
} else stringify(*(ldbl_t*)value.pointer);
|
||||
break;
|
||||
case VTYPE_POINTER: sprintf(LIBCDSB_BUILTIN_BUFFER[LIBCDSB_BUILTIN_COUNTER], (sizeof(void*) == 8) ? "0x%016lx" : "0x%08x", (uintptr_t)*(void**)v); break;
|
||||
case VTYPE_POINTER: sprintf(LIBCDSB_BUILTIN_BUFFER[LIBCDSB_BUILTIN_COUNTER], (sizeof(void*) == 8) ? "0x%016lx" : "0x%08x", (uintptr_t)*(void**)value.pointer); break;
|
||||
|
||||
default: sprintf(LIBCDSB_BUILTIN_BUFFER[LIBCDSB_BUILTIN_COUNTER], "<%s>", libcdsb_vtype_name(t));
|
||||
default: sprintf(LIBCDSB_BUILTIN_BUFFER[LIBCDSB_BUILTIN_COUNTER], "<%s>", libcdsb_vtype_name(value.type));
|
||||
break;
|
||||
}
|
||||
|
||||
|
14
src/vnode.c
14
src/vnode.c
@ -194,8 +194,10 @@ vnode_t libcdsb_builtin_vnode_create(const void* v, vtype t) {
|
||||
}
|
||||
|
||||
|
||||
void* libcdsb_builtin_vnode_peek(const vnode_t* x, vtype t) {
|
||||
switch (t) { default: abort();
|
||||
vtype_variable libcdsb_builtin_vnode_peek(const vnode_t* x, vtype t) {
|
||||
vtype_variable var = { .type = t };
|
||||
|
||||
switch (var.type) { default: abort();
|
||||
|
||||
case VTYPE_FLOAT: if (is_permissible(fl_t)) goto vt_; else goto pt_;
|
||||
case VTYPE_DOUBLE: if (is_permissible(dbl_t)) goto vt_; else goto pt_;
|
||||
@ -212,7 +214,8 @@ void* libcdsb_builtin_vnode_peek(const vnode_t* x, vtype t) {
|
||||
case VTYPE_UINT16:
|
||||
case VTYPE_INT32:
|
||||
case VTYPE_UINT32:
|
||||
vt_: return (void*)x;
|
||||
vt_: var.pointer = (void*)x;
|
||||
break;
|
||||
|
||||
case VTYPE_STRING: if (sizeof(str_t) == sizeof(void*)) goto vt_;
|
||||
case VTYPE_MAP:
|
||||
@ -220,8 +223,11 @@ void* libcdsb_builtin_vnode_peek(const vnode_t* x, vtype t) {
|
||||
case VTYPE_LIST:
|
||||
case VTYPE_SET:
|
||||
case VTYPE_DICT:
|
||||
pt_: return *x;
|
||||
pt_: var.pointer = *x;
|
||||
break;
|
||||
}
|
||||
|
||||
return var;
|
||||
}
|
||||
|
||||
|
||||
|
37
src/vtype.c
37
src/vtype.c
@ -59,25 +59,7 @@ static hash_t libcdsb_builtin_hash_float(ldbl_t s) {
|
||||
return hash;
|
||||
}
|
||||
|
||||
/*#####################################################################################################################*/
|
||||
|
||||
int libcdsb_builtin_vtype_compare_values(const void* s0, vtype t0, const void* s1, vtype t1) {
|
||||
if (t0 == t1) return libcdsb_builtin_vtype_compare_values_eq(s0, s1, t0);
|
||||
|
||||
if (t0 <= VTYPE_LDOUBLE && t1 <= VTYPE_LDOUBLE) {
|
||||
ldbl_t d0, d1;
|
||||
|
||||
d0 = libcdsb_builtin_normalize(s0, t0);
|
||||
d1 = libcdsb_builtin_normalize(s1, t1);
|
||||
|
||||
return (abs(d0 - d1) <= LDBL_EPSILON) ? 0 : (d0 < d1 ? -1 : 1);
|
||||
}
|
||||
|
||||
return t0 - t1;
|
||||
}
|
||||
|
||||
|
||||
int libcdsb_builtin_vtype_compare_values_eq(const void* s0, const void* s1, vtype t) {
|
||||
static int libcdsb_builtin_vtype_compare_values_eq(const void* s0, const void* s1, vtype t) {
|
||||
|
||||
#define compare(T, s0, s1) *(T*)s0 == *(T*)s1 ? 0 : (*(T*)s0 < *(T*)s1 ? -1 : 1)
|
||||
|
||||
@ -117,6 +99,23 @@ int libcdsb_builtin_vtype_compare_values_eq(const void* s0, const void* s1, vtyp
|
||||
|
||||
/*#####################################################################################################################*/
|
||||
|
||||
int libcdsb_builtin_variable_compare(vtype_variable s0, vtype_variable s1) {
|
||||
if (s0.type == s1.type) return libcdsb_builtin_vtype_compare_values_eq(s0.pointer, s1.pointer, s0.type);
|
||||
|
||||
if (s0.type <= VTYPE_LDOUBLE && s0.type <= VTYPE_LDOUBLE) {
|
||||
ldbl_t d0, d1;
|
||||
|
||||
d0 = libcdsb_builtin_normalize(s0.pointer, s0.type);
|
||||
d1 = libcdsb_builtin_normalize(s1.pointer, s1.type);
|
||||
|
||||
return (abs(d0 - d1) <= LDBL_EPSILON) ? 0 : (d0 < d1 ? -1 : 1);
|
||||
}
|
||||
|
||||
return s0.type - s1.type;
|
||||
}
|
||||
|
||||
/*#####################################################################################################################*/
|
||||
|
||||
hash_t libcdsb_builtin_vtype_hash(const void* v, vtype t) {
|
||||
|
||||
switch (t) { default: abort();
|
||||
|
@ -70,7 +70,7 @@ void print_container_value(const ssize_t* index, const void* value, const vtype
|
||||
printf("\e[%dG ", hpos+1);
|
||||
}
|
||||
|
||||
printf("\e[31m%24s\e[m", libcdsb_vtype_stringify(value, type));
|
||||
printf("\e[31m%24s\e[m", libcdsb_vtype_stringify(libcdsb_variable_build((void*)value, type)));
|
||||
|
||||
if (print_type) {
|
||||
printf(" \e[36m(\e[m\e[32;1m%s\e[m\e[36m)\e[m", libcdsb_vtype_name(type));
|
||||
|
Loading…
Reference in New Issue
Block a user