libcdsb/src/array/base.c

93 lines
2.0 KiB
C

/* 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;
}