-
Notifications
You must be signed in to change notification settings - Fork 0
/
vector.c
130 lines (95 loc) · 2.96 KB
/
vector.c
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
#include "vector.h"
#include "util.h"
#include <math.h>
struct vector {
char *data;
size_t element_size;
size_t len;
size_t capacity;
};
struct vector *vector_create(size_t element_size) {
invariant_assert(element_size > 0, "`element_size` of 0 impossible for vec");
struct vector *v = nonnull_malloc(sizeof(*v));
v->data = NULL;
v->element_size = element_size;
v->len = 0;
v->capacity = 0;
return v;
}
void vector_expand(struct vector *v, size_t min_size) {
size_t new_capacity = MAX(min_size, v->capacity ? v->capacity * 2 : 1);
char *new_data = nonnull_malloc(new_capacity * v->element_size);
memcpy(new_data, v->data, v->len * v->element_size);
if (v->data) {
free(v->data);
}
v->data = new_data;
v->capacity = new_capacity;
}
bool vector_empty(struct vector *v) { return v->len == 0; }
void *vector_push_front(struct vector *v, const void *data) {
size_t length = vector_length(v);
vector_extend(v, NULL, 1);
for (size_t i = length; i > 0; i--) {
void *curr = vector_get(v, i);
void *prev = vector_get(v, i - 1);
memmove(curr, prev, v->element_size);
}
void *head = vector_head(v);
memcpy(head, data, v->element_size);
return head;
}
void vector_remove_at(struct vector *v, size_t index) {
debug_assert(index < v->len, "index out of range");
v->len--;
size_t tail = v->len - index;
char *pos = &v->data[index * v->element_size];
memmove(pos, &pos[v->element_size], tail * v->element_size);
}
void vector_truncate(struct vector *v, size_t new_len) {
debug_assert(new_len <= v->len, "truncating out of range");
v->len = new_len;
}
void *vector_pop(struct vector *v) {
void *data = vector_get(v, v->len - 1);
vector_truncate(v, v->len - 1);
return data;
}
void *vector_push_back(struct vector *v, const void *data) {
vector_extend(v, data, 1);
return &v->data[(v->len - 1) * v->element_size];
}
void vector_extend(struct vector *v, const void *data, size_t num_elems) {
if (!num_elems) {
return;
}
if (v->len + num_elems > v->capacity) {
vector_expand(v, v->len + num_elems);
}
debug_assert(v->capacity >= v->len + num_elems,
"vector did not expand properly");
if (data) {
void *end = &v->data[v->len * v->element_size];
memcpy(end, data, v->element_size * num_elems);
}
v->len += num_elems;
}
void vector_resize(struct vector *v, size_t size) {
debug_assert(size <= v->len, "resizing too big");
v->len = size;
}
size_t vector_length(struct vector *v) { return v->len; }
size_t vector_byte_size(struct vector *v) { return v->len * v->element_size; }
void *vector_head(struct vector *v) { return v->data; }
void *vector_get(struct vector *v, size_t index) {
debug_assert(index < v->len, "index out of bounds!");
return &v->data[index * v->element_size];
}
void vector_copy_to(struct vector *v, void *dest) {
memcpy(dest, v->data, v->len * v->element_size);
}
void vector_free(struct vector **v) {
free((*v)->data);
free(*v);
*v = NULL;
}