Files
mie/mie/vector.c

156 lines
2.9 KiB
C

#include <mie/vector.h>
#include <stdlib.h>
#include <string.h>
#define DEFAULT_CAPACITY 4
struct vector {
void *v_buf;
size_t v_itemsz;
size_t v_count;
size_t v_max;
};
static void vector_wrap(
struct vector *v, void **vector, size_t item_size, size_t *count,
size_t *max)
{
v->v_buf = *vector;
v->v_itemsz = item_size;
v->v_count = *count;
v->v_max = *max;
}
static void vector_unwrap(
struct vector *v, void **vector, size_t item_size, size_t *count,
size_t *max)
{
*vector = v->v_buf;
*count = v->v_count;
*max = v->v_max;
}
static int vector_reserve(struct vector *v, size_t new_capacity)
{
if (v->v_max >= new_capacity) {
return 0;
}
void *ptr = realloc(v->v_buf, new_capacity * v->v_itemsz);
if (!ptr) {
return -1;
}
v->v_buf = ptr;
v->v_max = new_capacity;
return 0;
}
static int vector_push_back(struct vector *v, const void *item)
{
int err = vector_reserve(v, v->v_count + 1);
if (err != 0) {
return err;
}
void *dest = (char *)v->v_buf + (v->v_count * v->v_itemsz);
memcpy(dest, item, v->v_itemsz);
v->v_count++;
return 0;
}
static int vector_pop_back(struct vector *v)
{
if (v->v_count > 0) {
v->v_count--;
}
return 0;
}
static void *vector_emplace_back(struct vector *v)
{
int err = vector_reserve(v, v->v_count + 1);
if (err != 0) {
return NULL;
}
void *dest = (char *)v->v_buf + (v->v_count * v->v_itemsz);
memset(dest, 0x0, v->v_itemsz);
v->v_count++;
return dest;
}
static void vector_destroy_items(struct vector *v, void (*dtor)(void *))
{
for (size_t i = 0; i < v->v_count; i++) {
void *item = (char *)v->v_buf + (i * v->v_itemsz);
dtor(item);
}
}
static void vector_destroy(struct vector *v, void (*dtor)(void *))
{
if (dtor) {
vector_destroy_items(v, dtor);
}
if (v->v_buf) {
free(v->v_buf);
}
v->v_buf = NULL;
v->v_count = 0;
v->v_max = 0;
}
int __mie_vector_push_back(
void **vector, const void *item, size_t item_size, size_t *count,
size_t *max)
{
struct vector v = {};
int err = 0;
vector_wrap(&v, vector, item_size, count, max);
err = vector_push_back(&v, item);
vector_unwrap(&v, vector, item_size, count, max);
return err;
}
void __mie_vector_pop_back(
void **vector, size_t item_size, size_t *count, size_t *max)
{
struct vector v = {};
vector_wrap(&v, vector, item_size, count, max);
vector_pop_back(&v);
vector_unwrap(&v, vector, item_size, count, max);
}
void *__mie_vector_emplace_back(
void **vector, size_t item_size, size_t *count, size_t *max)
{
struct vector v = {};
void *p = 0;
vector_wrap(&v, vector, item_size, count, max);
p = vector_emplace_back(&v);
vector_unwrap(&v, vector, item_size, count, max);
return p;
}
void __mie_vector_destroy(
void **vector, size_t item_size, size_t *count, size_t *max,
void (*dtor)(void *))
{
struct vector v = {};
vector_wrap(&v, vector, item_size, count, max);
vector_destroy(&v, dtor);
vector_unwrap(&v, vector, item_size, count, max);
}