93 lines
2.0 KiB
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;
|
|
}
|