xref: /lighttpd1.4/src/vector.h (revision 5fe8322e)
1 #ifndef LI_VECTOR_H
2 #define LI_VECTOR_H
3 #include "first.h"
4 
5 #include "ck.h"         /* ck_assert() ck_calloc() */
6 
7 void vector_free(void *data);
8 
9 __attribute_returns_nonnull__
10 void *vector_resize(void *data, size_t elem_size, size_t *size, size_t used, size_t x);
11 
12 #define DEFINE_TYPED_VECTOR(name, entry, release) \
13 	typedef struct vector_ ## name { \
14 		entry* data; \
15 		size_t used; \
16 		size_t size; \
17 	} vector_ ## name; \
18 	static inline void vector_ ## name ## _init(vector_ ## name *v) { \
19 		v->data = NULL; \
20 		v->used = v->size = 0; \
21 	} \
22 	__attribute_malloc__ \
23 	__attribute_returns_nonnull__ \
24 	static inline vector_ ## name *vector_ ## name ## _alloc() { \
25 		return ck_calloc(1, sizeof(*v)); \
26 	} \
27 	static inline void vector_ ## name ## _clear(vector_ ## name *v) { \
28 		if (release) for (size_t i = 0; i < v->used; ++i) release(v->data[i]); \
29 		vector_free(v->data); \
30 		vector_ ## name ## _init(v); \
31 	} \
32 	static inline void vector_ ## name ## _free(vector_ ## name *v) { \
33 		if (NULL != v) { \
34 			vector_ ## name ## _clear(v); \
35 			vector_free(v); \
36 		} \
37 	} \
38 	static inline void vector_ ## name ## _reserve(vector_ ## name *v, size_t p) { \
39 		if (v->size - v->used < p) \
40 			v->data = vector_resize(v->data, sizeof(entry), &v->size, v->used, p); \
41 	} \
42 	static inline void vector_ ## name ## _push(vector_ ## name *v, entry e) { \
43 		vector_ ## name ## _reserve(v, 1); \
44 		v->data[v->used++] = e; \
45 	} \
46 	static inline entry vector_ ## name ## _pop(vector_ ## name *v) { \
47 		ck_assert(v->used > 0); \
48 		return v->data[--v->used]; \
49 	} \
50 	struct vector_ ## name /* expect trailing semicolon */ \
51 	/* end of DEFINE_TYPED_VECTOR */
52 
53 #define DEFINE_TYPED_VECTOR_NO_RELEASE(name, entry) \
54 	DEFINE_TYPED_VECTOR(name, entry, ((void(*)(entry)) NULL)) \
55 	/* end of DEFINE_TYPED_VECTOR_NO_RELEASE */
56 
57 
58 #endif
59