diff --git a/.gitignore b/.gitignore index 9daeafb..deb6f3f 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -test +test_array diff --git a/libkeke_array.h b/libkeke_array.h index db9a5ca..6db15c3 100644 --- a/libkeke_array.h +++ b/libkeke_array.h @@ -3,7 +3,12 @@ #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; @@ -13,7 +18,7 @@ struct KekeArray { }; static void *keke_array_alloc(size_t initial_len, size_t type_size) { - if(initial_len == 0) initial_len = 1; + //if(initial_len == 0) initial_len = 1; struct KekeArray *array = malloc(sizeof(*array)); array->len = initial_len; size_t max_len = 1; @@ -44,12 +49,12 @@ static void keke_array_set(struct KekeArray *array, size_t index, const void *va static void *keke_array_get(struct KekeArray *array, size_t index) { if(index >= array->len) return NULL; // is ur fault - return array->content + array->type_size * index; + 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->content + array->type_size * index, array->type_size); + memcpy(value, ARRAY_GET(array, index), array->type_size); return 0; } @@ -117,10 +122,10 @@ static int keke_array_plop(struct KekeArray *array, size_t index, struct KekeArr return 0; } -typedef void (*Callback_func)(void *, size_t, struct KekeArray *); +typedef void (*Foreach_func)(void *, size_t, struct KekeArray *); -static void keke_array_foreach(struct KekeArray *array, Callback_func callback) { - for(size_t i = 0; i < array->len; i++) callback(keke_array_get(array, i), i, 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) { @@ -131,4 +136,46 @@ static struct KekeArray *keke_array_clone(struct KekeArray *array) { 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); + } +} + +typedef bool (*Test_func)(void *, size_t, struct KekeArray *); + +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; +} + +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 + #endif diff --git a/libkeke_utils.h b/libkeke_utils.h new file mode 100644 index 0000000..7d44f30 --- /dev/null +++ b/libkeke_utils.h @@ -0,0 +1,18 @@ +#ifndef LIBKEKE_UTILS +#define LIBKEKE_UTILS + +#include + +#define BOOL_PRETTY(b) (b ? "True" : "False") + +static void keke_swap(void *a, void *b, size_t size) { + char *aa = a; + char *bb = b; + for(size_t i = 0; i < size; i++) { + aa[i] ^= bb[i]; + bb[i] ^= aa[i]; + aa[i] ^= bb[i]; + } +} + +#endif diff --git a/test.sh b/test.sh index cbe359c..9c9589c 100755 --- a/test.sh +++ b/test.sh @@ -1,6 +1,7 @@ #!/bin/bash -rm test +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 test.c -./test +$cc -O2 -Wall -Wextra -Wno-c2x-extensions -o test_$1 test_$1.c +./test_$1 diff --git a/test.c b/test_array.c similarity index 63% rename from test.c rename to test_array.c index 83a8bf5..5ff0f89 100644 --- a/test.c +++ b/test_array.c @@ -3,6 +3,7 @@ #include #include #include "libkeke_array.h" +#include "libkeke_utils.h" #define ARRAY_LEN 10 @@ -14,9 +15,27 @@ void output(void *i, size_t, struct KekeArray *) { printf("%d, ", *(int *)i); } +void sub4(void *i, size_t, struct KekeArray *) { + *(int *)i -= 4; +} + +bool heart(void *i, size_t, struct KekeArray *) { + return *(int *)i < 3; +} + +void add(void *vx, void *vacc) { + int *x = (int *)vx; + int *acc = (int *)vacc; + *acc += *x; +} + int main(void) { struct KekeArray *array = keke_array_alloc(ARRAY_LEN, sizeof(int)); + puts("Expected value:\n0"); + printf("%d", *(int *)keke_array_get(array, 0)); //initialized to 0 + puts("\n"); + keke_array_foreach(array, set); puts("Expected value:\n9, 8, 7, 6, 5, 4, 3, 2, 1, 0,"); keke_array_foreach(array, output); @@ -75,9 +94,39 @@ int main(void) { puts("Expected value:\n9, 8, 0, 0, 6,"); keke_array_foreach(array, output); puts("\n"); + + keke_array_fill(array, &j); + puts("Expected value:\n6, 6, 6, 6, 6,"); + keke_array_foreach(array, output); + puts("\n"); + + keke_array_reverse(array2); + puts("Expected value:\n6, 6, 5, 6, 7, 7,"); + keke_array_foreach(array2, output); + puts("\n"); + + keke_array_foreach(array2, sub4); + puts("Expected value:\n2, 2, 1, 2, 3, 3,"); + keke_array_foreach(array2, output); + puts("\n"); + + bool h = keke_array_some(array2, heart); + bool g = keke_array_all(array2, heart); + puts("Expected value:\nTrue, False"); + printf("%s, %s\n\n", BOOL_PRETTY(h), BOOL_PRETTY(g)); + + struct KekeArray *array4 = keke_array_filter(array2, heart); + puts("Expected value:\n2, 2, 1, 2,"); + keke_array_foreach(array4, output); + puts("\n"); + + j = 0; + keke_array_reduce(array4, add, &j); + printf("Expected value:\n7\n%d\n\n", j); keke_array_free(array); keke_array_free(array2); + keke_array_free(array4); puts("\n"); return 0; }