diff --git a/libkeke_array.c b/libkeke_array.c index 204be33..6a4227d 100644 --- a/libkeke_array.c +++ b/libkeke_array.c @@ -190,12 +190,30 @@ int compar(const void *a, const void *b, void *size_v) { #if defined(__BYTE_ORDER__)&&(__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) return memcmp(a, b, size); #else - const signed char *aa = a; + /*const signed char *aa = a; const signed char *bb = b; for(size_t i = 0; i < size; ++i) { size_t s = size - i - 1; if(aa[s] != bb[s]) return aa[s] - bb[s]; } + return 0;*/ + size_t rem = size % sizeof(int); + if(rem) { + size -= rem; + const char *c = a; + const char *d = b; + for(size_t i = 1; i <= rem; ++i) { + char j = c[size + rem - i] - d[size + rem - i]; + if(j != 0) return j; + } + } + const int *ia = a; + const int *ib = b; + size /= sizeof(int); + for(size_t i = 1; i <= size; ++i) { + int j = ia[size - i] - ib[size - i]; + if(j != 0) return j; + } return 0; #endif } @@ -256,6 +274,44 @@ KekeArray *keke_array_merge(KekeArray *a, KekeArray *b) { return c; } +KekeArray *keke_array_merge_by_header(KekeArray *a, KekeArray *b, size_t header_size) { + if(a->len == 0) { + KekeArray *r = keke_array_clone(b); + keke_array_set_len(b, 0); + return r; + } + if(b->len == 0) { + KekeArray *r = keke_array_clone(a); + keke_array_set_len(a, 0); + return r; + } + keke_array_reverse(a); + keke_array_reverse(b); + if(a->type_size != b->type_size) return NULL; + KekeArray *c = keke_array_alloc(a->len + b->len, a->type_size); + keke_array_set_len(c, 0); + void *s = malloc(a->type_size); + while(!!(a->len) && !!(b->len)) { + if(compar(ARRAY_GET(a, a->len - 1), ARRAY_GET(b, b->len - 1), &header_size) <= 0) { + keke_array_pop(a, s) ; + keke_array_push(c, s); + } else { + keke_array_pop(b, s); + keke_array_push(c, s); + } + } + while(a->len) { + keke_array_pop(a, s); + keke_array_push(c, s); + } + while(b->len) { + keke_array_pop(b, s); + keke_array_push(c, s); + } + free(s); + return c; +} + KekeArray *keke_array_filter(KekeArray *array, Test_func test) { KekeArray *ret = keke_array_alloc(0, array->type_size); for(size_t i = 0; i < array->len; i++) { diff --git a/libkeke_array.h b/libkeke_array.h index 2bdf804..f153c75 100644 --- a/libkeke_array.h +++ b/libkeke_array.h @@ -40,6 +40,7 @@ void keke_array_reverse(KekeArray *array); void keke_array_qsort(KekeArray *array); void keke_array_qsort_header(KekeArray *array, size_t start_header_size); KekeArray *keke_array_merge(KekeArray *a, KekeArray *b); +KekeArray *keke_array_merge_by_header(KekeArray *a, KekeArray *b, size_t start_header_size); typedef int (*Rng_fun)(int); void keke_array_shuffle(KekeArray *array, Rng_fun rng); diff --git a/test_array.c b/test_array.c index d2fb0c6..a7127da 100644 --- a/test_array.c +++ b/test_array.c @@ -6,15 +6,24 @@ #include "libkeke_utils.h" #define ARRAY_LEN 10 +#define ARRAY_ALT_LEN 512 void set(void *, size_t index, KekeArray *array) { keke_array_set(array, ARRAY_LEN - index - 1, &index); } +void set_alt(void *, size_t index, KekeArray *array) { + keke_array_set(array, ARRAY_ALT_LEN - index - 1, &index); +} + void output(void *i, size_t, KekeArray *) { printf("%d, ", *(int *)i); } +void output_hex(void *i, size_t, KekeArray *) { + printf("%x, ", *(int *)i); +} + void sub4(void *i, size_t, KekeArray *) { *(int *)i -= 4; } @@ -23,6 +32,10 @@ void add250(void *i, size_t, KekeArray *) { *(int *)i += 250; } +void sub250(void *i, size_t, KekeArray *) { + *(int *)i -= 250; +} + bool heart(void *i, size_t, KekeArray *) { return *(int *)i < 3; } diff --git a/test_array_u64.c b/test_array_u64.c new file mode 100644 index 0000000..f83a8d6 --- /dev/null +++ b/test_array_u64.c @@ -0,0 +1,197 @@ +#include +#include +#include +#include +#include "libkeke_array.h" +#include "libkeke_utils.h" + +#define ARRAY_LEN 10 +#define ARRAY_ALT_LEN 512 + +void set(void *, size_t index, KekeArray *array) { + keke_array_set(array, ARRAY_LEN - index - 1, &index); +} + +void set_alt(void *, size_t index, KekeArray *array) { + keke_array_set(array, ARRAY_ALT_LEN - index - 1, &index); +} + +void output(void *i, size_t, KekeArray *) { + printf("%lu, ", *(uint64_t *)i); +} + +void output_hex(void *i, size_t, KekeArray *) { + printf("%lx, ", *(uint64_t *)i); +} + +void sub4(void *i, size_t, KekeArray *) { + *(uint64_t *)i -= 4; +} + +void add250(void *i, size_t, KekeArray *) { + *(uint64_t *)i += 250; +} + +void sub250(void *i, size_t, KekeArray *) { + *(uint64_t *)i -= 250; +} + +bool heart(void *i, size_t, KekeArray *) { + return *(uint64_t *)i < 3; +} + +bool lt2(void *i, size_t, KekeArray *) { + return *(uint64_t *)i < 2; +} + +void add(void *vx, void *vacc) { + uint64_t *x = (uint64_t *)vx; + uint64_t *acc = (uint64_t *)vacc; + *acc += *x; +} + +int rng(int x) { + return rand() % x; +} + +int main(void) { + KekeArray *array = keke_array_alloc(ARRAY_LEN, sizeof(uint64_t)); + + puts("Expected value:\n0"); + printf("%lu", *(uint64_t *)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); + puts("\n"); + + KekeArray *array2 = keke_array_yoink(array, 2, 4); + puts("Expected value:\n7, 6, 5, 4,"); + keke_array_foreach(array2, output); + puts("\n"); + puts("Expected value:\n9, 8, 3, 2, 1, 0,"); + keke_array_foreach(array, output); + puts("\n"); + + const uint64_t k = 100; + keke_array_insert(array2, 2, &k); + puts("Expected value:\n7, 6, 100, 5, 4,"); + keke_array_foreach(array2, output); + puts("\n"); + + uint64_t j; + keke_array_remove(array2, 2, &j); + puts("Expected value:\n7, 6, 5, 0,\t100"); + keke_array_foreach(array2, output); + printf("\t%lu", j); + puts("\n"); + + keke_array_delete(array2, 3); + puts("Expected value:\n7, 6, 5"); + keke_array_foreach(array2, output); + puts("\n"); + + KekeArray *array3 = keke_array_clone(array2); + keke_array_plop(array2, 1, array3); //array3 is freed + puts("Expected value:\n7, 7, 6, 5, 6, 5,"); + keke_array_foreach(array2, output); + puts("\n"); + + keke_array_pop(array2, &j); + puts("Expected value:\n7, 7, 6, 5, 6,\t5"); + keke_array_foreach(array2, output); + printf("\t%lu", j); + puts("\n"); + + keke_array_copy(array2, 2, &j); + keke_array_push(array2, &j); + puts("Expected value:\n7, 7, 6, 5, 6, 6,"); + keke_array_foreach(array2, output); + puts("\n"); + + keke_array_set_len(array, 2); + puts("Expected value:\n9, 8,"); + keke_array_foreach(array, output); + puts("\n"); + + keke_array_set(array, 4, &j); + 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"); + + keke_array_qsort(array2); + puts("Expected value:\n1, 2, 2, 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)); + + KekeArray *array4 = keke_array_filter(array2, heart); + puts("Expected value:\n1, 2, 2, 2,"); + keke_array_foreach(array4, output); + puts("\n"); + + uint64_t *l = keke_array_find(array2, lt2); + puts("Expected value:\n1"); + printf("%lu\n\n", *l); + + l = keke_array_find_start(array2, l, sizeof(*l)); + puts("Expected value:\n1"); + printf("%lu\n\n", *l); + + j = 0; + keke_array_reduce(array4, add, &j); + printf("Expected value:\n7\n%lu\n\n", j); + + keke_array_foreach(array, set); + keke_array_qsort(array); + KekeArray *array5 = keke_array_merge(array, array2); + printf("Expected value:\n0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 5, 6, 7, 8, 9,\n"); + keke_array_foreach(array5, output); + puts("\n"); + + keke_array_shuffle(array5, rng); + printf("Expected value:\n2, 0, 3, 7, 3, 1, 8, 2, 2, 1, 3, 5, 6, 2, 9, 4,\n"); + keke_array_foreach(array5, output); + puts("\n"); + + keke_array_foreach(array5, add250); + keke_array_qsort_header(array5, sizeof(uint64_t)); + printf("Expected value:\n250, 251, 251, 252, 252, 252, 252, 253, 253, 253, 254, 255, 256, 257, 258, 259,\n"); + keke_array_foreach(array5, output); + puts("\n"); + + KekeArray *array6 = keke_array_alloc(512, sizeof(uint64_t)); + keke_array_foreach(array6, set_alt); + keke_array_reverse(array6); + keke_array_foreach(array5, sub250); + KekeArray *array7 = keke_array_merge(array6, array5); + keke_array_foreach(array7, output_hex); + puts("\n"); + + keke_array_free(array); + keke_array_free(array2); + keke_array_free(array4); + keke_array_free(array5); + keke_array_free(array6); + return 0; +}