/* 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); } 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); } 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; void (*free_)(void*); assert(!is_null(p)); switch (x->type) { default: #ifndef NDEBUG abort(); #endif case VTYPE_STRING: free_ = (void*)string_free; break; case VTYPE_ARRAY: free_ = (void*) array_free; break; case VTYPE_LIST: free_ = (void*) list_free; break; case VTYPE_MAP: free_ = (void*) map_free; break; case VTYPE_SET: free_ = (void*) vset_free; break; } do { free_(p); p += vtype_size(x->type); } while (--x->size); } free(x->mem); memset(x, 0, sizeof(*x)); } 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; }