From 57a8a08234d4752b62b0b61a7a5fc207a27ae982 Mon Sep 17 00:00:00 2001 From: Gregory Lirent Date: Fri, 19 Aug 2022 13:41:19 +0300 Subject: [PATCH] Refactor array, add attaching functional --- examples/array.c | 2 +- include/__generics.h | 55 +++++++++++++++ include/array.h | 103 ++++++++------------------- include/extra/array.h | 21 ------ src/array/{extra.c => access.c} | 42 ++--------- src/array/base.c | 119 -------------------------------- src/array/comparison.c | 35 ++++++++++ src/array/compute.c | 48 +++++++++++++ src/array/copy.c | 17 ----- src/array/generics.c | 67 ------------------ src/array/include.h | 18 ++++- src/array/memory.c | 49 +++++++++++++ src/array/modify.c | 55 +++++++++++++++ tests/src/array/plug.h | 2 +- tests/src/global/plug.h | 2 +- 15 files changed, 294 insertions(+), 341 deletions(-) delete mode 100644 include/extra/array.h rename src/array/{extra.c => access.c} (69%) delete mode 100644 src/array/base.c create mode 100644 src/array/comparison.c create mode 100644 src/array/compute.c delete mode 100644 src/array/generics.c create mode 100644 src/array/memory.c create mode 100644 src/array/modify.c diff --git a/examples/array.c b/examples/array.c index 29108c4..7dc68be 100644 --- a/examples/array.c +++ b/examples/array.c @@ -3,7 +3,7 @@ #include #include -#include "../include/extra/array.h" +#include "../include/array.h" typedef vtype_array arr_t; diff --git a/include/__generics.h b/include/__generics.h index 3f93adb..2bda8e2 100644 --- a/include/__generics.h +++ b/include/__generics.h @@ -4,6 +4,38 @@ #ifndef LIBCDSB_CORE_GENERICS_H #define LIBCDSB_CORE_GENERICS_H +#define vtypeof(x) (vtype)(_Generic((x),\ + const void*: VTYPE_POINTER, void*: VTYPE_POINTER,\ + const char**: VTYPE_STRING, char**: VTYPE_STRING,\ + const vtype_string*: VTYPE_STRING, vtype_string*: VTYPE_STRING,\ + const vtype_array*: VTYPE_ARRAY, vtype_array*: VTYPE_ARRAY,\ + const vtype_list*: VTYPE_LIST, vtype_list*: VTYPE_LIST,\ + const vtype_map*: VTYPE_MAP, vtype_map*: VTYPE_MAP,\ + const vtype_set*: VTYPE_SET, vtype_set*: VTYPE_SET,\ + const vtype_dict*: VTYPE_DICT, vtype_dict*: VTYPE_DICT,\ + vtype_bool: VTYPE_BOOLEAN,\ + vtype_uint8: VTYPE_UINT8,\ + vtype_uint16: VTYPE_UINT16,\ + vtype_uint32: VTYPE_UINT32,\ + vtype_uint64: VTYPE_UINT64,\ + vtype_int8: VTYPE_INT8,\ + vtype_int16: VTYPE_INT16,\ + vtype_int32: VTYPE_INT32,\ + vtype_int64: VTYPE_INT64,\ + vtype_float: VTYPE_FLOAT,\ + 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),\ + vtype_array*: (x), const vtype_array*: (x),\ + vtype_list*: (x), const vtype_list*: (x),\ + vtype_map*: (x), const vtype_map*: (x),\ + vtype_set*: (x), const vtype_set*: (x),\ + vtype_dict*: (x), const vtype_dict*: (x)) + + #define _LIBCDSB_Generic(T, f, v) _Generic((v),\ void*: T ## _ ## f ## _pointer, const void*: T ## _ ## f ## _pointer,\ char*: T ## _ ## f ## _cstring, const char*: T ## _ ## f ## _cstring,\ @@ -50,6 +82,29 @@ vtype_ldouble: _LIBCDSB_Generic(T, f ## _ldouble, v)\ ) +#define _LIBCDSB_Generic_attach(T, ins_f, att_f, v) _Generic((v),\ + void*: T ## _ ## ins_f ## _pointer, const void*: T ## _ ## ins_f ## _pointer,\ + char*: T ## _ ## ins_f ## _cstring, const char*: T ## _ ## ins_f ## _cstring,\ + vtype_string*: T ## _ ## att_f ## _string, const vtype_string*: T ## _ ## att_f ## _string,\ + vtype_array*: T ## _ ## att_f ## _array, const vtype_array*: T ## _ ## att_f ## _array,\ + vtype_list*: T ## _ ## att_f ## _list, const vtype_list*: T ## _ ## att_f ## _list,\ + vtype_map*: T ## _ ## att_f ## _map, const vtype_map*: T ## _ ## att_f ## _map,\ + vtype_set*: T ## _ ## att_f ## _vset, const vtype_set*: T ## _ ## att_f ## _vset,\ + vtype_dict*: T ## _ ## att_f ## _dict, const vtype_dict*: T ## _ ## att_f ## _dict,\ + vtype_bool: T ## _ ## ins_f ## _boolean,\ + vtype_uint8: T ## _ ## ins_f ## _uint8,\ + vtype_uint16: T ## _ ## ins_f ## _uint16,\ + vtype_uint32: T ## _ ## ins_f ## _uint32,\ + vtype_uint64: T ## _ ## ins_f ## _uint64,\ + vtype_int8: T ## _ ## ins_f ## _int8,\ + vtype_int16: T ## _ ## ins_f ## _int16,\ + vtype_int32: T ## _ ## ins_f ## _int32,\ + vtype_int64: T ## _ ## ins_f ## _int64,\ + vtype_float: T ## _ ## ins_f ## _float,\ + vtype_double: T ## _ ## ins_f ## _double,\ + vtype_ldouble: T ## _ ## ins_f ## _ldouble\ +) + #define _LIBCDSB_GenericS(T, f, v) _Generic((v),\ void*: T ## _ ## f ## _cstring, const void*: T ## _ ## f ## _cstring,\ char*: T ## _ ## f ## _cstring, const char*: T ## _ ## f ## _cstring,\ diff --git a/include/array.h b/include/array.h index 5b6d177..0e54ed0 100644 --- a/include/array.h +++ b/include/array.h @@ -7,89 +7,42 @@ #ifndef LIBCDSB_ARRAY_H #define LIBCDSB_ARRAY_H -/*#####################################################################################################################*/ - typedef int (*array_access_callback)(void* value, ssize_t index, vtype type, void* data); -extern void array_init (vtype_array* x, vtype type) Nonnull__(1); -extern void* array_at (const vtype_array* s, ssize_t index) Nonnull__(1); -extern size_t array_slice(vtype_array* x, vtype_array* src, ssize_t index, size_t count, bool cut) Nonnull__(1); +/*#####################################################################################################################*/ -extern void array_sort (vtype_array* x) Nonnull__(1); -extern void array_reverse(vtype_array* x) Nonnull__(1); +extern void array_init (vtype_array* x, vtype type) Nonnull__(1); +extern size_t array_slice (vtype_array* x, vtype_array* src, ssize_t index, size_t count, bool cut) Nonnull__(1); +extern void array_sort (vtype_array* x) Nonnull__(1); +extern void array_reverse (vtype_array* x) Nonnull__(1); -#define array_pop(x, value, data, callback) _LIBCDSB_Generic(libcdsb_array, find, value)(x, value, data, callback, 0, 1) -#define array_find(x, value, data, callback) _LIBCDSB_Generic(libcdsb_array, find, value)(x, value, data, callback, 0, 0) -#define array_rfind(x, value, data, callback) _LIBCDSB_Generic(libcdsb_array, find, value)(x, value, data, callback, 1, 0) -#define array_countof(x, value) _LIBCDSB_Generic(libcdsb_array, count, value)(x, value) -#define array_remove(x, value) array_pop(x, value, 0, 0) -#define in_array(x, value) (array_find(x, value, 0, 0) == 0) - -#define array_push_back(x, value) _LIBCDSB_Generic(libcdsb_array, push, value)(x, value) +extern void* at_array(const vtype_array* s, ssize_t index) Nonnull__(1); /*#####################################################################################################################*/ -extern void libcdsb_array_push_pointer(vtype_array* x, const void* value) Nonnull__(1); -extern void libcdsb_array_push_cstring(vtype_array* x, const char* value) Nonnull__(1,2); -extern void libcdsb_array_push_string (vtype_array* x, const vtype_string* value) Nonnull__(1,2); -extern void libcdsb_array_push_array (vtype_array* x, const vtype_array* value) Nonnull__(1,2); -extern void libcdsb_array_push_list (vtype_array* x, const vtype_list* value) Nonnull__(1,2); -extern void libcdsb_array_push_map (vtype_array* x, const vtype_map* value) Nonnull__(1,2); -extern void libcdsb_array_push_vset (vtype_array* x, const vtype_set* value) Nonnull__(1,2); -extern void libcdsb_array_push_dict (vtype_array* x, const vtype_dict* value) Nonnull__(1,2); -extern void libcdsb_array_push_boolean(vtype_array* x, vtype_bool value) Nonnull__(1); -extern void libcdsb_array_push_uint8 (vtype_array* x, vtype_uint8 value) Nonnull__(1); -extern void libcdsb_array_push_uint16 (vtype_array* x, vtype_uint16 value) Nonnull__(1); -extern void libcdsb_array_push_uint32 (vtype_array* x, vtype_uint32 value) Nonnull__(1); -extern void libcdsb_array_push_uint64 (vtype_array* x, vtype_uint64 value) Nonnull__(1); -extern void libcdsb_array_push_int8 (vtype_array* x, vtype_int8 value) Nonnull__(1); -extern void libcdsb_array_push_int16 (vtype_array* x, vtype_int16 value) Nonnull__(1); -extern void libcdsb_array_push_int32 (vtype_array* x, vtype_int32 value) Nonnull__(1); -extern void libcdsb_array_push_int64 (vtype_array* x, vtype_int64 value) Nonnull__(1); -extern void libcdsb_array_push_float (vtype_array* x, vtype_float value) Nonnull__(1); -extern void libcdsb_array_push_double (vtype_array* x, vtype_double value) Nonnull__(1); -extern void libcdsb_array_push_ldouble(vtype_array* x, vtype_ldouble value) Nonnull__(1); +#define array_pop(x, value, data, callback) libcdsb_array_find (x, _LIBCDSB_value_pointer(value), _LIBCDSB_vtypeof(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_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) -extern size_t libcdsb_array_count_pointer(const vtype_array* s, const void* value) Nonnull__(1); -extern size_t libcdsb_array_count_cstring(const vtype_array* s, const char* value) Nonnull__(1,2); -extern size_t libcdsb_array_count_string (const vtype_array* s, const vtype_string* value) Nonnull__(1,2); -extern size_t libcdsb_array_count_array (const vtype_array* s, const vtype_array* value) Nonnull__(1,2); -extern size_t libcdsb_array_count_list (const vtype_array* s, const vtype_list* value) Nonnull__(1,2); -extern size_t libcdsb_array_count_map (const vtype_array* s, const vtype_map* value) Nonnull__(1,2); -extern size_t libcdsb_array_count_vset (const vtype_array* s, const vtype_set* value) Nonnull__(1,2); -extern size_t libcdsb_array_count_dict (const vtype_array* s, const vtype_dict* value) Nonnull__(1,2); -extern size_t libcdsb_array_count_boolean(const vtype_array* s, vtype_bool value) Nonnull__(1); -extern size_t libcdsb_array_count_int8 (const vtype_array* s, vtype_int8 value) Nonnull__(1); -extern size_t libcdsb_array_count_int16 (const vtype_array* s, vtype_int16 value) Nonnull__(1); -extern size_t libcdsb_array_count_int32 (const vtype_array* s, vtype_int32 value) Nonnull__(1); -extern size_t libcdsb_array_count_int64 (const vtype_array* s, vtype_int64 value) Nonnull__(1); -extern size_t libcdsb_array_count_uint8 (const vtype_array* s, vtype_uint8 value) Nonnull__(1); -extern size_t libcdsb_array_count_uint16 (const vtype_array* s, vtype_uint16 value) Nonnull__(1); -extern size_t libcdsb_array_count_uint32 (const vtype_array* s, vtype_uint32 value) Nonnull__(1); -extern size_t libcdsb_array_count_uint64 (const vtype_array* s, vtype_uint64 value) Nonnull__(1); -extern size_t libcdsb_array_count_float (const vtype_array* s, vtype_float value) Nonnull__(1); -extern size_t libcdsb_array_count_double (const vtype_array* s, vtype_double value) Nonnull__(1); -extern size_t libcdsb_array_count_ldouble(const vtype_array* s, vtype_ldouble value) Nonnull__(1); +#define in_array(x, value) (array_get(x, value, 0, 0) == 0) -extern int libcdsb_array_find_pointer(vtype_array* x, const void* value, void* data, array_access_callback, bool reverse, bool cut) Nonnull__(1); -extern int libcdsb_array_find_cstring(vtype_array* x, const char* value, void* data, array_access_callback, bool reverse, bool cut) Nonnull__(1,2); -extern int libcdsb_array_find_string (vtype_array* x, const vtype_string* value, void* data, array_access_callback, bool reverse, bool cut) Nonnull__(1,2); -extern int libcdsb_array_find_array (vtype_array* x, const vtype_array* value, void* data, array_access_callback, bool reverse, bool cut) Nonnull__(1,2); -extern int libcdsb_array_find_list (vtype_array* x, const vtype_list* value, void* data, array_access_callback, bool reverse, bool cut) Nonnull__(1,2); -extern int libcdsb_array_find_map (vtype_array* x, const vtype_map* value, void* data, array_access_callback, bool reverse, bool cut) Nonnull__(1,2); -extern int libcdsb_array_find_vset (vtype_array* x, const vtype_set* value, void* data, array_access_callback, bool reverse, bool cut) Nonnull__(1,2); -extern int libcdsb_array_find_dict (vtype_array* x, const vtype_dict* value, void* data, array_access_callback, bool reverse, bool cut) Nonnull__(1,2); -extern int libcdsb_array_find_boolean(vtype_array* x, vtype_bool value, void* data, array_access_callback, bool reverse, bool cut) Nonnull__(1); -extern int libcdsb_array_find_uint8 (vtype_array* x, vtype_uint8 value, void* data, array_access_callback, bool reverse, bool cut) Nonnull__(1); -extern int libcdsb_array_find_uint16 (vtype_array* x, vtype_uint16 value, void* data, array_access_callback, bool reverse, bool cut) Nonnull__(1); -extern int libcdsb_array_find_uint32 (vtype_array* x, vtype_uint32 value, void* data, array_access_callback, bool reverse, bool cut) Nonnull__(1); -extern int libcdsb_array_find_uint64 (vtype_array* x, vtype_uint64 value, void* data, array_access_callback, bool reverse, bool cut) Nonnull__(1); -extern int libcdsb_array_find_int8 (vtype_array* x, vtype_int8 value, void* data, array_access_callback, bool reverse, bool cut) Nonnull__(1); -extern int libcdsb_array_find_int16 (vtype_array* x, vtype_int16 value, void* data, array_access_callback, bool reverse, bool cut) Nonnull__(1); -extern int libcdsb_array_find_int32 (vtype_array* x, vtype_int32 value, void* data, array_access_callback, bool reverse, bool cut) Nonnull__(1); -extern int libcdsb_array_find_int64 (vtype_array* x, vtype_int64 value, void* data, array_access_callback, bool reverse, bool cut) Nonnull__(1); -extern int libcdsb_array_find_float (vtype_array* x, vtype_float value, void* data, array_access_callback, bool reverse, bool cut) Nonnull__(1); -extern int libcdsb_array_find_double (vtype_array* x, vtype_double value, void* data, array_access_callback, bool reverse, bool cut) Nonnull__(1); -extern int libcdsb_array_find_ldouble(vtype_array* x, vtype_ldouble value, void* data, array_access_callback, bool reverse, bool cut) Nonnull__(1); +/*#####################################################################################################################*/ + +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 size_t libcdsb_array_count(const vtype_array* s, const void* value, vtype type) Pure__ Warn_unused_result__ Nonnull__(1); #endif /* LIBCDSB_ARRAY_H */ diff --git a/include/extra/array.h b/include/extra/array.h deleted file mode 100644 index 3728d2f..0000000 --- a/include/extra/array.h +++ /dev/null @@ -1,21 +0,0 @@ -/* This software is licensed by the MIT License, see LICENSE file */ -/* Copyright © 2022 Gregory Lirent */ - -#include "../array.h" - -#ifndef LIBCDSB_EXTRA_ARRAY_H -#define LIBCDSB_EXTRA_ARRAY_H - -#define array_get_by_index(s, index, data, callback) libcdsb_array_get(s, index, data, callback, 0) -#define array_pop_by_index(s, index, data, callback) libcdsb_array_get(s, index, data, callback, 1) -#define array_remove_by_index(s, index) libcdsb_array_get(s, index, 0, 0, 1) - -#define array_foreach(x, data, callback) libcdsb_array_foreach(x, data, callback, 0) - -extern ssize_t libcdsb_array_push (vtype_array* x, const void* value, vtype value_type) Nonnull__(1); -extern size_t libcdsb_array_count (const vtype_array* s, const void* value, vtype type) Pure__ Warn_unused_result__ 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); - -#endif /* LIBCDSB_EXTRA_ARRAY_H */ diff --git a/src/array/extra.c b/src/array/access.c similarity index 69% rename from src/array/extra.c rename to src/array/access.c index 1b35a78..d787eda 100644 --- a/src/array/extra.c +++ b/src/array/access.c @@ -2,45 +2,13 @@ /* Copyright © 2022 Gregory Lirent */ #include "include.h" -#include "../__internal/assert.h" -#include "../__internal/vnode.h" -ssize_t libcdsb_array_push(arr_t* x, const void* v, vtype t) { - ssize_t i = x->size; - vnode_t n = vnode_tcreate(x->type, v, t); - - x->mem = realloc(x->mem, ++x->size * vtype_size(x->type)); - memcpy(array_internal_at(x, i), vnode_peek(&n, x->type), vtype_size(x->type)); - - if (vtype_size(x->type) > sizeof(void*) && x->type < VTYPE_STRING) - vnode_free(&n, x->type); - - return i; +void* at_array(const arr_t* x, ssize_t i) { + if (i < 0 && (i += x->size) < 0) + i = 0; + return x->mem + i * vtype_size(x->type); } - -size_t libcdsb_array_count(const arr_t* s, const void* v, vtype t) { - void *p; - void *e; - int cmp; - size_t n; - - p = s->mem; - e = array_end(s); - n = 0; - - do { - cmp = vtype_compare(p, s->type, v, t); - - if (cmp == 0) ++n; - - p += vtype_size(s->type); - } while (p < e); - - return n; -} - - int libcdsb_array_get(vtype_array* x, ssize_t i, void* _, array_access_callback callback, vtype_bool cut) { int r = 0; @@ -55,7 +23,6 @@ int libcdsb_array_get(vtype_array* x, ssize_t i, void* _, array_access_callback return r; } - int libcdsb_array_find(arr_t* x, const void* v, vtype t, void* _, array_access_callback callback, bool r, bool cut) { void *p; ssize_t i; @@ -97,7 +64,6 @@ int libcdsb_array_find(arr_t* x, const void* v, vtype t, void* _, array_access_c return cmp; } - int libcdsb_array_foreach(vtype_array* x, void* data, array_access_callback callback, bool flush) { void* p; diff --git a/src/array/base.c b/src/array/base.c deleted file mode 100644 index f674b0c..0000000 --- a/src/array/base.c +++ /dev/null @@ -1,119 +0,0 @@ -/* This software is licensed by the MIT License, see LICENSE file */ -/* Copyright © 2022 Gregory Lirent */ - -#include "include.h" -#include "../__internal/assert.h" - -typedef void (*type_free)(void*); - -static inline type_free get_type_free(vtype type) { - switch (type) { - default: - #ifndef NDEBUG - abort(); - #endif - case VTYPE_STRING: return (void*)string_free; - case VTYPE_ARRAY: return (void*) array_free; - case VTYPE_LIST: return (void*) list_free; - case VTYPE_MAP: return (void*) map_free; - case VTYPE_SET: return (void*) vset_free; - case VTYPE_DICT: return (void*) dict_free; - } -} - -/*#####################################################################################################################*/ - -hash_t array_hash(const arr_t* s) { - hash_t hash = 0; - - if (s->size > 0) - hash = vtype_hash(s->mem, s->type); - - if (s->size > 1) - hash += vtype_hash(array_internal_at(s, s->size - 1), s->type); - - hash ^= s->size; - - return hash + VTYPE_ARRAY; -} - -void array_init(arr_t* x, vtype t) { - x->type = t; - x->size = 0; - x->mem = nullptr; -} - -void array_free(arr_t* x) { - if (x->size && x->type >= VTYPE_STRING) { - void* p = x->mem; - type_free free_; - - assert(!is_null(p)); - - free_ = get_type_free(x->type); - - do { - free_(p); - p += vtype_size(x->type); - } while (--x->size); - } - - free(x->mem); - memset(x, 0, sizeof(*x)); -} - -/*#####################################################################################################################*/ - -size_t array_size (const arr_t* x) { - return x->size; -} - -size_t array_nmemb(const arr_t* x) { - return x->size*vtype_size(x->type); -} - -void* array_at(const arr_t* x, ssize_t i) { - if (i < 0 && (i += x->size) < 0) i = 0; - return x->mem + i*vtype_size(x->type); -} - -/*#####################################################################################################################*/ - -int array_compare(const arr_t* s0, const arr_t* s1) { - - void *e; - void *p0; - void *p1; - int c; - - if (s0 == s1) - return 0; - - if (s0->type != s1->type) - return (s0->type < s1->type) ? -1 : 1; - - if (s0->size != s1->size) - return (s0->size < s1->size) ? -1 : 1; - - if (!s0->size && !s0->size) - return 0; - - assert(!is_null(s0->mem) && !is_null(s1->mem)); - - p0 = s0->mem; - p1 = s1->mem; - - e = array_end(s0); - - do { - c = vtype_compare_eq(p0, p1, s0->type); - - if (c == 0) { - p0 += vtype_size(s0->type); - p1 += vtype_size(s0->type); - } else return c; - - } while (p0 < e); - - return 0; -} diff --git a/src/array/comparison.c b/src/array/comparison.c new file mode 100644 index 0000000..f073b46 --- /dev/null +++ b/src/array/comparison.c @@ -0,0 +1,35 @@ +/* This software is licensed by the MIT License, see LICENSE file */ +/* Copyright © 2022 Gregory Lirent */ + +#include "include.h" + +int array_compare(const arr_t* s0, const arr_t* s1) { + void *e, *p0, *p1; + int cmp; + + if (s0 == s1 || (!s0->size && !s0->size)) + return 0; + + if (s0->type != s1->type) + return (s0->type < s1->type) ? -1 : 1; + + if (s0->size != s1->size) + return (s0->size < s1->size) ? -1 : 1; + + p0 = s0->mem; + p1 = s1->mem; + + e = array_end(s0); + + do { + cmp = vtype_compare_eq(p0, p1, s0->type); + + if (cmp == 0) { + p0 += vtype_size(s0->type); + p1 += vtype_size(s0->type); + } else return cmp; + + } while (p0 < e); + + return 0; +} diff --git a/src/array/compute.c b/src/array/compute.c new file mode 100644 index 0000000..eee0bdd --- /dev/null +++ b/src/array/compute.c @@ -0,0 +1,48 @@ +/* This software is licensed by the MIT License, see LICENSE file */ +/* Copyright © 2022 Gregory Lirent */ + +#include "include.h" +#include "../__internal/assert.h" + +size_t array_size (const arr_t* x) { + return x->size; +} + +size_t array_nmemb(const arr_t* x) { + return x->size*vtype_size(x->type); +} + +hash_t array_hash(const arr_t* s) { + hash_t hash = 0; + + if (s->size > 0) + hash = vtype_hash(s->mem, s->type); + + if (s->size > 1) + hash += vtype_hash(array_internal_at(s, s->size - 1), s->type); + + hash ^= s->size; + + return hash + VTYPE_ARRAY; +} + +size_t libcdsb_array_count(const arr_t* s, const void* v, vtype t) { + void *p; + void *e; + int cmp; + size_t n; + + p = s->mem; + e = array_end(s); + n = 0; + + do { + cmp = vtype_compare(p, s->type, v, t); + + if (cmp == 0) ++n; + + p += vtype_size(s->type); + } while (p < e); + + return n; +} diff --git a/src/array/copy.c b/src/array/copy.c index 0100ce7..7f2194e 100644 --- a/src/array/copy.c +++ b/src/array/copy.c @@ -4,23 +4,6 @@ #include "include.h" #include "../__internal/assert.h" -typedef void (*type_initializer)(void*, const void*); - -static inline type_initializer get_type_initializer(vtype type) { - switch (type) { - default: - #ifndef NDEBUG - abort(); - #endif - case VTYPE_STRING: return (void*)string_copy_init; - case VTYPE_ARRAY: return (void*) array_copy_init; - case VTYPE_LIST: return (void*) list_copy_init; - case VTYPE_MAP: return (void*) map_copy_init; - case VTYPE_SET: return (void*) vset_copy_init; - case VTYPE_DICT: return (void*) dict_copy_init; - } -} - arr_t array_copy(const arr_t* s) { arr_t x = { .mem = 0, .size = 0, .type = 0 }; diff --git a/src/array/generics.c b/src/array/generics.c deleted file mode 100644 index e34028a..0000000 --- a/src/array/generics.c +++ /dev/null @@ -1,67 +0,0 @@ -/* This software is licensed by the MIT License, see LICENSE file */ -/* Copyright © 2022 Gregory Lirent */ - -#include "include.h" - -int libcdsb_array_find_pointer(arr_t* x, const void* v, void* _, array_access_callback cb, bool r, bool cut) { return libcdsb_array_find(x, &v, vtypeof(&v), _, cb, r, cut); } -int libcdsb_array_find_cstring(arr_t* x, const char* v, void* _, array_access_callback cb, bool r, bool cut) { return libcdsb_array_find(x, &v, vtypeof(&v), _, cb, r, cut); } -int libcdsb_array_find_string (arr_t* x, const str_t* v, void* _, array_access_callback cb, bool r, bool cut) { return libcdsb_array_find(x, v, vtypeof( v), _, cb, r, cut); } -int libcdsb_array_find_array (arr_t* x, const arr_t* v, void* _, array_access_callback cb, bool r, bool cut) { return libcdsb_array_find(x, v, vtypeof( v), _, cb, r, cut); } -int libcdsb_array_find_list (arr_t* x, const list_t* v, void* _, array_access_callback cb, bool r, bool cut) { return libcdsb_array_find(x, v, vtypeof( v), _, cb, r, cut); } -int libcdsb_array_find_map (arr_t* x, const map_t* v, void* _, array_access_callback cb, bool r, bool cut) { return libcdsb_array_find(x, v, vtypeof( v), _, cb, r, cut); } -int libcdsb_array_find_vset (arr_t* x, const set_t* v, void* _, array_access_callback cb, bool r, bool cut) { return libcdsb_array_find(x, v, vtypeof( v), _, cb, r, cut); } -int libcdsb_array_find_dict (arr_t* x, const dict_t* v, void* _, array_access_callback cb, bool r, bool cut) { return libcdsb_array_find(x, v, vtypeof( v), _, cb, r, cut); } -int libcdsb_array_find_boolean(arr_t* x, bool v, void* _, array_access_callback cb, bool r, bool cut) { return libcdsb_array_find(x, &v, vtypeof(&v), _, cb, r, cut); } -int libcdsb_array_find_int8 (arr_t* x, s8_t v, void* _, array_access_callback cb, bool r, bool cut) { return libcdsb_array_find(x, &v, vtypeof(&v), _, cb, r, cut); } -int libcdsb_array_find_int16 (arr_t* x, s16_t v, void* _, array_access_callback cb, bool r, bool cut) { return libcdsb_array_find(x, &v, vtypeof(&v), _, cb, r, cut); } -int libcdsb_array_find_int32 (arr_t* x, s32_t v, void* _, array_access_callback cb, bool r, bool cut) { return libcdsb_array_find(x, &v, vtypeof(&v), _, cb, r, cut); } -int libcdsb_array_find_int64 (arr_t* x, s64_t v, void* _, array_access_callback cb, bool r, bool cut) { return libcdsb_array_find(x, &v, vtypeof(&v), _, cb, r, cut); } -int libcdsb_array_find_uint8 (arr_t* x, u8_t v, void* _, array_access_callback cb, bool r, bool cut) { return libcdsb_array_find(x, &v, vtypeof(&v), _, cb, r, cut); } -int libcdsb_array_find_uint16 (arr_t* x, u16_t v, void* _, array_access_callback cb, bool r, bool cut) { return libcdsb_array_find(x, &v, vtypeof(&v), _, cb, r, cut); } -int libcdsb_array_find_uint32 (arr_t* x, u32_t v, void* _, array_access_callback cb, bool r, bool cut) { return libcdsb_array_find(x, &v, vtypeof(&v), _, cb, r, cut); } -int libcdsb_array_find_uint64 (arr_t* x, u64_t v, void* _, array_access_callback cb, bool r, bool cut) { return libcdsb_array_find(x, &v, vtypeof(&v), _, cb, r, cut); } -int libcdsb_array_find_float (arr_t* x, fl_t v, void* _, array_access_callback cb, bool r, bool cut) { return libcdsb_array_find(x, &v, vtypeof(&v), _, cb, r, cut); } -int libcdsb_array_find_double (arr_t* x, dbl_t v, void* _, array_access_callback cb, bool r, bool cut) { return libcdsb_array_find(x, &v, vtypeof(&v), _, cb, r, cut); } -int libcdsb_array_find_ldouble(arr_t* x, ldbl_t v, void* _, array_access_callback cb, bool r, bool cut) { return libcdsb_array_find(x, &v, vtypeof(&v), _, cb, r, cut); } - -size_t libcdsb_array_count_pointer(const arr_t* x, const void* v) { return libcdsb_array_count(x, &v, vtypeof(&v)); } -size_t libcdsb_array_count_cstring(const arr_t* x, const char* v) { return libcdsb_array_count(x, &v, vtypeof(&v)); } -size_t libcdsb_array_count_string (const arr_t* x, const str_t* v) { return libcdsb_array_count(x, v, vtypeof( v)); } -size_t libcdsb_array_count_array (const arr_t* x, const arr_t* v) { return libcdsb_array_count(x, v, vtypeof( v)); } -size_t libcdsb_array_count_list (const arr_t* x, const list_t* v) { return libcdsb_array_count(x, v, vtypeof( v)); } -size_t libcdsb_array_count_map (const arr_t* x, const map_t* v) { return libcdsb_array_count(x, v, vtypeof( v)); } -size_t libcdsb_array_count_vset (const arr_t* x, const set_t* v) { return libcdsb_array_count(x, v, vtypeof( v)); } -size_t libcdsb_array_count_dict (const arr_t* x, const dict_t* v) { return libcdsb_array_count(x, v, vtypeof( v)); } -size_t libcdsb_array_count_boolean(const arr_t* x, bool v) { return libcdsb_array_count(x, &v, vtypeof(&v)); } -size_t libcdsb_array_count_int8 (const arr_t* x, s8_t v) { return libcdsb_array_count(x, &v, vtypeof(&v)); } -size_t libcdsb_array_count_int16 (const arr_t* x, s16_t v) { return libcdsb_array_count(x, &v, vtypeof(&v)); } -size_t libcdsb_array_count_int32 (const arr_t* x, s32_t v) { return libcdsb_array_count(x, &v, vtypeof(&v)); } -size_t libcdsb_array_count_int64 (const arr_t* x, s64_t v) { return libcdsb_array_count(x, &v, vtypeof(&v)); } -size_t libcdsb_array_count_uint8 (const arr_t* x, u8_t v) { return libcdsb_array_count(x, &v, vtypeof(&v)); } -size_t libcdsb_array_count_uint16 (const arr_t* x, u16_t v) { return libcdsb_array_count(x, &v, vtypeof(&v)); } -size_t libcdsb_array_count_uint32 (const arr_t* x, u32_t v) { return libcdsb_array_count(x, &v, vtypeof(&v)); } -size_t libcdsb_array_count_uint64 (const arr_t* x, u64_t v) { return libcdsb_array_count(x, &v, vtypeof(&v)); } -size_t libcdsb_array_count_float (const arr_t* x, fl_t v) { return libcdsb_array_count(x, &v, vtypeof(&v)); } -size_t libcdsb_array_count_double (const arr_t* x, dbl_t v) { return libcdsb_array_count(x, &v, vtypeof(&v)); } -size_t libcdsb_array_count_ldouble(const arr_t* x, ldbl_t v) { return libcdsb_array_count(x, &v, vtypeof(&v)); } - -void libcdsb_array_push_pointer(arr_t* x, const void* v) { libcdsb_array_push(x, &v, vtypeof(&v)); } -void libcdsb_array_push_cstring(arr_t* x, const char* v) { libcdsb_array_push(x, &v, vtypeof(&v)); } -void libcdsb_array_push_string (arr_t* x, const str_t* v) { libcdsb_array_push(x, v, vtypeof( v)); } -void libcdsb_array_push_array (arr_t* x, const arr_t* v) { libcdsb_array_push(x, v, vtypeof( v)); } -void libcdsb_array_push_list (arr_t* x, const list_t* v) { libcdsb_array_push(x, v, vtypeof( v)); } -void libcdsb_array_push_map (arr_t* x, const map_t* v) { libcdsb_array_push(x, v, vtypeof( v)); } -void libcdsb_array_push_vset (arr_t* x, const set_t* v) { libcdsb_array_push(x, v, vtypeof( v)); } -void libcdsb_array_push_dict (arr_t* x, const dict_t* v) { libcdsb_array_push(x, v, vtypeof( v)); } -void libcdsb_array_push_boolean(arr_t* x, bool v) { libcdsb_array_push(x, &v, vtypeof(&v)); } -void libcdsb_array_push_int8 (arr_t* x, s8_t v) { libcdsb_array_push(x, &v, vtypeof(&v)); } -void libcdsb_array_push_int16 (arr_t* x, s16_t v) { libcdsb_array_push(x, &v, vtypeof(&v)); } -void libcdsb_array_push_int32 (arr_t* x, s32_t v) { libcdsb_array_push(x, &v, vtypeof(&v)); } -void libcdsb_array_push_int64 (arr_t* x, s64_t v) { libcdsb_array_push(x, &v, vtypeof(&v)); } -void libcdsb_array_push_uint8 (arr_t* x, u8_t v) { libcdsb_array_push(x, &v, vtypeof(&v)); } -void libcdsb_array_push_uint16 (arr_t* x, u16_t v) { libcdsb_array_push(x, &v, vtypeof(&v)); } -void libcdsb_array_push_uint32 (arr_t* x, u32_t v) { libcdsb_array_push(x, &v, vtypeof(&v)); } -void libcdsb_array_push_uint64 (arr_t* x, u64_t v) { libcdsb_array_push(x, &v, vtypeof(&v)); } -void libcdsb_array_push_float (arr_t* x, fl_t v) { libcdsb_array_push(x, &v, vtypeof(&v)); } -void libcdsb_array_push_double (arr_t* x, dbl_t v) { libcdsb_array_push(x, &v, vtypeof(&v)); } -void libcdsb_array_push_ldouble(arr_t* x, ldbl_t v) { libcdsb_array_push(x, &v, vtypeof(&v)); } diff --git a/src/array/include.h b/src/array/include.h index a9c17b8..38db83c 100644 --- a/src/array/include.h +++ b/src/array/include.h @@ -2,12 +2,28 @@ /* Copyright © 2022 Gregory Lirent */ #include "../../include/array.h" -#include "../../include/extra/array.h" #include "../__internal/include.h" #ifndef LIBCDSB_SRC_ARRAY_INCLUDE_H #define LIBCDSB_SRC_ARRAY_INCLUDE_H +typedef void (*type_initializer)(void*, const void*); + +ainline(type_initializer get_type_initializer(vtype type)) { + switch (type) { + default: + #ifndef NDEBUG + abort(); + #endif + case VTYPE_STRING: return (void*)string_copy_init; + case VTYPE_ARRAY: return (void*) array_copy_init; + case VTYPE_LIST: return (void*) list_copy_init; + case VTYPE_MAP: return (void*) map_copy_init; + case VTYPE_SET: return (void*) vset_copy_init; + case VTYPE_DICT: return (void*) dict_copy_init; + } +} + ainline(void array_cut(arr_t* x, size_t i, size_t n)) { void* v = x->mem + i*vtype_size(x->type); void* e = v + n*vtype_size(x->type); diff --git a/src/array/memory.c b/src/array/memory.c new file mode 100644 index 0000000..5a84119 --- /dev/null +++ b/src/array/memory.c @@ -0,0 +1,49 @@ +/* This software is licensed by the MIT License, see LICENSE file */ +/* Copyright © 2022 Gregory Lirent */ + +#include "include.h" +#include "../__internal/assert.h" + +typedef void (*type_free)(void*); + +static inline type_free get_type_free(vtype type) { + switch (type) { + default: + #ifndef NDEBUG + abort(); + #endif + case VTYPE_STRING: return (void*)string_free; + case VTYPE_ARRAY: return (void*) array_free; + case VTYPE_LIST: return (void*) list_free; + case VTYPE_MAP: return (void*) map_free; + case VTYPE_SET: return (void*) vset_free; + case VTYPE_DICT: return (void*) dict_free; + } +} + +/*#####################################################################################################################*/ + +void array_init(arr_t* x, vtype t) { + x->type = t; + x->size = 0; + x->mem = nullptr; +} + +void array_free(arr_t* x) { + if (x->size && x->type >= VTYPE_STRING) { + void* p = x->mem; + type_free free_; + + assert(!is_null(p)); + + free_ = get_type_free(x->type); + + do { + free_(p); + p += vtype_size(x->type); + } while (--x->size); + } + + free(x->mem); + memset(x, 0, sizeof(*x)); +} diff --git a/src/array/modify.c b/src/array/modify.c new file mode 100644 index 0000000..0fe9e05 --- /dev/null +++ b/src/array/modify.c @@ -0,0 +1,55 @@ +/* This software is licensed by the MIT License, see LICENSE file */ +/* Copyright © 2022 Gregory Lirent */ + +#include "include.h" +#include "../__internal/assert.h" +#include "../__internal/vnode.h" + +ssize_t libcdsb_array_insert(arr_t* x, const void* v, vtype t) { + ssize_t i; + vnode_t n; + + i = x->size; + n = vnode_tcreate(x->type, v, t); + 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 (vtype_size(x->type) > sizeof(vnode_t)) + vnode_free(&n, x->type); + + } else if (x->type == t) { + get_type_initializer(t)(array_internal_at(x, i), v); + } + #ifndef NDEBUG + else abort(); + #endif + + return i; +} + +ssize_t libcdsb_array_attach(arr_t* x, const void* v, vtype t) { + 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 (vtype_size(x->type) > sizeof(vnode_t)) + vnode_free(&n, x->type); + + } else if (x->type == t) { + memcpy(array_internal_at(x, i), v, vtype_size(t)); + } + #ifndef NDEBUG + else abort(); + #endif + + return i; +} diff --git a/tests/src/array/plug.h b/tests/src/array/plug.h index f852e45..0243a08 100644 --- a/tests/src/array/plug.h +++ b/tests/src/array/plug.h @@ -3,7 +3,7 @@ #include #include "../../../include/extra/vtype.h" -#include "../../../include/extra/array.h" +#include "../../../include/array.h" #include "../../include/random.h" #include "../../include/test.h" diff --git a/tests/src/global/plug.h b/tests/src/global/plug.h index 6b280eb..3692f9c 100644 --- a/tests/src/global/plug.h +++ b/tests/src/global/plug.h @@ -2,7 +2,7 @@ /* Copyright © 2022 Gregory Lirent */ #include "../../../include/extra/string.h" -#include "../../../include/extra/array.h" +#include "../../../include/array.h" #include "../../../include/extra/list.h" #include "../../../include/extra/set.h" #include "../../../include/extra/map.h"