diff options
Diffstat (limited to 'vector.c')
-rw-r--r-- | vector.c | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/vector.c b/vector.c new file mode 100644 index 0000000..57f62d7 --- /dev/null +++ b/vector.c @@ -0,0 +1,37 @@ +#include <stddef.h> +#include <stdint.h> +#include <stdlib.h> + +#include "vector.h" + +#define VECTOR_TOOBIG(alloc,elemsize,arrayoff) ((SIZE_MAX - (arrayoff)) / (alloc) < (elemsize)) +#define VECTOR_ALLOCSIZE(alloc,elemsize,arrayoff) ((arrayoff) + (alloc) * (elemsize)) + +void *vector_init(size_t alloc, size_t elemsize, size_t arrayoff) +{ + if (VECTOR_TOOBIG(alloc, elemsize, arrayoff)) return NULL; + struct vector *v = malloc(VECTOR_ALLOCSIZE(alloc, elemsize, arrayoff)); + if (!v) return NULL; + + *v = (struct vector) { + .alloc = alloc, + .elemsize = elemsize, + .arrayoff = arrayoff, + }; + return v; +} + +void *vector_append(struct vector **vp) +{ + struct vector *v = *vp; + if (v->count >= v->alloc) { + size_t alloc = 2 * v->alloc; + if (VECTOR_TOOBIG(alloc, v->elemsize, v->arrayoff)) return NULL; + v = realloc(v, VECTOR_ALLOCSIZE(alloc, v->elemsize, v->arrayoff)); + if (!v) return NULL; + v->alloc = alloc; + *vp = v; + } + return (char*)v + v->arrayoff + v->count++ * v->elemsize; +} + |