Files
smallprojects/base.c
Krzosa Karol 9792517c41 Init repo
2026-05-10 13:24:39 +02:00

137 lines
3.9 KiB
C

#define Vec(T) struct { T *data; int len; int cap; }
typedef Vec(void) VecVoid;
#define vec_push(arr, elem) \
(vec_grow((VecVoid *)(arr), sizeof((arr)->data[0]), 1), (arr)->data[(arr)->len++] = (elem))
#define vec_insert(arr, idx, elem) do { \
assert((idx) >= 0 && (idx) <= (arr)->len); \
vec_grow((VecVoid *)(arr), sizeof((arr)->data[0]), 1); \
memmove(&(arr)->data[(idx) + 1], &(arr)->data[(idx)], sizeof((arr)->data[0]) * ((arr)->len - (idx))); \
(arr)->data[(idx)] = (elem); \
(arr)->len += 1; \
} while (0)
#define vec_pop(arr) \
(assert((arr)->len > 0), (arr)->data[--(arr)->len])
#define vec_del(arr, idx) do { \
assert((idx) >= 0 && (idx) < (arr)->len); \
memmove(&(arr)->data[(idx)], &(arr)->data[(idx) + 1], sizeof((arr)->data[0]) * ((arr)->len - (idx) - 1)); \
(arr)->len -= 1; \
} while (0)
#define vec_swap_del(arr, idx) do { \
assert((idx) >= 0 && (idx) < (arr)->len); \
(arr)->data[(idx)] = (arr)->data[(arr)->len - 1]; \
(arr)->len -= 1; \
} while (0)
#define vec_free(arr) do { \
free((arr)->data); \
(arr)->data = NULL; \
(arr)->len = 0; \
(arr)->cap = 0; \
} while (0)
void vec_grow(VecVoid *array, int elem_size, int add_len) {
if (array->len + add_len > array->cap) {
int cap = array->cap ? array->cap : 15;
int new_cap = (cap + add_len) * 2;
assert(new_cap > array->len + add_len);
array->data = realloc(array->data, elem_size * new_cap);
assert(array->data);
array->cap = new_cap;
}
}
void vec_test(void) {
Vec(int) int_vec = {0};
assert(int_vec.data == NULL);
assert(int_vec.len == 0);
assert(int_vec.cap == 0);
for (int i = 0; i < 32; i += 1) {
vec_push(&int_vec, i * 3);
assert(int_vec.len == i + 1);
assert(int_vec.cap >= int_vec.len);
assert(int_vec.data[int_vec.len - 1] == i * 3);
}
for (int i = 0; i < 32; i += 1) {
assert(int_vec.data[i] == i * 3);
}
int cap_after_ints = int_vec.cap;
vec_push(&int_vec, 12345);
assert(int_vec.len == 33);
assert(int_vec.data[32] == 12345);
assert(int_vec.cap >= cap_after_ints);
vec_insert(&int_vec, 0, 111);
assert(int_vec.len == 34);
assert(int_vec.data[0] == 111);
assert(int_vec.data[1] == 0);
vec_insert(&int_vec, 5, 222);
assert(int_vec.len == 35);
assert(int_vec.data[5] == 222);
assert(int_vec.data[6] == 12);
vec_insert(&int_vec, int_vec.len, 333);
assert(int_vec.len == 36);
assert(int_vec.data[int_vec.len - 1] == 333);
int popped = vec_pop(&int_vec);
assert(popped == 333);
assert(int_vec.len == 35);
vec_del(&int_vec, 5);
assert(int_vec.len == 34);
assert(int_vec.data[5] == 12);
int before_swap_del = int_vec.data[int_vec.len - 1];
vec_swap_del(&int_vec, 1);
assert(int_vec.len == 33);
assert(int_vec.data[1] == before_swap_del);
vec_free(&int_vec);
assert(int_vec.data == NULL);
assert(int_vec.len == 0);
assert(int_vec.cap == 0);
Vec(char *) str_vec = {0};
vec_push(&str_vec, "a");
vec_push(&str_vec, "bb");
vec_push(&str_vec, "ccc");
assert(str_vec.len == 3);
assert(strcmp(str_vec.data[0], "a") == 0);
assert(strcmp(str_vec.data[1], "bb") == 0);
assert(strcmp(str_vec.data[2], "ccc") == 0);
vec_insert(&str_vec, 1, "inserted");
assert(str_vec.len == 4);
assert(strcmp(str_vec.data[1], "inserted") == 0);
assert(strcmp(str_vec.data[2], "bb") == 0);
assert(strcmp(vec_pop(&str_vec), "ccc") == 0);
assert(str_vec.len == 3);
vec_del(&str_vec, 1);
assert(str_vec.len == 2);
assert(strcmp(str_vec.data[0], "a") == 0);
assert(strcmp(str_vec.data[1], "bb") == 0);
vec_swap_del(&str_vec, 0);
assert(str_vec.len == 1);
assert(strcmp(str_vec.data[0], "bb") == 0);
vec_free(&str_vec);
assert(str_vec.data == NULL);
assert(str_vec.len == 0);
assert(str_vec.cap == 0);
printf("vector tests passed\n");
}