parent
0404cc699d
commit
9ce9cb8c95
@ -0,0 +1,26 @@
|
|||||||
|
#ifndef _VECTOR_H
|
||||||
|
#define _VECTOR_H
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
size_t len, cap;
|
||||||
|
|
||||||
|
size_t element, scap;
|
||||||
|
|
||||||
|
void* ptr;
|
||||||
|
} vec_t;
|
||||||
|
|
||||||
|
#define VEC_DEFAULT_CAP 16
|
||||||
|
|
||||||
|
vec_t vec_new_with_cap(size_t elem, size_t cap);
|
||||||
|
void vec_push(vec_t* restrict self, const void* restrict item);
|
||||||
|
bool vec_pop(vec_t* restrict self, void* restrict item);
|
||||||
|
void* vec_index(const vec_t* restrict self, size_t i);
|
||||||
|
vec_t vec_clone(const vec_t* restrict self);
|
||||||
|
|
||||||
|
__attribute__((gnu_inline)) inline extern vec_t vec_new(size_t elem) { return vec_new_with_cap(elem, VEC_DEFAULT_CAP); }
|
||||||
|
__attribute__((gnu_inline)) inline extern void vec_free(vec_t v) { free(v.ptr); }
|
||||||
|
|
||||||
|
#endif /* _VECTOR_H */
|
@ -0,0 +1,61 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <vector.h>
|
||||||
|
|
||||||
|
__attribute__((gnu_inline)) inline static void* die_if_null(void* ptr)
|
||||||
|
{
|
||||||
|
if (!ptr) abort();
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec_t vec_new_with_cap(size_t elem, size_t cap) {
|
||||||
|
return (vec_t){
|
||||||
|
.len =0,
|
||||||
|
.cap = cap,
|
||||||
|
.scap = cap,
|
||||||
|
.element = elem,
|
||||||
|
.ptr = die_if_null(calloc(elem, cap)),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void vec_extend_one(vec_t* restrict self)
|
||||||
|
{
|
||||||
|
self->ptr = die_if_null(reallocarray(self->ptr, self->element, (self->cap+=self->scap)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void* vec_index(const vec_t* restrict self, size_t i)
|
||||||
|
{
|
||||||
|
if (i >= self->len) return NULL;
|
||||||
|
return (void*)(((uintptr_t)self->ptr)+ (self->element*i));
|
||||||
|
}
|
||||||
|
|
||||||
|
void vec_push(vec_t* restrict self, const void* restrict item)
|
||||||
|
{
|
||||||
|
if (self->len >= self->cap) {
|
||||||
|
vec_extend_one(self);
|
||||||
|
}
|
||||||
|
memcpy(die_if_null(vec_index(self, self->len++)), item, self->element);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool vec_pop(vec_t* restrict self, void* restrict item)
|
||||||
|
{
|
||||||
|
if (self->len>0) {
|
||||||
|
memcpy(item, die_if_null(vec_index(self, self->len--)), self->element);
|
||||||
|
return true;
|
||||||
|
} else return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec_t vec_clone(const vec_t* restrict self)
|
||||||
|
{
|
||||||
|
register vec_t new = {
|
||||||
|
.len = self->len,
|
||||||
|
.cap = self->cap,
|
||||||
|
.element = self->element,
|
||||||
|
.scap = self->scap,
|
||||||
|
.ptr = die_if_null(calloc(self->element, self->cap)),
|
||||||
|
};
|
||||||
|
memcpy(self->ptr, new.ptr, new.len * new.element);
|
||||||
|
return new;
|
||||||
|
}
|
Loading…
Reference in new issue