diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..39b6c56 --- /dev/null +++ b/Makefile @@ -0,0 +1,5 @@ +CC = clang +CFLAGS = -O2 -Wall -Wextra -Wno-c2x-extensions +test_array: + $(CC) $(CFLAGS) -o test_array test_array.c libkeke_array.c + ./test_array diff --git a/libkeke_array.c b/libkeke_array.c new file mode 100644 index 0000000..b4ee226 --- /dev/null +++ b/libkeke_array.c @@ -0,0 +1,182 @@ +#ifndef LIBKEKE_ARRAY +#define LIBKEKE_ARRAY + +#include +#include +#include +#include +#include +#include "libkeke_utils.h" +#include "libkeke_array.h" + +#define ARRAY_GET(array, i) ((array)->content + (array)->type_size * (i)) + +struct KekeArray { + size_t type_size; + size_t len; + size_t max_len; + void *content; +}; + +void *keke_array_alloc(size_t initial_len, size_t type_size) { + //if(initial_len == 0) initial_len = 1; + struct KekeArray *array = malloc(sizeof(*array)); + array->len = initial_len; + size_t max_len = 1; + while(initial_len >>= 1) max_len <<= 1; + + array->type_size = type_size; + array->max_len = max_len; + array->content = malloc(max_len * type_size); + memset(array->content, 0, max_len * type_size); + return array; +} + +void keke_array_free(struct KekeArray *array) { + free(array->content); + free(array); +} + + +void keke_array_set(struct KekeArray *array, size_t index, const void *value) { + if(index >= array->max_len) { + array->content = realloc(array->content, (array->max_len << 1) * array->type_size); + memset(array->content + array->max_len * array->type_size, 0, array->max_len * array->type_size); + array->max_len <<= 1; + } + if(index >= array->len) array->len = index + 1; + memcpy(array->content + index * array->type_size, value, array->type_size); +} + +void *keke_array_get(struct KekeArray *array, size_t index) { + if(index >= array->len) return NULL; // is ur fault + return ARRAY_GET(array, index); +} + +int keke_array_copy(struct KekeArray *array, size_t index, void *value) { + if(index >= array->len) return -1; // is ur fault + memcpy(value, ARRAY_GET(array, index), array->type_size); + return 0; +} + +void keke_array_set_len(struct KekeArray *array, size_t new_len) { + if(new_len >= array->max_len) { + size_t new_max_len = 1; + size_t len = new_len; + while(len >>= 1) new_max_len <<= 1; + array->content = realloc(array->content, new_max_len * array->type_size); + memset(array->content + array->max_len * array->type_size, 0, (new_max_len - array->max_len) * array->type_size); + array->max_len <<= 1; + } else if(new_len < array->len) { + memset(array->content + new_len * array->type_size, 0, (array->len - new_len) * array->type_size); + } + array->len = new_len; +} + +void keke_array_insert(struct KekeArray *array, size_t index, const void *value) { + keke_array_set_len(array, array->len + 1); + memmove(array->content + ((index + 1) * array->type_size), array->content + (index * array->type_size), (array->len - index - 1) * array->type_size); + memcpy(array->content + index * array->type_size, value, array->type_size); +} + +void keke_array_remove(struct KekeArray *array, size_t index, void *value) { + keke_array_set_len(array, array->len - 1); + memcpy(value, array->content + index * array->type_size, array->type_size); + memmove(array->content + (index * array->type_size), array->content + ((index + 1) * array->type_size), (array->len - index + 1) * array->type_size); +} + +void keke_array_push(struct KekeArray *array, const void *value) { + keke_array_set(array, array->len, value); +} + +void keke_array_pop(struct KekeArray *array, void *value) { + keke_array_remove(array, array->len - 1, value); +} + +void keke_array_delete(struct KekeArray *array, size_t index) { + keke_array_set_len(array, array->len - 1); + memmove(array->content + (index * array->type_size), array->content + ((index + 1) * array->type_size), (array->len - index + 1) * array->type_size); +} + +struct KekeArray *keke_array_yoink(struct KekeArray *array, size_t start_index, size_t len) { + if(start_index + len >= array->len) return NULL; + struct KekeArray *ret = keke_array_alloc(len, array->type_size); + memcpy(ret->content, array->content + start_index * array->type_size, len * array->type_size); + memmove(array->content + start_index * array->type_size, array->content + (start_index + len) * array->type_size, (array->len - len - start_index) * array->type_size); + keke_array_set_len(array, array->len - len); + return ret; +} + +int keke_array_insert_data(struct KekeArray *array, size_t index, void *data, size_t len) { + if(index >= array->len) return -1; + size_t current_len = array->len; + keke_array_set_len(array, current_len + len); + memmove(array->content + (index + len) * array->type_size, array->content + index * array->type_size, (current_len - index) * array->type_size); + memcpy(array->content + index * array->type_size, data, len * array->type_size); + return 0; +} + +int keke_array_plop(struct KekeArray *array, size_t index, struct KekeArray *array2) { + int ret = keke_array_insert_data(array, index, array2->content, array2->len); + if(ret) return ret; + keke_array_free(array2); + return 0; +} + +typedef void (*Foreach_func)(void *, size_t, struct KekeArray *); + +void keke_array_foreach(struct KekeArray *array, Foreach_func callback) { + for(size_t i = 0; i < array->len; i++) callback(ARRAY_GET(array, i), i, array); +} + +struct KekeArray *keke_array_clone(struct KekeArray *array) { + struct KekeArray *ret = malloc(sizeof(*array)); + memcpy(ret, array, sizeof(*array)); + ret->content = malloc(array->max_len * array->type_size); + memcpy(ret->content, array->content, array->max_len * array->type_size); + return ret; +} + +void keke_array_fill(struct KekeArray *array, const void *value) { + for(size_t i = 0; i < array->len; i++) memcpy(ARRAY_GET(array, i), value, array->type_size); +} + +void keke_array_reverse(struct KekeArray *array) { + for(size_t i = 0; i < array->len / 2; i++) { + keke_swap(ARRAY_GET(array, i), array->content + array->type_size * (array->len - i - 1), array->type_size); + } +} + +typedef bool (*Test_func)(void *, size_t, struct KekeArray *); + +bool keke_array_some(struct KekeArray *array, Test_func test) { + bool ret = false; + for(size_t i = 0; i < array->len; i++) ret = ret || test(ARRAY_GET(array, i), i, array); + return ret; +} + +bool keke_array_all(struct KekeArray *array, Test_func test) { + bool ret = true; + for(size_t i = 0; i < array->len; i++) ret = ret && test(ARRAY_GET(array, i), i, array); + return ret; +} + +struct KekeArray *keke_array_filter(struct KekeArray *array, Test_func test) { + struct KekeArray *ret = keke_array_alloc(0, array->type_size); + for(size_t i = 0; i < array->len; i++) { + if(test(ARRAY_GET(array, i), i, array)) { + keke_array_push(ret, ARRAY_GET(array, i)); + } + } + return ret; +} + +typedef void (*B_func)(void *, void *); + +void keke_array_reduce(struct KekeArray *array, B_func op, void *acc) { + for(size_t i = 0; i < array->len; i++) op(ARRAY_GET(array, i), acc); +} + +#undef ARRAY_GET + +#endif diff --git a/libkeke_array.h b/libkeke_array.h index 6db15c3..d7a02d1 100644 --- a/libkeke_array.h +++ b/libkeke_array.h @@ -2,13 +2,8 @@ #define LIBKEKE_ARRAY #include -#include #include -#include #include -#include "libkeke_utils.h" - -#define ARRAY_GET(array, i) ((array)->content + (array)->type_size * (i)) struct KekeArray { size_t type_size; @@ -17,165 +12,38 @@ struct KekeArray { void *content; }; -static void *keke_array_alloc(size_t initial_len, size_t type_size) { - //if(initial_len == 0) initial_len = 1; - struct KekeArray *array = malloc(sizeof(*array)); - array->len = initial_len; - size_t max_len = 1; - while(initial_len >>= 1) max_len <<= 1; +void *keke_array_alloc(size_t initial_len, size_t type_size); +void keke_array_free(struct KekeArray *array); - array->type_size = type_size; - array->max_len = max_len; - array->content = malloc(max_len * type_size); - memset(array->content, 0, max_len * type_size); - return array; -} +void keke_array_set(struct KekeArray *array, size_t index, const void *value); +void *keke_array_get(struct KekeArray *array, size_t index); -static void keke_array_free(struct KekeArray *array) { - free(array->content); - free(array); -} +int keke_array_copy(struct KekeArray *array, size_t index, void *value); +void keke_array_set_len(struct KekeArray *array, size_t new_len); +void keke_array_insert(struct KekeArray *array, size_t index, const void *value); +void keke_array_remove(struct KekeArray *array, size_t index, void *value); +void keke_array_push(struct KekeArray *array, const void *value); +void keke_array_pop(struct KekeArray *array, void *value); +void keke_array_delete(struct KekeArray *array, size_t index); - -static void keke_array_set(struct KekeArray *array, size_t index, const void *value) { - if(index >= array->max_len) { - array->content = realloc(array->content, (array->max_len << 1) * array->type_size); - memset(array->content + array->max_len * array->type_size, 0, array->max_len * array->type_size); - array->max_len <<= 1; - } - if(index >= array->len) array->len = index + 1; - memcpy(array->content + index * array->type_size, value, array->type_size); -} - -static void *keke_array_get(struct KekeArray *array, size_t index) { - if(index >= array->len) return NULL; // is ur fault - return ARRAY_GET(array, index); -} - -static int keke_array_copy(struct KekeArray *array, size_t index, void *value) { - if(index >= array->len) return -1; // is ur fault - memcpy(value, ARRAY_GET(array, index), array->type_size); - return 0; -} - -static void keke_array_set_len(struct KekeArray *array, size_t new_len) { - if(new_len >= array->max_len) { - size_t new_max_len = 1; - size_t len = new_len; - while(len >>= 1) new_max_len <<= 1; - array->content = realloc(array->content, new_max_len * array->type_size); - memset(array->content + array->max_len * array->type_size, 0, (new_max_len - array->max_len) * array->type_size); - array->max_len <<= 1; - } else if(new_len < array->len) { - memset(array->content + new_len * array->type_size, 0, (array->len - new_len) * array->type_size); - } - array->len = new_len; -} - -static void keke_array_insert(struct KekeArray *array, size_t index, const void *value) { - keke_array_set_len(array, array->len + 1); - memmove(array->content + ((index + 1) * array->type_size), array->content + (index * array->type_size), (array->len - index - 1) * array->type_size); - memcpy(array->content + index * array->type_size, value, array->type_size); -} - -static void keke_array_remove(struct KekeArray *array, size_t index, void *value) { - keke_array_set_len(array, array->len - 1); - memcpy(value, array->content + index * array->type_size, array->type_size); - memmove(array->content + (index * array->type_size), array->content + ((index + 1) * array->type_size), (array->len - index + 1) * array->type_size); -} - -static void keke_array_push(struct KekeArray *array, const void *value) { - keke_array_set(array, array->len, value); -} - -static void keke_array_pop(struct KekeArray *array, void *value) { - keke_array_remove(array, array->len - 1, value); -} - -static void keke_array_delete(struct KekeArray *array, size_t index) { - keke_array_set_len(array, array->len - 1); - memmove(array->content + (index * array->type_size), array->content + ((index + 1) * array->type_size), (array->len - index + 1) * array->type_size); -} - -static struct KekeArray *keke_array_yoink(struct KekeArray *array, size_t start_index, size_t len) { - if(start_index + len >= array->len) return NULL; - struct KekeArray *ret = keke_array_alloc(len, array->type_size); - memcpy(ret->content, array->content + start_index * array->type_size, len * array->type_size); - memmove(array->content + start_index * array->type_size, array->content + (start_index + len) * array->type_size, (array->len - len - start_index) * array->type_size); - keke_array_set_len(array, array->len - len); - return ret; -} - -static int keke_array_insert_data(struct KekeArray *array, size_t index, void *data, size_t len) { - if(index >= array->len) return -1; - size_t current_len = array->len; - keke_array_set_len(array, current_len + len); - memmove(array->content + (index + len) * array->type_size, array->content + index * array->type_size, (current_len - index) * array->type_size); - memcpy(array->content + index * array->type_size, data, len * array->type_size); - return 0; -} - -static int keke_array_plop(struct KekeArray *array, size_t index, struct KekeArray *array2) { - int ret = keke_array_insert_data(array, index, array2->content, array2->len); - if(ret) return ret; - keke_array_free(array2); - return 0; -} +struct KekeArray *keke_array_yoink(struct KekeArray *array, size_t start_index, size_t len); +int keke_array_insert_data(struct KekeArray *array, size_t index, void *data, size_t len); +int keke_array_plop(struct KekeArray *array, size_t index, struct KekeArray *array2); typedef void (*Foreach_func)(void *, size_t, struct KekeArray *); +void keke_array_foreach(struct KekeArray *array, Foreach_func callback); +struct KekeArray *keke_array_clone(struct KekeArray *array); -static void keke_array_foreach(struct KekeArray *array, Foreach_func callback) { - for(size_t i = 0; i < array->len; i++) callback(ARRAY_GET(array, i), i, array); -} - -static struct KekeArray *keke_array_clone(struct KekeArray *array) { - struct KekeArray *ret = malloc(sizeof(*array)); - memcpy(ret, array, sizeof(*array)); - ret->content = malloc(array->max_len * array->type_size); - memcpy(ret->content, array->content, array->max_len * array->type_size); - return ret; -} - -static void keke_array_fill(struct KekeArray *array, const void *value) { - for(size_t i = 0; i < array->len; i++) memcpy(ARRAY_GET(array, i), value, array->type_size); -} - -static void keke_array_reverse(struct KekeArray *array) { - for(size_t i = 0; i < array->len / 2; i++) { - keke_swap(ARRAY_GET(array, i), array->content + array->type_size * (array->len - i - 1), array->type_size); - } -} +void keke_array_fill(struct KekeArray *array, const void *value); +void keke_array_reverse(struct KekeArray *array); typedef bool (*Test_func)(void *, size_t, struct KekeArray *); +bool keke_array_some(struct KekeArray *array, Test_func test); +bool keke_array_all(struct KekeArray *array, Test_func test); -static bool keke_array_some(struct KekeArray *array, Test_func test) { - bool ret = false; - for(size_t i = 0; i < array->len; i++) ret = ret || test(ARRAY_GET(array, i), i, array); - return ret; -} - -static bool keke_array_all(struct KekeArray *array, Test_func test) { - bool ret = true; - for(size_t i = 0; i < array->len; i++) ret = ret && test(ARRAY_GET(array, i), i, array); - return ret; -} - -static struct KekeArray *keke_array_filter(struct KekeArray *array, Test_func test) { - struct KekeArray *ret = keke_array_alloc(0, array->type_size); - for(size_t i = 0; i < array->len; i++) { - if(test(ARRAY_GET(array, i), i, array)) { - keke_array_push(ret, ARRAY_GET(array, i)); - } - } - return ret; -} +struct KekeArray *keke_array_filter(struct KekeArray *array, Test_func test); typedef void (*B_func)(void *, void *); - -static void keke_array_reduce(struct KekeArray *array, B_func op, void *acc) { - for(size_t i = 0; i < array->len; i++) op(ARRAY_GET(array, i), acc); -} - -#undef ARRAY_GET +void keke_array_reduce(struct KekeArray *array, B_func op, void *acc); #endif diff --git a/test.sh b/test.sh deleted file mode 100755 index 9c9589c..0000000 --- a/test.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash -test "$1" = "" && exit 1 -test -f test_$1 && rm test_$1 -cc=clang -test "" = "$(which clang 2>&1)" && cc=gcc -$cc -O2 -Wall -Wextra -Wno-c2x-extensions -o test_$1 test_$1.c -./test_$1