xref: /lighttpd1.4/src/vector.h (revision 5fe8322e)
18455734fSStefan Bühler #ifndef LI_VECTOR_H
28455734fSStefan Bühler #define LI_VECTOR_H
38455734fSStefan Bühler #include "first.h"
48455734fSStefan Bühler 
55e14db43SGlenn Strauss #include "ck.h"         /* ck_assert() ck_calloc() */
68455734fSStefan Bühler 
704d76e7aSGlenn Strauss void vector_free(void *data);
819bc8885SGlenn Strauss 
9dde9df43SGlenn Strauss __attribute_returns_nonnull__
10*5fe8322eSGlenn Strauss void *vector_resize(void *data, size_t elem_size, size_t *size, size_t used, size_t x);
118455734fSStefan Bühler 
128455734fSStefan Bühler #define DEFINE_TYPED_VECTOR(name, entry, release) \
138455734fSStefan Bühler 	typedef struct vector_ ## name { \
148455734fSStefan Bühler 		entry* data; \
158455734fSStefan Bühler 		size_t used; \
168455734fSStefan Bühler 		size_t size; \
178455734fSStefan Bühler 	} vector_ ## name; \
188455734fSStefan Bühler 	static inline void vector_ ## name ## _init(vector_ ## name *v) { \
198455734fSStefan Bühler 		v->data = NULL; \
208455734fSStefan Bühler 		v->used = v->size = 0; \
218455734fSStefan Bühler 	} \
2220a68d73SGlenn Strauss 	__attribute_malloc__ \
2320a68d73SGlenn Strauss 	__attribute_returns_nonnull__ \
248455734fSStefan Bühler 	static inline vector_ ## name *vector_ ## name ## _alloc() { \
255e14db43SGlenn Strauss 		return ck_calloc(1, sizeof(*v)); \
268455734fSStefan Bühler 	} \
278455734fSStefan Bühler 	static inline void vector_ ## name ## _clear(vector_ ## name *v) { \
2820a68d73SGlenn Strauss 		if (release) for (size_t i = 0; i < v->used; ++i) release(v->data[i]); \
2920a68d73SGlenn Strauss 		vector_free(v->data); \
308455734fSStefan Bühler 		vector_ ## name ## _init(v); \
318455734fSStefan Bühler 	} \
328455734fSStefan Bühler 	static inline void vector_ ## name ## _free(vector_ ## name *v) { \
338455734fSStefan Bühler 		if (NULL != v) { \
348455734fSStefan Bühler 			vector_ ## name ## _clear(v); \
3504d76e7aSGlenn Strauss 			vector_free(v); \
368455734fSStefan Bühler 		} \
378455734fSStefan Bühler 	} \
388455734fSStefan Bühler 	static inline void vector_ ## name ## _reserve(vector_ ## name *v, size_t p) { \
39*5fe8322eSGlenn Strauss 		if (v->size - v->used < p) \
40*5fe8322eSGlenn Strauss 			v->data = vector_resize(v->data, sizeof(entry), &v->size, v->used, p); \
418455734fSStefan Bühler 	} \
428455734fSStefan Bühler 	static inline void vector_ ## name ## _push(vector_ ## name *v, entry e) { \
438455734fSStefan Bühler 		vector_ ## name ## _reserve(v, 1); \
448455734fSStefan Bühler 		v->data[v->used++] = e; \
458455734fSStefan Bühler 	} \
468455734fSStefan Bühler 	static inline entry vector_ ## name ## _pop(vector_ ## name *v) { \
4769920910SGlenn Strauss 		ck_assert(v->used > 0); \
488455734fSStefan Bühler 		return v->data[--v->used]; \
498455734fSStefan Bühler 	} \
508455734fSStefan Bühler 	struct vector_ ## name /* expect trailing semicolon */ \
518455734fSStefan Bühler 	/* end of DEFINE_TYPED_VECTOR */
528455734fSStefan Bühler 
538455734fSStefan Bühler #define DEFINE_TYPED_VECTOR_NO_RELEASE(name, entry) \
548455734fSStefan Bühler 	DEFINE_TYPED_VECTOR(name, entry, ((void(*)(entry)) NULL)) \
558455734fSStefan Bühler 	/* end of DEFINE_TYPED_VECTOR_NO_RELEASE */
568455734fSStefan Bühler 
578455734fSStefan Bühler 
588455734fSStefan Bühler #endif
59