From b61bb4e08e77c07a69ff49bdf6465d69c1651353 Mon Sep 17 00:00:00 2001 From: MCorange Date: Wed, 9 Jul 2025 10:59:56 +0300 Subject: [PATCH] Implemented marr --- src/include/marr.h | 29 ++++++---- src/marr.c | 141 ++++++++++++++++++++++++++++++++++++++------- 2 files changed, 139 insertions(+), 31 deletions(-) diff --git a/src/include/marr.h b/src/include/marr.h index 6f82073..3fc3887 100644 --- a/src/include/marr.h +++ b/src/include/marr.h @@ -2,8 +2,15 @@ #define _H_MARR #include +#include +#include #define MARR_DEFAULT_CAP 32 +#define MARR_RESIZE_FACTOR 2 +#define MARR_ASSERT assert +#define MARR_MALLOC malloc +#define MARR_REALLOC realloc +#define MARR_FREE free typedef struct marr_da_s { void* data; @@ -23,17 +30,17 @@ int _marr_remove(marr_da_t* da, size_t idx); bool _marr_contains(marr_da_t* da, void* val); bool _marr_map(marr_da_t* da, marr_da_t* da_out, bool (*func)(void* item, void* data), void* data); -#define marr_new(type) (type*)_marr_new(sizeof(type), MARR_DEFAULT_CAP); -#define marr_new_with_capacity(type, cap) (type*)_marr_new(sizeof(type), cap); -#define marr_push_front(da, val) _marr_push_front((marr_da_t)da, val); -#define marr_push_back(da, val) _marr_push_back((marr_da_t)da, val); -#define marr_pop_front(da, dest) _marr_pop_front((marr_da_t)da, dest); -#define marr_pop_back(da, dest) _marr_pop_back((marr_da_t)da, dest); -#define marr_append(to, from) _marr_append((marr_da_t)to, (marr_da_t)from); -#define marr_resize(da, new_size) _marr_resize((marr_da_t)da, new_size); -#define marr_remove(da, idx) _marr_remove((marr_da_t)da, idx); -#define marr_contains(da, val) _marr_contains((marr_da_t)da, val); -#define marr_map(da, da_out, fnc, data) _marr_map((marr_da_t)da, (marr_da_t)da_out, fnc, data); +#define marr_new(type) (type*)_marr_new(sizeof(type), MARR_DEFAULT_CAP) +#define marr_new_with_capacity(type, cap) (type*)_marr_new(sizeof(type), cap) +#define marr_push_front(da, val) _marr_push_front((marr_da_t*)da, val) +#define marr_push_back(da, val) _marr_push_back((marr_da_t*)da, val) +#define marr_pop_front(da, dest) _marr_pop_front((marr_da_t*)da, dest) +#define marr_pop_back(da, dest) _marr_pop_back((marr_da_t*)da, dest) +#define marr_append(to, from) _marr_append((marr_da_t*)to, (marr_da_t)from) +#define marr_resize(da, new_size) _marr_resize((marr_da_t*)da, new_size) +#define marr_remove(da, idx) _marr_remove((marr_da_t*)da, idx) +#define marr_contains(da, val) _marr_contains((marr_da_t*)da, val) +#define marr_map(da, da_out, fnc, data) _marr_map((marr_da_t*)da, (marr_da_t*)da_out, fnc, data) #define marr_len(da) (((marr_da_t*)(da))->len) #define marr_cap(da) (((marr_da_t*)(da))->cap) diff --git a/src/marr.c b/src/marr.c index e2b587a..76c989f 100644 --- a/src/marr.c +++ b/src/marr.c @@ -1,35 +1,136 @@ #include -#include +#include marr_da_t* _marr_new(size_t stride, size_t cap) { marr_da_t* da = malloc(sizeof(marr_da_t)); da->data = malloc(stride * cap); - if (!da->data) { - return NULL; - } + MARR_ASSERT(da->data && "MARR: Could not allocate new dyn array"); da->cap = cap; da->len = 0; return da; } -int _marr_push_front(marr_da_t* da, void* val) {} +// AKA end +int _marr_push_back(marr_da_t* da, void* val) { + MARR_ASSERT(da && "MARR: da is null"); + MARR_ASSERT(val && "MARR: value is null"); -int _marr_push_back(marr_da_t* da, void* val); -int _marr_pop_front(marr_da_t* da, void* dest); -int _marr_pop_back(marr_da_t* da, void* dest); -int _marr_append(marr_da_t* to, marr_da_t* from); - -int _marr_resize(marr_da_t* da, size_t new_cap) { - if (new_cap <= da->cap) { - return 1; - } - da->data = realloc(da->data, new_cap * da->stride); - if (!da->data) { - return 1; + if (marr_len(da) >= marr_cap(da)) { + if (marr_resize(da, marr_cap(da) * MARR_RESIZE_FACTOR)) { + return 1; + } } + memcpy(marr_as_ptr(void*, da) + (marr_len(da) * marr_stride(da)), val, marr_stride(da)); + marr_len(da) += 1; return 0; } -int _marr_remove(marr_da_t* da, size_t idx); -bool _marr_contains(marr_da_t* da, void* val); -bool _marr_map(marr_da_t* da, marr_da_t* da_out, bool (*func)(void* item, void* data), void* data); +// AKA start +int _marr_push_front(marr_da_t* da, void* val) { + MARR_ASSERT(da && "MARR: da is null"); + MARR_ASSERT(val && "MARR: value is null"); + if (marr_len(da) >= marr_cap(da)) { + if (marr_resize(da, marr_cap(da) * MARR_RESIZE_FACTOR)) { + return 1; + } + } + void* tmp_arr = MARR_MALLOC(marr_len(da) * marr_stride(da)); + MARR_ASSERT(tmp_arr && "MARR: Could not allocate temp_arr buffer"); + + memcpy(tmp_arr, marr_as_ptr(void*, da), marr_len(da) * marr_stride(da)); + memcpy(marr_as_ptr(void*, da), val, marr_stride(da)); + memcpy(marr_as_ptr(void*, da) + marr_stride(da), tmp_arr, marr_len(da) * marr_stride(da)); + marr_len(da) += 1; + return 1; +} + +// AKA end +int _marr_pop_back(marr_da_t* da, void* dest) { + MARR_ASSERT(da && "MARR: da is null"); + if (marr_len(da) < 1) { + return 1; + } + if (dest) { + memcpy(marr_as_ptr(void*, da) + ((marr_len(da) - 1) * marr_stride(da)), dest, marr_stride(da)); + } + + marr_len(da) -= 1; + return 0; +} + +// AKA start +int _marr_pop_front(marr_da_t* da, void* dest) { + MARR_ASSERT(da && "MARR: da is null"); + if (dest) { + memcpy(dest, marr_as_ptr(void*, da), marr_stride(da)); + } + memcpy(marr_as_ptr(void*, da), marr_as_ptr(void*, da) + marr_stride(da), marr_stride(da) * marr_len(da)); + return 0; +} + +int _marr_append(marr_da_t* to, marr_da_t* from) { + MARR_ASSERT(to && "MARR: da is null"); + MARR_ASSERT(from && "MARR: da is null"); + MARR_ASSERT(marr_stride(to) == marr_stride(from) && "arrays do not have the same type"); + + void* tmp = MARR_MALLOC(marr_stride(from)); + for (int i = 0; i < marr_len(from); i++) { + if (marr_pop_front(from, tmp)) { + return 1; + } + if (marr_push_back(to, tmp)) { + return 1; + } + } + + MARR_FREE(tmp); + return 1; +} + +int _marr_resize(marr_da_t* da, size_t new_cap) { + MARR_ASSERT(da && "MARR: da is null"); + if (new_cap <= da->cap) { + return 1; + } + da->data = MARR_REALLOC(da->data, new_cap * da->stride); + + MARR_ASSERT(marr_as_ptr(void*, da) && "MARR: Could not resize dyn arr"); + return 0; +} + +int _marr_remove(marr_da_t* da, size_t idx) { + MARR_ASSERT(da && "MARR: da is null"); + void* tmp_arr = MARR_MALLOC((marr_len(da) - 1) * marr_stride(da)); + MARR_ASSERT(tmp_arr && "MARR: Could not allocate temp_arr buffer"); + memcpy(tmp_arr, marr_as_ptr(void*, da), marr_stride(da) * idx); + memcpy(tmp_arr, marr_as_ptr(void*, da) + (marr_stride(da) * idx + 1), (marr_stride(da) * marr_len(da)) - (marr_stride(da) * idx)); + memcpy(marr_as_ptr(void*, da), tmp_arr, (marr_len(da) - 1) * marr_stride(da)); + MARR_FREE(tmp_arr); + marr_len(da) -= 1; + return 0; +} + +bool _marr_contains(marr_da_t* da, void* val) { + MARR_ASSERT(da && "MARR: da is null"); + for (int i = 0; i < marr_len(da); i++) { + if (memcmp(marr_as_ptr(void*, da) + (marr_stride(da) * i), val, marr_stride(da)) == 0) { + return true; + } + } + return false; +} + +bool _marr_map(marr_da_t* da, marr_da_t* da_out, bool (*func)(void* item, void* data), void* data) { + MARR_ASSERT(da && "MARR: da is null"); + bool found = false; + for (int i = 0; i < marr_len(da); i++) { + if (func(marr_as_ptr(void*, da) + (marr_stride(da) * i), data)) { + found = true; + if (da_out) { + MARR_ASSERT(marr_stride(da) == marr_stride(da_out) && "arrays do not have the same type"); + marr_push_back(da_out, marr_as_ptr(void*, da) + (marr_stride(da) * i)); + } + } + } + return found; +}