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
|
#ifndef LIBGE_GEVECTOR_H
#define LIBGE_GEVECTOR_H
#include <stdbool.h>
#include <stdlib.h>
#define GEVECTOR_DEF(t, n) \
GEVECTOR_DEF_API(t, n) \
GEVECTOR_DEF_IMPL(t, n)
#define GEVECTOR_DEF_API(t, n) GEVECTOR_DEF_API_HELPER(t, n, n##_t)
#define GEVECTOR_DEF_API_HELPER(t, n, n_t) \
typedef struct { \
double gfac; \
size_t cap; \
size_t len; \
t *data; \
} n_t; \
\
int n##_new(n_t *, size_t, double); \
int n##_push(n_t *, t); \
int n##_insert(n_t *, t, size_t); \
void n##_remove(n_t *, size_t); \
int n##_resize(n_t *, size_t);
#define GEVECTOR_DEF_IMPL(t, n) GEVECTOR_DEF_IMPL_HELPER(t, n, n##_t)
#define GEVECTOR_DEF_IMPL_HELPER(t, n, n_t) \
int \
n##_new(n_t *vec, size_t cap, double gfac) \
{ \
*vec = (n_t) { \
.gfac = gfac == 0 ? 1.5f : gfac, \
.cap = cap == 0 ? 16 : cap, \
.len = 0, \
.data = calloc(cap == 0 ? 16 : cap, sizeof(t)) \
}; \
return vec->data == NULL ? -1 : 0; \
} \
\
int \
n##_push(n_t *vec, t elem) \
{ \
return n##_insert(vec, elem, vec->len); \
} \
\
int \
n##_insert(n_t *vec, t elem, size_t i) \
{ \
if (vec->len == vec->cap) { \
size_t ncap = (size_t) (vec->cap * vec->gfac); \
if (ncap == vec->cap) \
ncap++; \
if (n##_resize(vec, ncap) == -1) \
return -1; \
} \
for (size_t j = vec->len; j > i; j--) \
vec->data[j] = vec->data[j - 1]; \
vec->data[i] = elem; \
vec->len++; \
return 0; \
} \
\
void \
n##_remove(n_t *vec, size_t i) \
{ \
for (size_t j = i; j < vec->len - 1; j++) \
vec->data[j] = vec->data[j + 1]; \
vec->len--; \
} \
\
int \
n##_resize(n_t *vec, size_t ncap) \
{ \
vec->data = realloc(vec->data, sizeof(t) * ncap); \
if (vec->data == NULL) \
return -1; \
vec->cap = ncap; \
return 0; \
}
#define GEVECTOR_ENUMERATE(t, i, e, v) \
for (bool __ge_c = true; __ge_c; __ge_c = false) \
for (t e = (v).data[0]; __ge_c; __ge_c = false) \
for (size_t i = 0; i < (v).len; e = (v).data[++i])
#define GEVECTOR_FOREACH(t, e, v) GEVECTOR_ENUMERATE(t, __ge_i, e, v)
#endif /* !LIBGE_GEVECTOR_H */
|