Implemented marr
This commit is contained in:
parent
cf6b35e7f8
commit
b61bb4e08e
|
@ -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)
|
||||||
|
|
141
src/marr.c
141
src/marr.c
|
@ -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);
|
return 1;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user