Implemented marr

This commit is contained in:
Gvidas Juknevičius 2025-07-09 10:59:56 +03:00
parent cf6b35e7f8
commit b61bb4e08e
Signed by: MCorange
GPG Key ID: 5BE6B533CB76FE86
2 changed files with 139 additions and 31 deletions

View File

@ -2,8 +2,15 @@
#define _H_MARR #define _H_MARR
#include <stddef.h> #include <stddef.h>
#include <stdlib.h>
#include <assert.h>
#define MARR_DEFAULT_CAP 32 #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 { typedef struct marr_da_s {
void* data; 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_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); 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(type) (type*)_marr_new(sizeof(type), MARR_DEFAULT_CAP)
#define marr_new_with_capacity(type, cap) (type*)_marr_new(sizeof(type), 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_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_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_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_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_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_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_remove(da, idx) _marr_remove((marr_da_t*)da, idx)
#define marr_contains(da, val) _marr_contains((marr_da_t)da, val); #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_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_len(da) (((marr_da_t*)(da))->len)
#define marr_cap(da) (((marr_da_t*)(da))->cap) #define marr_cap(da) (((marr_da_t*)(da))->cap)

View File

@ -1,35 +1,136 @@
#include <marr.h> #include <marr.h>
#include <stdlib.h> #include <string.h>
marr_da_t* _marr_new(size_t stride, size_t cap) { marr_da_t* _marr_new(size_t stride, size_t cap) {
marr_da_t* da = malloc(sizeof(marr_da_t)); marr_da_t* da = malloc(sizeof(marr_da_t));
da->data = malloc(stride * cap); da->data = malloc(stride * cap);
if (!da->data) { MARR_ASSERT(da->data && "MARR: Could not allocate new dyn array");
return NULL;
}
da->cap = cap; da->cap = cap;
da->len = 0; da->len = 0;
return da; 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); if (marr_len(da) >= marr_cap(da)) {
int _marr_pop_front(marr_da_t* da, void* dest); if (marr_resize(da, marr_cap(da) * MARR_RESIZE_FACTOR)) {
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; return 1;
} }
da->data = realloc(da->data, new_cap * da->stride);
if (!da->data) {
return 1;
} }
memcpy(marr_as_ptr(void*, da) + (marr_len(da) * marr_stride(da)), val, marr_stride(da));
marr_len(da) += 1;
return 0; return 0;
} }
int _marr_remove(marr_da_t* da, size_t idx); // AKA start
bool _marr_contains(marr_da_t* da, void* val); int _marr_push_front(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); 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;
}