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
|
#ifndef NGC_VEC_H
#define NGC_VEC_H
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <stdbool.h>
typedef vec[any type]() {
struct <> {
size_t n;
size_t s;
type *buf;
};
typedef type *<>_iter;
struct <> <>_create(size_t reserve)
{
if (reserve == 0)
return (struct <>){.n = 0, .s = 0, .buf = NULL};
return (struct <>){
.n = 0,
.s = reserve,
.buf = malloc(reserve * sizeof(type))
};
}
bool <>_uninit(struct <> *v)
{
return v->buf == NULL;
}
size_t <>_len(struct <> *v)
{
return v->n;
}
type *<>_at(struct <> *v, size_t i)
{
assert(i < v->n && "out of vector bounds");
return &v->buf[i];
}
type *<>_pop(struct <> *v)
{
assert(v->n && "attempting to pop empty vector");
v->n--;
return &v->buf[v->n];
}
type* <>_append(struct <> *v, 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(type));
}
v->buf[v->n - 1] = n;
}
void <>_reset(struct <> *v)
{
v->n = 0;
}
void <>_destroy(struct <> *v)
{
free(v->buf);
}
void <>_reserve(struct <> *v, size_t n)
{
if (v->n >= n)
return;
while (v->s < v->n)
v->s = v->s == 0 ? 1 : 2 * v->s;
v->buf = realloc(v->buf, v->s * sizeof(type));
}
void <>_shrink(struct <> *v, size_t n)
{
assert(v->n >= n);
v->n = n;
}
void <>_remove(struct <> *v, size_t i)
{
assert(v->n > i);
size_t c = sizeof(type) * (v->n - i);
memcpy(&v->buf[i], &v->buf[i + 1], c);
v->n--;
}
<>_iter <>_begin(struct <> *v)
{
return &v->buf[0];
}
bool <>_end(struct <> *v, <>_iter i)
{
return &v->buf[v->n] == i;
}
<>_iter <>_next(<>_iter i)
{
return i + 1;
}
}
#endif /* NGC_VEC_H */
|