diff --git a/examples/array.c b/examples/array.c index 7dc68be..bf35430 100644 --- a/examples/array.c +++ b/examples/array.c @@ -7,11 +7,11 @@ typedef vtype_array arr_t; -int print_value(void* value, ssize_t index, vtype type, void* data) { +int print_value(vtype_variable value, ssize_t index, void* data) { const char *n = data; - vtype_int32 *v = value; + vtype_int32 *v = value.pointer; - assert(type == VTYPE_INT32); + assert(value.type == VTYPE_INT32); printf("%s %d (index: %ld)\n", n, *v, index); diff --git a/examples/dict.c b/examples/dict.c index c4bebbb..604d6b6 100644 --- a/examples/dict.c +++ b/examples/dict.c @@ -8,28 +8,28 @@ typedef vtype_dict dict_t; -int print_value(const void* key, vtype key_type, void* value, vtype value_type, void* data) { +int print_value(vtype_variable key, vtype_variable value, void* data) { const char *n = data; - switch (key_type) { + switch (key.type) { default: abort(); case VTYPE_INT32: - printf("%s %d: ", n, *(vtype_int32*)key); + printf("%s %d: ", n, *(vtype_int32*)key.pointer); break; case VTYPE_FLOAT: - printf("%s %f: ", n, *(vtype_float*)key); + printf("%s %f: ", n, *(vtype_float*)key.pointer); break; } - switch (value_type) { + switch (value.type) { default: abort(); case VTYPE_INT32: - printf("%d\n", *(vtype_int32*)value); + printf("%d\n", *(vtype_int32*)value.pointer); break; case VTYPE_FLOAT: - printf("%f\n", *(vtype_float*)value); + printf("%f\n", *(vtype_float*)value.pointer); break; } diff --git a/examples/list.c b/examples/list.c index 83ca85a..e2a8e7b 100644 --- a/examples/list.c +++ b/examples/list.c @@ -8,17 +8,17 @@ typedef vtype_list list_t; -int print_value(void* value, ssize_t index, vtype type, void* data) { +int print_value(vtype_variable value, ssize_t index, void* data) { const char *n = data; - switch (type) { + switch (value.type) { default: abort(); case VTYPE_INT32: - printf("%s %d (index: %ld)\n", n, *(vtype_int32*)value, index); + printf("%s %d (index: %ld)\n", n, *(vtype_int32*)value.pointer, index); break; case VTYPE_FLOAT: - printf("%s %f (index: %ld)\n", n, *(vtype_float*)value, index); + printf("%s %f (index: %ld)\n", n, *(vtype_float*)value.pointer, index); break; } diff --git a/examples/map.c b/examples/map.c index 30c8a2a..a60b02f 100644 --- a/examples/map.c +++ b/examples/map.c @@ -8,22 +8,22 @@ typedef vtype_map map_t; -int print_value(const void* key, vtype key_type, void* value, vtype value_type, void* data) { +int print_value(vtype_variable key, vtype_variable value, void* data) { const char *n = data; - vtype_int32 *k = (void*)key; + vtype_int32 *k = (void*)key.pointer; - assert(key_type == VTYPE_INT32); + assert(key.type == VTYPE_INT32); printf("%s %d: ", n, *k); - switch (value_type) { + switch (value.type) { default: abort(); case VTYPE_INT32: - printf("%d\n", *(vtype_int32*)value); + printf("%d\n", *(vtype_int32*)value.pointer); break; case VTYPE_FLOAT: - printf("%f\n", *(vtype_float*)value); + printf("%f\n", *(vtype_float*)value.pointer); break; } diff --git a/examples/set.c b/examples/set.c index d05a978..643c22e 100644 --- a/examples/set.c +++ b/examples/set.c @@ -7,11 +7,11 @@ typedef vtype_set vset_t; -int print_value(const void* value, vtype type, void* data) { +int print_value(vtype_variable value, void* data) { const char *n = data; - vtype_int32 *v = (void*)value; + vtype_int32 *v = (void*)value.pointer; - assert(type == VTYPE_INT32); + assert(value.type == VTYPE_INT32); printf("%s %d\n", n, *v); diff --git a/include/array.h b/include/array.h index 68b37c3..e6ca9ff 100644 --- a/include/array.h +++ b/include/array.h @@ -7,7 +7,7 @@ #ifndef LIBCDSB_ARRAY_H #define LIBCDSB_ARRAY_H -typedef int (*array_access_callback)(void* value, ssize_t index, vtype type, void* data); +typedef int (*array_access_callback)(vtype_variable, ssize_t index, void* data); /*#####################################################################################################################*/ @@ -22,15 +22,15 @@ inline void array_init (vtype_array* x, vtype type) { x->type = type; x->me /*#####################################################################################################################*/ -#define array_pop(x, value, data, callback) libcdsb_array_find (x, _LIBCDSB_value_pointer(value), _LIBCDSB_vtypeof(value), data, callback, 0, 1) +#define array_pop(x, value, data, callback) libcdsb_array_find (x, _LIBCDSB_var(value), data, callback, 0, 1) #define array_get array_find #define array_pop_by_index(x, index, data, callback) libcdsb_array_get (x, index, data, callback, 1) #define array_get_by_index(x, index, data, callback) libcdsb_array_get (x, index, data, callback, 0) -#define array_find(x, value, data, callback) libcdsb_array_find (x, _LIBCDSB_value_pointer(value), _LIBCDSB_vtypeof(value), data, callback, 0, 0) -#define array_rfind(x, value, data, callback) libcdsb_array_find (x, _LIBCDSB_value_pointer(value), _LIBCDSB_vtypeof(value), data, callback, 1, 0) -#define array_countof(x, value) libcdsb_array_count (x, _LIBCDSB_value_pointer(value), _LIBCDSB_vtypeof(value)) -#define array_push_back(x, value) libcdsb_array_insert (x, _LIBCDSB_value_pointer(value), _LIBCDSB_vtypeof(value)) -#define array_attach_back(x, value) libcdsb_array_attach (x, _LIBCDSB_value_pointer(value), _LIBCDSB_vtypeof(value)) +#define array_find(x, value, data, callback) libcdsb_array_find (x, _LIBCDSB_var(value), data, callback, 0, 0) +#define array_rfind(x, value, data, callback) libcdsb_array_find (x, _LIBCDSB_var(value), data, callback, 1, 0) +#define array_countof(x, value) libcdsb_array_count (x, _LIBCDSB_var(value)) +#define array_push_back(x, value) libcdsb_array_insert (x, _LIBCDSB_var(value)) +#define array_attach_back(x, value) libcdsb_array_attach (x, _LIBCDSB_var(value)) #define array_foreach(x, data, callback) libcdsb_array_foreach(x, data, callback, 0) #define array_remove(x, value) array_pop (x, value, 0, 0) #define array_remove_by_index(x, index) array_pop_by_index (x, index, 0, 0) @@ -39,12 +39,12 @@ inline void array_init (vtype_array* x, vtype type) { x->type = type; x->me /*#####################################################################################################################*/ -extern ssize_t libcdsb_array_insert (vtype_array* x, const void* value, vtype type) Nonnull__(1); -extern ssize_t libcdsb_array_attach (vtype_array* x, const void* value, vtype type) Nonnull__(1); -extern int libcdsb_array_find (vtype_array* x, const void* value, vtype type, void* data, array_access_callback, bool reverse, bool cut) Nonnull__(1); -extern int libcdsb_array_get (vtype_array* x, ssize_t index, void* data, array_access_callback, bool cut) Nonnull__(1); -extern int libcdsb_array_foreach (vtype_array* x, void* data, array_access_callback, bool flush) Nonnull__(1,3); +extern ssize_t libcdsb_array_insert (vtype_array* x, vtype_variable) Nonnull__(1); +extern ssize_t libcdsb_array_attach (vtype_array* x, vtype_variable) Nonnull__(1); +extern int libcdsb_array_find (vtype_array* x, vtype_variable, void* data, array_access_callback, bool reverse, bool cut) Nonnull__(1); +extern int libcdsb_array_get (vtype_array* x, ssize_t index, void* data, array_access_callback, bool cut) Nonnull__(1); +extern int libcdsb_array_foreach (vtype_array* x, void* data, array_access_callback, bool flush) Nonnull__(1,3); -extern size_t libcdsb_array_count(const vtype_array* s, const void* value, vtype type) Pure__ Warn_unused_result__ Nonnull__(1); +extern size_t libcdsb_array_count(const vtype_array* s, vtype_variable) Pure__ Warn_unused_result__ Nonnull__(1); #endif /* LIBCDSB_ARRAY_H */ diff --git a/include/bits/__generics.h b/include/bits/__generics.h index c88ca32..c085835 100644 --- a/include/bits/__generics.h +++ b/include/bits/__generics.h @@ -26,6 +26,7 @@ vtype_double: VTYPE_DOUBLE,\ vtype_ldouble: VTYPE_LDOUBLE)) + #define _LIBCDSB_vtypeof(x) vtypeof(_Generic((x), default: (x), const char*: &(x), char*: &(x))) #define _LIBCDSB_value_pointer(x) _Generic((x), default: &(x),\ vtype_string*: (x), const vtype_string*: (x),\ @@ -34,6 +35,7 @@ vtype_map*: (x), const vtype_map*: (x),\ vtype_set*: (x), const vtype_set*: (x),\ vtype_dict*: (x), const vtype_dict*: (x)) +#define _LIBCDSB_var(x) libcdsb_variable_build(_LIBCDSB_value_pointer(x), _LIBCDSB_vtypeof(x)) #define _LIBCDSB_to_cstring(x) _Generic((x), default: _LIBCDSB_nothing,\ vtype_string*: _LIBCDSB_deref1, const vtype_string*: _LIBCDSB_deref1,\ diff --git a/include/dict.h b/include/dict.h index 80b705b..cab0590 100644 --- a/include/dict.h +++ b/include/dict.h @@ -7,7 +7,7 @@ #ifndef LIBCDSB_DICT_H #define LIBCDSB_DICT_H -typedef int (*dict_access_callback)(const void* key, vtype key_type, void* value, vtype value_type, void* data); +typedef int (*dict_access_callback)(vtype_variable key, vtype_variable value, void* data); /*#####################################################################################################################*/ @@ -17,21 +17,21 @@ inline void dict_init(vtype_dict* x) { x->nodes = (void*)(x->capacity = x->size /*#####################################################################################################################*/ -#define dict_pop(x, key, data, callback) libcdsb_dict_find (x, _LIBCDSB_value_pointer(key), _LIBCDSB_vtypeof(key), data, callback, 1) -#define dict_get(x, key, data, callback) libcdsb_dict_find (x, _LIBCDSB_value_pointer(key), _LIBCDSB_vtypeof(key), data, callback, 0) -#define dict_update(x, key, value) libcdsb_dict_update (x, _LIBCDSB_value_pointer(key), _LIBCDSB_vtypeof(key), _LIBCDSB_value_pointer(value), _LIBCDSB_vtypeof(value), 0, 0) -#define dict_inject(x, key, value) libcdsb_dict_inject (x, _LIBCDSB_value_pointer(key), _LIBCDSB_vtypeof(key), _LIBCDSB_value_pointer(value), _LIBCDSB_vtypeof(value), 0, 0) -#define dict_foreach(x, data, callback) libcdsb_dict_foreach (x, data, callback, 0) -#define dict_remove(x, key) dict_pop (x, key, 0, 0) +#define dict_pop(x, key, data, callback) libcdsb_dict_find (x, _LIBCDSB_var(key), data, callback, 1) +#define dict_get(x, key, data, callback) libcdsb_dict_find (x, _LIBCDSB_var(key), data, callback, 0) +#define dict_update(x, key, value) libcdsb_dict_update (x, _LIBCDSB_var(key), _LIBCDSB_var(value), 0, 0) +#define dict_inject(x, key, value) libcdsb_dict_inject (x, _LIBCDSB_var(key), _LIBCDSB_var(value), 0, 0) +#define dict_foreach(x, data, callback) libcdsb_dict_foreach(x, data, callback, 0) +#define dict_remove(x, key) dict_pop (x, key, 0, 0) #define in_dict(x, key) (dict_get(&x, key, 0, 0) == 0) /*#####################################################################################################################*/ -extern bool libcdsb_dict_update (vtype_dict* x, const void* key, vtype key_type, const void* value, vtype value_type, void* data, dict_access_callback) Nonnull__(1); -extern bool libcdsb_dict_inject (vtype_dict* x, const void* key, vtype key_type, const void* value, vtype value_type, void* data, dict_access_callback) Nonnull__(1); -extern int libcdsb_dict_find (vtype_dict* x, const void* key, vtype key_type, void* data, dict_access_callback, bool cut) Nonnull__(1); -extern int libcdsb_dict_foreach (vtype_dict* x, void* data, dict_access_callback, bool flush) Nonnull__(1,3); -extern bool libcdsb_dict_shrink_to_fit(vtype_dict* x) Nonnull__(1); +extern bool libcdsb_dict_update (vtype_dict* x, vtype_variable key, vtype_variable value, void* data, dict_access_callback) Nonnull__(1); +extern bool libcdsb_dict_inject (vtype_dict* x, vtype_variable key, vtype_variable value, void* data, dict_access_callback) Nonnull__(1); +extern int libcdsb_dict_find (vtype_dict* x, vtype_variable key, void* data, dict_access_callback, bool cut) Nonnull__(1); +extern int libcdsb_dict_foreach (vtype_dict* x, void* data, dict_access_callback, bool flush) Nonnull__(1,3); +extern bool libcdsb_dict_shrink_to_fit(vtype_dict* x) Nonnull__(1); #endif /* LIBCDSB_DICT_H */ diff --git a/include/list.h b/include/list.h index 01fe796..d2e3ccb 100644 --- a/include/list.h +++ b/include/list.h @@ -7,7 +7,7 @@ #ifndef LIBCDSB_LIST_H #define LIBCDSB_LIST_H -typedef int (*list_access_callback)(void* value, ssize_t index, vtype type, void* data); +typedef int (*list_access_callback)(vtype_variable, ssize_t index, void* data); /*#####################################################################################################################*/ @@ -21,19 +21,19 @@ inline void list_init (vtype_list* x) { x->first = x->last = 0; } /*#####################################################################################################################*/ -#define list_pop(x, value, data, callback) libcdsb_list_find (x, _LIBCDSB_value_pointer(value), _LIBCDSB_vtypeof(value), data, callback, 0, 1) +#define list_pop(x, value, data, callback) libcdsb_list_find (x, _LIBCDSB_var(value), data, callback, 0, 1) #define list_get list_find #define list_pop_by_index(x, index, data, callback) libcdsb_list_get (x, index, data, callback, 1) #define list_get_by_index(x, index, data, callback) libcdsb_list_get (x, index, data, callback, 0) -#define list_find(x, value, data, callback) libcdsb_list_find (x, _LIBCDSB_value_pointer(value), _LIBCDSB_vtypeof(value), data, callback, 0, 0) -#define list_rfind(x, value, data, callback) libcdsb_list_find (x, _LIBCDSB_value_pointer(value), _LIBCDSB_vtypeof(value), data, callback, 1, 0) -#define list_countof(x, value) libcdsb_list_count (x, _LIBCDSB_value_pointer(value), _LIBCDSB_vtypeof(value)) -#define list_insert(x, index, value) libcdsb_list_insert (x, index, _LIBCDSB_value_pointer(value), _LIBCDSB_vtypeof(value), -1, 0, 0) -#define list_replace(x, index, value) libcdsb_list_insert (x, index, _LIBCDSB_value_pointer(value), _LIBCDSB_vtypeof(value), 0, 0, 0) -#define list_push_back(x, value) libcdsb_list_insert (x, -1, _LIBCDSB_value_pointer(value), _LIBCDSB_vtypeof(value), 1, 0, 0) -#define list_push_front(x, value) libcdsb_list_insert (x, 0, _LIBCDSB_value_pointer(value), _LIBCDSB_vtypeof(value), -1, 0, 0) -#define list_attach_back(x, value) libcdsb_list_attach (x, -1, _LIBCDSB_value_pointer(value), _LIBCDSB_vtypeof(value), 1, 0, 0) -#define list_attach_front(x, value) libcdsb_list_attach (x, 0, _LIBCDSB_value_pointer(value), _LIBCDSB_vtypeof(value), -1, 0, 0) +#define list_find(x, value, data, callback) libcdsb_list_find (x, _LIBCDSB_var(value), data, callback, 0, 0) +#define list_rfind(x, value, data, callback) libcdsb_list_find (x, _LIBCDSB_var(value), data, callback, 1, 0) +#define list_countof(x, value) libcdsb_list_count (x, _LIBCDSB_var(value)) +#define list_insert(x, index, value) libcdsb_list_insert (x, index, _LIBCDSB_var(value), -1, 0, 0) +#define list_replace(x, index, value) libcdsb_list_insert (x, index, _LIBCDSB_var(value), 0, 0, 0) +#define list_push_back(x, value) libcdsb_list_insert (x, -1, _LIBCDSB_var(value), 1, 0, 0) +#define list_push_front(x, value) libcdsb_list_insert (x, 0, _LIBCDSB_var(value), -1, 0, 0) +#define list_attach_back(x, value) libcdsb_list_attach (x, -1, _LIBCDSB_var(value), 1, 0, 0) +#define list_attach_front(x, value) libcdsb_list_attach (x, 0, _LIBCDSB_var(value), -1, 0, 0) #define list_foreach(x, data, callback) libcdsb_list_foreach(x, data, callback, 0) #define list_remove(x, value) list_pop (x, value, 0, 0) #define list_remove_by_index(x, index) list_pop_by_index (x, index, 0, 0) @@ -42,12 +42,12 @@ inline void list_init (vtype_list* x) { x->first = x->last = 0; } /*#####################################################################################################################*/ -extern bool libcdsb_list_insert (vtype_list* x, ssize_t index, const void* value, vtype type, int ins_direction, void* data, list_access_callback) Nonnull__(1); -extern bool libcdsb_list_attach (vtype_list* x, ssize_t index, const void* value, vtype type, int ins_direction, void* data, list_access_callback) Nonnull__(1); -extern int libcdsb_list_find (vtype_list* x, const void* value, vtype type, void* data, list_access_callback, bool reverse, bool cut) Nonnull__(1); -extern int libcdsb_list_get (vtype_list* x, ssize_t index, void* data, list_access_callback, bool cut) Nonnull__(1); -extern int libcdsb_list_foreach (vtype_list* x, void* data, list_access_callback, bool flush) Nonnull__(1,3); +extern bool libcdsb_list_insert (vtype_list* x, ssize_t index, vtype_variable, int ins_direction, void* data, list_access_callback) Nonnull__(1); +extern bool libcdsb_list_attach (vtype_list* x, ssize_t index, vtype_variable, int ins_direction, void* data, list_access_callback) Nonnull__(1); +extern int libcdsb_list_find (vtype_list* x, vtype_variable, void* data, list_access_callback, bool reverse, bool cut) Nonnull__(1); +extern int libcdsb_list_get (vtype_list* x, ssize_t index, void* data, list_access_callback, bool cut) Nonnull__(1); +extern int libcdsb_list_foreach (vtype_list* x, void* data, list_access_callback, bool flush) Nonnull__(1,3); -extern size_t libcdsb_list_count(const vtype_list* s, const void* value, vtype type) Pure__ Warn_unused_result__ Nonnull__(1); +extern size_t libcdsb_list_count(const vtype_list* s, vtype_variable) Pure__ Warn_unused_result__ Nonnull__(1); #endif /* LIBCDSB_LIST_H */ diff --git a/include/map.h b/include/map.h index f5ed144..de6b3b5 100644 --- a/include/map.h +++ b/include/map.h @@ -8,7 +8,7 @@ #ifndef LIBCDSB_MAP_H #define LIBCDSB_MAP_H -typedef int (*map_access_callback)(const void* key, vtype key_type, void* value, vtype value_type, void* data); +typedef int (*map_access_callback)(vtype_variable key, vtype_variable value, void* data); /*#####################################################################################################################*/ @@ -16,10 +16,10 @@ extern void map_init(vtype_map* x, vtype key_type) Nonnull__(1); /*#####################################################################################################################*/ -#define map_pop(x, key, data, callback) libcdsb_map_find (x, _LIBCDSB_value_pointer(key), _LIBCDSB_vtypeof(key), data, callback, 1) -#define map_get(x, key, data, callback) libcdsb_map_find (x, _LIBCDSB_value_pointer(key), _LIBCDSB_vtypeof(key), data, callback, 0) -#define map_update(x, key, value) libcdsb_map_update (x, _LIBCDSB_value_pointer(key), _LIBCDSB_vtypeof(key), _LIBCDSB_value_pointer(value), _LIBCDSB_vtypeof(value), 0, 0) -#define map_inject(x, key, value) libcdsb_map_inject (x, _LIBCDSB_value_pointer(key), _LIBCDSB_vtypeof(key), _LIBCDSB_value_pointer(value), _LIBCDSB_vtypeof(value), 0, 0) +#define map_pop(x, key, data, callback) libcdsb_map_find (x, _LIBCDSB_var(key), data, callback, 1) +#define map_get(x, key, data, callback) libcdsb_map_find (x, _LIBCDSB_var(key), data, callback, 0) +#define map_update(x, key, value) libcdsb_map_update (x, _LIBCDSB_var(key), _LIBCDSB_var(value), 0, 0) +#define map_inject(x, key, value) libcdsb_map_inject (x, _LIBCDSB_var(key), _LIBCDSB_var(value), 0, 0) #define map_foreach(x, data, callback) libcdsb_map_foreach(x, data, callback, RBFOREACH_UNSPECIFIED, 0) #define map_remove(x, key) map_pop (x, key, 0, 0) @@ -27,9 +27,9 @@ extern void map_init(vtype_map* x, vtype key_type) Nonnull__(1); /*#####################################################################################################################*/ -extern bool libcdsb_map_update (vtype_map* x, const void* key, vtype key_type, const void* value, vtype value_type, void* data, map_access_callback) Nonnull__(1); -extern bool libcdsb_map_inject (vtype_map* x, const void* key, vtype key_type, const void* value, vtype value_type, void* data, map_access_callback) Nonnull__(1); -extern int libcdsb_map_find (vtype_map* x, const void* key, vtype key_type, void* data, map_access_callback, bool cut) Nonnull__(1); -extern int libcdsb_map_foreach(vtype_map* x, void* data, map_access_callback, rbforeach_t, bool flush) Nonnull__(1,3); +extern bool libcdsb_map_update (vtype_map* x, vtype_variable key, vtype_variable value, void* data, map_access_callback) Nonnull__(1); +extern bool libcdsb_map_inject (vtype_map* x, vtype_variable key, vtype_variable value, void* data, map_access_callback) Nonnull__(1); +extern int libcdsb_map_find (vtype_map* x, vtype_variable key, void* data, map_access_callback, bool cut) Nonnull__(1); +extern int libcdsb_map_foreach(vtype_map* x, void* data, map_access_callback, rbforeach_t, bool flush) Nonnull__(1,3); #endif /* LIBCDSB_MAP_H */ diff --git a/include/set.h b/include/set.h index e9ffa04..c64ff29 100644 --- a/include/set.h +++ b/include/set.h @@ -8,7 +8,7 @@ #ifndef LIBCDSB_SET_H #define LIBCDSB_SET_H -typedef int (*vset_access_callback)(const void* value, vtype type, void* data); +typedef int (*vset_access_callback)(vtype_variable value, void* data); /*#####################################################################################################################*/ @@ -16,10 +16,10 @@ extern void vset_init(vtype_set* x, vtype type) Nonnull__(1); /*#####################################################################################################################*/ -#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_pop(x, value, data, callback) libcdsb_vset_find (x, _LIBCDSB_var(value), data, callback, 1) +#define vset_get(x, value, data, callback) libcdsb_vset_find (x, _LIBCDSB_var(value), data, callback, 0) +#define vset_push(x, value) libcdsb_vset_insert (x, _LIBCDSB_var(value)) +#define vset_attach(x, value) libcdsb_vset_attach (x, _LIBCDSB_var(value)) #define vset_foreach(x, data, callback) libcdsb_vset_foreach(x, data, callback, RBFOREACH_UNSPECIFIED, 0) #define vset_remove(x, value) vset_pop (x, value, 0, 0) @@ -27,9 +27,9 @@ extern void vset_init(vtype_set* x, vtype type) 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, rbforeach_t, bool flush) Nonnull__(1,3); +extern bool libcdsb_vset_insert (vtype_set* x, vtype_variable) Nonnull__(1); +extern bool libcdsb_vset_attach (vtype_set* x, vtype_variable) Nonnull__(1); +extern int libcdsb_vset_find (vtype_set* x, vtype_variable, void* data, vset_access_callback, bool cut) Nonnull__(1); +extern int libcdsb_vset_foreach(vtype_set* x, void* data, vset_access_callback, rbforeach_t, bool flush) Nonnull__(1,3); #endif /* LIBCDSB_SET_H */ diff --git a/include/vtype.h b/include/vtype.h index d807f6d..693c436 100644 --- a/include/vtype.h +++ b/include/vtype.h @@ -36,6 +36,11 @@ typedef enum libcdsb_value_types { /*#####################################################################################################################*/ +struct libcdsb_variable { + void* pointer; + vtype type; +}; + struct libcdsb_string { char* buffer; }; struct libcdsb_array { void* mem; size_t size; vtype type; }; @@ -66,16 +71,19 @@ typedef long double vtype_ldouble; typedef size_t vtype_hash; -typedef struct libcdsb_array vtype_array; -typedef struct libcdsb_map vtype_map; -typedef struct libcdsb_set vtype_set; -typedef struct libcdsb_list vtype_list; -typedef struct libcdsb_dict vtype_dict; -typedef struct libcdsb_string vtype_string; +typedef struct libcdsb_array vtype_array; +typedef struct libcdsb_map vtype_map; +typedef struct libcdsb_set vtype_set; +typedef struct libcdsb_list vtype_list; +typedef struct libcdsb_dict vtype_dict; +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_variable_stringify(vtype_variable value) Warn_unused_result__; +inline vtype_variable libcdsb_variable_build (void* value, vtype t) Always_inline__; /*#####################################################################################################################*/ @@ -161,4 +169,13 @@ inline void string_copy_init(vtype_string* x, const vtype_string* s) { x->buffer = libcdsb_strdup(s->buffer); } +inline vtype_variable libcdsb_variable_build(void* value, vtype t) { + vtype_variable var; + + var.pointer = value; + var.type = t; + + return var; +} + #endif /* LIBCDSB_VTYPE_H */ diff --git a/src/__internal/include.h b/src/__internal/include.h index ab46005..417c362 100644 --- a/src/__internal/include.h +++ b/src/__internal/include.h @@ -48,21 +48,21 @@ typedef vtype_float fl_t; typedef vtype_double dbl_t; typedef vtype_ldouble ldbl_t; -typedef vtype_string str_t; -typedef vtype_array arr_t; -typedef vtype_list list_t; -typedef vtype_map map_t; -typedef vtype_set set_t; -typedef vtype_dict dict_t; +typedef vtype_string str_t; +typedef vtype_array arr_t; +typedef vtype_list list_t; +typedef vtype_map map_t; +typedef vtype_set set_t; +typedef vtype_dict dict_t; +typedef vtype_variable var_t; 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(var_t s0, var_t s1) pure__ wur__; +extern hash_t libcdsb_builtin_variable_hash (var_t value) pure__ wur__; ainline(stack_t* libcdsb_builtin_stack_insert(stack_t* x, void* v)) { stack_t* p = x->prev; @@ -93,11 +93,11 @@ ainline(stack_t* libcdsb_builtin_stack_insert(stack_t* x, void* v)) { #define strndup libcdsb_strndup #define memndup libcdsb_memndup -#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_stringify libcdsb_variable_stringify +#define variable_hash libcdsb_builtin_variable_hash +#define variable_compare libcdsb_builtin_variable_compare + #endif /* LIBCDSB_SRC_INTERNAL_INCLUDE */ diff --git a/src/__internal/vnode.h b/src/__internal/vnode.h index 06f021d..401711a 100644 --- a/src/__internal/vnode.h +++ b/src/__internal/vnode.h @@ -9,61 +9,53 @@ #define is_permissible(T) (sizeof(void*) >= sizeof(T) && _Alignof(void*) >= _Alignof(T)) -typedef union { - void* ptr; bool b; - str_t s; arr_t a; list_t l; - map_t m; set_t vs; dict_t vd; - u8_t u8; u16_t u16; u32_t u32; u64_t u64; - fl_t f; dbl_t d; ldbl_t ld; -} var_t; - typedef void* vnode_t; -extern vnode_t libcdsb_builtin_vnode_create (const void* value, vtype type) wur__; -extern vnode_t libcdsb_builtin_vnode_create_target(vtype target_type, const void* value, vtype type) wur__; +extern vnode_t libcdsb_builtin_vnode_create ( var_t) wur__; +extern vnode_t libcdsb_builtin_vnode_create_ex(vtype xt, var_t) 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 var_t libcdsb_builtin_vnode_peek(const vnode_t* x, vtype type) pure__ wur__ Nonnull__(1); +extern void libcdsb_builtin_vnode_free( vnode_t* x, vtype type) Nonnull__(1); -ainline(void libcdsb_builtin_vnode_attach(vnode_t* node, const void* value, vtype type)) { - if (type < VTYPE_STRING) { - *node = libcdsb_builtin_vnode_create(value, type); - } else if (sizeof(str_t) == sizeof(void*) && type == VTYPE_STRING) { - *node = *(char**)value; +ainline(void libcdsb_builtin_vnode_attach(vnode_t* node, var_t value)) { + if (value.type < VTYPE_STRING) { + *node = libcdsb_builtin_vnode_create(value); + } else if (sizeof(str_t) == sizeof(void*) && value.type == VTYPE_STRING) { + *node = *(char**)value.pointer; } else { - *node = malloc(vtype_size(type)); - memcpy(*node, value, vtype_size(type)); + *node = malloc(vtype_size(value.type)); + memcpy(*node, value.pointer, vtype_size(value.type)); } } -ainline(void libcdsb_builtin_vnode_tattach(vnode_t* node, vtype target_type, const void* value, vtype type)) { - if (type < VTYPE_STRING) { - *node = libcdsb_builtin_vnode_create_target(target_type, value, type); +ainline(void libcdsb_builtin_vnode_attach_ex(vnode_t* node, vtype target, var_t value)) { + if (value.type < VTYPE_STRING) { + *node = libcdsb_builtin_vnode_create_ex(target, value); } else { - type_assert(target_type, type); + type_assert(target, value.type); - if (sizeof(str_t) == sizeof(void*) && type == VTYPE_STRING) { - *node = *(char**)value; + if (sizeof(str_t) == sizeof(void*) && value.type == VTYPE_STRING) { + *node = *(char**)value.pointer; } else { - *node = malloc(vtype_size(type)); - memcpy(*node, value, vtype_size(type)); + *node = malloc(vtype_size(value.type)); + memcpy(*node, value.pointer, vtype_size(value.type)); } } } -#define vnode_create libcdsb_builtin_vnode_create -#define vnode_tcreate libcdsb_builtin_vnode_create_target -#define vnode_attach libcdsb_builtin_vnode_attach -#define vnode_tattach libcdsb_builtin_vnode_tattach -#define vnode_peek libcdsb_builtin_vnode_peek -#define vnode_free libcdsb_builtin_vnode_free +#define vnode_create libcdsb_builtin_vnode_create +#define vnode_attach libcdsb_builtin_vnode_attach +#define vnode_create_ex libcdsb_builtin_vnode_create_ex +#define vnode_attach_ex libcdsb_builtin_vnode_attach_ex -#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_tduplicate(target_type, vnode, type) vnode_tcreate(target_type, vnode_peek(vnode, type), type) +#define vnode_peek libcdsb_builtin_vnode_peek +#define vnode_free libcdsb_builtin_vnode_free -#define vnode_stringify(n, t) vtype_stringify(vnode_peek(n, t), t) +#define vnode_hash(n, t) variable_hash(vnode_peek(n, t)) +#define vnode_compare(s0, t0, s1, t1) variable_compare(vnode_peek(s0, t0), vnode_peek(s1, t1)) +#define vnode_stringify(n, t) variable_stringify(vnode_peek(n, t)) + +#define vnode_duplicate(n, t) vnode_create(vnode_peek(n, t)) +#define vnode_duplicate_ex(xt, n, t) vnode_create_ex(xt, vnode_peek(n, t)) #endif /* LIBCDSB_SRC_INTERNAL_VNODE_H */ diff --git a/src/array/access.c b/src/array/access.c index d787eda..3976b47 100644 --- a/src/array/access.c +++ b/src/array/access.c @@ -16,14 +16,14 @@ int libcdsb_array_get(vtype_array* x, ssize_t i, void* _, array_access_callback if (i < 0 && (i += x->size) < 0) i = 0; if (i < x->size) { - if (callback) r = callback(array_internal_at(x, i), i, x->type, _); + if (callback) r = callback(libcdsb_variable_build(array_internal_at(x, i), x->type), i, _); if (cut) array_cut(x, i, 1); } else return -1; return r; } -int libcdsb_array_find(arr_t* x, const void* v, vtype t, void* _, array_access_callback callback, bool r, bool cut) { +int libcdsb_array_find(arr_t* x, var_t var, void* _, array_access_callback callback, bool r, bool cut) { void *p; ssize_t i; int cmp; @@ -35,7 +35,7 @@ int libcdsb_array_find(arr_t* x, const void* v, vtype t, void* _, array_access_c i = 0; do { - cmp = vtype_compare(p, x->type, v, t); + 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, const void* v, vtype t, void* _, array_access_c while (i--) { p -= vtype_size(x->type); - cmp = vtype_compare(p, x->type, v, t); + cmp = variable_compare(libcdsb_variable_build(p, x->type), var); if (cmp == 0) break; } @@ -58,7 +58,7 @@ int libcdsb_array_find(arr_t* x, const void* v, vtype t, void* _, array_access_c if (i < 0) return i; } - if (callback) cmp = callback(p, i, x->type, _); + if (callback) cmp = callback(libcdsb_variable_build(p, x->type), i, _); if (cut) array_cut(x, i, 1); return cmp; @@ -77,7 +77,7 @@ int libcdsb_array_foreach(vtype_array* x, void* data, array_access_callback call r = 0; while (p < e) { - if ((r = callback(p, n, x->type, data))) + if ((r = callback(libcdsb_variable_build(p, x->type), n, data))) break; p += vtype_size(x->type); diff --git a/src/array/comparison.c b/src/array/comparison.c index f073b46..fa74476 100644 --- a/src/array/comparison.c +++ b/src/array/comparison.c @@ -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); diff --git a/src/array/compute.c b/src/array/compute.c index 637fb37..a6daeb2 100644 --- a/src/array/compute.c +++ b/src/array/compute.c @@ -13,10 +13,10 @@ hash_t array_hash(const arr_t* s) { hash_t hash = 0; if (s->size > 0) - hash = vtype_hash(s->mem, s->type); + hash = variable_hash(libcdsb_variable_build(s->mem, s->type)); if (s->size > 1) - hash += vtype_hash(array_internal_at(s, s->size - 1), s->type); + hash += variable_hash(libcdsb_variable_build(array_internal_at(s, s->size - 1), s->type)); hash ^= s->size; @@ -24,7 +24,7 @@ hash_t array_hash(const arr_t* s) { } -size_t libcdsb_array_count(const arr_t* s, const void* v, vtype t) { +size_t libcdsb_array_count(const arr_t* s, var_t var) { void *p; void *e; int cmp; @@ -35,7 +35,7 @@ size_t libcdsb_array_count(const arr_t* s, const void* v, vtype t) { n = 0; do { - cmp = vtype_compare(p, s->type, v, t); + cmp = variable_compare(libcdsb_variable_build(p, s->type), var); if (cmp == 0) ++n; diff --git a/src/array/modify.c b/src/array/modify.c index 849b013..550a9bf 100644 --- a/src/array/modify.c +++ b/src/array/modify.c @@ -5,47 +5,47 @@ #include "../__internal/assert.h" #include "../__internal/vnode.h" -ssize_t libcdsb_array_insert(arr_t* x, const void* v, vtype t) { +ssize_t libcdsb_array_insert(arr_t* x, var_t var) { ssize_t i; vnode_t n; i = x->size; - n = vnode_tcreate(x->type, v, t); + n = vnode_create_ex(x->type, var); x->mem = realloc(x->mem, ++x->size * vtype_size(x->type)); - if (t < VTYPE_STRING) { - n = vnode_tcreate(x->type, v, t); - memcpy(array_internal_at(x, i), vnode_peek(&n, x->type), vtype_size(x->type)); + if (var.type < VTYPE_STRING) { + n = vnode_create_ex(x->type, var); + 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); } else { - type_assert(x->type, t); - copy_init(array_internal_at(x, i), v, t); + type_assert(x->type, var.type); + copy_init(array_internal_at(x, i), var.pointer, var.type); } return i; } -ssize_t libcdsb_array_attach(arr_t* x, const void* v, vtype t) { +ssize_t libcdsb_array_attach(arr_t* x, var_t var) { ssize_t i; vnode_t n; i = x->size; x->mem = realloc(x->mem, ++x->size * vtype_size(x->type)); - if (t < VTYPE_STRING) { - n = vnode_tcreate(x->type, v, t); - memcpy(array_internal_at(x, i), vnode_peek(&n, x->type), vtype_size(x->type)); + if (var.type < VTYPE_STRING) { + n = vnode_create_ex(x->type, var); + 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); } else { - type_assert(x->type, t); - memcpy(array_internal_at(x, i), v, vtype_size(t)); + type_assert(x->type, var.type); + memcpy(array_internal_at(x, i), var.pointer, vtype_size(var.type)); } return i; diff --git a/src/dict/access.c b/src/dict/access.c index 596fbb6..31ab0ef 100644 --- a/src/dict/access.c +++ b/src/dict/access.c @@ -3,18 +3,20 @@ #include "include.h" -int libcdsb_dict_find(dict_t* x, const void* k, vtype t, void* dt, dict_access_callback callback, bool cut) { +int libcdsb_dict_find(dict_t* x, var_t kvar, void* dt, dict_access_callback callback, bool cut) { dnode_t *c, **p; int r; - void* key; + var_t k, v; if (x->capacity) { - c = *(p = x->nodes + (vtype_hash(k, t) % x->capacity)); + c = *(p = x->nodes + (variable_hash(kvar) % x->capacity)); while (!is_null(c)) { - key = vnode_peek(&c->key, c->key_type); - if (vtype_compare(k, t, key, c->key_type) == 0) { - r = (callback) ? callback(key, c->key_type, 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; @@ -37,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; + var_t k, v; r = 0; i = x->capacity; @@ -45,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(vnode_peek(&c->key, c->key_type), c->key_type, - 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) { diff --git a/src/dict/modify.c b/src/dict/modify.c index 5720b10..48be73f 100644 --- a/src/dict/modify.c +++ b/src/dict/modify.c @@ -50,22 +50,25 @@ bool libcdsb_dict_shrink_to_fit(dict_t* s) { } -bool libcdsb_dict_update(dict_t* x, const void* k, vtype kt, const void* v, vtype vt, void* dt, dict_access_callback callback) { +bool libcdsb_dict_update(dict_t* x, var_t key, var_t value, void* dt, dict_access_callback callback) { dnode_t *c, **p; + var_t k; if (!x->capacity || (double)x->size / x->capacity > REBUILD_POINT_MAX) libcdsb_builtin_rehash(x, x->capacity + CAPACITY_BLOCK); - c = *(p = x->nodes + (vtype_hash(k, kt) % x->capacity)); + c = *(p = x->nodes + (variable_hash(key) % x->capacity)); while (!is_null(c)) { - if (vtype_compare(k, kt, vnode_peek(&c->key, c->key_type), c->key_type) == 0) { - if (!callback) callback(vnode_peek(&c->key, c->key_type), c->key_type, - 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); - c->value = vnode_create(v, c->value_type = vt); + c->value = vnode_create(value); + c->value_type = value.type; return true; } else c = c->prev; @@ -73,9 +76,11 @@ bool libcdsb_dict_update(dict_t* x, const void* k, vtype kt, const void* v, vtyp c = malloc(sizeof(*c)); - c->prev = *p; - c->key = vnode_create(k, c->key_type = kt); - c->value = vnode_create(v, c->value_type = vt); + c->prev = *p; + c->key = vnode_create(key); + c->value = vnode_create(value); + c->key_type = key.type; + c->value_type = value.type; *p = c; ++x->size; @@ -84,32 +89,41 @@ bool libcdsb_dict_update(dict_t* x, const void* k, vtype kt, const void* v, vtyp } -bool libcdsb_dict_inject(dict_t* x, const void* k, vtype kt, const void* v, vtype vt, void* dt, dict_access_callback callback) { +bool libcdsb_dict_inject(dict_t* x, var_t key, var_t value, void* dt, dict_access_callback callback) { dnode_t *c, **p; + var_t k; if (!x->capacity || (double)x->size / x->capacity > REBUILD_POINT_MAX) libcdsb_builtin_rehash(x, x->capacity + CAPACITY_BLOCK); - c = *(p = x->nodes + (vtype_hash(k, kt) % x->capacity)); + c = *(p = x->nodes + (variable_hash(key) % x->capacity)); while (!is_null(c)) { - if (vtype_compare(k, kt, vnode_peek(&c->key, c->key_type), c->key_type) == 0) { - if (!callback) callback(vnode_peek(&c->key, c->key_type), c->key_type, - 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); - vnode_attach(&c->key, k, c->key_type = kt); - vnode_attach(&c->value, v, c->value_type = vt); + vnode_attach(&c->key, key); + vnode_attach(&c->value, value); + + c->key_type = key.type; + c->value_type = value.type; return true; } else c = c->prev; } (c = malloc(sizeof(*c)))->prev = *p; - vnode_attach(&c->key, k, c->key_type = kt); - vnode_attach(&c->value, v, c->value_type = vt); + + vnode_attach(&c->key, key); + vnode_attach(&c->value, value); + + c->key_type = key.type; + c->value_type = value.type; *p = c; ++x->size; diff --git a/src/list/access.c b/src/list/access.c index 1d6834e..6337a53 100644 --- a/src/list/access.c +++ b/src/list/access.c @@ -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(vnode_peek(&c->node, c->type), i, c->type, _) : 0; + i = (callback) ? callback(vnode_peek(&c->node, c->type), i, _) : 0; if (cut) libcdsb_builtin_cut(x, c); @@ -51,21 +50,23 @@ int libcdsb_list_get(vtype_list* x, ssize_t i, void* _, list_access_callback cal } -int libcdsb_list_find(vtype_list* x, const void* v, vtype t, void* _, list_access_callback callback, bool r, bool cut) { +int libcdsb_list_find(vtype_list* x, var_t value, void* _, list_access_callback callback, bool r, bool cut) { ldir_t dir; lnode_t* c; ssize_t i; int cmp; + var_t 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, v, t); + v = vnode_peek(&c->node, c->type); + cmp = variable_compare(v, value); if (cmp == 0) { - i = (callback) ? callback(vnode_peek(&c->node, c->type), (r)?~i:i, c->type, _) : 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, const void* v, vtype t, void* _, list_acces 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(vnode_peek(&c->node, c->type), i, c->type, data)) != 0) + if ((r = callback(vnode_peek(&c->node, c->type), i, data)) != 0) break; n = c->next; diff --git a/src/list/compute.c b/src/list/compute.c index 7d40aee..0aae992 100644 --- a/src/list/compute.c +++ b/src/list/compute.c @@ -36,8 +36,7 @@ hash_t list_hash(const list_t* s) { } -size_t libcdsb_list_count(const list_t* s, const void* v, vtype t) { - +size_t libcdsb_list_count(const list_t* s, var_t value) { lnode_t* c; size_t n; int cmp; @@ -46,7 +45,7 @@ size_t libcdsb_list_count(const list_t* s, const void* v, vtype t) { n = 0; while (!is_null(c)) { - cmp = vtype_compare(vnode_peek(&c->node, c->type), c->type, v, t); + cmp = variable_compare(vnode_peek(&c->node, c->type), value); if (cmp == 0) ++n; diff --git a/src/list/modify.c b/src/list/modify.c index c9265ea..16f7fbd 100644 --- a/src/list/modify.c +++ b/src/list/modify.c @@ -3,8 +3,7 @@ #include "include.h" -bool libcdsb_list_insert(list_t* x, ssize_t i, const void* v, vtype t, int ins, void* dt, list_access_callback callback) { - +bool libcdsb_list_insert(list_t* x, ssize_t i, var_t value, int ins, void* dt, list_access_callback callback) { ldir_t dir; lnode_t* c; @@ -42,19 +41,18 @@ bool libcdsb_list_insert(list_t* x, ssize_t i, const void* v, vtype t, int ins, ldir_dir(ldir_inv(c, dir), dir) = c; } else { - if (callback) callback(vnode_peek(&c->node, c->type), -1, c->type, dt); + if (callback) callback(vnode_peek(&c->node, c->type), -1, dt); vnode_free(&c->node, c->type); } - c->node = vnode_create(v, t); - c->type = t; + c->node = vnode_create(value); + c->type = value.type; return true; } -bool libcdsb_list_attach(list_t* x, ssize_t i, const void* v, vtype t, int ins, void* dt, list_access_callback callback) { - +bool libcdsb_list_attach(list_t* x, ssize_t i, var_t value, int ins, void* dt, list_access_callback callback) { ldir_t dir; lnode_t* c; @@ -92,11 +90,12 @@ bool libcdsb_list_attach(list_t* x, ssize_t i, const void* v, vtype t, int ins, ldir_dir(ldir_inv(c, dir), dir) = c; } else { - if (callback) callback(vnode_peek(&c->node, c->type), -1, c->type, dt); + if (callback) callback(vnode_peek(&c->node, c->type), -1, dt); vnode_free(&c->node, c->type); } - vnode_attach(&c->node, v, c->type = t); + vnode_attach(&c->node, value); + c->type = value.type; return true; } diff --git a/src/map/access.c b/src/map/access.c index 72fed74..8bd4f85 100644 --- a/src/map/access.c +++ b/src/map/access.c @@ -22,7 +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(vnode_peek(&n->key, x->type), x->type, 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; @@ -45,19 +45,19 @@ static int libcdsb_builtin_foreach(map_t* x, void* data, map_access_callback cal /*#####################################################################################################################*/ -int libcdsb_map_find(map_t* x, const void* k, vtype t, void* _, map_access_callback callback, bool cut) { +int libcdsb_map_find(map_t* x, var_t key, void* _, map_access_callback callback, bool cut) { mnode_t* c; - void *key; int cmp; + var_t k; c = x->root; while (!mnode_is_empty(c)) { - key = vnode_peek(&c->key, x->type); - cmp = vtype_compare(k, t, key, x->type); + k = vnode_peek(&c->key, x->type); + cmp = variable_compare(key, k); if (cmp == 0) { - cmp = (callback) ? callback(key, x->type, 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); @@ -96,7 +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(vnode_peek(&n->key, x->type), x->type, 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; diff --git a/src/map/comparison.c b/src/map/comparison.c index a2b74a0..acf16ae 100644 --- a/src/map/comparison.c +++ b/src/map/comparison.c @@ -4,7 +4,7 @@ #include "include.h" static inline int libcdsb_builtin_compare(const mnode_t* s0, const mnode_t* s1, vtype t) { - int c = vnode_compare_eq(&s0->key, &s1->key, t); + int c = vnode_compare(&s0->key, t, &s1->key, t); return !c ? vnode_compare(&s0->value, s0->type, &s1->value, s1->type) : c; } diff --git a/src/map/modify.c b/src/map/modify.c index 32c5461..4b06da4 100644 --- a/src/map/modify.c +++ b/src/map/modify.c @@ -3,23 +3,25 @@ #include "include.h" -bool libcdsb_map_update(map_t* x, const void* k, vtype kt, const void* v, vtype vt, void* dt, map_access_callback callback) { +bool libcdsb_map_update(map_t* x, vtype_variable key, vtype_variable value, void* dt, map_access_callback callback) { int cmp; mnode_t* n; mnode_t* p; + vtype_variable k; if (!mnode_is_empty(n = x->root)) { do { - p = n; - cmp = vtype_compare(k, kt, vnode_peek(&n->key, kt), kt); + p = n; + k = vnode_peek(&n->key, x->type); + cmp = variable_compare(key, k); if (cmp == 0) { - if (callback) callback(vnode_peek(&n->key, x->type), x->type, - 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); - n->value = vnode_create(v, n->type = vt); + n->value = vnode_create(value); + n->type = value.type; return true; } @@ -37,39 +39,40 @@ bool libcdsb_map_update(map_t* x, const void* k, vtype kt, const void* v, vtype } else n = x->root = mnode_create(nullptr, mnode_empty, 0); - n->key = vnode_tcreate(x->type, k, kt); - n->value = vnode_create(v, vt); - n->type = vt; + n->key = vnode_create_ex(x->type, key); + n->value = vnode_create(value); + n->type = value.type; return false; } -bool libcdsb_map_inject(map_t* x, const void* k, vtype kt, const void* v, vtype vt, void* dt, map_access_callback callback) { +bool libcdsb_map_inject(map_t* x, vtype_variable key, vtype_variable value, void* dt, map_access_callback callback) { int cmp; mnode_t* n; mnode_t* p; vnode_t kn; + vtype_variable k; - vnode_tattach(&kn, x->type, k, kt); - n = x->root; - kt = x->type; - k = vnode_peek(&kn, kt); + vnode_attach_ex(&kn, x->type, key); + n = x->root; + key = vnode_peek(&kn, x->type); if (!mnode_is_empty(n)) { do { + k = vnode_peek(&n->key, x->type); p = n; - cmp = vtype_compare(k, kt, vnode_peek(&n->key, kt), kt); + cmp = variable_compare(key, k); if (cmp == 0) { - if (callback) callback(vnode_peek(&n->key, x->type), x->type, - 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); - n->key = kn; - vnode_attach(&n->value, v, n->type = vt); + n->key = kn; + n->type = value.type; + vnode_attach(&n->value, value); return true; } @@ -87,7 +90,8 @@ bool libcdsb_map_inject(map_t* x, const void* k, vtype kt, const void* v, vtype } else n = x->root = mnode_create(kn, mnode_empty, 0); - vnode_attach(&n->value, v, n->type = vt); + vnode_attach(&n->value, value); + n->type = value.type; return false; } diff --git a/src/set/access.c b/src/set/access.c index 25633fd..ed7b41b 100644 --- a/src/set/access.c +++ b/src/set/access.c @@ -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(vnode_peek(&n->value, x->type), x->type, data); + r = callback(vnode_peek(&n->value, x->type), data); } else { stack_flush(&z); return r; @@ -46,19 +46,19 @@ static int libcdsb_builtin_foreach(set_t* x, void* data, vset_access_callback ca /*#####################################################################################################################*/ -int libcdsb_vset_find(vtype_set* x, const void* v, vtype t, void* _, vset_access_callback callback, bool cut) { +int libcdsb_vset_find(vtype_set* x, var_t value, void* _, vset_access_callback callback, bool cut) { rbnode_t* c; - void *val; int cmp; + var_t v; c = x->root; while (!rbnode_is_empty(c)) { - val = vnode_peek(&c->value, x->type); - cmp = vtype_compare(v, t, val, x->type); + v = vnode_peek(&c->value, x->type); + cmp = variable_compare(value, v); if (cmp == 0) { - cmp = (callback) ? callback(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(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; diff --git a/src/set/modify.c b/src/set/modify.c index 42066da..d5f28da 100644 --- a/src/set/modify.c +++ b/src/set/modify.c @@ -5,7 +5,7 @@ #include "../__internal/rbtree.h" #include "../__internal/assert.h" -bool libcdsb_vset_insert(set_t* x, const void* v, vtype t) { +bool libcdsb_vset_insert(set_t* x, vtype_variable value) { int cmp; rbnode_t* n; rbnode_t* p; @@ -13,7 +13,7 @@ bool libcdsb_vset_insert(set_t* x, const void* v, vtype t) { if (!rbnode_is_empty(n = x->root)) { do { p = n; - cmp = vtype_compare(v, t, vnode_peek(&n->value, t), t); + cmp = variable_compare(value, vnode_peek(&n->value, x->type)); if (cmp == 0) return false; @@ -30,30 +30,30 @@ bool libcdsb_vset_insert(set_t* x, const void* v, vtype t) { } else n = x->root = rbnode_create(nullptr, rbnode_empty, 0); - n->value = vnode_tcreate(x->type, v, t); + n->value = vnode_create_ex(x->type, value); return true; } -bool libcdsb_vset_attach(set_t* x, const void* v, vtype t) { +bool libcdsb_vset_attach(set_t* x, vtype_variable value) { int cmp; rbnode_t* n; rbnode_t* p; vnode_t vn; - vnode_tattach(&vn, x->type, v, t); - n = x->root; - t = x->type; - v = vnode_peek(&vn, t); + vnode_attach_ex(&vn, x->type, value); + n = x->root; + value.type = x->type; + value.pointer = vnode_peek(&vn, value.type).pointer; if (!rbnode_is_empty(n)) { do { p = n; - cmp = vtype_compare(v, t, vnode_peek(&n->value, t), t); + cmp = variable_compare(value, vnode_peek(&n->value, x->type)); if (cmp == 0) { - vnode_free(&vn, t); + vnode_free(&vn, value.type); return false; } diff --git a/src/stringify.c b/src/stringify.c index 054ea29..0149113 100644 --- a/src/stringify.c +++ b/src/stringify.c @@ -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_variable_stringify(var_t 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; } diff --git a/src/vnode.c b/src/vnode.c index 33babed..6cd2768 100644 --- a/src/vnode.c +++ b/src/vnode.c @@ -5,6 +5,14 @@ #include "__internal/vnode.h" #include "../include/string.h" +typedef union { + void* ptr; bool b; + str_t s; arr_t a; list_t l; + map_t m; set_t vs; dict_t vd; + u8_t u8; u16_t u16; u32_t u32; u64_t u64; + fl_t f; dbl_t d; ldbl_t ld; +} any_t; + static vtype libcdsb_builtin_round(u64_t* x, ldbl_t v) { if (v > 0) { *x = (u64_t)(v + 0.5); @@ -15,9 +23,8 @@ static vtype libcdsb_builtin_round(u64_t* x, ldbl_t v) { } } - static vnode_t libcdsb_builtin_create_value(vtype xt, const void* v, vtype t) { - var_t _; + any_t _; if (t == VTYPE_FLOAT) { t = libcdsb_builtin_round(&_.u64, *(fl_t*)v); @@ -82,9 +89,8 @@ static vnode_t libcdsb_builtin_create_value(vtype xt, const void* v, vtype t) { return _.ptr; } - static vnode_t libcdsb_builtin_create_float(vtype xt, const void* v, vtype t) { - var_t _; + any_t _; if (t == VTYPE_UINT8 || t == VTYPE_BOOLEAN ) { _.ld = *(u8_t*)v; @@ -131,71 +137,112 @@ static vnode_t libcdsb_builtin_create_float(vtype xt, const void* v, vtype t) { /*#####################################################################################################################*/ -vnode_t libcdsb_builtin_vnode_create(const void* v, vtype t) { - var_t _ = { .ptr = 0 }; +vnode_t libcdsb_builtin_vnode_create(var_t var) { + any_t _ = { .ptr = 0 }; - switch (t) { default: abort(); + switch (var.type) { default: abort(); case VTYPE_INT8: - case VTYPE_UINT8: _.u8 = *(u8_t*)v; + case VTYPE_UINT8: _.u8 = *(u8_t*)var.pointer; break; case VTYPE_INT16: - case VTYPE_UINT16: _.u16 = *(u16_t*)v; + case VTYPE_UINT16: _.u16 = *(u16_t*)var.pointer; break; case VTYPE_INT32: - case VTYPE_UINT32: _.u32 = *(u32_t*)v; + case VTYPE_UINT32: _.u32 = *(u32_t*)var.pointer; break; case VTYPE_INT64: - case VTYPE_UINT64: if (is_x64) _.u64 = *(u64_t*)v; - else _.ptr = memndup(v, sizeof(u64_t)); + case VTYPE_UINT64: if (is_x64) _.u64 = *(u64_t*)var.pointer; + else _.ptr = memndup(var.pointer, sizeof(u64_t)); break; - case VTYPE_FLOAT: if (is_permissible(fl_t)) _.f = *(fl_t*)v; - else _.ptr = memndup(v, sizeof(fl_t)); + case VTYPE_FLOAT: if (is_permissible(fl_t)) _.f = *(fl_t*)var.pointer; + else _.ptr = memndup(var.pointer, sizeof(fl_t)); break; - case VTYPE_DOUBLE: if (is_permissible(dbl_t)) _.d = *(dbl_t*)v; - else _.ptr = memndup(v, sizeof(dbl_t)); + case VTYPE_DOUBLE: if (is_permissible(dbl_t)) _.d = *(dbl_t*)var.pointer; + else _.ptr = memndup(var.pointer, sizeof(dbl_t)); break; - case VTYPE_LDOUBLE: if (is_permissible(ldbl_t)) _.ld = *(ldbl_t*)v; - else _.ptr = memndup(v, sizeof(ldbl_t)); + case VTYPE_LDOUBLE: if (is_permissible(ldbl_t)) _.ld = *(ldbl_t*)var.pointer; + else _.ptr = memndup(var.pointer, sizeof(ldbl_t)); break; - case VTYPE_BOOLEAN: _.b = *(bool*)v; + case VTYPE_BOOLEAN: _.b = *(bool*)var.pointer; break; - case VTYPE_POINTER: _.ptr = *(void**)v; + case VTYPE_POINTER: _.ptr = *(void**)var.pointer; break; case VTYPE_STRING: if (sizeof(str_t) == sizeof(void*)) { - _.ptr = strdup(*(char**)v); - } else _.ptr = string_duplicate(v); + _.ptr = strdup(*(char**)var.pointer); + } else _.ptr = string_duplicate(var.pointer); break; - case VTYPE_MAP: _.ptr = map_duplicate(v); + case VTYPE_MAP: _.ptr = map_duplicate(var.pointer); break; - case VTYPE_ARRAY: _.ptr = array_duplicate(v); + case VTYPE_ARRAY: _.ptr = array_duplicate(var.pointer); break; - case VTYPE_LIST: _.ptr = list_duplicate(v); + case VTYPE_LIST: _.ptr = list_duplicate(var.pointer); break; - case VTYPE_SET: _.ptr = vset_duplicate(v); + case VTYPE_SET: _.ptr = vset_duplicate(var.pointer); break; } return _.ptr; } +vnode_t libcdsb_builtin_vnode_create_ex(vtype xt, var_t var) { + any_t _ = { .ptr = 0 }; -void* libcdsb_builtin_vnode_peek(const vnode_t* x, vtype t) { - switch (t) { default: abort(); + if (xt <= VTYPE_LDOUBLE) { + if (var.type >= VTYPE_STRING) var.type = VTYPE_POINTER; + + if (xt <= VTYPE_INT64) + return libcdsb_builtin_create_value(xt, var.pointer, var.type); + return libcdsb_builtin_create_float(xt, var.pointer, var.type); + } else if (var.type == VTYPE_POINTER && (var.type = xt) > VTYPE_STRING) { + var.pointer = *(void**)var.pointer; + } + + type_assert(xt, var.type); + + switch (xt) { default: abort(); + case VTYPE_STRING: if (sizeof(str_t) == sizeof(void*)) { + _.ptr = strdup(*(char**)var.pointer); + } else _.ptr = string_duplicate(var.pointer); + break; + + case VTYPE_MAP: _.ptr = map_duplicate(var.pointer); + break; + + case VTYPE_ARRAY: _.ptr = array_duplicate(var.pointer); + break; + + case VTYPE_LIST: _.ptr = list_duplicate(var.pointer); + break; + + case VTYPE_SET: _.ptr = vset_duplicate(var.pointer); + break; + + case VTYPE_DICT: _.ptr = dict_duplicate(var.pointer); + break; + } + + return _.ptr; +} + +var_t libcdsb_builtin_vnode_peek(const vnode_t* x, vtype t) { + var_t 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 +259,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,10 +268,12 @@ 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; +} void libcdsb_builtin_vnode_free(vnode_t* x, vtype t) { @@ -262,44 +312,3 @@ void libcdsb_builtin_vnode_free(vnode_t* x, vtype t) { *x = 0; } - - -vnode_t libcdsb_builtin_vnode_create_target(vtype xt, const void* v, vtype t) { - var_t _ = { .ptr = 0 }; - - if (xt <= VTYPE_LDOUBLE) { - if (t >= VTYPE_STRING) t = VTYPE_POINTER; - - if (xt <= VTYPE_INT64) - return libcdsb_builtin_create_value(xt, v, t); - return libcdsb_builtin_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: if (sizeof(str_t) == sizeof(void*)) { - _.ptr = strdup(*(char**)v); - } else _.ptr = string_duplicate(v); - break; - - case VTYPE_MAP: _.ptr = map_duplicate(v); - break; - - case VTYPE_ARRAY: _.ptr = array_duplicate(v); - break; - - case VTYPE_LIST: _.ptr = list_duplicate(v); - break; - - case VTYPE_SET: _.ptr = vset_duplicate(v); - break; - - case VTYPE_DICT: _.ptr = dict_duplicate(v); - break; - } - - return _.ptr; -} diff --git a/src/vtype.c b/src/vtype.c index e8389e5..bac6aae 100644 --- a/src/vtype.c +++ b/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,38 +99,54 @@ int libcdsb_builtin_vtype_compare_values_eq(const void* s0, const void* s1, vtyp /*#####################################################################################################################*/ -hash_t libcdsb_builtin_vtype_hash(const void* v, vtype t) { +int libcdsb_builtin_variable_compare(var_t s0, var_t s1) { + if (s0.type == s1.type) return libcdsb_builtin_vtype_compare_values_eq(s0.pointer, s1.pointer, s0.type); - switch (t) { default: abort(); + 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_variable_hash(var_t value) { + switch (value.type) { default: abort(); case VTYPE_BOOLEAN: case VTYPE_INT8: - case VTYPE_UINT8: return (hash_t)(*(u8_t*)v); + case VTYPE_UINT8: return (hash_t)(*(u8_t*)value.pointer); case VTYPE_INT16: - case VTYPE_UINT16: return (hash_t)(*(u16_t*)v); + case VTYPE_UINT16: return (hash_t)(*(u16_t*)value.pointer); case VTYPE_INT32: case VTYPE_UINT32: - x86_ptr: return (hash_t)(*(u32_t*)v); + x86_ptr: return (hash_t)(*(u32_t*)value.pointer); case VTYPE_POINTER: if (!is_x64) goto x86_ptr; case VTYPE_INT64: case VTYPE_UINT64: if (sizeof(hash_t) == sizeof(u64_t)) { - return (hash_t)(*(u64_t*)v); + return (hash_t)(*(u64_t*)value.pointer); } else { - return (hash_t)(*(u32_t*)v) ^ (*((u32_t*)v + 1)); + return (hash_t)(*(u32_t*)value.pointer) ^ (*((u32_t*)value.pointer + 1)); } - case VTYPE_STRING: return string_hash(v); - case VTYPE_ARRAY: return array_hash(v); - case VTYPE_LIST: return list_hash(v); - case VTYPE_MAP: return map_hash(v); - case VTYPE_SET: return vset_hash(v); - case VTYPE_DICT: return dict_hash(v); + case VTYPE_STRING: return string_hash(value.pointer); + case VTYPE_ARRAY: return array_hash(value.pointer); + case VTYPE_LIST: return list_hash(value.pointer); + case VTYPE_MAP: return map_hash(value.pointer); + case VTYPE_SET: return vset_hash(value.pointer); + case VTYPE_DICT: return dict_hash(value.pointer); - case VTYPE_FLOAT: return libcdsb_builtin_hash_float(*(fl_t*)v); - case VTYPE_DOUBLE: return libcdsb_builtin_hash_float(*(dbl_t*)v); - case VTYPE_LDOUBLE: return libcdsb_builtin_hash_float(*(ldbl_t*)v); + case VTYPE_FLOAT: return libcdsb_builtin_hash_float(*(fl_t*)value.pointer); + case VTYPE_DOUBLE: return libcdsb_builtin_hash_float(*(dbl_t*)value.pointer); + case VTYPE_LDOUBLE: return libcdsb_builtin_hash_float(*(ldbl_t*)value.pointer); } } diff --git a/tests/include/random.h b/tests/include/random.h index 517c27b..b5fb891 100644 --- a/tests/include/random.h +++ b/tests/include/random.h @@ -7,11 +7,6 @@ #ifndef LIBCDSB_TESTS_RANDOM_H #define LIBCDSB_TESTS_RANDOM_H -typedef struct { - var_t value[1]; - vtype type; -} value_t; - extern int random_init(int argc, char** argv); extern vtype_bool random_boolean(); @@ -32,6 +27,6 @@ extern vtype_int64 random_int64(); extern char random_ascii_char(); extern unsigned int random_unicode_symbol(); -extern value_t random_value(); +extern var_t random_variable(int rand); #endif /* LIBCDSB_TESTS_RANDOM_H */ diff --git a/tests/include/test.h b/tests/include/test.h index 51b96cf..3d80b17 100644 --- a/tests/include/test.h +++ b/tests/include/test.h @@ -9,7 +9,7 @@ extern void put_separator(unsigned int hpos); extern void print_container_values_prefix(const char* name, const char* prefix, unsigned int hpos); -extern void print_container_value(const ssize_t* index, const void* value, const vtype type, _Bool print_type, unsigned int hpos); +extern void print_container_value(const ssize_t* index, vtype_variable var, _Bool print_type, unsigned int hpos); extern void print_container_info(const char* name, const char* el_name, const vtype* type, ssize_t size, ssize_t nmemb, unsigned int hpos); extern void test_init(int argc, char** argv); diff --git a/tests/src/array/src/io.c b/tests/src/array/src/io.c index 127eaec..e0ec8c9 100644 --- a/tests/src/array/src/io.c +++ b/tests/src/array/src/io.c @@ -3,8 +3,8 @@ #include "../plug.h" -static int array_value_print(void* v, ssize_t i, vtype t, void* _) { - print_container_value(&i, v, t, 1, *(unsigned int*)_); +static int array_value_print(vtype_variable v, ssize_t i, void* _) { + print_container_value(&i, v, 1, *(unsigned int*)_); return 0; } diff --git a/tests/src/array/src/random.c b/tests/src/array/src/random.c index be9de57..de59003 100644 --- a/tests/src/array/src/random.c +++ b/tests/src/array/src/random.c @@ -3,27 +3,27 @@ #include "../plug.h" -static int remove_callback(void* v, ssize_t i, vtype t, void* _) { +static int remove_callback(vtype_variable v, ssize_t i, void* _) { struct { arr_t* x; _Bool s; unsigned int p; } *x = _; - if (!x->s) print_container_value(0, v, t, 1, x->p); + if (!x->s) print_container_value(0, v, 1, x->p); - if (libcdsb_array_find(x->x, v, t, 0, 0, 1, 1)) + if (libcdsb_array_find(x->x, libcdsb_variable_build(v.pointer, v.type), 0, 0, 1, 1)) return -2; return 0; } -static int change_callback(void* v, ssize_t i, vtype t, void* _) { - struct { value_t v; _Bool s; unsigned int p; } *x = _; +static int change_callback(vtype_variable v, ssize_t i, void* _) { + struct { vtype_variable v; _Bool s; unsigned int p; } *x = _; - while (x->v.type != t) { x->v = random_value(); } + while (x->v.type != v.type) { x->v = random_variable(-1); } - memcpy(v, &x->v, vtype_size(t)); + memcpy(v.pointer, x->v.pointer, vtype_size(v.type)); return 0; } void array_push_random(arr_t* x, _Bool silent, unsigned int hpos) { - struct { value_t v; _Bool s; unsigned int p; } _ = { .v = random_value(), .s = silent, .p = hpos }; + struct { vtype_variable v; _Bool s; unsigned int p; } _ = { .v = random_variable(-1), .s = silent, .p = hpos }; _Bool r; if (random_boolean()) { @@ -31,7 +31,7 @@ void array_push_random(arr_t* x, _Bool silent, unsigned int hpos) { printf("\e[%dG\e[36mTry to push value to back of the array:\e[m\n", hpos+1); } - r = libcdsb_array_insert(x, _.v.value, _.v.type) >= 0; + r = libcdsb_array_insert(x, _.v) >= 0; } else { ssize_t i = array_size(x); @@ -46,7 +46,7 @@ void array_push_random(arr_t* x, _Bool silent, unsigned int hpos) { } if (!silent) { - print_container_value(0, _.v.value, _.v.type, 1, hpos); + print_container_value(0, _.v, 1, hpos); printf("\e[%dG%s\n", hpos+1, r ? "\e[32;1mSUCCESS\e[m" : "\e[31;1mFAILURE\e[m"); put_separator(hpos); } @@ -62,7 +62,7 @@ void array_remove_random(arr_t* x, _Bool silent, unsigned int hpos) { if (random_boolean()) { if (!silent) { printf("\e[%dG\e[36mTry to remove value from list by index:\e[m\n", hpos+1); - print_container_value(0, &i, (sizeof(ssize_t) == 8) ? VTYPE_INT64 : VTYPE_INT32, 0, hpos); + print_container_value(0, libcdsb_variable_build(&i, (sizeof(ssize_t) == 8) ? VTYPE_INT64 : VTYPE_INT32), 0, hpos); } switch (array_remove_by_index(x, i)) { case 0: if (!silent) printf("\e[%dG\e[32;1mSUCCESS\e[m\n", hpos+1); break; diff --git a/tests/src/dict/src/io.c b/tests/src/dict/src/io.c index d0c4336..53a4899 100644 --- a/tests/src/dict/src/io.c +++ b/tests/src/dict/src/io.c @@ -3,8 +3,8 @@ #include "../plug.h" -static int node_print_callback(const void* k, vtype kt, void* v, vtype vt, void* _) { - print_container_value(0, k, kt, 0, *(unsigned int*)_); +static int node_print_callback(vtype_variable k, vtype_variable v, void* _) { + print_container_value(0, k, 0, *(unsigned int*)_); return 0; } diff --git a/tests/src/dict/src/random.c b/tests/src/dict/src/random.c index 1149260..375c548 100644 --- a/tests/src/dict/src/random.c +++ b/tests/src/dict/src/random.c @@ -3,13 +3,13 @@ #include "../plug.h" -static int remove_callback(const void* k, vtype kt, void* v, vtype vt, void* _) { +static int remove_callback(vtype_variable k, vtype_variable v, void* _) { struct { size_t n; dict_t* x; unsigned int hp; } *d = _; if (!d->n--) { - print_container_value(0, k, kt, 0, d->hp); + print_container_value(0, k, 0, d->hp); - if (libcdsb_dict_find(d->x, k, kt, 0, 0, 1) == 0) { + if (libcdsb_dict_find(d->x, k, 0, 0, 1) == 0) { printf("\e[%dG\e[32;1mSUCCESS\e[m\n", d->hp+1); } else printf("\e[%dG\e[31;1mFAILURE\e[m\n", d->hp+1); @@ -20,15 +20,15 @@ static int remove_callback(const void* k, vtype kt, void* v, vtype vt, void* _) void dict_push_random(dict_t* x, _Bool silent, unsigned int hpos) { - value_t k = random_value(); - value_t v = random_value(); + vtype_variable k = random_variable(-1); + vtype_variable v = random_variable(-1); if (!silent) { printf("\e[%dG\e[36mUpdate value in dict with key:\e[m\n", hpos+1); - print_container_value(0, k.value, k.type, 1, hpos); + print_container_value(0, k, 1, hpos); } - if (libcdsb_dict_update(x, k.value, k.type, v.value, v.type)) { + if (libcdsb_dict_update(x, k, v, 0, 0)) { if (!silent) printf("\e[%dG\e[33;1mCHANGE\e[m\n", hpos+1); } else if (!silent) printf("\e[%dG\e[32;1mINSERT\e[m\n", hpos+1); diff --git a/tests/src/global/main.c b/tests/src/global/main.c index 6717c31..9d60475 100644 --- a/tests/src/global/main.c +++ b/tests/src/global/main.c @@ -6,29 +6,29 @@ int main(int argc, char** argv) { test_init(argc, argv); - value_t x = random_container(0); + vtype_variable x = random_container(0); switch (x.type) { default: abort(); case VTYPE_ARRAY: - array_info((void*)x.value, 0); - array_free((void*)x.value); + array_info((void*)x.pointer, 0); + array_free((void*)x.pointer); return 0; case VTYPE_MAP: - map_info((void*)x.value, 0); - map_free((void*)x.value); + map_info((void*)x.pointer, 0); + map_free((void*)x.pointer); return 0; case VTYPE_LIST: - list_info((void*)x.value, 0); - list_free((void*)x.value); + list_info((void*)x.pointer, 0); + list_free((void*)x.pointer); return 0; case VTYPE_SET: - vset_info((void*)x.value, 0); - vset_free((void*)x.value); + vset_info((void*)x.pointer, 0); + vset_free((void*)x.pointer); return 0; case VTYPE_DICT: - dict_info((void*)x.value, 0); - dict_free((void*)x.value); + dict_info((void*)x.pointer, 0); + dict_free((void*)x.pointer); return 0; } } diff --git a/tests/src/global/plug.h b/tests/src/global/plug.h index 97d1eda..6e26625 100644 --- a/tests/src/global/plug.h +++ b/tests/src/global/plug.h @@ -12,8 +12,8 @@ #include "../../include/test.h" #include "../../include/time.h" -extern value_t random_container(bool embd); -extern value_t real_random_value(bool embd); +extern vtype_variable random_container(bool embd); +extern vtype_variable real_random_value(bool embd); extern void array_info(arr_t* x, unsigned int hpos); extern void list_info (list_t* x, unsigned int hpos); diff --git a/tests/src/global/src/random.c b/tests/src/global/src/random.c index cef5267..5e5569f 100644 --- a/tests/src/global/src/random.c +++ b/tests/src/global/src/random.c @@ -5,275 +5,188 @@ #define MAX_ELEMENTS 2000 -static arr_t random_array(bool embd); -static list_t random_list (bool embd); -static set_t random_set (bool embd); -static map_t random_map (bool embd); -static dict_t random_dict (bool embd); +static vtype_variable random_array(bool embd); +static vtype_variable random_list (bool embd); +static vtype_variable random_set (bool embd); +static vtype_variable random_map (bool embd); +static vtype_variable random_dict (bool embd); -static str_t random_string() { - str_t x; +static vtype_variable random_string() { + static str_t values[16]; + static size_t pos = 0; + + if (pos == 16) pos = 0; + + str_t* x = &values[pos++]; size_t n = random_uint16()%MAX_ELEMENTS; - string_init(&x, 0); + string_init(x, 0); while (n--) { - string_concat(&x, random_unicode_symbol()); + string_concat(x, random_unicode_symbol()); } - return x; + return libcdsb_variable_build(x, VTYPE_STRING); } -static value_t random_value2() { - value_t v; - switch (random_uint8()%14) { - default: - case 0: v.value[0].b = random_boolean(); v.type = VTYPE_BOOLEAN; break; - case 1: v.value[0].u8 = random_uint8 (); v.type = VTYPE_UINT8; break; - case 2: v.value[0].u16 = random_uint16 (); v.type = VTYPE_UINT16; break; - case 3: v.value[0].u32 = random_uint32 (); v.type = VTYPE_UINT32; break; - case 4: v.value[0].u64 = random_uint64 (); v.type = VTYPE_UINT64; break; - case 5: v.value[0].u8 = random_int8 (); v.type = VTYPE_INT8; break; - case 6: v.value[0].u16 = random_uint16 (); v.type = VTYPE_INT16; break; - case 7: v.value[0].u32 = random_int32 (); v.type = VTYPE_INT32; break; - case 8: v.value[0].u64 = random_int64 (); v.type = VTYPE_INT64; break; - case 9: v.value[0].f = random_float (); v.type = VTYPE_FLOAT; break; - case 10: v.value[0].d = random_double (); v.type = VTYPE_DOUBLE; break; - case 11: v.value[0].ld = random_ldouble(); v.type = VTYPE_LDOUBLE; break; - case 12: v.value[0].ptr = (void*)(uintptr_t)random_uint64(); v.type = VTYPE_POINTER; break; - case 13: v.value[0].s = random_string(); v.type = VTYPE_STRING; break; +static vtype_variable random_variable2() { + vtype_variable v; + int rand; + + switch (rand = random_uint8()%14) { + default: v = random_variable(rand); break; + case 13: v = random_string(); break; } return v; } -static value_t random_value_by_type(vtype type, bool embd) { - value_t v; +static vtype_variable random_value_by_type(vtype type, bool embd) { + vtype_variable v; switch ((v.type = type)) { default: - case VTYPE_BOOLEAN: v.value[0].b = random_boolean(); break; - case VTYPE_UINT8: v.value[0].u8 = random_uint8 (); break; - case VTYPE_UINT16: v.value[0].u16 = random_uint16 (); break; - case VTYPE_UINT32: v.value[0].u32 = random_uint32 (); break; - case VTYPE_UINT64: v.value[0].u64 = random_uint64 (); break; - case VTYPE_INT8: v.value[0].u8 = random_int8 (); break; - case VTYPE_INT16: v.value[0].u16 = random_uint16 (); break; - case VTYPE_INT32: v.value[0].u32 = random_int32 (); break; - case VTYPE_INT64: v.value[0].u64 = random_int64 (); break; - case VTYPE_FLOAT: v.value[0].f = random_float (); break; - case VTYPE_DOUBLE: v.value[0].d = random_double (); break; - case VTYPE_LDOUBLE: v.value[0].ld = random_ldouble(); break; - case VTYPE_STRING: v.value[0].s = random_string(); break; - case VTYPE_ARRAY: v.value[0].a = random_array(embd); break; - case VTYPE_MAP: v.value[0].m = random_map (embd); break; - case VTYPE_DICT: v.value[0].vd = random_dict (embd); break; - case VTYPE_LIST: v.value[0].l = random_list (embd); break; - case VTYPE_SET: v.value[0].vs = random_set (embd); break; - case VTYPE_POINTER: v.value[0].ptr = (void*)(uintptr_t)random_uint64(); break; + case VTYPE_BOOLEAN: v = random_variable( 0); break; + case VTYPE_UINT8: v = random_variable( 1); break; + case VTYPE_UINT16: v = random_variable( 2); break; + case VTYPE_UINT32: v = random_variable( 3); break; + case VTYPE_UINT64: v = random_variable( 4); break; + case VTYPE_INT8: v = random_variable( 5); break; + case VTYPE_INT16: v = random_variable( 6); break; + case VTYPE_INT32: v = random_variable( 7); break; + case VTYPE_INT64: v = random_variable( 8); break; + case VTYPE_FLOAT: v = random_variable( 9); break; + case VTYPE_DOUBLE: v = random_variable(10); break; + case VTYPE_LDOUBLE: v = random_variable(11); break; + case VTYPE_STRING: v = random_string (); break; + case VTYPE_ARRAY: v = random_array (embd); break; + case VTYPE_MAP: v = random_map (embd); break; + case VTYPE_DICT: v = random_dict (embd); break; + case VTYPE_LIST: v = random_list (embd); break; + case VTYPE_SET: v = random_set (embd); break; + case VTYPE_POINTER: v = random_variable(12); break; } return v; } -static arr_t random_array(bool embd) { - arr_t x; - size_t n = random_uint16()%((!embd)?MAX_ELEMENTS:100); - value_t v = (!embd) ? random_value2() : real_random_value(1); +static vtype_variable random_array(bool embd) { + static arr_t values[16]; + static size_t pos = 0; - array_init(&x, v.type); + if (pos == 16) pos = 0; - while(n--) { + arr_t* x = &values[pos++]; + size_t n = random_uint16()%((!embd)?MAX_ELEMENTS:100); + vtype_variable v = (!embd) ? random_variable2() : real_random_value(1); - libcdsb_array_insert(&x, v.value, v.type); + array_init(x, v.type); - switch (v.type) { - default: break; - case VTYPE_STRING: string_free((void*)v.value); break; - case VTYPE_ARRAY: array_free((void*)v.value); break; - case VTYPE_LIST: list_free((void*)v.value); break; - case VTYPE_MAP: map_free((void*)v.value); break; - case VTYPE_SET: vset_free((void*)v.value); break; - case VTYPE_DICT: dict_free((void*)v.value); break; - } - - v = random_value_by_type(v.type, 1); + for(;;) { + libcdsb_array_attach(x, v); + if (--n) v = random_value_by_type(v.type, 1); + else break; } - switch (v.type) { - default: break; - case VTYPE_STRING: string_free((void*)v.value); break; - case VTYPE_ARRAY: array_free((void*)v.value); break; - case VTYPE_LIST: list_free((void*)v.value); break; - case VTYPE_MAP: map_free((void*)v.value); break; - case VTYPE_SET: vset_free((void*)v.value); break; - case VTYPE_DICT: dict_free((void*)v.value); break; - } - - return x; + return libcdsb_variable_build(x, VTYPE_ARRAY); } -static set_t random_set(bool embd) { - set_t x; - size_t n = random_uint16()%((!embd)?MAX_ELEMENTS:100); - value_t v = (!embd) ? random_value2() : real_random_value(1); +static vtype_variable random_set(bool embd) { + static set_t values[16]; + static size_t pos = 0; - vset_init(&x, v.type); + if (pos == 16) pos = 0; - while(n--) { + set_t* x = &values[pos++]; + size_t n = random_uint16()%((!embd)?MAX_ELEMENTS:100); + vtype_variable v = (!embd) ? random_variable2() : real_random_value(1); - libcdsb_vset_insert(&x, v.value, v.type); + vset_init(x, v.type); - switch (v.type) { - default: break; - case VTYPE_STRING: string_free((void*)v.value); break; - case VTYPE_ARRAY: array_free((void*)v.value); break; - case VTYPE_LIST: list_free((void*)v.value); break; - case VTYPE_MAP: map_free((void*)v.value); break; - case VTYPE_SET: vset_free((void*)v.value); break; - case VTYPE_DICT: dict_free((void*)v.value); break; - } - - v = random_value_by_type(v.type, 1); + for(;;) { + libcdsb_vset_attach(x, v); + if (--n) v = random_value_by_type(v.type, 1); + else break; } - switch (v.type) { - default: break; - case VTYPE_STRING: string_free((void*)v.value); break; - case VTYPE_ARRAY: array_free((void*)v.value); break; - case VTYPE_LIST: list_free((void*)v.value); break; - case VTYPE_MAP: map_free((void*)v.value); break; - case VTYPE_SET: vset_free((void*)v.value); break; - case VTYPE_DICT: dict_free((void*)v.value); break; - } - - return x; + return libcdsb_variable_build(x, VTYPE_SET); } -static list_t random_list(bool embd) { - list_t x; - value_t v; - size_t n = random_uint16()%((!embd)?MAX_ELEMENTS:100); +static vtype_variable random_list(bool embd) { + static list_t values[16]; + static size_t pos = 0; - list_init(&x); + if (pos == 16) pos = 0; + + list_t* x = &values[pos++]; + size_t n = random_uint16()%((!embd)?MAX_ELEMENTS:100); + vtype_variable v; + + list_init(x); while(n--) { - v = (!embd) ? random_value2() : real_random_value(1); - libcdsb_list_insert(&x, -1, v.value, v.type, 1); - - switch (v.type) { - default: break; - case VTYPE_STRING: string_free((void*)v.value); break; - case VTYPE_ARRAY: array_free ((void*)v.value); break; - case VTYPE_LIST: list_free ((void*)v.value); break; - case VTYPE_MAP: map_free ((void*)v.value); break; - case VTYPE_SET: vset_free ((void*)v.value); break; - case VTYPE_DICT: dict_free ((void*)v.value); break; - } + v = (!embd) ? random_variable2() : real_random_value(1); + libcdsb_list_attach(x, -1, v, 1, 0, 0); } - return x; + return libcdsb_variable_build(x, VTYPE_LIST); } -static map_t random_map(bool embd) { - map_t x; - size_t n = random_uint16()%((!embd)?MAX_ELEMENTS:100); - value_t k = (!embd) ? random_value2() : real_random_value(1); +static vtype_variable random_map(bool embd) { + static map_t values[16]; + static size_t pos = 0; - map_init(&x, k.type); + if (pos == 16) pos = 0; - while(n--) { - value_t v = (!embd) ? random_value2() : real_random_value(1); + map_t* x = &values[pos++]; + size_t n = random_uint16()%((!embd)?MAX_ELEMENTS:100); + vtype_variable k = (!embd) ? random_variable2() : real_random_value(1); + vtype_variable v; - libcdsb_map_update(&x, k.value, k.type, v.value, v.type); + map_init(x, k.type); - switch (k.type) { - default: break; - case VTYPE_STRING: string_free((void*)k.value); break; - case VTYPE_ARRAY: array_free((void*)k.value); break; - case VTYPE_LIST: list_free((void*)k.value); break; - case VTYPE_MAP: map_free((void*)k.value); break; - case VTYPE_SET: vset_free((void*)k.value); break; - case VTYPE_DICT: dict_free((void*)k.value); break; - } - - switch (v.type) { - default: break; - case VTYPE_STRING: string_free((void*)v.value); break; - case VTYPE_ARRAY: array_free ((void*)v.value); break; - case VTYPE_LIST: list_free ((void*)v.value); break; - case VTYPE_MAP: map_free ((void*)v.value); break; - case VTYPE_SET: vset_free ((void*)v.value); break; - case VTYPE_DICT: dict_free ((void*)v.value); break; - } - - k = random_value_by_type(k.type, 1); + for(;;) { + v = (!embd) ? random_variable2() : real_random_value(1); + libcdsb_map_inject(x, k, v, 0, 0); + if (--n) k = random_value_by_type(k.type, 1); + else break; } - switch (k.type) { - default: break; - case VTYPE_STRING: string_free((void*)k.value); break; - case VTYPE_ARRAY: array_free((void*)k.value); break; - case VTYPE_LIST: list_free((void*)k.value); break; - case VTYPE_MAP: map_free((void*)k.value); break; - case VTYPE_SET: vset_free((void*)k.value); break; - case VTYPE_DICT: dict_free((void*)k.value); break; - } - - return x; - + return libcdsb_variable_build(x, VTYPE_MAP); } -static dict_t random_dict(bool embd) { - dict_t x; - value_t k, v; - size_t n = random_uint16()%((!embd)?MAX_ELEMENTS:100); +static vtype_variable random_dict(bool embd) { + static dict_t values[16]; + static size_t pos = 0; - dict_init(&x); + if (pos == 16) pos = 0; - while(n--) { - k = (!embd) ? random_value2() : real_random_value(1); - v = (!embd) ? random_value2() : real_random_value(1); - libcdsb_dict_update(&x, k.value, k.type, v.value, v.type); + dict_t* x = &values[pos++]; + size_t n = random_uint16()%((!embd)?MAX_ELEMENTS:100); + vtype_variable k; + vtype_variable v; - switch (v.type) { - default: break; - case VTYPE_STRING: string_free((void*)v.value); break; - case VTYPE_ARRAY: array_free ((void*)v.value); break; - case VTYPE_LIST: list_free ((void*)v.value); break; - case VTYPE_MAP: map_free ((void*)v.value); break; - case VTYPE_SET: vset_free ((void*)v.value); break; - case VTYPE_DICT: dict_free ((void*)v.value); break; - } + dict_init(x); - switch (k.type) { - default: break; - case VTYPE_STRING: string_free((void*)k.value); break; - case VTYPE_ARRAY: array_free ((void*)k.value); break; - case VTYPE_LIST: list_free ((void*)k.value); break; - case VTYPE_MAP: map_free ((void*)k.value); break; - case VTYPE_SET: vset_free ((void*)k.value); break; - case VTYPE_DICT: dict_free ((void*)k.value); break; - } + while (n--) { + k = (!embd) ? random_variable2() : real_random_value(1); + v = (!embd) ? random_variable2() : real_random_value(1); + libcdsb_dict_inject(x, k, v, 0, 0); } - return x; + return libcdsb_variable_build(x, VTYPE_DICT); } -value_t random_container(bool embd) { - value_t v; - +vtype_variable random_container(bool embd) { switch (random_uint8()%5) { default: - case 0: v.value[0].a = random_array(embd); v.type = VTYPE_ARRAY; break; - case 1: v.value[0].m = random_map (embd); v.type = VTYPE_MAP; break; - case 2: v.value[0].vd = random_dict (embd); v.type = VTYPE_DICT; break; - case 3: v.value[0].l = random_list (embd); v.type = VTYPE_LIST; break; - case 4: v.value[0].vs = random_set (embd); v.type = VTYPE_SET; break; + case 0: return random_array(embd); + case 1: return random_map (embd); + case 2: return random_dict (embd); + case 3: return random_list (embd); + case 4: return random_set (embd); } - - return v; } -value_t real_random_value(bool embd) { - return random_boolean() ? random_value2() : random_container(embd); +vtype_variable real_random_value(bool embd) { + return random_boolean() ? random_variable2() : random_container(embd); } diff --git a/tests/src/list/src/io.c b/tests/src/list/src/io.c index fb61586..6e1e1a0 100644 --- a/tests/src/list/src/io.c +++ b/tests/src/list/src/io.c @@ -3,8 +3,8 @@ #include "../plug.h" -static int list_node_print(void* v, ssize_t i, vtype t, void* _) { - print_container_value(&i, v, t, 1, *(unsigned int*)_); +static int list_node_print(vtype_variable v, ssize_t i, void* _) { + print_container_value(&i, v, 1, *(unsigned int*)_); return 0; } diff --git a/tests/src/list/src/random.c b/tests/src/list/src/random.c index 504c5ad..d6d406e 100644 --- a/tests/src/list/src/random.c +++ b/tests/src/list/src/random.c @@ -3,13 +3,13 @@ #include "../plug.h" -static int remove_callback(void* v, ssize_t i, vtype t, void* _) { +static int remove_callback(vtype_variable v, ssize_t i, void* _) { struct { list_t* x; _Bool s; unsigned int p; } *x = _; if (!x->s) { - print_container_value(0, v, t, 1, x->p); + print_container_value(0, v, 1, x->p); } - if (libcdsb_list_find(x->x, v, t, 0, 0, 1, 1)) { + if (libcdsb_list_find(x->x, libcdsb_variable_build(v.pointer, v.type), 0, 0, 1, 1)) { return -2; } @@ -19,19 +19,19 @@ static int remove_callback(void* v, ssize_t i, vtype t, void* _) { void list_push_random(list_t* x, _Bool silent, unsigned int hpos) { - value_t v = random_value(); + vtype_variable v = random_variable(-1); _Bool r; if (random_boolean()) { if (!silent) { printf("\e[%dG\e[36mTry to push value to back of the list:\e[m\n", hpos+1); } - r = libcdsb_list_insert(x, -1, v.value, v.type, 1); + r = libcdsb_list_insert(x, -1, v, 1, 0, 0); } else if (random_boolean()) { if (!silent) { printf("\e[%dG\e[36mTry to push value to front of the list:\e[m\n", hpos+1); } - r = libcdsb_list_insert(x, -1, v.value, v.type, 1); + r = libcdsb_list_insert(x, -1, v, 1, 0, 0); } else { ssize_t i = list_size(x); i = random_uint64()% (i ? i : 1); @@ -41,11 +41,11 @@ void list_push_random(list_t* x, _Bool silent, unsigned int hpos) { printf("\e[%dG\e[36mTry to change value with index \e[32;1m%ld\e[36m in the list:\e[m\n", hpos+1, i); } - r = libcdsb_list_insert(x, i, v.value, v.type, 0); + r = libcdsb_list_insert(x, i, v, 0, 0, 0); } if (!silent) { - print_container_value(0, v.value, v.type, 1, hpos); + print_container_value(0, v, 1, hpos); printf("\e[%dG%s\n", hpos+1, r ? "\e[32;1mSUCCESS\e[m" : "\e[31;1mFAILURE\e[m"); put_separator(hpos); } @@ -61,7 +61,7 @@ void list_remove_random(list_t* x, _Bool silent, unsigned int hpos) { if (random_boolean()) { if (!silent) { printf("\e[%dG\e[36mTry to remove value from list by index:\e[m\n", hpos+1); - print_container_value(0, &i, (sizeof(ssize_t) == 8) ? VTYPE_INT64 : VTYPE_INT32, 0, hpos); + print_container_value(0, libcdsb_variable_build(&i, (sizeof(ssize_t) == 8) ? VTYPE_INT64 : VTYPE_INT32), 0, hpos); } switch (list_remove_by_index(x, i)) { case 0: if (!silent) printf("\e[%dG\e[32;1mSUCCESS\e[m\n", hpos+1); break; diff --git a/tests/src/map/src/io.c b/tests/src/map/src/io.c index a01da4b..c83a4ef 100644 --- a/tests/src/map/src/io.c +++ b/tests/src/map/src/io.c @@ -3,8 +3,8 @@ #include "../plug.h" -static int node_print_callback(const void* k, vtype kt, void* v, vtype vt, void* _) { - print_container_value(0, k, kt, 0, *(unsigned int*)_); +static int node_print_callback(vtype_variable k, vtype_variable v, void* _) { + print_container_value(0, k, 0, *(unsigned int*)_); return 0; } diff --git a/tests/src/map/src/random.c b/tests/src/map/src/random.c index c4615f2..46b04e9 100644 --- a/tests/src/map/src/random.c +++ b/tests/src/map/src/random.c @@ -3,13 +3,13 @@ #include "../plug.h" -static int remove_callback(const void* k, vtype kt, void* v, vtype vt, void* _) { +static int remove_callback(vtype_variable k, vtype_variable v, void* _) { struct { size_t n; map_t* x; unsigned int hp; } *d = _; if (!d->n--) { - print_container_value(0, k, kt, 0, d->hp); + print_container_value(0, k, 0, d->hp); - if (libcdsb_map_find(d->x, k, kt, 0, 0, 1) == 0) { + if (libcdsb_map_find(d->x, k, 0, 0, 1) == 0) { printf("\e[%dG\e[32;1mSUCCESS\e[m\n", d->hp+1); } else printf("\e[%dG\e[31;1mFAILURE\e[m\n", d->hp+1); @@ -20,15 +20,15 @@ static int remove_callback(const void* k, vtype kt, void* v, vtype vt, void* _) void map_push_random(map_t* x, _Bool silent, unsigned int hpos) { - value_t k = random_value(); - value_t v = random_value(); + vtype_variable k = random_variable(-1); + vtype_variable v = random_variable(-1); if (!silent) { printf("\e[%dG\e[36mUpdate value in map (\e[m\e[32;1m%s\e[m\e[36m) with key:\e[m\n", hpos+1, vtype_name(x->type)); - print_container_value(0, k.value, k.type, 1, hpos); + print_container_value(0, k, 1, hpos); } - if (libcdsb_map_update(x, k.value, k.type, v.value, v.type)) { + if (libcdsb_map_update(x, k, v, 0, 0)) { if (!silent) printf("\e[%dG\e[33;1mCHANGE\e[m\n", hpos+1); } else if (!silent) printf("\e[%dG\e[32;1mINSERT\e[m\n", hpos+1); diff --git a/tests/src/random.c b/tests/src/random.c index 337932c..7825ccd 100644 --- a/tests/src/random.c +++ b/tests/src/random.c @@ -110,23 +110,32 @@ unsigned int random_unicode_symbol() { } } -value_t random_value() { - value_t v; - switch (random_uint8()%13) { +vtype_variable random_variable(int rand) { + static char values[2*sizeof(void*) * 16]; + static size_t n = 0; + + if (n == 16) n = 0; + + vtype_variable v = { .pointer = &values[n++*2] }; + + if (rand < 0 || rand > 12) + rand = random_uint8()%13; + + switch (rand) { default: - case 0: v.value[0].b = random_boolean(); v.type = VTYPE_BOOLEAN; break; - case 1: v.value[0].u8 = random_uint8 (); v.type = VTYPE_UINT8; break; - case 2: v.value[0].u16 = random_uint16 (); v.type = VTYPE_UINT16; break; - case 3: v.value[0].u32 = random_uint32 (); v.type = VTYPE_UINT32; break; - case 4: v.value[0].u64 = random_uint64 (); v.type = VTYPE_UINT64; break; - case 5: v.value[0].u8 = random_int8 (); v.type = VTYPE_INT8; break; - case 6: v.value[0].u16 = random_int16 (); v.type = VTYPE_INT16; break; - case 7: v.value[0].u32 = random_int32 (); v.type = VTYPE_INT32; break; - case 8: v.value[0].u64 = random_int64 (); v.type = VTYPE_INT64; break; - case 9: v.value[0].f = random_float (); v.type = VTYPE_FLOAT; break; - case 10: v.value[0].d = random_double (); v.type = VTYPE_DOUBLE; break; - case 11: v.value[0].ld = random_ldouble(); v.type = VTYPE_LDOUBLE; break; - case 12: v.value[0].ptr = (void*)(uintptr_t)random_uint64(); v.type = VTYPE_POINTER; break; + case 0: *(vtype_bool*) v.pointer = random_boolean(); v.type = VTYPE_BOOLEAN; break; + case 1: *(vtype_uint8*) v.pointer = random_uint8 (); v.type = VTYPE_UINT8; break; + case 2: *(vtype_uint16*) v.pointer = random_uint16 (); v.type = VTYPE_UINT16; break; + case 3: *(vtype_uint32*) v.pointer = random_uint32 (); v.type = VTYPE_UINT32; break; + case 4: *(vtype_uint64*) v.pointer = random_uint64 (); v.type = VTYPE_UINT64; break; + case 5: *(vtype_int8*) v.pointer = random_int8 (); v.type = VTYPE_INT8; break; + case 6: *(vtype_int16*) v.pointer = random_int16 (); v.type = VTYPE_INT16; break; + case 7: *(vtype_int32*) v.pointer = random_int32 (); v.type = VTYPE_INT32; break; + case 8: *(vtype_int64*) v.pointer = random_int64 (); v.type = VTYPE_INT64; break; + case 9: *(vtype_float*) v.pointer = random_float (); v.type = VTYPE_FLOAT; break; + case 10: *(vtype_double*) v.pointer = random_double (); v.type = VTYPE_DOUBLE; break; + case 11: *(vtype_ldouble*) v.pointer = random_ldouble(); v.type = VTYPE_LDOUBLE; break; + case 12: *(vtype_uint64*) v.pointer = random_uint64 (); v.type = VTYPE_POINTER; break; } return v; diff --git a/tests/src/set/src/io.c b/tests/src/set/src/io.c index 378aaf6..98e2f61 100644 --- a/tests/src/set/src/io.c +++ b/tests/src/set/src/io.c @@ -4,8 +4,8 @@ #include "../plug.h" -static int node_print_callback(const void* v, vtype t, void* _) { - print_container_value(0, v, t, 0, *(unsigned int*)_); +static int node_print_callback(vtype_variable v, void* _) { + print_container_value(0, v, 0, *(unsigned int*)_); return 0; } diff --git a/tests/src/set/src/random.c b/tests/src/set/src/random.c index dc6d6d5..00f72e5 100644 --- a/tests/src/set/src/random.c +++ b/tests/src/set/src/random.c @@ -3,13 +3,13 @@ #include "../plug.h" -static int remove_callback(const void* v, vtype t, void* _) { +static int remove_callback(var_t v, void* _) { struct { size_t n; set_t* x; unsigned int hp; } *d = _; if (!d->n--) { - print_container_value(0, v, t, 0, d->hp); + print_container_value(0, v, 0, d->hp); - if (libcdsb_vset_find(d->x, v, t, 0, 0, 1) == 0) { + if (libcdsb_vset_find(d->x, v, 0, 0, 1) == 0) { printf("\e[%dG\e[32;1mSUCCESS\e[m\n", d->hp+1); } else printf("\e[%dG\e[31;1mFAILURE\e[m\n", d->hp+1); @@ -20,14 +20,14 @@ static int remove_callback(const void* v, vtype t, void* _) { void vset_push_random(set_t* x, _Bool silent, unsigned int hpos) { - value_t v = random_value(); + var_t v = random_variable(-1); if (!silent) { printf("\e[%dG\e[36mUpdate value in set (\e[m\e[32;1m%s\e[m\e[36m):\e[m\n", hpos+1, vtype_name(x->type)); - print_container_value(0, v.value, v.type, 1, hpos); + print_container_value(0, v, 1, hpos); } - if (libcdsb_vset_insert(x, v.value, v.type)) { + if (libcdsb_vset_insert(x, v)) { if (!silent) printf("\e[%dG\e[32;1mSUCCESS\e[m\n", hpos+1); } else if (!silent) printf("\e[%dG\e[31;1mFAILURE\e[m\n", hpos+1); diff --git a/tests/src/test.c b/tests/src/test.c index 32e11e4..b1fa11e 100644 --- a/tests/src/test.c +++ b/tests/src/test.c @@ -63,17 +63,17 @@ void print_container_values_prefix(const char* name, const char* prefix, unsigne } } -void print_container_value(const ssize_t* index, const void* value, const vtype type, _Bool print_type, unsigned int hpos) { +void print_container_value(const ssize_t* index, vtype_variable var, _Bool print_type, unsigned int hpos) { if (index) { printf("\e[%dG\e[32;1m%5ld: \e[m", hpos+1, *index); } else { printf("\e[%dG ", hpos+1); } - printf("\e[31m%24s\e[m", libcdsb_vtype_stringify(value, type)); + printf("\e[31m%24s\e[m", libcdsb_variable_stringify(libcdsb_variable_build((void*)var.pointer, var.type))); if (print_type) { - printf(" \e[36m(\e[m\e[32;1m%s\e[m\e[36m)\e[m", libcdsb_vtype_name(type)); + printf(" \e[36m(\e[m\e[32;1m%s\e[m\e[36m)\e[m", libcdsb_vtype_name(var.type)); } puts("");