Merge branch 'rbtree' into discrete-tests

This commit is contained in:
Gregory Lirent 2022-06-06 11:35:20 +03:00
commit 4edaea54b3
23 changed files with 905 additions and 106 deletions

View File

@ -10,11 +10,13 @@
#define array_pop(x, s, index) libcdsb_array_get(x, s, index, 1)
#define array_remove(s, index) libcdsb_array_get(0, s, index, 1)
#define array_foreach libcdsb_array_foreach
extern ssize_t libcdsb_array_get(vtype_value* x, vtype_array* s, ssize_t index, _Bool cut) LIBCDSB_nt__ LIBCDSB_nn2__;
extern ssize_t libcdsb_array_find(const vtype_array* x, const void* value, vtype value_type) LIBCDSB_nt__ LIBCDSB_nn1__;
extern ssize_t libcdsb_array_push( vtype_array* x, const void* value, vtype value_type) LIBCDSB_nt__ LIBCDSB_nn1__;
extern int array_foreach(vtype_array* x, int (*callback)(void* value, ssize_t index, vtype type)) LIBCDSB_nt__ LIBCDSB_nn12__;
extern int libcdsb_array_foreach(vtype_array* x, int (*callback)(void* value, ssize_t index, vtype type)) LIBCDSB_nt__ LIBCDSB_nn12__;
#endif /* LIBCDSB_EXTRA_ARRAY_H */

View File

@ -1,7 +1,6 @@
/* This software is licensed by the MIT License, see LICENSE file */
/* Copyright © 2022 Gregory Lirent */
#include <assert.h>
#include "../list.h"
#ifndef LIBCDSB_EXTRA_LIST_H
@ -11,6 +10,8 @@
#define list_pop_by_index(x, s, index) libcdsb_list_get(x, s, index, 1)
#define list_remove_by_index(s, index) libcdsb_list_get(0, s, index, 1)
#define list_foreach libcdsb_list_foreach
extern ssize_t libcdsb_list_find (vtype_value* x, vtype_list* s, const void* value, vtype type, _Bool reverse, _Bool cut) LIBCDSB_nt__ LIBCDSB_nn2__;
extern _Bool libcdsb_list_update(vtype_list* x, ssize_t index, const void* value, vtype type, int ins_direction) LIBCDSB_nt__ LIBCDSB_nn1__;
@ -18,6 +19,6 @@ extern size_t libcdsb_list_count(const vtype_list* s, const void* value, vtype
extern ssize_t libcdsb_list_get(vtype_value* x, vtype_list* s, ssize_t index, _Bool cut) LIBCDSB_nt__ LIBCDSB_nn2__;
extern int list_foreach(const vtype_list* x, int (*callback)(void* value, ssize_t index, vtype type)) LIBCDSB_nt__ LIBCDSB_nn12__;
extern int libcdsb_list_foreach(const vtype_list* x, int (*callback)(void* value, ssize_t index, vtype type)) LIBCDSB_nt__ LIBCDSB_nn12__;
#endif /* LIBCDSB_EXTRA_LIST_H */

16
include/extra/set.h Normal file
View File

@ -0,0 +1,16 @@
/* 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 libcdsb_vset_foreach
extern _Bool libcdsb_vset_find (vtype_value* x, vtype_set* s, const void* value, vtype type, _Bool cut);
extern _Bool libcdsb_vset_insert(vtype_set* x, const void* value, vtype type);
extern int libcdsb_vset_foreach(const vtype_set* x, int (*callback)(const void* value, vtype type)) LIBCDSB_nt__ LIBCDSB_nn12__;
#endif /* LIBCDSB_EXTRA_SET_H */

View File

@ -27,9 +27,10 @@ extern size_t string_align_center(vtype_string* x, size_t padsize, int padchr) L
extern size_t string_align_right (vtype_string* x, size_t padsize, int padchr) LIBCDSB_nt__ LIBCDSB_nn1__;
extern size_t string_align_left (vtype_string* x, size_t padsize, int padchr) LIBCDSB_nt__ LIBCDSB_nn1__;
extern int string_compare_case_insensitive(const vtype_string* s0, const vtype_string* s1) LIBCDSB_cmpattr__;
extern void libcdsb_string_replace(vtype_string* x, char* dest, size_t dest_nmemb, const char* src, size_t nmemb);
/*#####################################################################################################################*/
inline vtype_array libcdsb_string_split_string (const vtype_string* x, const vtype_string* sep, size_t maxn) __attribute__((always_inline));

57
include/set.h Normal file
View File

@ -0,0 +1,57 @@
/* This software is licensed by the MIT License, see LICENSE file */
/* Copyright © 2022 Gregory Lirent */
#include "__generics.h"
#include "vtype.h"
#ifndef LIBCDSB_SET_H
#define LIBCDSB_SET_H
extern void vset_init(vtype_set* x, vtype type);
#define vset_remove(x, value) _LIBCDSB_Generic (libcdsb_vset, touch, key)(x, value, 1)
#define vset_push(x, value) _LIBCDSB_Generic (libcdsb_vset, push, key)(x, value)
#define in_vset(x, value) _LIBCDSB_Generic (libcdsb_vset, touch, key)(x, value, 0)
extern _Bool libcdsb_vset_push_pointer(vtype_set* x, const void* value);
extern _Bool libcdsb_vset_push_cstring(vtype_set* x, const char* value);
extern _Bool libcdsb_vset_push_string (vtype_set* x, const vtype_string* value);
extern _Bool libcdsb_vset_push_array (vtype_set* x, const vtype_array* value);
extern _Bool libcdsb_vset_push_list (vtype_set* x, const vtype_list* value);
extern _Bool libcdsb_vset_push_map (vtype_set* x, const vtype_map* value);
extern _Bool libcdsb_vset_push_vset (vtype_set* x, const vtype_set* value);
extern _Bool libcdsb_vset_push_boolean(vtype_set* x, vtype_bool value);
extern _Bool libcdsb_vset_push_uint8 (vtype_set* x, vtype_uint8 value);
extern _Bool libcdsb_vset_push_uint16 (vtype_set* x, vtype_uint16 value);
extern _Bool libcdsb_vset_push_uint32 (vtype_set* x, vtype_uint32 value);
extern _Bool libcdsb_vset_push_uint64 (vtype_set* x, vtype_uint64 value);
extern _Bool libcdsb_vset_push_int8 (vtype_set* x, vtype_int8 value);
extern _Bool libcdsb_vset_push_int16 (vtype_set* x, vtype_int16 value);
extern _Bool libcdsb_vset_push_int32 (vtype_set* x, vtype_int32 value);
extern _Bool libcdsb_vset_push_int64 (vtype_set* x, vtype_int64 value);
extern _Bool libcdsb_vset_push_float (vtype_set* x, vtype_float value);
extern _Bool libcdsb_vset_push_double (vtype_set* x, vtype_double value);
extern _Bool libcdsb_vset_push_ldouble(vtype_set* x, vtype_ldouble value);
extern _Bool libcdsb_vset_touch_pointer(vtype_set* x, const void* value, _Bool cut);
extern _Bool libcdsb_vset_touch_cstring(vtype_set* x, const char* value, _Bool cut);
extern _Bool libcdsb_vset_touch_string (vtype_set* x, const vtype_string* value, _Bool cut);
extern _Bool libcdsb_vset_touch_array (vtype_set* x, const vtype_array* value, _Bool cut);
extern _Bool libcdsb_vset_touch_list (vtype_set* x, const vtype_list* value, _Bool cut);
extern _Bool libcdsb_vset_touch_map (vtype_set* x, const vtype_map* value, _Bool cut);
extern _Bool libcdsb_vset_touch_vset (vtype_set* x, const vtype_set* value, _Bool cut);
extern _Bool libcdsb_vset_touch_boolean(vtype_set* x, vtype_bool value, _Bool cut);
extern _Bool libcdsb_vset_touch_uint8 (vtype_set* x, vtype_uint8 value, _Bool cut);
extern _Bool libcdsb_vset_touch_uint16 (vtype_set* x, vtype_uint16 value, _Bool cut);
extern _Bool libcdsb_vset_touch_uint32 (vtype_set* x, vtype_uint32 value, _Bool cut);
extern _Bool libcdsb_vset_touch_uint64 (vtype_set* x, vtype_uint64 value, _Bool cut);
extern _Bool libcdsb_vset_touch_int8 (vtype_set* x, vtype_int8 value, _Bool cut);
extern _Bool libcdsb_vset_touch_int16 (vtype_set* x, vtype_int16 value, _Bool cut);
extern _Bool libcdsb_vset_touch_int32 (vtype_set* x, vtype_int32 value, _Bool cut);
extern _Bool libcdsb_vset_touch_int64 (vtype_set* x, vtype_int64 value, _Bool cut);
extern _Bool libcdsb_vset_touch_float (vtype_set* x, vtype_float value, _Bool cut);
extern _Bool libcdsb_vset_touch_double (vtype_set* x, vtype_double value, _Bool cut);
extern _Bool libcdsb_vset_touch_ldouble(vtype_set* x, vtype_ldouble value, _Bool cut);
#endif /* LIBCDSB_SET_H */

53
src/__internal/rbtree.h Normal file
View File

@ -0,0 +1,53 @@
/* This software is licensed by the Apache License 2.0, see LICENSE file */
/* Copyright © 2022 Gregory Lirent */
#include "vnode.h"
#ifndef LIBCDSB_SRC_INTERNAL_RBTREE_H
#define LIBCDSB_SRC_INTERNAL_RBTREE_H
typedef enum libcdsb_rbtree_iter_flags {
RBI_INORDER = 0,
RBI_PREORDER = 1,
RBI_POSTORDER = 2,
RBI_REVERSE = 4,
} rbiter_f;
typedef struct libcdsb_rbtree_node {
struct libcdsb_rbtree_node* left;
struct libcdsb_rbtree_node* right;
struct libcdsb_rbtree_node* parent;
vnode_t value;
short colored;
} rbnode_t;
typedef struct libcdsb_rbtree_iter {
struct libcdsb_rbtree_node* cursor;
int flags;
} rbiter_t;
extern const rbnode_t LIBCDSB_RBTREE_NODE_EMPTY[1];
extern void* libcdsb_rbtree_node_create(void* value, rbnode_t* parent, int colored, int size);
extern void libcdsb_rbtree_node_fixup (rbnode_t** root, rbnode_t* node);
extern rbnode_t* libcdsb_rbtree_node_delete(rbnode_t** root, rbnode_t* node);
extern _Bool libcdsb_rbtree_iter_init (rbiter_t* iter, rbnode_t *const *root, rbiter_f flags);
extern rbnode_t* libcdsb_rbtree_iter_next (rbiter_t* iter);
extern void libcdsb_rbtree_iter_reset(rbiter_t* iter);
#define rbnode_empty ((rbnode_t*)LIBCDSB_RBTREE_NODE_EMPTY)
#define rbnode_create(v, p, c) ((rbnode_t*)libcdsb_rbtree_node_create(v, p, c, sizeof(rbnode_t)))
#define rbnode_fixup libcdsb_rbtree_node_fixup
#define rbnode_delete libcdsb_rbtree_node_delete
#define rbiter_init libcdsb_rbtree_iter_init
#define rbiter_next libcdsb_rbtree_iter_next
#define rbiter_reset libcdsb_rbtree_iter_reset
#define rbnode_is_empty(n) ((n) == rbnode_empty)
#define rbnode_is_root(n) rbnode_is_empty((n)->parent)
#endif /* LIBCDSB_SRC_INTERNAL_RBTREE_H */

View File

@ -6,12 +6,6 @@
#ifndef LIBCDSB_SRC_INTERNAL_VNODE_H
#define LIBCDSB_SRC_INTERNAL_VNODE_H
#define mark_ptr(x, m) ((void*)((uintptr_t)(x)|(uintptr_t)(m)))
#define unmark_ptr(x) ((void*)((uintptr_t)(x)&~(uintptr_t)(_Alignof(max_align_t)-1)))
#define get_mark(x) ((int)((uintptr_t)(x)&(uintptr_t)(_Alignof(max_align_t)-1)))
#define unmark_ptr16(x) ((void*)((uintptr_t)(x)&~(uintptr_t)(15)))
#define get_mark16(x) ((int)((uintptr_t)(x)&(uintptr_t)(15)))
#define is_permissible(T) (sizeof(void*) >= sizeof(T) && _Alignof(void*) >= _Alignof(T))
typedef union {

View File

@ -76,7 +76,7 @@ ssize_t libcdsb_array_get(val_t* x, arr_t* s, ssize_t i, _Bool cut) {
/*#####################################################################################################################*/
int array_foreach(vtype_array* x, int (*callback)(void* value, ssize_t index, vtype type)) {
int libcdsb_array_foreach(vtype_array* x, int (*callback)(void* value, ssize_t index, vtype type)) {
void* p;
void* e;

View File

@ -163,7 +163,7 @@ _Bool libcdsb_list_update(list_t* x, ssize_t i, const void* v, vtype t, int ins)
/*#####################################################################################################################*/
int list_foreach(const vtype_list* x, int (*callback)(void* value, ssize_t index, vtype type)) {
int libcdsb_list_foreach(const vtype_list* x, int (*callback)(void* value, ssize_t index, vtype type)) {
lnode_t* c;
size_t n;

383
src/rbtree.c Normal file
View File

@ -0,0 +1,383 @@
/* This software is licensed by the MIT License, see LICENSE file */
/* Copyright © 2022 Gregory Lirent */
#include "__internal/rbtree.h"
#define RBI_BREAK ((rbiter_f)3)
#define RBI_FIRST ((rbiter_f)8)
typedef enum libcdsb_rbtree_node_direction {
RBD_LEFT = 1,
RBD_RIGHT = 2
} rbdir_t;
#define rbdir_dir(cur, d) (&((cur)->left))[(d)>>1]
#define rbdir_inv(cur, d) (&((cur)->left))[(d)&1]
/*#####################################################################################################################*/
const rbnode_t LIBCDSB_RBTREE_NODE_EMPTY[1] = {{
.colored = 0,
.value = 0,
.parent = rbnode_empty,
.left = rbnode_empty,
.right = rbnode_empty
}};
/*#####################################################################################################################*/
static inline void rotate(rbnode_t **x, rbnode_t *c, rbdir_t d) {
rbnode_t* n = rbdir_inv(c, d);
rbdir_inv(c, d) = rbdir_dir(n, d);
n->parent = c->parent;
if (!rbnode_is_empty(rbdir_dir(n, d))) {
rbdir_dir(n, d)->parent = c;
}
if (!rbnode_is_root(c)) {
rbnode_t* p = c->parent;
if (rbdir_dir(p, d) == c) {
rbdir_dir(p, d) = n;
} else rbdir_inv(c, d) = n;
} else *x = n;
rbdir_inv(n, d) = c;
c->parent = n;
}
static inline void replace(rbnode_t** x, rbnode_t* c, rbnode_t* n) {
rbnode_t* p;
p = c->parent;
if (!rbnode_is_empty(p)) {
if (p->left == c) {
p->left = n;
} else p->right = n;
} else *x = n;
n->parent = p;
}
/*#####################################################################################################################*/
static rbnode_t* inorder_next(rbnode_t* c, rbiter_f f) {
rbdir_t d = (f&RBI_REVERSE) ? RBD_RIGHT : RBD_LEFT;
rbnode_t* p;
for (;;) {
if (rbnode_is_empty(rbdir_inv(c, d))) {
p = c->parent;
if (rbnode_is_root(p) || rbdir_dir(p, d) == c) {
return p;
}
c = p;
p = c->parent;
if (rbnode_is_root(p) || rbdir_dir(p, d) == c) {
return p;
}
do {
c = p;
p = c->parent;
} while(rbdir_inv(p, d) == c);
c = p;
} else { c = rbdir_inv(c, d); break; }
if (rbnode_is_root(c)) return c;
}
while (!rbnode_is_empty(rbdir_dir(c, d)))
c = rbdir_dir(c, d);
return c;
}
static rbnode_t* postorder_next(rbnode_t* c, rbiter_f f) {
rbdir_t d = (f&RBI_REVERSE) ? RBD_RIGHT : RBD_LEFT;
rbnode_t* p;
if (rbnode_is_empty(p = c->parent))
return c;
if (rbdir_dir(p, d) == c && !rbnode_is_empty(rbdir_inv(p, d))) {
c = rbdir_inv(p, d);
while (!rbnode_is_empty(c)) {
p = c;
c = (!rbnode_is_empty(rbdir_inv(p, d)))
? rbdir_inv(p, d)
: rbdir_dir(p, d);
}
}
return p;
}
static rbnode_t* preorder_next(rbnode_t* c, rbiter_f f) {
rbdir_t d = (f&RBI_REVERSE) ? RBD_RIGHT : RBD_LEFT;
rbnode_t* p;
if (!rbnode_is_empty(rbdir_dir(c, d)))
return rbdir_dir(c, d);
for (;;) {
if (!rbnode_is_empty(rbdir_inv(c, d))) {
return rbdir_inv(c, d);
}
p = c->parent;
while (rbdir_inv(p, d) == c) {
c = p;
p = c->parent;
}
if (rbnode_is_empty(p))
return c;
c = p;
}
}
/*#####################################################################################################################*/
static void delete_fixup(rbnode_t** x, rbnode_t* n) {
rbdir_t d;
rbnode_t *s, *p;
while (!rbnode_is_root(n) && !n->colored) {
p = n->parent;
d = (p->left == n) ? RBD_LEFT : RBD_RIGHT;
s = rbdir_inv(p, d);
if (s->colored) {
s->colored = 0;
p->colored = 1;
rotate(x, p, d);
p = n->parent;
s = rbdir_inv(p, d);
}
if (!rbdir_dir(s, d)->colored && !rbdir_inv(s, d)->colored) {
s->colored = 1;
n = p;
} else {
if (!rbdir_inv(s, d)->colored) {
rbdir_dir(s, d)->colored = 0;
s->colored = 1;
rotate(x, s, (d == RBD_LEFT) ? RBD_RIGHT : RBD_LEFT);
p = n->parent;
s = rbdir_inv(p, d);
}
s->colored = p->colored;
p->colored = 0;
rbdir_inv(s, d)->colored = 0;
rotate(x, p, d);
n = *x;
}
}
n->colored = 0;
}
/*#####################################################################################################################*/
rbnode_t* libcdsb_rbtree_node_delete(rbnode_t** x, rbnode_t* c) {
rbnode_t *n, *t;
int s;
void* v;
s = c->colored;
if (rbnode_is_empty(c->left)) {
n = c->right;
replace(x, c, c->right);
} else if (rbnode_is_empty(c->right)) {
n = c->left;
replace(x, c, c->left);
} else {
t = c->right;
while (!rbnode_is_empty(t->left)) {
t = t->left;
}
s = t->colored;
n = t->right;
if (t->parent == c) {
n->parent = t;
} else {
replace(x, t, t->right);
c->right->parent = t;
t->right = c->right;
}
replace(x, c, t);
c->left->parent = t;
t->colored = c->colored;
t->left = c->left;
}
if (!s) delete_fixup(x, n);
return c;
}
void libcdsb_rbtree_node_fixup(rbnode_t** x, rbnode_t* n) {
rbdir_t d[2];
rbnode_t *u, *p, *gp;
while (n->parent->colored) {
p = n->parent;
gp = p->parent;
d[0] = (gp->right == p) ? RBD_LEFT : RBD_RIGHT;
u = rbdir_dir(gp, d[0]);
if (rbdir_dir(p, d[0]) == n) {
d[1] = (d[0] == RBD_LEFT) ? RBD_RIGHT : RBD_LEFT;
} else d[1] = 0;
if (u->colored) {
u->colored = 0;
p->colored = 0;
gp->colored = 1;
n = gp;
} else {
if (d[1]) {
rotate(x, n = p, d[1]);
p = n->parent;
gp = p->parent;
}
p->colored = 0;
gp->colored = 1;
rotate(x, gp, d[0]);
}
if (rbnode_is_root(n)) break;
}
(*x)->colored = 0;
}
void* libcdsb_rbtree_node_create(void* v, rbnode_t* p, int c, int n) {
rbnode_t* x;
x = malloc(n);
x->left = rbnode_empty;
x->right = rbnode_empty;
x->value = v;
x->colored = c;
x->parent = p;
return x;
}
/*#####################################################################################################################*/
_Bool libcdsb_rbtree_iter_init(rbiter_t* iter, rbnode_t *const *root, rbiter_f f) {
rbdir_t d = (f&RBI_REVERSE) ? RBD_RIGHT : RBD_LEFT;
rbnode_t* c = *root;
if (!rbnode_is_empty(c)) {
if (!(f&RBI_BREAK)) {
while (rbdir_dir(c, d) != rbnode_empty) {
c = rbdir_dir(c, d);
}
} else if ((f&RBI_BREAK) == RBI_POSTORDER) {
rbnode_t* p;
do {
p = c;
c = (!rbnode_is_empty(rbdir_dir(c, d))) ? rbdir_dir(c, d) : rbdir_inv(c, d);
} while (!rbnode_is_empty(c));
c = p;
}
} else {
iter->cursor = rbnode_empty;
iter->flags = 0;
return false;
}
iter->cursor = c;
iter->flags = f|RBI_FIRST;
return true;
}
void libcdsb_rbtree_iter_reset(rbiter_t* iter) {
if (iter->flags&RBI_FIRST) return;
while (!rbnode_is_empty(iter->cursor->parent)) {
iter->cursor = iter->cursor->parent;
}
if ((iter->flags&RBI_BREAK) == RBI_BREAK) {
libcdsb_rbtree_iter_init(iter, &iter->cursor, iter->flags&~RBI_BREAK);
} else libcdsb_rbtree_iter_init(iter, &iter->cursor, iter->flags);
}
rbnode_t* hhttpc_rbtree_iter_next(rbiter_t* iter) {
rbnode_t* c;
c = iter->cursor;
if (rbnode_is_empty(c))
return rbnode_empty;
if (!(iter->flags&RBI_FIRST)) {
if (rbnode_is_root(c)) {
if ((iter->flags&RBI_BREAK) == RBI_INORDER) {
iter->flags |= RBI_BREAK;
} else {
libcdsb_rbtree_iter_reset(iter);
if (iter->flags&RBI_POSTORDER) {
iter->flags |= RBI_BREAK;
return c;
} else return rbnode_empty;
}
}
} else if ((iter->flags&RBI_BREAK) == RBI_BREAK) {
iter->flags = (iter->flags&~(RBI_BREAK^RBI_POSTORDER));
return rbnode_empty;
} else iter->flags &= ~RBI_FIRST;
switch (iter->flags&RBI_BREAK) {
case RBI_POSTORDER: iter->cursor = postorder_next(c, iter->flags); break;
case RBI_PREORDER: iter->cursor = preorder_next(c, iter->flags); break;
case RBI_INORDER:
default: iter->cursor = inorder_next(c, iter->flags); break;
}
return c;
}

98
src/set/base.c Normal file
View File

@ -0,0 +1,98 @@
/* 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;
}

59
src/set/copy.c Normal file
View File

@ -0,0 +1,59 @@
/* This software is licensed by the MIT License, see LICENSE file */
/* Copyright © 2022 Gregory Lirent */
#include "../../include/set.h"
#include "../__internal/rbtree.h"
/*#####################################################################################################################*/
static void copy_child(rbnode_t* x, vtype t, const rbnode_t* l, const rbnode_t* r) {
if (!rbnode_is_empty(l)) {
x->left = rbnode_create(vnode_duplicate(&l->value, t), x, l->colored);
copy_child(x->left, t, l->left, l->right);
} else x->left = rbnode_empty;
if (!rbnode_is_empty(r)) {
x->left = rbnode_create(vnode_duplicate(&r->value, t), x, r->colored);
copy_child(x->right, t, r->right, r->right);
} else x->right = rbnode_empty;
}
/*#####################################################################################################################*/
vtype_set vset_copy(const vtype_set* s) {
set_t x = { .type = s->type };
if (!rbnode_is_empty(s->root)) {
x.root = rbnode_create(vnode_duplicate(&s->root->value, s->type), rbnode_empty, 0);
copy_child(x.root, s->type, s->root->left, s->root->right);
} else x.root = rbnode_empty;
return x;
}
vtype_set* vset_duplicate(const vtype_set* s) {
set_t* x = malloc(sizeof(*x));
x->type = s->type;
if (!rbnode_is_empty(s->root)) {
x->root = rbnode_create(vnode_duplicate(&s->root->value, s->type), rbnode_empty, 0);
copy_child(x->root, s->type, s->root->left, s->root->right);
} else x->root = rbnode_empty;
return x;
}
void vset_copy_init(vtype_set* x, const vtype_set* s) {
x->type = s->type;
if (!rbnode_is_empty(s->root)) {
x->root = rbnode_create(vnode_duplicate(&s->root->value, s->type), rbnode_empty, 0);
copy_child(x->root, s->type, s->root->left, s->root->right);
} else x->root = rbnode_empty;
}

86
src/set/extra.c Normal file
View File

@ -0,0 +1,86 @@
/* This software is licensed by the MIT License, see LICENSE file */
/* Copyright © 2022 Gregory Lirent */
#include "../../include/extra/set.h"
#include "../__internal/rbtree.h"
/*#####################################################################################################################*/
_Bool libcdsb_vset_find(val_t* x, set_t* s, const void* v, vtype t, _Bool cut) {
rbnode_t* c;
int cmp;
c = s->root;
while (!rbnode_is_empty(c)) {
cmp = vtype_compare(vnode_peek(&c->value, s->type), s->type, v, t);
if (cmp == 0) {
if (cut) {
c = rbnode_delete(&s->root, c);
if (!is_null(x)) {
value_set(x, c->value, s->type, VF_WRITEABLE|VF_REMOVABLE);
} else vnode_free(&c->value, s->type);
free(c);
} else if (!is_null(x)) value_set(x, c->value, s->type, VF_UNDEFINED);
return true;
}
c = (cmp < 0) ? c->right : c->left;
}
return rbnode_empty;
}
_Bool libcdsb_vset_insert(set_t* x, const void* v, vtype t) {
int cmp;
rbnode_t* n;
rbnode_t* p;
n = x->root;
if (!rbnode_is_empty(n)) {
do {
p = n;
cmp = vtype_compare(vnode_peek(&n->value, x->type), x->type, v, t);
if (cmp == 0) return false;
n = (cmp > 0) ? n->left : n->right;
} while (!rbnode_is_empty(n));
n = rbnode_create(0, p, 1);
if (cmp > 0) p->left = n;
else p->right = n;
if (!rbnode_is_root(n->parent))
rbnode_fixup(&x->root, n);
} else n = x->root = rbnode_create(0, p, 1);
n->value = vnode_tcreate(x->type, v, t);
return true;
}
/*#####################################################################################################################*/
int libcdsb_vset_foreach(const vtype_set* x, int (*callback)(const void* value, vtype type)) {
rbiter_t i;
int r;
if (rbiter_init(&i, &x->root, 0)) {
while (!rbnode_is_empty(rbiter_next(&i))) {
if ((r = callback(vnode_peek(&i.cursor->value, x->type), x->type)))
return r;
}
}
return 0;
}

45
src/set/generics.c Normal file
View File

@ -0,0 +1,45 @@
/* This software is licensed by the MIT License, see LICENSE file */
/* Copyright © 2022 Gregory Lirent */
#include "../../include/extra/set.h"
#include "../__internal/include.h"
_Bool libcdsb_vset_touch_pointer(set_t* x, const void* k, _Bool f) { return libcdsb_vset_find(0, x, &k, vtypeof(&k), f); }
_Bool libcdsb_vset_touch_cstring(set_t* x, const char* k, _Bool f) { return libcdsb_vset_find(0, x, &k, vtypeof(&k), f); }
_Bool libcdsb_vset_touch_string (set_t* x, const str_t* k, _Bool f) { return libcdsb_vset_find(0, x, k, vtypeof( k), f); }
_Bool libcdsb_vset_touch_array (set_t* x, const arr_t* k, _Bool f) { return libcdsb_vset_find(0, x, k, vtypeof( k), f); }
_Bool libcdsb_vset_touch_list (set_t* x, const list_t* k, _Bool f) { return libcdsb_vset_find(0, x, k, vtypeof( k), f); }
_Bool libcdsb_vset_touch_map (set_t* x, const map_t* k, _Bool f) { return libcdsb_vset_find(0, x, k, vtypeof( k), f); }
_Bool libcdsb_vset_touch_vset (set_t* x, const set_t* k, _Bool f) { return libcdsb_vset_find(0, x, k, vtypeof( k), f); }
_Bool libcdsb_vset_touch_boolean(set_t* x, _Bool k, _Bool f) { return libcdsb_vset_find(0, x, &k, vtypeof(&k), f); }
_Bool libcdsb_vset_touch_int8 (set_t* x, s8_t k, _Bool f) { return libcdsb_vset_find(0, x, &k, vtypeof(&k), f); }
_Bool libcdsb_vset_touch_int16 (set_t* x, s16_t k, _Bool f) { return libcdsb_vset_find(0, x, &k, vtypeof(&k), f); }
_Bool libcdsb_vset_touch_int32 (set_t* x, s32_t k, _Bool f) { return libcdsb_vset_find(0, x, &k, vtypeof(&k), f); }
_Bool libcdsb_vset_touch_int64 (set_t* x, s64_t k, _Bool f) { return libcdsb_vset_find(0, x, &k, vtypeof(&k), f); }
_Bool libcdsb_vset_touch_uint8 (set_t* x, u8_t k, _Bool f) { return libcdsb_vset_find(0, x, &k, vtypeof(&k), f); }
_Bool libcdsb_vset_touch_uint16 (set_t* x, u16_t k, _Bool f) { return libcdsb_vset_find(0, x, &k, vtypeof(&k), f); }
_Bool libcdsb_vset_touch_uint32 (set_t* x, u32_t k, _Bool f) { return libcdsb_vset_find(0, x, &k, vtypeof(&k), f); }
_Bool libcdsb_vset_touch_uint64 (set_t* x, u64_t k, _Bool f) { return libcdsb_vset_find(0, x, &k, vtypeof(&k), f); }
_Bool libcdsb_vset_touch_float (set_t* x, fl_t k, _Bool f) { return libcdsb_vset_find(0, x, &k, vtypeof(&k), f); }
_Bool libcdsb_vset_touch_double (set_t* x, dbl_t k, _Bool f) { return libcdsb_vset_find(0, x, &k, vtypeof(&k), f); }
_Bool libcdsb_vset_touch_ldouble(set_t* x, ldbl_t k, _Bool f) { return libcdsb_vset_find(0, x, &k, vtypeof(&k), f); }
_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_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)); }

View File

@ -60,7 +60,7 @@ int string_compare(const str_t* s0, const str_t* s1) {
/*#####################################################################################################################*/
_Bool string_concat_cstring(str_t* x, const char* s) {
_Bool libcdsb_string_concat_cstring(str_t* x, const char* s) {
size_t n;
size_t xn;
@ -77,7 +77,7 @@ _Bool string_concat_cstring(str_t* x, const char* s) {
}
_Bool string_concat_char(str_t* x, int chr) {
_Bool libcdsb_string_concat_char(str_t* x, int chr) {
size_t xn;
size_t n;
char *e;

View File

@ -3,7 +3,7 @@
#include "include.h"
arr_t string_split_cstring(const str_t* s, const char* a, size_t maxn) {
arr_t libcdsb_string_split_cstring(const str_t* s, const char* a, size_t maxn) {
arr_t x = { .mem = 0, .size = 0, .type = VTYPE_STRING };
size_t n;
@ -46,7 +46,7 @@ arr_t string_split_cstring(const str_t* s, const char* a, size_t maxn) {
}
arr_t string_split_char(const str_t* s, int ac, size_t maxn) {
arr_t libcdsb_string_split_char(const str_t* s, int ac, size_t maxn) {
arr_t x = { .mem = 0, .size = 0, .type = VTYPE_STRING };
char a[5] = { 0 };

View File

@ -4,7 +4,7 @@
#include <ctype.h>
#include "include.h"
int string_case_compare(const str_t* s0, const str_t* s1) {
int string_compare_case_insensitive(const str_t* s0, const str_t* s1) {
const char *p0, *p1, *t0, *t1;
ssize_t n0, n1;
u32_t uc0, uc1;
@ -76,7 +76,7 @@ size_t string_to_lower(str_t* x) {
es = tochar_unicode(ps, uc1);
if (!is_null(es)) {
string_replace(x, p, e-p, ps, es-ps);
libcdsb_string_replace(x, p, e-p, ps, es-ps);
++n;
}
}
@ -112,7 +112,7 @@ size_t string_to_upper(str_t* x) {
es = tochar_unicode(ps, uc1);
if (!is_null(es)) {
string_replace(x, p, e-p, ps, es-ps);
libcdsb_string_replace(x, p, e-p, ps, es-ps);
++n;
}
}
@ -146,7 +146,7 @@ size_t string_capitalize(str_t* x) {
es = tochar_unicode(ps, uc1);
if (!is_null(es)) {
string_replace(x, p, e-p, ps, es-ps);
libcdsb_string_replace(x, p, e-p, ps, es-ps);
++n;
}
}
@ -164,7 +164,7 @@ size_t string_capitalize(str_t* x) {
es = tochar_unicode(ps, uc1);
if (!is_null(es)) {
string_replace(x, p, e-p, ps, es-ps);
libcdsb_string_replace(x, p, e-p, ps, es-ps);
++n;
}
}
@ -207,3 +207,22 @@ size_t string_reverse(str_t* x) {
return n;
}
/*#####################################################################################################################*/
void libcdsb_string_replace(str_t* x, char* p, size_t n, const char* v, size_t vn) {
if (n != vn) {
size_t l = strlen(x->buffer);
if (n < vn) {
char* t = x->buffer;
x->buffer = realloc(x->buffer, l + (vn - n) + 1);
p = x->buffer + (p - t);
}
memmove(p+vn, p+n, l - (p+n - x->buffer) + 1);
}
memcpy(p, v, vn);
}

View File

@ -63,7 +63,7 @@ _Bool string_slice(str_t* x, str_t* s, ssize_t i, size_t c, _Bool cut) {
/*#####################################################################################################################*/
ssize_t string_indexof_cstring(const str_t* s, const char* a) {
ssize_t libcdsb_string_indexof_cstring(const str_t* s, const char* a) {
char *e, *p;
size_t n;
@ -92,7 +92,7 @@ ssize_t string_indexof_cstring(const str_t* s, const char* a) {
}
ssize_t string_indexof_char(const str_t* s, int ac) {
ssize_t libcdsb_string_indexof_char(const str_t* s, int ac) {
size_t n;
char* e;
@ -127,7 +127,7 @@ ssize_t string_indexof_char(const str_t* s, int ac) {
/*#####################################################################################################################*/
size_t string_count_cstring(const str_t* s, const char* a) {
size_t libcdsb_string_count_cstring(const str_t* s, const char* a) {
char* p;
size_t n, c;
@ -148,7 +148,7 @@ size_t string_count_cstring(const str_t* s, const char* a) {
}
size_t string_count_char(const str_t* s, int ac) {
size_t libcdsb_string_count_char(const str_t* s, int ac) {
size_t n, c;
char a[5] = {0};

View File

@ -29,35 +29,4 @@ ainline(char* prev_char(char* s)) {
return s;
}
extern void libcdsb_string_replace(str_t* x, char* p, size_t n, const char* v, size_t vn);
#ifdef string_replace
#undef string_replace
#endif
#ifdef string_trim_spaces
#undef string_trim_spaces
#endif
#define string_replace libcdsb_string_replace
#define string_indexof_cstring libcdsb_string_indexof_cstring
#define string_indexof_char libcdsb_string_indexof_char
#define string_count_cstring libcdsb_string_count_cstring
#define string_count_char libcdsb_string_count_char
#define string_concat_cstring libcdsb_string_concat_cstring
#define string_concat_char libcdsb_string_concat_char
#define string_trim_spaces libcdsb_string_trim_spaces
#define string_trim_cstring libcdsb_string_trim_cstring
#define string_trim_char libcdsb_string_trim_char
#define string_replace_cstring_cstring libcdsb_string_replace_cstring_cstring
#define string_replace_cstring_char libcdsb_string_replace_cstring_char
#define string_replace_char_cstring libcdsb_string_replace_char_cstring
#define string_replace_char_char libcdsb_string_replace_char_char
#define string_split_string libcdsb_string_split_string
#define string_split_cstring libcdsb_string_split_cstring
#define string_split_char libcdsb_string_split_char
#define string_replace_cstring_cstring_r libcdsb_string_replace_r_cstring_cstring
#define string_replace_cstring_char_r libcdsb_string_replace_r_cstring_char
#define string_replace_char_cstring_r libcdsb_string_replace_r_char_cstring
#endif /* LIBCDSB_SRC_STRING_INCLUDE_H */

View File

@ -1,21 +0,0 @@
/* This software is licensed by the MIT License, see LICENSE file */
/* Copyright © 2022 Gregory Lirent */
#include "include.h"
void string_replace(str_t* x, char* p, size_t n, const char* v, size_t vn) {
if (n != vn) {
size_t l = strlen(x->buffer);
if (n < vn) {
char* t = x->buffer;
x->buffer = realloc(x->buffer, l + (vn - n) + 1);
p = x->buffer + (p - t);
}
memmove(p+vn, p+n, l - (p+n - x->buffer) + 1);
}
memcpy(p, v, vn);
}

View File

@ -3,7 +3,7 @@
#include "include.h"
size_t string_replace_cstring_cstring(str_t* x, const char* a, const char* d, size_t maxn) {
size_t libcdsb_string_replace_cstring_cstring(str_t* x, const char* a, const char* d, size_t maxn) {
char *p, *t, *r;
size_t c, n, an, dn;
@ -38,7 +38,7 @@ size_t string_replace_cstring_cstring(str_t* x, const char* a, const char* d, si
}
while (maxn-- && !is_null(p = strstr(p, a))) {
string_replace(x, p, an, d, dn);
libcdsb_string_replace(x, p, an, d, dn);
p += an;
++c;
}
@ -49,7 +49,7 @@ size_t string_replace_cstring_cstring(str_t* x, const char* a, const char* d, si
}
size_t string_replace_cstring_char(str_t* x, const char* a, int dc, size_t maxn) {
size_t libcdsb_string_replace_cstring_char(str_t* x, const char* a, int dc, size_t maxn) {
char *p, *t;
char d[4];
size_t c, n, an, dn;
@ -77,7 +77,7 @@ size_t string_replace_cstring_char(str_t* x, const char* a, int dc, size_t maxn)
}
while (maxn-- && !is_null(p = strstr(p, a))) {
string_replace(x, p, an, d, dn);
libcdsb_string_replace(x, p, an, d, dn);
p += an;
++c;
}
@ -87,7 +87,7 @@ size_t string_replace_cstring_char(str_t* x, const char* a, int dc, size_t maxn)
}
size_t string_replace_char_cstring(str_t* x, int ac, const char* d, size_t maxn) {
size_t libcdsb_string_replace_char_cstring(str_t* x, int ac, const char* d, size_t maxn) {
char *p, *t;
char a[4];
size_t c, n, an, dn;
@ -110,7 +110,7 @@ size_t string_replace_char_cstring(str_t* x, int ac, const char* d, size_t maxn)
}
while (maxn-- && !is_null(p = strstr(p, a))) {
string_replace(x, p, an, d, dn);
libcdsb_string_replace(x, p, an, d, dn);
p += an;
++c;
}
@ -120,7 +120,7 @@ size_t string_replace_char_cstring(str_t* x, int ac, const char* d, size_t maxn)
}
size_t string_replace_char_char(str_t* x, int ac, int dc, size_t maxn) {
size_t libcdsb_string_replace_char_char(str_t* x, int ac, int dc, size_t maxn) {
char* p;
char a[4];
char d[4];
@ -139,7 +139,7 @@ size_t string_replace_char_char(str_t* x, int ac, int dc, size_t maxn) {
c = 0;
while (maxn-- && !is_null(p = strstr(p, a))) {
string_replace(x, p, an, d, dn);
libcdsb_string_replace(x, p, an, d, dn);
p += an;
++c;
}
@ -149,7 +149,7 @@ size_t string_replace_char_char(str_t* x, int ac, int dc, size_t maxn) {
size_t string_replace_cstring_cstring_r(str_t* x, const char*restrict a, const char*restrict d, size_t maxn) {
size_t libcdsb_string_replace_r_cstring_cstring(str_t* x, const char*restrict a, const char*restrict d, size_t maxn) {
char *restrict p;
size_t c, an, dn;
@ -163,7 +163,7 @@ size_t string_replace_cstring_cstring_r(str_t* x, const char*restrict a, const c
c = 0;
while (maxn-- && !is_null(p = strstr(p, a))) {
string_replace(x, p, an, d, dn);
libcdsb_string_replace(x, p, an, d, dn);
p += an;
++c;
}
@ -172,7 +172,7 @@ size_t string_replace_cstring_cstring_r(str_t* x, const char*restrict a, const c
}
size_t string_replace_cstring_char_r(str_t* x, const char*restrict a, int dc, size_t maxn) {
size_t libcdsb_string_replace_r_cstring_char(str_t* x, const char*restrict a, int dc, size_t maxn) {
char *restrict p;
char d[4];
size_t c, an, dn;
@ -188,7 +188,7 @@ size_t string_replace_cstring_char_r(str_t* x, const char*restrict a, int dc, si
c = 0;
while (maxn-- && !is_null(p = strstr(p, a))) {
string_replace(x, p, an, d, dn);
libcdsb_string_replace(x, p, an, d, dn);
p += an;
++c;
}
@ -197,7 +197,7 @@ size_t string_replace_cstring_char_r(str_t* x, const char*restrict a, int dc, si
}
size_t string_replace_char_cstring_r(str_t* x, int ac, const char*restrict d, size_t maxn) {
size_t libcdsb_string_replace_r_char_cstring(str_t* x, int ac, const char*restrict d, size_t maxn) {
char *restrict p;
char a[4];
size_t c, an, dn;
@ -214,7 +214,7 @@ size_t string_replace_char_cstring_r(str_t* x, int ac, const char*restrict d, si
c = 0;
while (maxn-- && !is_null(p = strstr(p, a))) {
string_replace(x, p, an, d, dn);
libcdsb_string_replace(x, p, an, d, dn);
p += an;
++c;
}

View File

@ -7,7 +7,7 @@
/*#####################################################################################################################*/
void string_trim_spaces(str_t* x, int direction) {
void libcdsb_string_trim_spaces(str_t* x, int direction) {
static size_t m[32/(sizeof(size_t))] = {0};
u8_t* l;
@ -51,7 +51,7 @@ void string_trim_spaces(str_t* x, int direction) {
/*#####################################################################################################################*/
void string_trim_cstring(str_t* x, const char* s, int direction) {
void libcdsb_string_trim_cstring(str_t* x, const char* s, int direction) {
u8_t* l;
u8_t* r;
@ -122,7 +122,7 @@ void string_trim_cstring(str_t* x, const char* s, int direction) {
}
void string_trim_char(str_t* x, int sc, int direction) {
void libcdsb_string_trim_char(str_t* x, int sc, int direction) {
u8_t* l;
u8_t* r;

View File

@ -3,6 +3,7 @@
#include "__internal/assert.h"
#include "__internal/vnode.h"
#include "../include/string.h"
/*#####################################################################################################################*/
@ -10,6 +11,17 @@
static vnode_t create_value(vtype xt, const void* v, vtype t) {
var_t _;
if (t == VTYPE_FLOAT) {
_.u64 = (s64_t)roundf(*(fl_t*)v);
t = VTYPE_INT64;
} else if (t == VTYPE_DOUBLE) {
_.u64 = (s64_t)round (*(dbl_t*)v);
t = VTYPE_INT64;
} else {
_.u64 = (s64_t)roundl(*(ldbl_t*)v);
t = VTYPE_INT64;
}
if (sizeof(void*) == 8) {
if (t == VTYPE_UINT8 || t == VTYPE_INT8 || t == VTYPE_BOOLEAN ) {
_.u64 = *(u8_t*)v;
@ -63,11 +75,27 @@ static vnode_t create_value(vtype xt, const void* v, vtype t) {
static vnode_t create_float(vtype xt, const void* v, vtype t) {
var_t _;
if (t == VTYPE_FLOAT) {
if (t == VTYPE_UINT8 || t == VTYPE_BOOLEAN ) {
_.ld = *(u8_t*)v;
} else if (t == VTYPE_UINT16) {
_.ld = *(u16_t*)v;
} else if (t == VTYPE_UINT32 || (sizeof(void*) == 4 && t == VTYPE_POINTER)) {
_.ld = *(u32_t*)v;
} else if (t == VTYPE_UINT64 || (sizeof(void*) == 8 && t == VTYPE_POINTER)) {
_.ld = *(u64_t*)v;
} else if (t == VTYPE_INT8) {
_.ld = *(s8_t*)v;
} else if (t == VTYPE_INT16) {
_.ld = *(s16_t*)v;
} else if (t == VTYPE_INT32) {
_.ld = *(s32_t*)v;
} else if (t == VTYPE_INT64) {
_.ld = *(s64_t*)v;
} else if (t == VTYPE_FLOAT) {
_.ld = *(fl_t*)v;
} else if (t == VTYPE_DOUBLE) {
_.ld = *(dbl_t*)v;
} else { // (t == VTYPE_LDOUBLE)
} else {
_.ld = *(ldbl_t*)v;
}
@ -81,7 +109,7 @@ static vnode_t create_float(vtype xt, const void* v, vtype t) {
if (!is_permissible(dbl_t)) {
_.ptr = memndup(&_.d, sizeof(_.d));
}
} else { // (xt == VTYPE_LDOUBLE)
} else {
if (!is_permissible(ldbl_t)) {
_.ptr = memndup(&_.ld, sizeof(_.ld));
}
@ -135,7 +163,9 @@ vnode_t libcdsb_vnode_create(const void* v, vtype t) {
case VTYPE_POINTER: _.ptr = *(void**)v;
break;
case VTYPE_STRING: _.ptr = string_duplicate(v);
case VTYPE_STRING: if (sizeof(str_t) == sizeof(void*)) {
_.ptr = strdup(*(char**)v);
} else _.ptr = string_duplicate(v);
break;
case VTYPE_MAP: _.ptr = map_duplicate(v);
@ -178,7 +208,7 @@ void* libcdsb_vnode_peek(const vnode_t* x, vtype t) {
case VTYPE_UINT32:
vt_: return (void*)x;
case VTYPE_STRING:
case VTYPE_STRING: if (sizeof(str_t) == sizeof(void*)) goto vt_;
case VTYPE_MAP:
case VTYPE_ARRAY:
case VTYPE_LIST:
@ -210,7 +240,10 @@ void libcdsb_vnode_free(vnode_t* x, vtype t) {
vt_:
break;
case VTYPE_STRING: string_free(*x); goto pt_;
case VTYPE_STRING: if (sizeof(str_t) > sizeof(void*)) {
string_free(*x);
}
goto pt_;
case VTYPE_MAP: map_free(*x); goto pt_;
case VTYPE_ARRAY: array_free(*x); goto pt_;
case VTYPE_LIST: list_free(*x); goto pt_;
@ -229,18 +262,22 @@ void libcdsb_vnode_free(vnode_t* x, vtype t) {
vnode_t libcdsb_vnode_create_target(vtype xt, const void* v, vtype t) {
var_t _ = { .ptr = 0 };
if (is_integer(xt)) {
tvalue_assert(t);
if (xt <= VTYPE_LDOUBLE) {
if (t >= VTYPE_STRING) t = VTYPE_POINTER;
if (xt <= VTYPE_INT64)
return create_value(xt, v, t);
return create_value(xt, v, t);
} else if (is_float(xt)) {
tfloat_assert(t);
return create_float(xt, v, t);
} else if (t == VTYPE_POINTER && (t = xt) > VTYPE_STRING) {
v = *(void**)v;
}
type_assert(xt, t);
switch (xt) { default: abort();
case VTYPE_STRING: _.ptr = string_duplicate(v);
case VTYPE_STRING: if (sizeof(str_t) == sizeof(void*)) {
_.ptr = strdup(*(char**)v);
} else _.ptr = string_duplicate(v);
break;
case VTYPE_MAP: _.ptr = map_duplicate(v);