summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorJonathan Bradley <jcb@pikum.xyz>2025-08-26 13:23:37 -0400
committerJonathan Bradley <jcb@pikum.xyz>2025-08-26 13:23:37 -0400
commit78956339691db1fb0de02e63823dc9100c0cd7e7 (patch)
treebf8aef0abcbe2b55d19a3ba04e809c571a2c995e /test
parent488ee1d60e32502645d4fce9a8261b012ec1ba6a (diff)
pkiter: add iterator for pkarr and pkbktarr
Diffstat (limited to 'test')
-rw-r--r--test/pkarr.c101
-rw-r--r--test/pkarr.cpp87
-rw-r--r--test/pkbktarr.c133
-rw-r--r--test/pkbktarr.cpp140
4 files changed, 459 insertions, 2 deletions
diff --git a/test/pkarr.c b/test/pkarr.c
index 74ff27d..25ae171 100644
--- a/test/pkarr.c
+++ b/test/pkarr.c
@@ -1,6 +1,7 @@
// NOTE: only intended for performance testing
// TODO: move flag to compiler and run tests more than once for full coverage
+#define PK_IMPL_ITER
#define PK_ARR_MOVE_IN_PLACE
#define PK_IMPL_MEM
#define PK_IMPL_ARR
@@ -13,8 +14,8 @@
* When compiling with `-O3`, one (or maybe more?) of the tests fails
* The issue is resolved now; leaving this for testing purposes.
*/
-#undef PK_LOGV_INF
-#define PK_LOGV_INF(str, ...) (void)str
+// #undef PK_LOGV_INF
+// #define PK_LOGV_INF(str, ...) (void)str
struct some_complex_struct {
char uhh;
@@ -307,5 +308,101 @@ int main(int argc, char *argv[])
}
PK_LOGV_INF("%s", "[init via append, soft clear] end\n\n");
+ PK_LOGV_INF("%s", "[iter forward] begin\n");
+ {
+ bool res;
+ test_spinup(&arr, &bkt);
+ arr.stride = sizeof(uint8_t);
+ arr.alignment = alignof(uint8_t);
+
+ for (i = 4; i > 0; --i) {
+ uint8_t u = (uint8_t)i - 1;
+ pk_arr_append(&arr, &u);
+ }
+
+ struct pk_iter it;
+ res = pk_arr_iter_begin(&arr, &it);
+ if (res == false) exit(1);
+ if (it.data == nullptr) exit(1);
+ if (it.id.arr.i != 0) exit(1);
+ if (*(uint8_t*)it.data != 3) exit(1);
+ PK_LOGV_INF("iter.data: %p iter.val: %i\n", it.data, *(uint8_t*)it.data);
+
+ res = pk_arr_iter_increment(&arr, &it);
+ if (res == false) exit(1);
+ if (it.data == nullptr) exit(1);
+ if (it.id.arr.i != 1) exit(1);
+ if (*(uint8_t*)it.data != 2) exit(1);
+ PK_LOGV_INF("iter.data: %p iter.val: %i\n", it.data, *(uint8_t*)it.data);
+
+ res = pk_arr_iter_increment(&arr, &it);
+ if (res == false) exit(1);
+ if (it.data == nullptr) exit(1);
+ if (it.id.arr.i != 2) exit(1);
+ if (*(uint8_t*)it.data != 1) exit(1);
+ PK_LOGV_INF("iter.data: %p iter.val: %i\n", it.data, *(uint8_t*)it.data);
+
+ res = pk_arr_iter_increment(&arr, &it);
+ if (res == false) exit(1);
+ if (it.data == nullptr) exit(1);
+ if (it.id.arr.i != 3) exit(1);
+ if (*(uint8_t*)it.data != 0) exit(1);
+ PK_LOGV_INF("iter.data: %p iter.val: %i\n", it.data, *(uint8_t*)it.data);
+
+ res = pk_arr_iter_increment(&arr, &it);
+ if (res == true) exit(1);
+
+ test_teardown(&arr, &bkt);
+ }
+ PK_LOGV_INF("%s", "[iter forward] end\n\n");
+
+ PK_LOGV_INF("%s", "[iter reverse] begin\n");
+ {
+ bool res;
+ test_spinup(&arr, &bkt);
+ arr.stride = sizeof(uint8_t);
+ arr.alignment = alignof(uint8_t);
+
+ for (i = 4; i > 0; --i) {
+ uint8_t u = (uint8_t)i - 1;
+ pk_arr_append(&arr, &u);
+ }
+
+ struct pk_iter it;
+ res = pk_arr_iter_end(&arr, &it);
+ if (res == false) exit(1);
+ if (it.data == nullptr) exit(1);
+ if (it.id.arr.i != 3) exit(1);
+ if (*(uint8_t*)it.data != 0) exit(1);
+ PK_LOGV_INF("iter.data: %p iter.val: %i\n", it.data, *(uint8_t*)it.data);
+
+ res = pk_arr_iter_decrement(&arr, &it);
+ if (res == false) exit(1);
+ if (it.data == nullptr) exit(1);
+ if (it.id.arr.i != 2) exit(1);
+ if (*(uint8_t*)it.data != 1) exit(1);
+ PK_LOGV_INF("iter.data: %p iter.val: %i\n", it.data, *(uint8_t*)it.data);
+
+ res = pk_arr_iter_decrement(&arr, &it);
+ if (res == false) exit(1);
+ if (it.data == nullptr) exit(1);
+ if (it.id.arr.i != 1) exit(1);
+ if (*(uint8_t*)it.data != 2) exit(1);
+ PK_LOGV_INF("iter.data: %p iter.val: %i\n", it.data, *(uint8_t*)it.data);
+
+ res = pk_arr_iter_decrement(&arr, &it);
+ if (res == false) exit(1);
+ if (it.data == nullptr) exit(1);
+ if (it.id.arr.i != 0) exit(1);
+ if (*(uint8_t*)it.data != 3) exit(1);
+ PK_LOGV_INF("iter.data: %p iter.val: %i\n", it.data, *(uint8_t*)it.data);
+
+ res = pk_arr_iter_decrement(&arr, &it);
+ if (res == true) exit(1);
+
+ test_teardown(&arr, &bkt);
+ }
+ PK_LOGV_INF("%s", "[iter reverse] end\n\n");
+
return 0;
}
diff --git a/test/pkarr.cpp b/test/pkarr.cpp
index 4b03922..db42ad8 100644
--- a/test/pkarr.cpp
+++ b/test/pkarr.cpp
@@ -1,4 +1,5 @@
+#define PK_IMPL_ITER
#define PK_IMPL_MEM
#define PK_IMPL_ARR
@@ -155,6 +156,92 @@ int main(int argc, char *argv[])
fprintf(stdout, "[%s] Ending move assignment test\n\n", __FILE__);
test_teardown(&bkt);
+ test_spinup(&bkt);
+ fprintf(stdout, "[%s] Starting iter forward test\n", __FILE__);
+ {
+ bool res;
+ uint8_t u, u2;
+ pk_arr_t<uint8_t> arr(bkt);
+ for (u = 4; u > 0; --u) {
+ u2 = u - 1;
+ pk_arr_append_t(&arr, u2);
+ }
+
+ struct pk_iter_t<uint8_t> it;
+ res = pk_arr_iter_begin(&arr, &it);
+ if (res == false) exit(1);
+ if (it.id.arr.i != 0) exit(1);
+ if (it != 3) exit(1);
+ PK_LOGV_INF("iter.data: %p iter.val: %i\n", it.data, *(uint8_t*)it.data);
+
+ res = pk_arr_iter_increment(&arr, &it);
+ if (res == false) exit(1);
+ if (it.id.arr.i != 1) exit(1);
+ if (it != 2) exit(1);
+ PK_LOGV_INF("iter.data: %p iter.val: %i\n", it.data, *(uint8_t*)it.data);
+
+ res = pk_arr_iter_increment(&arr, &it);
+ if (res == false) exit(1);
+ if (it.id.arr.i != 2) exit(1);
+ if (it != 1) exit(1);
+ PK_LOGV_INF("iter.data: %p iter.val: %i\n", it.data, *(uint8_t*)it.data);
+
+ res = pk_arr_iter_increment(&arr, &it);
+ if (res == false) exit(1);
+ if (it.id.arr.i != 3) exit(1);
+ if (it != 0) exit(1);
+ PK_LOGV_INF("iter.data: %p iter.val: %i\n", it.data, *(uint8_t*)it.data);
+
+ res = pk_arr_iter_increment(&arr, &it);
+ if (res == true) exit(1);
+
+ }
+ fprintf(stdout, "[%s] Ending iter forward test\n\n", __FILE__);
+ test_teardown(&bkt);
+
+ test_spinup(&bkt);
+ fprintf(stdout, "[%s] Starting iter reverse test\n", __FILE__);
+ {
+ bool res;
+ uint8_t u, u2;
+ pk_arr_t<uint8_t> arr(bkt);
+ for (u = 4; u > 0; --u) {
+ u2 = u - 1;
+ pk_arr_append_t(&arr, u2);
+ }
+
+ struct pk_iter_t<uint8_t> it;
+ res = pk_arr_iter_end(&arr, &it);
+ if (res == false) exit(1);
+ if (it.id.arr.i != 3) exit(1);
+ if (it != 0) exit(1);
+ PK_LOGV_INF("iter.data: %p iter.val: %i\n", it.data, *(uint8_t*)it.data);
+
+ res = pk_arr_iter_decrement(&arr, &it);
+ if (res == false) exit(1);
+ if (it.id.arr.i != 2) exit(1);
+ if (it != 1) exit(1);
+ PK_LOGV_INF("iter.data: %p iter.val: %i\n", it.data, *(uint8_t*)it.data);
+
+ res = pk_arr_iter_decrement(&arr, &it);
+ if (res == false) exit(1);
+ if (it.id.arr.i != 1) exit(1);
+ if (it != 2) exit(1);
+ PK_LOGV_INF("iter.data: %p iter.val: %i\n", it.data, *(uint8_t*)it.data);
+
+ res = pk_arr_iter_decrement(&arr, &it);
+ if (res == false) exit(1);
+ if (it.id.arr.i != 0) exit(1);
+ if (it != 3) exit(1);
+ PK_LOGV_INF("iter.data: %p iter.val: %i\n", it.data, *(uint8_t*)it.data);
+
+ res = pk_arr_iter_decrement(&arr, &it);
+ if (res == true) exit(1);
+
+ }
+ fprintf(stdout, "[%s] Ending iter reverse test\n\n", __FILE__);
+ test_teardown(&bkt);
+
fprintf(stdout, "[%s] End\n", __FILE__);
return 0;
diff --git a/test/pkbktarr.c b/test/pkbktarr.c
index 6767cbc..012bc90 100644
--- a/test/pkbktarr.c
+++ b/test/pkbktarr.c
@@ -1,5 +1,6 @@
#include "../pkmem.h"
+#define PK_IMPL_ITER
#define PK_IMPL_MEM
#define PK_IMPL_BKTARR
#include "../pkbktarr.h"
@@ -470,6 +471,138 @@ int main(int argc, char *argv[])
while (false);
test_teardown(&bkt_buckets, &bkt_data);
+ fprintf(stdout, "[%s] test iter forwards w/ empty slot begin\n", __FILE__);
+ test_spinup(&bkt_buckets, &bkt_data);
+ {
+ assert(bkt_buckets != nullptr);
+ assert(bkt_data != nullptr);
+ uint8_t u;
+ bool b;
+ struct pk_bkt_arr arr = {0};
+ struct pk_bkt_arr_handle h;
+ struct pk_bkt_arr_handle limits;
+ limits.b = 1;
+ limits.i = 5;
+
+ pk_bkt_arr_init(&arr, sizeof(uint8_t), alignof(uint8_t), limits, bkt_buckets, bkt_data);
+
+ for (u = 0; u < 5; ++u) {
+ h = pk_bkt_arr_new_handle(&arr);
+ uint8_t *typed_arr = (uint8_t*)arr.bucketed_data[h.b];
+ typed_arr[h.i] = u;
+ }
+
+ h.b = 0;
+ h.i = 2;
+ pk_bkt_arr_free_handle(&arr, h);
+
+ struct pk_iter it;
+ b = pk_bkt_arr_iter_begin(&arr, &it);
+ if (b == false) exit(1);
+ if (it.data == nullptr) exit(1);
+ if (it.id.bkt.b != 0) exit(1);
+ if (it.id.bkt.i != 0) exit(1);
+ if (*(uint8_t*)it.data != 0) exit(1);
+ fprintf(stdout, "it.data: %p, val: %i\n", it.data, *(uint8_t*)it.data);
+
+ b = pk_bkt_arr_iter_increment(&arr, &it);
+ if (b == false) exit(1);
+ if (it.data == nullptr) exit(1);
+ if (it.id.bkt.b != 0) exit(1);
+ if (it.id.bkt.i != 1) exit(1);
+ if (*(uint8_t*)it.data != 1) exit(1);
+ fprintf(stdout, "it.data: %p, val: %i\n", it.data, *(uint8_t*)it.data);
+
+ b = pk_bkt_arr_iter_increment(&arr, &it);
+ if (b == false) exit(1);
+ if (it.data == nullptr) exit(1);
+ if (it.id.bkt.b != 0) exit(1);
+ if (it.id.bkt.i != 3) exit(1);
+ if (*(uint8_t*)it.data != 3) exit(1);
+ fprintf(stdout, "it.data: %p, val: %i\n", it.data, *(uint8_t*)it.data);
+
+ b = pk_bkt_arr_iter_increment(&arr, &it);
+ if (b == false) exit(1);
+ if (it.data == nullptr) exit(1);
+ if (it.id.bkt.b != 0) exit(1);
+ if (it.id.bkt.i != 4) exit(1);
+ if (*(uint8_t*)it.data != 4) exit(1);
+ fprintf(stdout, "it.data: %p, val: %i\n", it.data, *(uint8_t*)it.data);
+
+ b = pk_bkt_arr_iter_increment(&arr, &it);
+ if (b == true) exit(1);
+
+ pk_bkt_arr_teardown(&arr);
+ }
+ fprintf(stdout, "[%s] test iter forwards w/ empty slot end\n\n", __FILE__);
+ test_teardown(&bkt_buckets, &bkt_data);
+
+ fprintf(stdout, "[%s] test iter reverse w/ empty slot begin\n", __FILE__);
+ test_spinup(&bkt_buckets, &bkt_data);
+ {
+ assert(bkt_buckets != nullptr);
+ assert(bkt_data != nullptr);
+ uint8_t u;
+ bool b;
+ struct pk_bkt_arr arr = {0};
+ struct pk_bkt_arr_handle h;
+ struct pk_bkt_arr_handle limits;
+ limits.b = 1;
+ limits.i = 5;
+
+ pk_bkt_arr_init(&arr, sizeof(uint8_t), alignof(uint8_t), limits, bkt_buckets, bkt_data);
+
+ for (u = 0; u < 5; ++u) {
+ h = pk_bkt_arr_new_handle(&arr);
+ uint8_t *typed_arr = (uint8_t*)arr.bucketed_data[h.b];
+ typed_arr[h.i] = u;
+ }
+
+ h.b = 0;
+ h.i = 2;
+ pk_bkt_arr_free_handle(&arr, h);
+
+ struct pk_iter it;
+ b = pk_bkt_arr_iter_end(&arr, &it);
+ if (b == false) exit(1);
+ if (it.data == nullptr) exit(1);
+ if (it.id.bkt.b != 0) exit(1);
+ if (it.id.bkt.i != 4) exit(1);
+ if (*(uint8_t*)it.data != 4) exit(1);
+ fprintf(stdout, "it.data: %p, val: %i\n", it.data, *(uint8_t*)it.data);
+
+ b = pk_bkt_arr_iter_decrement(&arr, &it);
+ if (b == false) exit(1);
+ if (it.data == nullptr) exit(1);
+ if (it.id.bkt.b != 0) exit(1);
+ if (it.id.bkt.i != 3) exit(1);
+ if (*(uint8_t*)it.data != 3) exit(1);
+ fprintf(stdout, "it.data: %p, val: %i\n", it.data, *(uint8_t*)it.data);
+
+ b = pk_bkt_arr_iter_decrement(&arr, &it);
+ if (b == false) exit(1);
+ if (it.data == nullptr) exit(1);
+ if (it.id.bkt.b != 0) exit(1);
+ if (it.id.bkt.i != 1) exit(1);
+ if (*(uint8_t*)it.data != 1) exit(1);
+ fprintf(stdout, "it.data: %p, val: %i\n", it.data, *(uint8_t*)it.data);
+
+ b = pk_bkt_arr_iter_decrement(&arr, &it);
+ if (b == false) exit(1);
+ if (it.data == nullptr) exit(1);
+ if (it.id.bkt.b != 0) exit(1);
+ if (it.id.bkt.i != 0) exit(1);
+ if (*(uint8_t*)it.data != 0) exit(1);
+ fprintf(stdout, "it.data: %p, val: %i\n", it.data, *(uint8_t*)it.data);
+
+ b = pk_bkt_arr_iter_decrement(&arr, &it);
+ if (b == true) exit(1);
+
+ pk_bkt_arr_teardown(&arr);
+ }
+ test_teardown(&bkt_buckets, &bkt_data);
+ fprintf(stdout, "[%s] test iter reverse w/ empty slot end\n\n", __FILE__);
+
return 0;
uncaught_err:
PK_LOGV_ERR("%s: failed to catch err.\n", __FILE__);
diff --git a/test/pkbktarr.cpp b/test/pkbktarr.cpp
index 23a7132..db30e56 100644
--- a/test/pkbktarr.cpp
+++ b/test/pkbktarr.cpp
@@ -1,6 +1,7 @@
#include "../pkmem.h"
#include "../pktmpln.h"
+#define PK_IMPL_ITER
#define PK_IMPL_MEM
#define PK_IMPL_BKTARR
#include "../pkbktarr.h"
@@ -135,4 +136,143 @@ int main(int argc, char *argv[])
if (bkt_data->alloc_count != 0) exit(1);
}
test_teardown(&bkt_buckets, &bkt_data);
+
+ // test pointers
+ test_spinup(&bkt_buckets, &bkt_data);
+ {
+ assert(bkt_buckets != nullptr);
+ assert(bkt_data != nullptr);
+ const int base_array_len = 16;
+ int i;
+ struct pk_bkt_arr_t<int *> arr(pk_bkt_arr_handle_MAX_constexpr, bkt_buckets, bkt_data);
+
+ for (i = 0; i < base_array_len; ++i) {
+ auto handle = pk_bkt_arr_new_handle(&arr);
+ arr[handle] = new int{i};
+ }
+
+ pk_bkt_arr_t<int*>::FN_Iter cb_wrapper{};
+ i = 0;
+ cb_wrapper.func = [&i](int **lhs)
+ {
+ int *val_ptr = *lhs;
+ int val = *val_ptr;
+ if (val != i) {
+ fprintf(stderr, "[pkbktarr.cpp] int pointer did not match, expected: %i, got: %i", i, val);
+ exit(1);
+ }
+ i += 1;
+ return;
+ };
+ pk_bkt_arr_iterate(&arr, &pk_bkt_arr_t<int>::FN_Iter::invoke, &cb_wrapper);
+
+ arr.~pk_bkt_arr_t<int*>();
+ if (bkt_buckets->alloc_count != 0) exit(1);
+ if (bkt_data->alloc_count != 0) exit(1);
+ }
+ test_teardown(&bkt_buckets, &bkt_data);
+
+ fprintf(stdout, "[%s] test iter forwards w/ empty slot begin\n", __FILE__);
+ test_spinup(&bkt_buckets, &bkt_data);
+ {
+ assert(bkt_buckets != nullptr);
+ assert(bkt_data != nullptr);
+ uint8_t u, uu;
+ bool b;
+ struct pk_bkt_arr_handle h;
+ struct pk_bkt_arr_handle limits;
+ limits.b = 2;
+ limits.i = 5;
+ struct pk_bkt_arr_t<uint8_t> arr(limits, bkt_buckets, bkt_data);
+
+ for (u = 0; u < limits.b; ++u) {
+ for (uu = 0; uu < limits.i; ++uu) {
+ h = pk_bkt_arr_new_handle(&arr);
+ arr[h] = uu;
+ }
+ }
+
+ h.b = 0;
+ h.i = 2;
+ pk_bkt_arr_free_handle(&arr, h);
+ h.b = 1;
+ pk_bkt_arr_free_handle(&arr, h);
+
+ struct pk_iter_t<uint8_t> it;
+
+ for (u = 0; u < limits.b; ++u) {
+ for (uu = 0; uu < limits.i; ++uu) {
+ if (uu == 2) continue;
+ if (u == 0 && uu == 0) {
+ b = pk_bkt_arr_iter_begin(&arr, &it);
+ } else {
+ b = pk_bkt_arr_iter_increment(&arr, &it);
+ }
+ if (b == false) exit(1);
+ fprintf(stdout, "it.data: %p, val: %i\n", it.data, *(uint8_t*)it.data);
+ if (it.id.bkt.b != u) exit(1);
+ if (it.id.bkt.i != uu) exit(1);
+ if (it != uu) exit(1);
+ }
+ }
+
+ b = pk_bkt_arr_iter_increment(&arr, &it);
+ if (b == true) exit(1);
+
+ pk_bkt_arr_teardown(&arr);
+ }
+ fprintf(stdout, "[%s] test iter forwards w/ empty slot end\n\n", __FILE__);
+ test_teardown(&bkt_buckets, &bkt_data);
+
+ fprintf(stdout, "[%s] test iter reverse w/ empty slot begin\n", __FILE__);
+ test_spinup(&bkt_buckets, &bkt_data);
+ {
+ assert(bkt_buckets != nullptr);
+ assert(bkt_data != nullptr);
+ uint8_t u, uu;
+ bool b;
+ struct pk_bkt_arr_handle h;
+ struct pk_bkt_arr_handle limits;
+ limits.b = 2;
+ limits.i = 5;
+ pk_bkt_arr_t<uint8_t> arr(limits, bkt_buckets, bkt_data);
+
+ for (u = 0; u < 5; ++u) {
+ for (uu = 0; uu < 5; ++uu) {
+ h = pk_bkt_arr_new_handle(&arr);
+ arr[h] = uu;
+ }
+ }
+
+ h.b = 0;
+ h.i = 2;
+ pk_bkt_arr_free_handle(&arr, h);
+ h.b = 1;
+ pk_bkt_arr_free_handle(&arr, h);
+
+ struct pk_iter_t<uint8_t> it;
+
+ for (u = limits.b; u > 0; --u) {
+ for (uu = limits.i; uu > 0; --uu) {
+ if (uu-1 == 2) continue;
+ if (u == limits.b && uu == limits.i) {
+ b = pk_bkt_arr_iter_end(&arr, &it);
+ } else {
+ b = pk_bkt_arr_iter_decrement(&arr, &it);
+ }
+ if (b == false) exit(1);
+ fprintf(stdout, "it.data: %p, val: %i\n", it.data, *(uint8_t*)it.data);
+ if (it.id.bkt.b != u-1) exit(1);
+ if (it.id.bkt.i != uu-1) exit(1);
+ if (it != uu-1) exit(1);
+ }
+ }
+
+ b = pk_bkt_arr_iter_decrement(&arr, &it);
+ if (b == true) exit(1);
+
+ pk_bkt_arr_teardown(&arr);
+ }
+ test_teardown(&bkt_buckets, &bkt_data);
+ fprintf(stdout, "[%s] test iter reverse w/ empty slot end\n\n", __FILE__);
}