Refactor array, add attaching functional

This commit is contained in:
2022-08-19 13:41:19 +03:00
parent f85aa8493f
commit 57a8a08234
15 changed files with 294 additions and 341 deletions
+4 -38
View File
@@ -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
View File
@@ -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
View 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
View 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;
}
-17
View File
@@ -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 };
-67
View File
@@ -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)); }
+17 -1
View File
@@ -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
View 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
View 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;
}