1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
/**
\file
Typesafe dynamically sized arrays
*/
#pragma once
#include <stdbool.h>
#include <stdlib.h>
/** A vector descriptor */
typedef struct _vector_desc {
size_t allocated; /**< The number of elements currently allocated */
size_t length; /**< The actual number of elements in the vector */
} vector_desc_t;
/**
A type for a vector of \e type elements
\hideinitializer
*/
#define VECTOR(type) struct { \
vector_desc_t desc; \
type *data; \
}
bool _vector_resize(vector_desc_t *desc, void **data, size_t n, size_t elemsize);
bool _vector_insert(vector_desc_t *desc, void **data, void *element, size_t pos, size_t elemsize);
void _vector_delete(vector_desc_t *desc, void **data, size_t pos, size_t elemsize);
/**
Resizes the vector \e a to \e n elements
\hideinitializer
*/
#define VECTOR_RESIZE(v, n) ({ \
__typeof__(v) *_v = &(v); \
_vector_resize(&_v->desc, (void **)&_v->data, (n), sizeof(*_v->data)); \
})
/**
Frees all resources used by the vector \e v
\hideinitializer
*/
#define VECTOR_FREE(v) free((v).data)
/**
Returns the number of elements in the vector \e v
\hideinitializer
*/
#define VECTOR_LEN(v) ((v).desc.length)
/**
Returns the element with index \e i in the vector \e v
\hideinitializer
*/
#define VECTOR_INDEX(v, i) ((v).data[i])
/**
Returns a pointer to the vector elements of \e v
\hideinitializer
*/
#define VECTOR_DATA(v) ((v).data)
/**
Inserts the element \e elem at index \e pos of vector \e v
\hideinitializer
*/
#define VECTOR_INSERT(v, elem, pos) ({ \
__typeof__(v) *_v = &(v); \
__typeof__(*_v->data) _e = (elem); \
_vector_insert(&_v->desc, (void **)&_v->data, &_e, (pos), sizeof(_e)); \
})
/**
Adds the element \e elem at the end of vector \e v
\hideinitializer
*/
#define VECTOR_ADD(v, elem) ({ \
__typeof__(v) *_v = &(v); \
__typeof__(*_v->data) _e = (elem); \
_vector_insert(&_v->desc, (void **)&_v->data, &_e, _v->desc.length, sizeof(_e)); \
})
/**
Deletes the element at index \e pos of vector \e v
\hideinitializer
*/
#define VECTOR_DELETE(v, pos) ({ \
__typeof__(v) *_v = &(v); \
_vector_delete(&_v->desc, (void **)&_v->data, (pos), sizeof(*_v->data)); \
})
/**
Performs a binary search on the vector \e v, returning a pointer to a matching vector element
\hideinitializer
*/
#define VECTOR_BSEARCH(key, v, cmp) ({ \
__typeof__(v) *_v = &(v); \
const __typeof__(*_v->data) *_key = (key); \
int (*_cmp)(__typeof__(_key), __typeof__(_key)) = (cmp); \
(__typeof__(_v->data))bsearch(_key, _v->data, _v->desc.length, sizeof(*_v->data), (int (*)(const void *, const void *))_cmp); \
})
|