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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
|
#ifndef VEC_TYPE
#error "Need vector type"
#endif
#ifndef VEC_NAME
#error "Need vector name"
#endif
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include "conts.h"
#define VEC(a) CONTS_JOIN(VEC_NAME, a)
#define VEC_STRUCT VEC_NAME
struct VEC_STRUCT {
size_t n;
size_t s;
VEC_TYPE *buf;
};
static inline struct VEC_STRUCT VEC(create)(size_t reserve)
{
if (reserve == 0)
return (struct VEC_STRUCT) {.n = 0, .s = 0, .buf = NULL};
return (struct VEC_STRUCT) {
.n = 0,
.s = reserve,
.buf = malloc(reserve * sizeof(VEC_TYPE)),
};
}
static inline bool VEC(uninit)(struct VEC_STRUCT *v)
{
return v->buf == NULL;
}
static inline size_t VEC(len)(struct VEC_STRUCT *v)
{
return v->n;
}
static inline VEC_TYPE *VEC(at)(struct VEC_STRUCT *v, size_t i)
{
assert(i < v->n && "out of vector bounds");
return &v->buf[i];
}
static inline VEC_TYPE *VEC(back)(struct VEC_STRUCT *v)
{
assert(v->n);
return &v->buf[v->n - 1];
}
static inline VEC_TYPE *VEC(pop)(struct VEC_STRUCT *v)
{
assert(v->n && "attempting to pop empty vector");
v->n--;
return &v->buf[v->n];
}
static inline void VEC(append)(struct VEC_STRUCT *v, VEC_TYPE n)
{
v->n++;
if (v->n >= v->s) {
v->s = v->s == 0 ? 1 : 2 * v->s;
v->buf = realloc(v->buf, v->s * sizeof(VEC_TYPE));
}
v->buf[v->n - 1] = n;
}
static inline void VEC(reset)(struct VEC_STRUCT *v)
{
v->n = 0;
}
static inline void VEC(destroy)(struct VEC_STRUCT *v) {
free(v->buf);
}
typedef int (*VEC(comp_t))(VEC_TYPE *a, VEC_TYPE *b);
static inline void VEC(sort)(struct VEC_STRUCT *v, VEC(comp_t) comp)
{
qsort(v->buf, v->n, sizeof(VEC_TYPE), (__compar_fn_t)comp);
}
static inline void VEC(reserve)(struct VEC_STRUCT *v, size_t n)
{
if (v->n >= n)
return;
v->n = n;
if (v->s >= v->n)
return;
while (v->s < v->n)
v->s = v->s == 0 ? 1 : 2 * v->s;
v->buf = realloc(v->buf, v->s * sizeof(VEC_TYPE));
}
static inline void VEC(shrink)(struct VEC_STRUCT *v, size_t n)
{
assert(v->n >= n);
v->n = n;
}
static inline void VEC(remove)(struct VEC_STRUCT *v, size_t i)
{
assert(v->n > i);
size_t c = sizeof(VEC_TYPE) * (v->n - i);
memcpy(&v->buf[i], &v->buf[i + 1], c);
v->n--;
}
static inline VEC_TYPE *VEC(begin)(struct VEC_STRUCT *v)
{
return &v->buf[0];
}
static inline bool VEC(end)(struct VEC_STRUCT *v, VEC_TYPE *i)
{
return &v->buf[v->n] == i;
}
static inline VEC_TYPE *VEC(next)(VEC_TYPE *i)
{
return i + 1;
}
#undef VEC
#undef VEC_TYPE
#undef VEC_NAME
#undef VEC_STRUCT
|