diff options
author | Stefan Bühler <stbuehler@web.de> | 2016-03-19 15:27:36 +0000 |
---|---|---|
committer | Stefan Bühler <stbuehler@web.de> | 2016-03-19 15:27:36 +0000 |
commit | 8455734f4ae908735fd0d4aa9524301aa8915397 (patch) | |
tree | e1a6b5b7e6d926fa399bfe2007cfa53f89835ab0 /src/vector.h | |
parent | 15ac5b6986334901c546b74e3903dc837827e4c5 (diff) | |
download | lighttpd-git-8455734f4ae908735fd0d4aa9524301aa8915397.tar.gz |
[core] add generic vector implementation
From: Stefan Bühler <stbuehler@web.de>
git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-1.4.x@3115 152afb58-edef-0310-8abb-c4023f1b3aa9
Diffstat (limited to 'src/vector.h')
-rw-r--r-- | src/vector.h | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/src/vector.h b/src/vector.h new file mode 100644 index 00000000..7ba5dcf2 --- /dev/null +++ b/src/vector.h @@ -0,0 +1,75 @@ +#ifndef LI_VECTOR_H +#define LI_VECTOR_H +#include "first.h" + +#ifndef SIZE_MAX +# ifdef SIZE_T_MAX +# define SIZE_MAX SIZE_T_MAX +# else +# define SIZE_MAX ((size_t)~0) +# endif +#endif + +#include <stdlib.h> +#include <string.h> + +static inline size_t vector_align_size(size_t s) { + size_t a = (s + 16) & ((size_t)~15); + return (a < s) ? s : a; +} + +void *vector_realloc(void *data, size_t elem_size, size_t size, size_t used); + +#define DEFINE_TYPED_VECTOR(name, entry, release) \ + typedef struct vector_ ## name { \ + entry* data; \ + size_t used; \ + size_t size; \ + } vector_ ## name; \ + static inline void vector_ ## name ## _init(vector_ ## name *v) { \ + v->data = NULL; \ + v->used = v->size = 0; \ + } \ + static inline vector_ ## name *vector_ ## name ## _alloc() { \ + vector_ ## name *v = malloc(sizeof(*v)); \ + force_assert(NULL != v); \ + vector_ ## name ## _init(v); \ + return v; \ + } \ + static inline void vector_ ## name ## _clear(vector_ ## name *v) { \ + size_t ndx; \ + vector_ ## name vcopy = *v; \ + vector_ ## name ## _init(v); \ + if (release) for (ndx = 0; ndx < vcopy.used; ++ndx) release(vcopy.data[ndx]); \ + free(vcopy.data); \ + } \ + static inline void vector_ ## name ## _free(vector_ ## name *v) { \ + if (NULL != v) { \ + vector_ ## name ## _clear(v); \ + free(v); \ + } \ + } \ + static inline void vector_ ## name ## _reserve(vector_ ## name *v, size_t p) { \ + force_assert(v->used < SIZE_MAX - p); \ + if (v->size < v->used + p) { \ + v->size = vector_align_size(v->used + p); \ + v->data = vector_realloc(v->data, sizeof(entry), v->size, v->used); \ + } \ + } \ + static inline void vector_ ## name ## _push(vector_ ## name *v, entry e) { \ + vector_ ## name ## _reserve(v, 1); \ + v->data[v->used++] = e; \ + } \ + static inline entry vector_ ## name ## _pop(vector_ ## name *v) { \ + force_assert(v->used > 0); \ + return v->data[--v->used]; \ + } \ + struct vector_ ## name /* expect trailing semicolon */ \ + /* end of DEFINE_TYPED_VECTOR */ + +#define DEFINE_TYPED_VECTOR_NO_RELEASE(name, entry) \ + DEFINE_TYPED_VECTOR(name, entry, ((void(*)(entry)) NULL)) \ + /* end of DEFINE_TYPED_VECTOR_NO_RELEASE */ + + +#endif |