/* 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_find(const arr_t* x, const void* v, vtype vt) { int c; ssize_t index; if (is_integer(x->type)) { tvalue_assert(vt); } else if (is_float(x->type)) { tvalue_assert(vt); } else type_assert(x->type, vt); index = -1; if (!x->size) return index; void* p = x->mem; void* e = array_end(x); assert(!is_null(x->mem)); do { ++index; c = vtype_compare(p, x->type, v, vt); if (c == 0) return index; p += vtype_size(x->type); } while (p < e); return -1; } ssize_t libcdsb_array_push(arr_t* x, const void* v, vtype vt) { ssize_t i = x->size; vnode_t n = vnode_tcreate(x->type, v, vt); 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; } ssize_t libcdsb_array_get(val_t* x, arr_t* s, ssize_t i, _Bool cut) { if (i < 0 && (i += s->size) < 0) i = 0; if (i < s->size) { assert(!is_null(s->mem)); if (cut) { if (!is_null(x)) { vnode_t n = vnode_create(array_internal_at(s, i), s->type); value_set(x, n, s->type, VF_WRITEABLE|VF_REMOVABLE); } array_cut(s, i, 1); } else value_set(x, array_internal_at(s, i), s->type, VF_WRITEABLE); } else { i = -1; memset(x, 0, sizeof(*x)); } return i; }