Refactor array, add attaching functional
This commit is contained in:
parent
f85aa8493f
commit
57a8a08234
@ -3,7 +3,7 @@
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include "../include/extra/array.h"
|
||||
#include "../include/array.h"
|
||||
|
||||
typedef vtype_array arr_t;
|
||||
|
||||
|
@ -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,\
|
||||
|
103
include/array.h
103
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 */
|
||||
|
@ -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 */
|
@ -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;
|
119
src/array/base.c
119
src/array/base.c
@ -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;
|
||||
}
|
35
src/array/comparison.c
Normal file
35
src/array/comparison.c
Normal file
@ -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;
|
||||
}
|
48
src/array/compute.c
Normal file
48
src/array/compute.c
Normal file
@ -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;
|
||||
}
|
@ -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 };
|
||||
|
||||
|
@ -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)); }
|
@ -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);
|
||||
|
49
src/array/memory.c
Normal file
49
src/array/memory.c
Normal file
@ -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));
|
||||
}
|
55
src/array/modify.c
Normal file
55
src/array/modify.c
Normal file
@ -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;
|
||||
}
|
@ -3,7 +3,7 @@
|
||||
|
||||
#include <string.h>
|
||||
#include "../../../include/extra/vtype.h"
|
||||
#include "../../../include/extra/array.h"
|
||||
#include "../../../include/array.h"
|
||||
|
||||
#include "../../include/random.h"
|
||||
#include "../../include/test.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"
|
||||
|
Loading…
Reference in New Issue
Block a user