xref: /lighttpd1.4/src/vector.h (revision 94edf7e8)
1 #ifndef LI_VECTOR_H
2 #define LI_VECTOR_H
3 #include "first.h"
4 
5 #include "buffer.h"     /* force_assert() */
6 
7 static inline size_t vector_align_size(size_t s) {
8 	size_t a = (s + 15) & ~(size_t)15uL;
9 	return (a < s) ? s : a;
10 }
11 
12 void vector_free(void *data);
13 
14 __attribute_malloc__
15 void *vector_malloc(size_t sz);
16 
17 __attribute_returns_nonnull__
18 void *vector_realloc(void *data, size_t elem_size, size_t size, size_t used);
19 
20 #define DEFINE_TYPED_VECTOR(name, entry, release) \
21 	typedef struct vector_ ## name { \
22 		entry* data; \
23 		size_t used; \
24 		size_t size; \
25 	} vector_ ## name; \
26 	static inline void vector_ ## name ## _init(vector_ ## name *v) { \
27 		v->data = NULL; \
28 		v->used = v->size = 0; \
29 	} \
30 	__attribute_malloc__ \
31 	__attribute_returns_nonnull__ \
32 	static inline vector_ ## name *vector_ ## name ## _alloc() { \
33 		vector_ ## name *v = vector_malloc(sizeof(*v)); \
34 		force_assert(NULL != v); \
35 		vector_ ## name ## _init(v); \
36 		return v; \
37 	} \
38 	static inline void vector_ ## name ## _clear(vector_ ## name *v) { \
39 		if (release) for (size_t i = 0; i < v->used; ++i) release(v->data[i]); \
40 		vector_free(v->data); \
41 		vector_ ## name ## _init(v); \
42 	} \
43 	static inline void vector_ ## name ## _free(vector_ ## name *v) { \
44 		if (NULL != v) { \
45 			vector_ ## name ## _clear(v); \
46 			vector_free(v); \
47 		} \
48 	} \
49 	static inline void vector_ ## name ## _reserve(vector_ ## name *v, size_t p) { \
50 		if (v->size - v->used < p) { \
51 			force_assert(v->used < SIZE_MAX - p); \
52 			v->size = vector_align_size(v->used + p); \
53 			v->data = vector_realloc(v->data, sizeof(entry), v->size, v->used); \
54 		} \
55 	} \
56 	static inline void vector_ ## name ## _push(vector_ ## name *v, entry e) { \
57 		vector_ ## name ## _reserve(v, 1); \
58 		v->data[v->used++] = e; \
59 	} \
60 	static inline entry vector_ ## name ## _pop(vector_ ## name *v) { \
61 		force_assert(v->used > 0); \
62 		return v->data[--v->used]; \
63 	} \
64 	struct vector_ ## name /* expect trailing semicolon */ \
65 	/* end of DEFINE_TYPED_VECTOR */
66 
67 #define DEFINE_TYPED_VECTOR_NO_RELEASE(name, entry) \
68 	DEFINE_TYPED_VECTOR(name, entry, ((void(*)(entry)) NULL)) \
69 	/* end of DEFINE_TYPED_VECTOR_NO_RELEASE */
70 
71 
72 #endif
73