-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathvector.c
156 lines (132 loc) · 3.42 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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
// adapted from https://github.com/RaphGL/CLibs/
#include "vector.h"
#include "parser.h"
#include <math.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct vec_vector {
size_t len;
size_t capacity;
ns_Item *vec;
} vec_Vector;
// Initializes a new vector
vec_Vector *vec_new(void) {
vec_Vector *new = malloc(sizeof(vec_Vector));
new->capacity = 0;
new->len = 0;
new->vec = NULL;
return new;
}
// Resizes vector to fit length
static bool vec_fit(vec_Vector *vec) {
const size_t power = ceilf(log2f(vec->len + 1));
const size_t new_capacity = sizeof(ns_Item) * powf(2, power);
if (new_capacity < vec->capacity || new_capacity > vec->capacity) {
ns_Item *tmp = realloc(vec->vec, new_capacity);
if (!tmp) {
return false;
}
vec->vec = tmp;
vec->capacity = new_capacity;
}
return true;
}
// Pushes a value to vector
bool vec_push(vec_Vector *restrict vec, ns_Item item) {
// initialize vector if needed
if (!vec->vec) {
vec->vec = malloc(sizeof(ns_Item));
if (!vec->vec) {
return false;
}
vec->capacity = sizeof(ns_Item);
vec->len = 1;
vec->vec[0] = item;
return true;
}
vec_fit(vec);
vec->vec[vec->len] = item;
vec->len++;
return true;
}
// Returns how many items are in the vector
size_t vec_len(const vec_Vector *vec) { return vec->len; }
// Returns the total amount of items that can currently be stored
size_t vec_capacity(const vec_Vector *vec) { return vec->capacity; }
// Removes an item from the end of the vector and assigns it to dest
ns_Item vec_pop(vec_Vector *restrict vec) {
if (!vec->vec || vec->len <= 0 || vec->capacity == 0) {
return (ns_Item){.content = NULL};
}
vec->len--;
vec_fit(vec);
return vec->vec[vec->len];
}
// Clears out all the memory used by the vector
void vec_free(vec_Vector *restrict vec) {
if (!vec->vec) {
return;
}
free(vec->vec);
free(vec);
}
// Returns item at index
ns_Item vec_get(const vec_Vector *vec, const size_t index) {
if (!vec->vec || index >= vec->len || vec->capacity == 0) {
return (ns_Item){.content = NULL};
}
return vec->vec[index];
}
// Prints the vector with the specified format specifier
void vec_printf(const char *restrict fmt, const vec_Vector *vec) {
printf("[");
for (size_t i = 0; i < vec_len(vec); i++) {
printf(" ");
printf(fmt, vec->vec[i]);
}
printf(" ]\n");
}
// Inserts a new item at index
bool vec_insert(vec_Vector *vec, const size_t index, ns_Item *item) {
size_t len = vec->len - 1; // length before growing
if (index > len) {
return false;
}
vec_push(vec, vec->vec[len]);
for (size_t i = vec->len; i > index; i--) {
vec->vec[i] = vec->vec[i - 1];
}
vec->vec[index] = *item;
return true;
}
// Removes an item at index
bool vec_remove(vec_Vector *restrict vec, const size_t index) {
size_t len = vec->len - 1;
if (index > len) {
return false;
}
for (size_t i = index; i < vec->len; i++) {
if (i + 1 < vec->len) {
vec->vec[i] = vec->vec[i + 1];
}
}
vec_pop(vec);
return true;
}
bool vec_is_empty(const vec_Vector *vec) {
if (vec->len == 0 || vec->capacity == 0 || !vec->vec) {
return true;
}
return false;
}
// Appends vector from src to dest
bool vec_append(vec_Vector *restrict dest, const vec_Vector *src) {
for (size_t i = 0; i < src->len; i++) {
if (!vec_push(dest, src->vec[i])) {
return false;
}
}
return true;
}