From 4b2389ad627e7093af33031c040920bcc23d7c38 Mon Sep 17 00:00:00 2001 From: laentropia Date: Sun, 19 Apr 2026 12:32:11 -0600 Subject: [PATCH 01/16] feature: Added structure for ArrayListSlices --- include/arraylist.h | 11 ++--------- src/arraylist.c | 8 ++++++++ 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/include/arraylist.h b/include/arraylist.h index 3fbf677..e461e3a 100644 --- a/include/arraylist.h +++ b/include/arraylist.h @@ -7,15 +7,7 @@ typedef struct ArrayList ArrayList; -// FUCK, i forgot one of the main reasons i wanted to -// implement arrays myself was because i needed -// array slices or something like this and i completely -// forgot, fuck, guess i will implement it once i get -// the tests done. -typedef struct { - ArrayList *array; - size_t offset; -} ArrayListSlice; +typedef struct ArrayListSlice ArrayListSlice; typedef enum { ARRLIST_OK = 0, @@ -26,6 +18,7 @@ typedef enum { ARRLIST_NULL_ARG, ARRLIST_INVALID_ELEM_SIZE, ARRLIST_INVALID_CAPACITY, + ARRLIST_IS_BORROWED, } ArrayListErr; ArrayList *arraylist_init(size_t capacity, size_t elem_size); diff --git a/src/arraylist.c b/src/arraylist.c index f29e7b0..b7300ad 100644 --- a/src/arraylist.c +++ b/src/arraylist.c @@ -11,6 +11,14 @@ struct ArrayList{ size_t elem_size; }; +struct ArrayListSlice { + ArrayList *arr; + size_t start; + size_t end; + size_t current; + bool is_safe; +}; + // Grow and shrink factor is 2, 1.5 might give different results i guess // but i'm basing myself in that Rust implementation of array does use // 2 as the factor so i guess is good :) -- 2.51.0 From 04a52e34551768e8fed0c12322b99fdd62d06842 Mon Sep 17 00:00:00 2001 From: laentropia Date: Sun, 19 Apr 2026 21:57:28 -0600 Subject: [PATCH 02/16] addtition: Added function declarations --- include/arraylist.h | 23 ++++++++++++++++++++++- src/arraylist.c | 3 ++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/include/arraylist.h b/include/arraylist.h index e461e3a..93df972 100644 --- a/include/arraylist.h +++ b/include/arraylist.h @@ -7,7 +7,7 @@ typedef struct ArrayList ArrayList; -typedef struct ArrayListSlice ArrayListSlice; +typedef struct ArraySlice ArraySlice; typedef enum { ARRLIST_OK = 0, @@ -24,6 +24,7 @@ typedef enum { ArrayList *arraylist_init(size_t capacity, size_t elem_size); ArrayListErr arraylist_destroy(ArrayList **arr); ArrayListErr arraylist_clear(ArrayList *arr); +ArrayList *arraylist_copy(ArrayList *arr); size_t arraylist_size(const ArrayList *arr); size_t arraylist_capacity(const ArrayList *arr); @@ -44,4 +45,24 @@ ArrayListErr arraylist_set(ArrayList *arr, size_t index, void *data); ArrayListErr arraylist_resize(ArrayList *arr, size_t new_capacity); ArrayListErr arraylist_reserve(ArrayList *arr, size_t size_to_reserve); +//Slice stuff +ArraySlice *arraylist_slice(ArrayList *arr, size_t start, size_t len); +ArraySlice *arraylist_slice_unsafe(ArrayList *arr, size_t start, size_t len); +ArrayListErr arrayslice_destroy(ArraySlice **slice); + +bool arrayslice_is_valid(ArraySlice *slice); +size_t arrayslice_size(ArraySlice *slice); +bool arrayslice_empty(ArraySlice *slice); + +// peek and next can be null, get can't, like, why would you use get without +// actually getting something?, for validating an index?, use size idiot +ArrayListErr *arrayslice_peek(ArraySlice *slice, void *out); +ArrayListErr *arrayslice_next(ArraySlice *slice, void *out); +ArrayListErr *arrayslice_get(ArraySlice *slice, void *out); + +ArrayListErr *arrayslice_reset(ArraySlice *slice); +ArrayListErr *arrayslice_advance(ArraySlice *slice, size_t n); + +ArrayList *arrayslice_to_arraylist(ArraySlice *slice); + #endif diff --git a/src/arraylist.c b/src/arraylist.c index b7300ad..01d0001 100644 --- a/src/arraylist.c +++ b/src/arraylist.c @@ -9,9 +9,10 @@ struct ArrayList{ size_t capacity; size_t len; size_t elem_size; + size_t borrows; }; -struct ArrayListSlice { +struct ArraySlice { ArrayList *arr; size_t start; size_t end; -- 2.51.0 From 6088895ad07ab7bbcbac955fecf1b01222a3c9d8 Mon Sep 17 00:00:00 2001 From: laentropia Date: Mon, 20 Apr 2026 08:43:58 -0600 Subject: [PATCH 03/16] addition: create slice and unsafe, also destroy --- include/arraylist.h | 14 +++--- src/arraylist.c | 115 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 122 insertions(+), 7 deletions(-) diff --git a/include/arraylist.h b/include/arraylist.h index 93df972..60cc16d 100644 --- a/include/arraylist.h +++ b/include/arraylist.h @@ -24,7 +24,7 @@ typedef enum { ArrayList *arraylist_init(size_t capacity, size_t elem_size); ArrayListErr arraylist_destroy(ArrayList **arr); ArrayListErr arraylist_clear(ArrayList *arr); -ArrayList *arraylist_copy(ArrayList *arr); +ArrayList *arraylist_copy(const ArrayList *arr); size_t arraylist_size(const ArrayList *arr); size_t arraylist_capacity(const ArrayList *arr); @@ -50,19 +50,19 @@ ArraySlice *arraylist_slice(ArrayList *arr, size_t start, size_t len); ArraySlice *arraylist_slice_unsafe(ArrayList *arr, size_t start, size_t len); ArrayListErr arrayslice_destroy(ArraySlice **slice); -bool arrayslice_is_valid(ArraySlice *slice); -size_t arrayslice_size(ArraySlice *slice); -bool arrayslice_empty(ArraySlice *slice); +bool arrayslice_is_valid(const ArraySlice *slice); +size_t arrayslice_size(const ArraySlice *slice); +bool arrayslice_empty(const ArraySlice *slice); // peek and next can be null, get can't, like, why would you use get without // actually getting something?, for validating an index?, use size idiot -ArrayListErr *arrayslice_peek(ArraySlice *slice, void *out); +ArrayListErr *arrayslice_peek(const ArraySlice *slice, void *out); ArrayListErr *arrayslice_next(ArraySlice *slice, void *out); -ArrayListErr *arrayslice_get(ArraySlice *slice, void *out); +ArrayListErr *arrayslice_get(const ArraySlice *slice, void *out); ArrayListErr *arrayslice_reset(ArraySlice *slice); ArrayListErr *arrayslice_advance(ArraySlice *slice, size_t n); -ArrayList *arrayslice_to_arraylist(ArraySlice *slice); +ArrayList *arrayslice_to_arraylist(const ArraySlice *slice); #endif diff --git a/src/arraylist.c b/src/arraylist.c index 01d0001..e517f7b 100644 --- a/src/arraylist.c +++ b/src/arraylist.c @@ -60,6 +60,10 @@ ArrayListErr arraylist_destroy(ArrayList **arr) { return ARRLIST_NULL_ARG; } + if ((*arr)->borrows > 0) { + return ARRLIST_IS_BORROWED; + } + // No problem on using free on NULL :) free((*arr)->buffer); free(*arr); @@ -73,6 +77,10 @@ ArrayListErr arraylist_clear(ArrayList *arr) { return ARRLIST_NULL_ARG; } + if (arr->borrows > 0) { + return ARRLIST_IS_BORROWED; + } + arr->len = 0; return ARRLIST_OK; } @@ -140,6 +148,10 @@ ArrayListErr arraylist_push_back(ArrayList *arr, void *data) { return ARRLIST_NULL_ARG; } + if (arr->borrows > 0) { + return ARRLIST_IS_BORROWED; + } + if (arr->len >= arr->capacity) { ArrayListErr err = arraylist_grow(arr); @@ -158,6 +170,10 @@ ArrayListErr arraylist_push_front(ArrayList *arr, void *data) { return ARRLIST_NULL_ARG; } + if (arr->borrows > 0) { + return ARRLIST_IS_BORROWED; + } + if (arr->len >= arr->capacity) { ArrayListErr err = arraylist_grow(arr); @@ -188,6 +204,10 @@ ArrayListErr arraylist_insert(ArrayList *arr, size_t index, void *data) { return ARRLIST_NULL_ARG; } + if (arr->borrows > 0) { + return ARRLIST_IS_BORROWED; + } + if (index > arr->len) { return ARRLIST_OUT_OF_BOUNDS; } @@ -218,6 +238,10 @@ ArrayListErr arraylist_pop_back(ArrayList *arr, void *out) { return ARRLIST_NULL_ARG; } + if (arr->borrows > 0) { + return ARRLIST_IS_BORROWED; + } + if (arr->len < 1) { return ARRLIST_EMPTY; } @@ -246,6 +270,10 @@ ArrayListErr arraylist_pop_front(ArrayList *arr, void *out) { return ARRLIST_NULL_ARG; } + if (arr->borrows > 0) { + return ARRLIST_IS_BORROWED; + } + if (arr->len < 1) { return ARRLIST_EMPTY; } @@ -280,6 +308,10 @@ ArrayListErr arraylist_remove_at(ArrayList *arr, size_t index, void *out) { return ARRLIST_NULL_ARG; } + if (arr->borrows > 0) { + return ARRLIST_IS_BORROWED; + } + if (index >= arr->len) { return ARRLIST_OUT_OF_BOUNDS; } @@ -345,6 +377,10 @@ ArrayListErr arraylist_resize(ArrayList *arr, size_t new_capacity) { return ARRLIST_NULL_ARG; } + if (arr->borrows > 0) { + return ARRLIST_IS_BORROWED; + } + if (new_capacity < 1) { return ARRLIST_INVALID_CAPACITY; } @@ -368,6 +404,10 @@ ArrayListErr arraylist_reserve(ArrayList *arr, size_t size_to_reserve) { return ARRLIST_NULL_ARG; } + if (arr->borrows > 0) { + return ARRLIST_IS_BORROWED; + } + if (arr->capacity + size_to_reserve > SIZE_MAX / arr->elem_size || size_to_reserve > SIZE_MAX / arr->elem_size) { @@ -386,3 +426,78 @@ ArrayListErr arraylist_reserve(ArrayList *arr, size_t size_to_reserve) { arr->capacity += size_to_reserve; return ARRLIST_OK; } + +ArraySlice *arraylist_slice(ArrayList *arr, size_t start, size_t len) { + if (arr == NULL) { + return NULL; + } + + if (arr->len == 0 || len == 0) { + return NULL; + } + + if (start > SIZE_MAX / arr->elem_size || len > SIZE_MAX / arr->elem_size) { + return NULL; + } + + if (start + len > arr->len) { + return NULL; + } + + ArraySlice *slice = malloc(sizeof(ArraySlice)); + if (slice == NULL) { + return NULL; + } + + slice->arr = arr; + slice->start = start; + slice->end = start + len; + slice->current = start; + slice->is_safe = true; + + arr->borrows++; + + return slice; +} + +ArraySlice *arraylist_slice_unsafe(ArrayList *arr, size_t start, size_t len) { + if (arr == NULL) { + return NULL; + } + + if (arr->len == 0 || len == 0) { + return NULL; + } + + if (start > SIZE_MAX / arr->elem_size || len > SIZE_MAX / arr->elem_size) { + return NULL; + } + + if (start + len > arr->len) { + return NULL; + } + + ArraySlice *slice = malloc(sizeof(ArraySlice)); + if (slice == NULL) { + return NULL; + } + + slice->arr = arr; + slice->start = start; + slice->end = start + len; + slice->current = start; + slice->is_safe = false; + + return slice; +} + +ArrayListErr arrayslice_destroy(ArraySlice **slice) { + if (slice == NULL || *slice == NULL) { + return ARRLIST_NULL_ARG; + } + + free(*slice); + *slice = NULL; + + return ARRLIST_OK; +} -- 2.51.0 From dafaa5b87e67753dc5e5d97219906e24475f6194 Mon Sep 17 00:00:00 2001 From: laentropia Date: Tue, 21 Apr 2026 09:10:53 -0600 Subject: [PATCH 04/16] fix: fixed problems with init and destroy slice --- src/arraylist.c | 5 +++++ test/test_arraylist.c | 24 ++++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/src/arraylist.c b/src/arraylist.c index e517f7b..e986ff5 100644 --- a/src/arraylist.c +++ b/src/arraylist.c @@ -46,6 +46,7 @@ ArrayList *arraylist_init(size_t capacity, size_t elem_size) { arr->capacity = capacity; arr->elem_size = elem_size; arr->len = 0; + arr->borrows = 0; arr->buffer = malloc(capacity * elem_size); if (arr->buffer == NULL) { free(arr); @@ -496,6 +497,10 @@ ArrayListErr arrayslice_destroy(ArraySlice **slice) { return ARRLIST_NULL_ARG; } + if ((*slice)->is_safe) { + (*slice)->arr->borrows--; + } + free(*slice); *slice = NULL; diff --git a/test/test_arraylist.c b/test/test_arraylist.c index 42942fb..f12acc6 100644 --- a/test/test_arraylist.c +++ b/test/test_arraylist.c @@ -1014,6 +1014,24 @@ static void test_reserve_size_0(void **state) { arraylist_destroy(&arr); } +// Slice creation +static void test_slice_valid_init(void **state) { + (void) state; + + ArrayList *arr = arraylist_init(64, sizeof(int)); + assert_non_null(arr); + + for (size_t i = 0; i < 10; i++) { + assert_uint_equal(arraylist_push_back(arr, &i), ARRLIST_OK); + } + + ArraySlice *slice = arraylist_slice(arr, 0, 10); + assert_non_null(slice); + + arrayslice_destroy(&slice); + arraylist_destroy(&arr); +} + int main(void) { const struct CMUnitTest init[] = { cmocka_unit_test(test_init_valid_parameters), @@ -1125,6 +1143,10 @@ int main(void) { cmocka_unit_test(test_reserve_size_max), }; + const struct CMUnitTest slice_init[] = { + cmocka_unit_test(test_slice_valid_init), + }; + int rc = 0; rc += cmocka_run_group_tests(init, NULL, NULL); @@ -1142,5 +1164,7 @@ int main(void) { rc += cmocka_run_group_tests(resize, NULL, NULL); rc += cmocka_run_group_tests(reserve, NULL, NULL); + rc += cmocka_run_group_tests(slice_init, NULL, NULL); + return rc; } -- 2.51.0 From b313045153f70d316673655b427d1aaa6662b6b3 Mon Sep 17 00:00:00 2001 From: laentropia Date: Tue, 21 Apr 2026 11:16:11 -0600 Subject: [PATCH 05/16] test: Check for borrows before changing array state --- test/test_arraylist.c | 249 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 249 insertions(+) diff --git a/test/test_arraylist.c b/test/test_arraylist.c index f12acc6..6acc4a2 100644 --- a/test/test_arraylist.c +++ b/test/test_arraylist.c @@ -80,6 +80,26 @@ static void test_destroy_double(void **state) { assert_null(arr); } +static void test_destroy_while_borrowed(void **state) { + (void) state; + + ArrayList *arr = arraylist_init(64, sizeof(int)); + assert_non_null(arr); + + for (int i = 0; i < 10; i++) { + assert_uint_equal(arraylist_push_back(arr, &i), ARRLIST_OK); + } + + ArraySlice *slice = arraylist_slice(arr, 0, arraylist_size(arr)); + assert_non_null(slice); + + + assert_uint_equal(arraylist_destroy(&arr), ARRLIST_IS_BORROWED); + + arrayslice_destroy(&slice); + arraylist_destroy(&arr); +} + // State static void test_capacity_after_init(void **state) { (void) state; @@ -254,6 +274,26 @@ static void test_push_back_null_data(void **state) { arraylist_destroy(&arr); } +static void test_push_back_while_borrowed(void **state) { + (void) state; + + ArrayList *arr = arraylist_init(64, sizeof(int)); + assert_non_null(arr); + + for (int i = 0; i < 10; i++) { + assert_uint_equal(arraylist_push_back(arr, &i), ARRLIST_OK); + } + + ArraySlice *slice = arraylist_slice(arr, 0, arraylist_size(arr)); + assert_non_null(slice); + + int n = 8; + assert_uint_equal(arraylist_push_back(arr, &n), ARRLIST_IS_BORROWED); + + arrayslice_destroy(&slice); + arraylist_destroy(&arr); +} + // Push front static void test_push_front_single_element(void **state) { (void) state; @@ -311,6 +351,26 @@ static void test_push_front_null_data(void **state) { arraylist_destroy(&arr); } +static void test_push_front_while_borrowed(void **state) { + (void) state; + + ArrayList *arr = arraylist_init(64, sizeof(int)); + assert_non_null(arr); + + for (int i = 0; i < 10; i++) { + assert_uint_equal(arraylist_push_back(arr, &i), ARRLIST_OK); + } + + ArraySlice *slice = arraylist_slice(arr, 0, arraylist_size(arr)); + assert_non_null(slice); + + int n = 8; + assert_uint_equal(arraylist_push_front(arr, &n), ARRLIST_IS_BORROWED); + + arrayslice_destroy(&slice); + arraylist_destroy(&arr); +} + // Insert static void test_insert_at_beginning(void **state) { (void) state; @@ -409,6 +469,26 @@ static void test_insert_null_data(void **state) { arraylist_destroy(&arr); } +static void test_insert_while_borrowed(void **state) { + (void) state; + + ArrayList *arr = arraylist_init(64, sizeof(int)); + assert_non_null(arr); + + for (int i = 0; i < 10; i++) { + assert_uint_equal(arraylist_push_back(arr, &i), ARRLIST_OK); + } + + ArraySlice *slice = arraylist_slice(arr, 0, arraylist_size(arr)); + assert_non_null(slice); + + int n = 8; + assert_uint_equal(arraylist_insert(arr, 2, &n), ARRLIST_IS_BORROWED); + + arrayslice_destroy(&slice); + arraylist_destroy(&arr); +} + // Pop back static void test_pop_back_single_element(void **state) { (void) state; @@ -504,6 +584,26 @@ static void test_pop_back_null_out(void **state) { arraylist_destroy(&arr); } +static void test_pop_back_while_borrowed(void **state) { + (void) state; + + ArrayList *arr = arraylist_init(64, sizeof(int)); + assert_non_null(arr); + + for (int i = 0; i < 10; i++) { + assert_uint_equal(arraylist_push_back(arr, &i), ARRLIST_OK); + } + + ArraySlice *slice = arraylist_slice(arr, 0, arraylist_size(arr)); + assert_non_null(slice); + + int n = 8; + assert_uint_equal(arraylist_pop_back(arr, &n), ARRLIST_IS_BORROWED); + + arrayslice_destroy(&slice); + arraylist_destroy(&arr); +} + // Pop front static void test_pop_front_single_element(void **state) { (void) state; @@ -601,6 +701,26 @@ static void test_pop_front_null_out(void **state) { arraylist_destroy(&arr); } +static void test_pop_front_while_borrowed(void **state) { + (void) state; + + ArrayList *arr = arraylist_init(64, sizeof(int)); + assert_non_null(arr); + + for (int i = 0; i < 10; i++) { + assert_uint_equal(arraylist_push_back(arr, &i), ARRLIST_OK); + } + + ArraySlice *slice = arraylist_slice(arr, 0, arraylist_size(arr)); + assert_non_null(slice); + + int n = 8; + assert_uint_equal(arraylist_pop_front(arr, &n), ARRLIST_IS_BORROWED); + + arrayslice_destroy(&slice); + arraylist_destroy(&arr); +} + // Remove at static void test_remove_at_beginning(void **state) { (void) state; @@ -695,6 +815,26 @@ static void test_remove_at_null_data(void **state) { arraylist_destroy(&arr); } +static void test_remove_at_while_borrowed(void **state) { + (void) state; + + ArrayList *arr = arraylist_init(64, sizeof(int)); + assert_non_null(arr); + + for (int i = 0; i < 10; i++) { + assert_uint_equal(arraylist_push_back(arr, &i), ARRLIST_OK); + } + + ArraySlice *slice = arraylist_slice(arr, 0, arraylist_size(arr)); + assert_non_null(slice); + + int n = 8; + assert_uint_equal(arraylist_remove_at(arr, 5, &n), ARRLIST_IS_BORROWED); + + arrayslice_destroy(&slice); + arraylist_destroy(&arr); +} + // Get static void test_get_valid_index(void **state) { (void) state; @@ -788,6 +928,26 @@ static void test_get_null_out(void **state) { arraylist_destroy(&arr); } +static void test_get_while_borrowed(void **state) { + (void) state; + + ArrayList *arr = arraylist_init(64, sizeof(int)); + assert_non_null(arr); + + for (int i = 0; i < 10; i++) { + assert_uint_equal(arraylist_push_back(arr, &i), ARRLIST_OK); + } + + ArraySlice *slice = arraylist_slice(arr, 0, arraylist_size(arr)); + assert_non_null(slice); + + int n = 8; + assert_uint_equal(arraylist_get(arr, 5, &n), ARRLIST_OK); + + arrayslice_destroy(&slice); + arraylist_destroy(&arr); +} + // Set static void test_set_valid_index(void **state) { (void) state; @@ -883,6 +1043,26 @@ static void test_set_null_data(void **state) { arraylist_destroy(&arr); } +static void test_set_while_borrowed(void **state) { + (void) state; + + ArrayList *arr = arraylist_init(64, sizeof(int)); + assert_non_null(arr); + + for (int i = 0; i < 10; i++) { + assert_uint_equal(arraylist_push_back(arr, &i), ARRLIST_OK); + } + + ArraySlice *slice = arraylist_slice(arr, 0, arraylist_size(arr)); + assert_non_null(slice); + + int n = 8; + assert_uint_equal(arraylist_set(arr, 5, &n), ARRLIST_OK); + + arrayslice_destroy(&slice); + arraylist_destroy(&arr); +} + //Clear static void test_clear_non_empty_array(void **state) { (void) state; @@ -920,6 +1100,25 @@ static void test_clear_null_array(void **state) { assert_uint_equal(arraylist_clear(arr), ARRLIST_NULL_ARG); } +static void test_clear_while_borrowed(void **state) { + (void) state; + + ArrayList *arr = arraylist_init(64, sizeof(int)); + assert_non_null(arr); + + for (int i = 0; i < 10; i++) { + assert_uint_equal(arraylist_push_back(arr, &i), ARRLIST_OK); + } + + ArraySlice *slice = arraylist_slice(arr, 0, arraylist_size(arr)); + assert_non_null(slice); + + assert_uint_equal(arraylist_clear(arr), ARRLIST_IS_BORROWED); + + arrayslice_destroy(&slice); + arraylist_destroy(&arr); +} + //Resize static void test_resize_increase_capacity(void **state) { (void) state; @@ -977,6 +1176,25 @@ static void test_resize_null_array(void **state) { assert_uint_equal(arraylist_resize(arr, 65), ARRLIST_NULL_ARG); } +static void test_resize_while_borrowed(void **state) { + (void) state; + + ArrayList *arr = arraylist_init(64, sizeof(int)); + assert_non_null(arr); + + for (int i = 0; i < 10; i++) { + assert_uint_equal(arraylist_push_back(arr, &i), ARRLIST_OK); + } + + ArraySlice *slice = arraylist_slice(arr, 0, arraylist_size(arr)); + assert_non_null(slice); + + assert_uint_equal(arraylist_resize(arr, 128), ARRLIST_IS_BORROWED); + + arrayslice_destroy(&slice); + arraylist_destroy(&arr); +} + // Reserve static void test_reserve_normal_capacity(void **state) { (void) state; @@ -1014,6 +1232,25 @@ static void test_reserve_size_0(void **state) { arraylist_destroy(&arr); } +static void test_reserve_while_borrowed(void **state) { + (void) state; + + ArrayList *arr = arraylist_init(64, sizeof(int)); + assert_non_null(arr); + + for (int i = 0; i < 10; i++) { + assert_uint_equal(arraylist_push_back(arr, &i), ARRLIST_OK); + } + + ArraySlice *slice = arraylist_slice(arr, 0, arraylist_size(arr)); + assert_non_null(slice); + + assert_uint_equal(arraylist_reserve(arr, 128), ARRLIST_IS_BORROWED); + + arrayslice_destroy(&slice); + arraylist_destroy(&arr); +} + // Slice creation static void test_slice_valid_init(void **state) { (void) state; @@ -1044,6 +1281,7 @@ int main(void) { cmocka_unit_test(test_destroy_valid_array), cmocka_unit_test(test_destroy_null_array), cmocka_unit_test(test_destroy_double), + cmocka_unit_test(test_destroy_while_borrowed), }; const struct CMUnitTest state[] = { @@ -1060,6 +1298,7 @@ int main(void) { cmocka_unit_test(test_push_back_multiple_elements), cmocka_unit_test(test_push_back_null_array), cmocka_unit_test(test_push_back_null_data), + cmocka_unit_test(test_push_back_while_borrowed), }; const struct CMUnitTest push_front[] = { @@ -1067,6 +1306,7 @@ int main(void) { cmocka_unit_test(test_push_front_multiple_elements), cmocka_unit_test(test_push_front_null_array), cmocka_unit_test(test_push_front_null_data), + cmocka_unit_test(test_push_front_while_borrowed), }; const struct CMUnitTest insert[] = { @@ -1076,6 +1316,7 @@ int main(void) { cmocka_unit_test(test_insert_at_invalid_index), cmocka_unit_test(test_insert_null_array), cmocka_unit_test(test_insert_null_data), + cmocka_unit_test(test_insert_while_borrowed), }; const struct CMUnitTest pop_back[] = { @@ -1085,6 +1326,7 @@ int main(void) { cmocka_unit_test(test_pop_back_empty_array), cmocka_unit_test(test_pop_back_null_array), cmocka_unit_test(test_pop_back_null_out), + cmocka_unit_test(test_pop_back_while_borrowed), }; const struct CMUnitTest pop_front[] = { @@ -1094,6 +1336,7 @@ int main(void) { cmocka_unit_test(test_pop_front_empty_array), cmocka_unit_test(test_pop_front_null_array), cmocka_unit_test(test_pop_front_null_out), + cmocka_unit_test(test_pop_front_while_borrowed), }; const struct CMUnitTest remove_at[] = { @@ -1103,6 +1346,7 @@ int main(void) { cmocka_unit_test(test_remove_at_invalid_index), cmocka_unit_test(test_remove_at_null_array), cmocka_unit_test(test_remove_at_null_data), + cmocka_unit_test(test_remove_at_while_borrowed), }; const struct CMUnitTest get[] = { @@ -1112,6 +1356,7 @@ int main(void) { cmocka_unit_test(test_get_invalid_index), cmocka_unit_test(test_get_null_array), cmocka_unit_test(test_get_null_out), + cmocka_unit_test(test_get_while_borrowed), }; const struct CMUnitTest set[] = { @@ -1121,12 +1366,14 @@ int main(void) { cmocka_unit_test(test_set_invalid_index), cmocka_unit_test(test_set_null_array), cmocka_unit_test(test_set_null_data), + cmocka_unit_test(test_set_while_borrowed), }; const struct CMUnitTest clear[] = { cmocka_unit_test(test_clear_non_empty_array), cmocka_unit_test(test_clear_already_empty_array), cmocka_unit_test(test_clear_null_array), + cmocka_unit_test(test_clear_while_borrowed), }; const struct CMUnitTest resize[] = { @@ -1135,12 +1382,14 @@ int main(void) { cmocka_unit_test(test_resize_to_zero), cmocka_unit_test(test_resize_to_size_max), cmocka_unit_test(test_resize_null_array), + cmocka_unit_test(test_resize_while_borrowed), }; const struct CMUnitTest reserve[] = { cmocka_unit_test(test_reserve_normal_capacity), cmocka_unit_test(test_reserve_size_0), cmocka_unit_test(test_reserve_size_max), + cmocka_unit_test(test_reserve_while_borrowed), }; const struct CMUnitTest slice_init[] = { -- 2.51.0 From 198997e2b67b9f029d7fb97bb9819a26b310c90d Mon Sep 17 00:00:00 2001 From: laentropia Date: Tue, 21 Apr 2026 19:57:58 -0600 Subject: [PATCH 06/16] test: arraylist_slice tested --- test/test_arraylist.c | 79 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 77 insertions(+), 2 deletions(-) diff --git a/test/test_arraylist.c b/test/test_arraylist.c index 6acc4a2..80becad 100644 --- a/test/test_arraylist.c +++ b/test/test_arraylist.c @@ -1269,6 +1269,76 @@ static void test_slice_valid_init(void **state) { arraylist_destroy(&arr); } +static void test_slice_invalid_index(void **state) { + (void) state; + + ArrayList *arr = arraylist_init(64, sizeof(int)); + assert_non_null(arr); + + for (size_t i = 0; i < 10; i++) { + assert_uint_equal(arraylist_push_back(arr, &i), ARRLIST_OK); + } + + ArraySlice *slice = arraylist_slice(arr, 32, 10); + assert_null(slice); + + arraylist_destroy(&arr); +} + +static void test_slice_invalid_len(void **state) { + (void) state; + + ArrayList *arr = arraylist_init(64, sizeof(int)); + assert_non_null(arr); + + for (size_t i = 0; i < 10; i++) { + assert_uint_equal(arraylist_push_back(arr, &i), ARRLIST_OK); + } + + ArraySlice *slice = arraylist_slice(arr, 0, 300); + assert_null(slice); + + arraylist_destroy(&arr); +} + +static void test_slice_len_zero(void **state) { + (void) state; + + ArrayList *arr = arraylist_init(64, sizeof(int)); + assert_non_null(arr); + + for (size_t i = 0; i < 10; i++) { + assert_uint_equal(arraylist_push_back(arr, &i), ARRLIST_OK); + } + + ArraySlice *slice = arraylist_slice(arr, 0, 0); + assert_null(slice); + + arraylist_destroy(&arr); +} + +static void test_slice_empty_array(void **state) { + (void) state; + + ArrayList *arr = arraylist_init(64, sizeof(int)); + assert_non_null(arr); + + + ArraySlice *slice = arraylist_slice(arr, 0, 10); + assert_null(slice); + + arraylist_destroy(&arr); +} + +static void test_slice_null_arr(void **state) { + (void) state; + + ArrayList *arr = NULL; + + ArraySlice *slice = arraylist_slice(arr, 0, 10); + assert_null(slice); +} + int main(void) { const struct CMUnitTest init[] = { cmocka_unit_test(test_init_valid_parameters), @@ -1392,8 +1462,13 @@ int main(void) { cmocka_unit_test(test_reserve_while_borrowed), }; - const struct CMUnitTest slice_init[] = { + const struct CMUnitTest slice_array[] = { cmocka_unit_test(test_slice_valid_init), + cmocka_unit_test(test_slice_invalid_index), + cmocka_unit_test(test_slice_invalid_len), + cmocka_unit_test(test_slice_len_zero), + cmocka_unit_test(test_slice_empty_array), + cmocka_unit_test(test_slice_null_arr), }; int rc = 0; @@ -1413,7 +1488,7 @@ int main(void) { rc += cmocka_run_group_tests(resize, NULL, NULL); rc += cmocka_run_group_tests(reserve, NULL, NULL); - rc += cmocka_run_group_tests(slice_init, NULL, NULL); + rc += cmocka_run_group_tests(slice_array, NULL, NULL); return rc; } -- 2.51.0 From b34fb9902fa12ac520603d193a78272156b2144a Mon Sep 17 00:00:00 2001 From: laentropia Date: Wed, 22 Apr 2026 17:26:49 -0600 Subject: [PATCH 07/16] test: added tests for slice_unsafe --- test/test_arraylist.c | 98 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) diff --git a/test/test_arraylist.c b/test/test_arraylist.c index 80becad..b52d403 100644 --- a/test/test_arraylist.c +++ b/test/test_arraylist.c @@ -1339,6 +1339,94 @@ static void test_slice_null_arr(void **state) { assert_null(slice); } +// Slice Unsafe +static void test_slice_unsafe_valid_init(void **state) { + (void) state; + + ArrayList *arr = arraylist_init(64, sizeof(int)); + assert_non_null(arr); + + for (size_t i = 0; i < 10; i++) { + assert_uint_equal(arraylist_push_back(arr, &i), ARRLIST_OK); + } + + ArraySlice *slice = arraylist_slice(arr, 0, 10); + assert_non_null(slice); + + arrayslice_destroy(&slice); + arraylist_destroy(&arr); +} + +static void test_slice_unsafe_invalid_index(void **state) { + (void) state; + + ArrayList *arr = arraylist_init(64, sizeof(int)); + assert_non_null(arr); + + for (size_t i = 0; i < 10; i++) { + assert_uint_equal(arraylist_push_back(arr, &i), ARRLIST_OK); + } + + ArraySlice *slice = arraylist_slice(arr, 32, 10); + assert_null(slice); + + arraylist_destroy(&arr); +} + +static void test_slice_unsafe_invalid_len(void **state) { + (void) state; + + ArrayList *arr = arraylist_init(64, sizeof(int)); + assert_non_null(arr); + + for (size_t i = 0; i < 10; i++) { + assert_uint_equal(arraylist_push_back(arr, &i), ARRLIST_OK); + } + + ArraySlice *slice = arraylist_slice(arr, 0, 300); + assert_null(slice); + + arraylist_destroy(&arr); +} + +static void test_slice_unsafe_len_zero(void **state) { + (void) state; + + ArrayList *arr = arraylist_init(64, sizeof(int)); + assert_non_null(arr); + + for (size_t i = 0; i < 10; i++) { + assert_uint_equal(arraylist_push_back(arr, &i), ARRLIST_OK); + } + + ArraySlice *slice = arraylist_slice(arr, 0, 0); + assert_null(slice); + + arraylist_destroy(&arr); +} + +static void test_slice_unsafe_empty_array(void **state) { + (void) state; + + ArrayList *arr = arraylist_init(64, sizeof(int)); + assert_non_null(arr); + + + ArraySlice *slice = arraylist_slice(arr, 0, 10); + assert_null(slice); + + arraylist_destroy(&arr); +} + +static void test_slice_unsafe_null_arr(void **state) { + (void) state; + + ArrayList *arr = NULL; + + ArraySlice *slice = arraylist_slice(arr, 0, 10); + assert_null(slice); +} + int main(void) { const struct CMUnitTest init[] = { cmocka_unit_test(test_init_valid_parameters), @@ -1471,6 +1559,15 @@ int main(void) { cmocka_unit_test(test_slice_null_arr), }; + const struct CMUnitTest slice_array_unsafe[] = { + cmocka_unit_test(test_slice_unsafe_valid_init), + cmocka_unit_test(test_slice_unsafe_invalid_index), + cmocka_unit_test(test_slice_unsafe_invalid_len), + cmocka_unit_test(test_slice_unsafe_len_zero), + cmocka_unit_test(test_slice_unsafe_empty_array), + cmocka_unit_test(test_slice_unsafe_null_arr), + }; + int rc = 0; rc += cmocka_run_group_tests(init, NULL, NULL); @@ -1489,6 +1586,7 @@ int main(void) { rc += cmocka_run_group_tests(reserve, NULL, NULL); rc += cmocka_run_group_tests(slice_array, NULL, NULL); + rc += cmocka_run_group_tests(slice_array_unsafe, NULL, NULL); return rc; } -- 2.51.0 From 94dc859a8fb94ac924d737ad729d6203513f60af Mon Sep 17 00:00:00 2001 From: laentropia Date: Wed, 22 Apr 2026 17:55:14 -0600 Subject: [PATCH 08/16] test: added tests for slice_destroy --- test/test_arraylist.c | 59 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/test/test_arraylist.c b/test/test_arraylist.c index b52d403..3f8b551 100644 --- a/test/test_arraylist.c +++ b/test/test_arraylist.c @@ -1427,6 +1427,58 @@ static void test_slice_unsafe_null_arr(void **state) { assert_null(slice); } +// Slice Destroy +static void test_slice_destroy_valid(void **state) { + (void) state; + + ArrayList *arr = arraylist_init(64, sizeof(int)); + assert_non_null(arr); + + for (int i = 0; i < 10; i++) { + assert_uint_equal(arraylist_push_back(arr, &i), ARRLIST_OK); + } + + ArraySlice *slice = arraylist_slice(arr, 0, arraylist_size(arr)); + assert_non_null(slice); + + assert_uint_equal(arrayslice_destroy(&slice), ARRLIST_OK); + arraylist_destroy(&arr); +} + +static void test_slice_destroy_null_slice(void **state) { + (void) state; + + ArrayList *arr = arraylist_init(64, sizeof(int)); + assert_non_null(arr); + + for (int i = 0; i < 10; i++) { + assert_uint_equal(arraylist_push_back(arr, &i), ARRLIST_OK); + } + + ArraySlice *slice = NULL; + + assert_uint_equal(arrayslice_destroy(&slice), ARRLIST_NULL_ARG); + arraylist_destroy(&arr); +} + +static void test_slice_double_destroy(void **state) { + (void) state; + + ArrayList *arr = arraylist_init(64, sizeof(int)); + assert_non_null(arr); + + for (int i = 0; i < 10; i++) { + assert_uint_equal(arraylist_push_back(arr, &i), ARRLIST_OK); + } + + ArraySlice *slice = arraylist_slice(arr, 0, arraylist_size(arr)); + assert_non_null(slice); + + assert_uint_equal(arrayslice_destroy(&slice), ARRLIST_OK); + assert_uint_equal(arrayslice_destroy(&slice), ARRLIST_NULL_ARG); + arraylist_destroy(&arr); +} + int main(void) { const struct CMUnitTest init[] = { cmocka_unit_test(test_init_valid_parameters), @@ -1568,6 +1620,12 @@ int main(void) { cmocka_unit_test(test_slice_unsafe_null_arr), }; + const struct CMUnitTest slice_destroy[] = { + cmocka_unit_test(test_slice_destroy_valid), + cmocka_unit_test(test_slice_destroy_null_slice), + cmocka_unit_test(test_slice_double_destroy), + }; + int rc = 0; rc += cmocka_run_group_tests(init, NULL, NULL); @@ -1587,6 +1645,7 @@ int main(void) { rc += cmocka_run_group_tests(slice_array, NULL, NULL); rc += cmocka_run_group_tests(slice_array_unsafe, NULL, NULL); + rc += cmocka_run_group_tests(slice_destroy, NULL, NULL); return rc; } -- 2.51.0 From e8aaa006de582bdc8d84c59b71749f2b57a89b9c Mon Sep 17 00:00:00 2001 From: laentropia Date: Thu, 23 Apr 2026 08:47:45 -0600 Subject: [PATCH 09/16] addition: next and peek, need testing --- include/arraylist.h | 11 +++++------ src/arraylist.c | 47 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 6 deletions(-) diff --git a/include/arraylist.h b/include/arraylist.h index 60cc16d..d60aeaa 100644 --- a/include/arraylist.h +++ b/include/arraylist.h @@ -19,6 +19,7 @@ typedef enum { ARRLIST_INVALID_ELEM_SIZE, ARRLIST_INVALID_CAPACITY, ARRLIST_IS_BORROWED, + ARRLIST_INVALID_SLICE, } ArrayListErr; ArrayList *arraylist_init(size_t capacity, size_t elem_size); @@ -52,16 +53,14 @@ ArrayListErr arrayslice_destroy(ArraySlice **slice); bool arrayslice_is_valid(const ArraySlice *slice); size_t arrayslice_size(const ArraySlice *slice); -bool arrayslice_empty(const ArraySlice *slice); // peek and next can be null, get can't, like, why would you use get without // actually getting something?, for validating an index?, use size idiot -ArrayListErr *arrayslice_peek(const ArraySlice *slice, void *out); -ArrayListErr *arrayslice_next(ArraySlice *slice, void *out); -ArrayListErr *arrayslice_get(const ArraySlice *slice, void *out); +ArrayListErr arrayslice_peek(const ArraySlice *slice, void *out); +ArrayListErr arrayslice_next(ArraySlice *slice, void *out); -ArrayListErr *arrayslice_reset(ArraySlice *slice); -ArrayListErr *arrayslice_advance(ArraySlice *slice, size_t n); +ArrayListErr arrayslice_reset(ArraySlice *slice); +ArrayListErr arrayslice_advance(ArraySlice *slice, size_t n); ArrayList *arrayslice_to_arraylist(const ArraySlice *slice); diff --git a/src/arraylist.c b/src/arraylist.c index e986ff5..e76acbf 100644 --- a/src/arraylist.c +++ b/src/arraylist.c @@ -506,3 +506,50 @@ ArrayListErr arrayslice_destroy(ArraySlice **slice) { return ARRLIST_OK; } + +bool arrayslice_is_valid(const ArraySlice *slice) { + if (slice == NULL) { + return false; + } + + return slice->current != slice->end; +} + +size_t arrayslice_size(const ArraySlice *slice) { + if (slice == NULL) { + return 0; + } + + return slice->end - slice->start; +} + +ArrayListErr arrayslice_peek(const ArraySlice *slice, void *out) { + if (slice == NULL || out == NULL) { + return ARRLIST_NULL_ARG; + } + + if (slice->current == slice->end) { + return ARRLIST_INVALID_SLICE; + } + + arraylist_get(slice->arr, slice->current, out); + + return ARRLIST_OK; +} + +ArrayListErr arrayslice_next(ArraySlice *slice, void *out) { + // HERE, it makes sense that you want to advance to the next + // without actually getting the value so it's good + if (slice == NULL) { + return ARRLIST_NULL_ARG; + } + + if (slice->current == slice->end) { + return ARRLIST_INVALID_SLICE; + } + + arraylist_get(slice->arr, slice->current, out); + + slice->current++; + return ARRLIST_OK; +} -- 2.51.0 From dd992cf6b9badf1515051d34c6cf8413be218e75 Mon Sep 17 00:00:00 2001 From: laentropia Date: Thu, 23 Apr 2026 08:59:12 -0600 Subject: [PATCH 10/16] addtition: reset and advance, need testing --- src/arraylist.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/arraylist.c b/src/arraylist.c index e76acbf..a147a0e 100644 --- a/src/arraylist.c +++ b/src/arraylist.c @@ -553,3 +553,27 @@ ArrayListErr arrayslice_next(ArraySlice *slice, void *out) { slice->current++; return ARRLIST_OK; } + +ArrayListErr arrayslice_reset(ArraySlice *slice) { + if (slice == NULL) { + return ARRLIST_NULL_ARG; + } + + slice->current = slice->start; + + return ARRLIST_OK; +} + +ArrayListErr arrayslice_advance(ArraySlice *slice, size_t n) { + if (slice == NULL) { + return ARRLIST_NULL_ARG; + } + + if (n > SIZE_MAX - slice->current || slice->current + n >= slice->end) { + return ARRLIST_OUT_OF_BOUNDS; + } + + slice->current += n; + + return ARRLIST_OK; +} -- 2.51.0 From 4a1575e833c70f1fe652b6ce0fee3ac4ef27a33a Mon Sep 17 00:00:00 2001 From: laentropia Date: Thu, 23 Apr 2026 09:18:18 -0600 Subject: [PATCH 11/16] addtition: slice to array, needs testing --- include/arraylist.h | 2 +- src/arraylist.c | 26 ++++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/include/arraylist.h b/include/arraylist.h index d60aeaa..a22f97e 100644 --- a/include/arraylist.h +++ b/include/arraylist.h @@ -25,7 +25,7 @@ typedef enum { ArrayList *arraylist_init(size_t capacity, size_t elem_size); ArrayListErr arraylist_destroy(ArrayList **arr); ArrayListErr arraylist_clear(ArrayList *arr); -ArrayList *arraylist_copy(const ArrayList *arr); +ArrayList *arraylist_clone(const ArrayList *arr); size_t arraylist_size(const ArrayList *arr); size_t arraylist_capacity(const ArrayList *arr); diff --git a/src/arraylist.c b/src/arraylist.c index a147a0e..335605c 100644 --- a/src/arraylist.c +++ b/src/arraylist.c @@ -577,3 +577,29 @@ ArrayListErr arrayslice_advance(ArraySlice *slice, size_t n) { return ARRLIST_OK; } + +ArrayList *arrayslice_to_arraylist(const ArraySlice *slice) { + if (slice == NULL) { + return NULL; + } + + if (slice->current >= slice->end) { + return NULL; + } + + ArrayList *new_arr = arraylist_init( + arraylist_capacity(slice->arr), + slice->arr->elem_size); + + if (new_arr == NULL) { + return NULL; + } + + memcpy( + new_arr->buffer, + slice->arr->buffer + (slice->start * slice->arr->elem_size), + slice->arr->elem_size * (slice->end - slice->current) + ); + + return new_arr; +} -- 2.51.0 From 9920b518bf5bc38c6bb7c16b422069294a286872 Mon Sep 17 00:00:00 2001 From: laentropia Date: Thu, 23 Apr 2026 09:39:59 -0600 Subject: [PATCH 12/16] test: peek tests done --- src/arraylist.c | 4 +-- test/test_arraylist.c | 82 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+), 2 deletions(-) diff --git a/src/arraylist.c b/src/arraylist.c index 335605c..9b1b804 100644 --- a/src/arraylist.c +++ b/src/arraylist.c @@ -528,7 +528,7 @@ ArrayListErr arrayslice_peek(const ArraySlice *slice, void *out) { return ARRLIST_NULL_ARG; } - if (slice->current == slice->end) { + if (slice->current >= slice->end) { return ARRLIST_INVALID_SLICE; } @@ -569,7 +569,7 @@ ArrayListErr arrayslice_advance(ArraySlice *slice, size_t n) { return ARRLIST_NULL_ARG; } - if (n > SIZE_MAX - slice->current || slice->current + n >= slice->end) { + if (n > SIZE_MAX - slice->current || slice->current + n > slice->end) { return ARRLIST_OUT_OF_BOUNDS; } diff --git a/test/test_arraylist.c b/test/test_arraylist.c index 3f8b551..596e968 100644 --- a/test/test_arraylist.c +++ b/test/test_arraylist.c @@ -1479,6 +1479,80 @@ static void test_slice_double_destroy(void **state) { arraylist_destroy(&arr); } +// Slice peek +static void test_slice_peek_valid_array(void **state) { + (void) state; + + ArrayList *arr = arraylist_init(64, sizeof(int)); + assert_non_null(arr); + + for (int i = 0; i < 10; i++) { + assert_uint_equal(arraylist_push_back(arr, &i), ARRLIST_OK); + } + + ArraySlice *slice = arraylist_slice(arr, 0, arraylist_size(arr)); + assert_non_null(slice); + + int m; + assert_uint_equal(arrayslice_peek(slice, &m), ARRLIST_OK); + assert_int_equal(m, 0); + + arrayslice_destroy(&slice); + arraylist_destroy(&arr); +} + +static void test_slice_peek_invalid_array(void **state) { + (void) state; + + ArrayList *arr = arraylist_init(64, sizeof(int)); + assert_non_null(arr); + + for (int i = 0; i < 10; i++) { + assert_uint_equal(arraylist_push_back(arr, &i), ARRLIST_OK); + } + + ArraySlice *slice = arraylist_slice(arr, 0, arraylist_size(arr)); + assert_non_null(slice); + + assert_uint_equal(arrayslice_advance(slice, 10), ARRLIST_OK); + + int m; + assert_uint_equal(arrayslice_peek(slice, &m), ARRLIST_INVALID_SLICE); + assert_int_equal(m, 0); + + arrayslice_destroy(&slice); + arraylist_destroy(&arr); +} + +static void test_slice_peek_null_out(void **state) { + (void) state; + + ArrayList *arr = arraylist_init(64, sizeof(int)); + assert_non_null(arr); + + for (int i = 0; i < 10; i++) { + assert_uint_equal(arraylist_push_back(arr, &i), ARRLIST_OK); + } + + ArraySlice *slice = arraylist_slice(arr, 0, arraylist_size(arr)); + assert_non_null(slice); + + assert_uint_equal(arrayslice_peek(slice, NULL), ARRLIST_NULL_ARG); + + arrayslice_destroy(&slice); + arraylist_destroy(&arr); +} + +static void test_slice_peek_null_slice(void **state) { + (void) state; + + ArraySlice *slice = NULL; + + int m; + assert_uint_equal(arrayslice_peek(slice, &m), ARRLIST_NULL_ARG); + assert_int_equal(m, 0); +} + int main(void) { const struct CMUnitTest init[] = { cmocka_unit_test(test_init_valid_parameters), @@ -1626,6 +1700,13 @@ int main(void) { cmocka_unit_test(test_slice_double_destroy), }; + const struct CMUnitTest slice_peek[] = { + cmocka_unit_test(test_slice_peek_valid_array), + cmocka_unit_test(test_slice_peek_invalid_array), + cmocka_unit_test(test_slice_peek_null_slice), + cmocka_unit_test(test_slice_peek_null_out), + }; + int rc = 0; rc += cmocka_run_group_tests(init, NULL, NULL); @@ -1646,6 +1727,7 @@ int main(void) { rc += cmocka_run_group_tests(slice_array, NULL, NULL); rc += cmocka_run_group_tests(slice_array_unsafe, NULL, NULL); rc += cmocka_run_group_tests(slice_destroy, NULL, NULL); + rc += cmocka_run_group_tests(slice_peek, NULL, NULL); return rc; } -- 2.51.0 From e04fc30f4e094ce3e8cba16d83920c6aa541b591 Mon Sep 17 00:00:00 2001 From: laentropia Date: Thu, 23 Apr 2026 10:03:55 -0600 Subject: [PATCH 13/16] test: next tests done --- test/test_arraylist.c | 107 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) diff --git a/test/test_arraylist.c b/test/test_arraylist.c index 596e968..0ef6a15 100644 --- a/test/test_arraylist.c +++ b/test/test_arraylist.c @@ -1553,6 +1553,104 @@ static void test_slice_peek_null_slice(void **state) { assert_int_equal(m, 0); } +// Slice next +static void test_slice_next_valid_array(void **state) { + (void) state; + + ArrayList *arr = arraylist_init(64, sizeof(int)); + assert_non_null(arr); + + for (int i = 0; i < 10; i++) { + assert_uint_equal(arraylist_push_back(arr, &i), ARRLIST_OK); + } + + ArraySlice *slice = arraylist_slice(arr, 0, arraylist_size(arr)); + assert_non_null(slice); + + int m; + assert_uint_equal(arrayslice_next(slice, &m), ARRLIST_OK); + assert_int_equal(m, 0); + + arrayslice_destroy(&slice); + arraylist_destroy(&arr); +} + +static void test_slice_next_invalid_array(void **state) { + (void) state; + + ArrayList *arr = arraylist_init(64, sizeof(int)); + assert_non_null(arr); + + for (int i = 0; i < 10; i++) { + assert_uint_equal(arraylist_push_back(arr, &i), ARRLIST_OK); + } + + ArraySlice *slice = arraylist_slice(arr, 0, arraylist_size(arr)); + assert_non_null(slice); + + assert_uint_equal(arrayslice_advance(slice, 10), ARRLIST_OK); + + int m; + assert_uint_equal(arrayslice_next(slice, &m), ARRLIST_INVALID_SLICE); + assert_int_equal(m, 0); + + arrayslice_destroy(&slice); + arraylist_destroy(&arr); +} + +static void test_slice_next_null_out(void **state) { + (void) state; + + ArrayList *arr = arraylist_init(64, sizeof(int)); + assert_non_null(arr); + + for (int i = 0; i < 10; i++) { + assert_uint_equal(arraylist_push_back(arr, &i), ARRLIST_OK); + } + + ArraySlice *slice = arraylist_slice(arr, 0, arraylist_size(arr)); + assert_non_null(slice); + + assert_uint_equal(arrayslice_next(slice, NULL), ARRLIST_OK); + + arrayslice_destroy(&slice); + arraylist_destroy(&arr); +} + +static void test_slice_next_null_slice(void **state) { + (void) state; + + ArraySlice *slice = NULL; + + int m; + assert_uint_equal(arrayslice_next(slice, &m), ARRLIST_NULL_ARG); + assert_int_equal(m, 0); +} + +static void test_slice_next_until_invalid(void **state) { + (void) state; + + ArrayList *arr = arraylist_init(64, sizeof(int)); + assert_non_null(arr); + + for (int i = 0; i < 10; i++) { + assert_uint_equal(arraylist_push_back(arr, &i), ARRLIST_OK); + } + + ArraySlice *slice = arraylist_slice(arr, 0, arraylist_size(arr)); + assert_non_null(slice); + + int m; + for (int i = 0; i < 10; i++) { + assert_uint_equal(arrayslice_next(slice, &m), ARRLIST_OK); + assert_uint_equal(m, i); + } + assert_false(arrayslice_is_valid(slice)); + + arrayslice_destroy(&slice); + arraylist_destroy(&arr); +} + int main(void) { const struct CMUnitTest init[] = { cmocka_unit_test(test_init_valid_parameters), @@ -1706,6 +1804,14 @@ int main(void) { cmocka_unit_test(test_slice_peek_null_slice), cmocka_unit_test(test_slice_peek_null_out), }; + + const struct CMUnitTest slice_next[] = { + cmocka_unit_test(test_slice_next_valid_array), + cmocka_unit_test(test_slice_next_invalid_array), + cmocka_unit_test(test_slice_next_null_slice), + cmocka_unit_test(test_slice_next_null_out), + cmocka_unit_test(test_slice_next_until_invalid), + }; int rc = 0; @@ -1728,6 +1834,7 @@ int main(void) { rc += cmocka_run_group_tests(slice_array_unsafe, NULL, NULL); rc += cmocka_run_group_tests(slice_destroy, NULL, NULL); rc += cmocka_run_group_tests(slice_peek, NULL, NULL); + rc += cmocka_run_group_tests(slice_next, NULL, NULL); return rc; } -- 2.51.0 From a515f8eaf23d91b5c3080639d2352d668420c5ab Mon Sep 17 00:00:00 2001 From: laentropia Date: Thu, 23 Apr 2026 10:29:53 -0600 Subject: [PATCH 14/16] test: reset tests done --- test/test_arraylist.c | 45 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/test/test_arraylist.c b/test/test_arraylist.c index 0ef6a15..ad9997f 100644 --- a/test/test_arraylist.c +++ b/test/test_arraylist.c @@ -1651,6 +1651,45 @@ static void test_slice_next_until_invalid(void **state) { arraylist_destroy(&arr); } +//Slice reset +static void test_slice_reset_valid_slice(void **state) { + (void) state; + + ArrayList *arr = arraylist_init(64, sizeof(int)); + assert_non_null(arr); + + for (int i = 0; i < 10; i++) { + assert_uint_equal(arraylist_push_back(arr, &i), ARRLIST_OK); + } + + ArraySlice *slice = arraylist_slice(arr, 0, arraylist_size(arr)); + assert_non_null(slice); + + int m; + for (int i = 0; i < 10; i++) { + assert_uint_equal(arrayslice_next(slice, &m), ARRLIST_OK); + assert_uint_equal(m, i); + } + + assert_uint_equal(arrayslice_reset(slice), ARRLIST_OK); + + for (int i = 0; i < 10; i++) { + assert_uint_equal(arrayslice_next(slice, &m), ARRLIST_OK); + assert_uint_equal(m, i); + } + + arrayslice_destroy(&slice); + arraylist_destroy(&arr); +} + +static void test_slice_reset_null_slice(void **state) { + (void) state; + + ArraySlice *slice = NULL; + + assert_uint_equal(arrayslice_reset(slice), ARRLIST_NULL_ARG); +} + int main(void) { const struct CMUnitTest init[] = { cmocka_unit_test(test_init_valid_parameters), @@ -1813,6 +1852,11 @@ int main(void) { cmocka_unit_test(test_slice_next_until_invalid), }; + const struct CMUnitTest slice_reset[] = { + cmocka_unit_test(test_slice_reset_valid_slice), + cmocka_unit_test(test_slice_reset_null_slice), + }; + int rc = 0; rc += cmocka_run_group_tests(init, NULL, NULL); @@ -1835,6 +1879,7 @@ int main(void) { rc += cmocka_run_group_tests(slice_destroy, NULL, NULL); rc += cmocka_run_group_tests(slice_peek, NULL, NULL); rc += cmocka_run_group_tests(slice_next, NULL, NULL); + rc += cmocka_run_group_tests(slice_reset, NULL, NULL); return rc; } -- 2.51.0 From 51f1166f315af04b63380ba11a258deff6d54a34 Mon Sep 17 00:00:00 2001 From: laentropia Date: Thu, 23 Apr 2026 10:47:23 -0600 Subject: [PATCH 15/16] test: advance tests done --- test/test_arraylist.c | 94 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) diff --git a/test/test_arraylist.c b/test/test_arraylist.c index ad9997f..1aa942b 100644 --- a/test/test_arraylist.c +++ b/test/test_arraylist.c @@ -1690,6 +1690,92 @@ static void test_slice_reset_null_slice(void **state) { assert_uint_equal(arrayslice_reset(slice), ARRLIST_NULL_ARG); } +//Slice advance +//out ou bounds +//null +static void test_slice_advance_valid_slice(void **state) { + (void) state; + + ArrayList *arr = arraylist_init(64, sizeof(int)); + assert_non_null(arr); + + for (int i = 0; i < 10; i++) { + assert_uint_equal(arraylist_push_back(arr, &i), ARRLIST_OK); + } + + ArraySlice *slice = arraylist_slice(arr, 0, arraylist_size(arr)); + assert_non_null(slice); + + int m; + for (int i = 0; i < 5; i++) { + assert_uint_equal(arrayslice_next(slice, &m), ARRLIST_OK); + assert_uint_equal(m, i); + } + + assert_uint_equal(arrayslice_advance(slice, 5), ARRLIST_OK); + + arrayslice_destroy(&slice); + arraylist_destroy(&arr); +} + +static void test_slice_advance_out_of_bounds(void **state) { + (void) state; + + ArrayList *arr = arraylist_init(64, sizeof(int)); + assert_non_null(arr); + + for (int i = 0; i < 10; i++) { + assert_uint_equal(arraylist_push_back(arr, &i), ARRLIST_OK); + } + + ArraySlice *slice = arraylist_slice(arr, 0, arraylist_size(arr)); + assert_non_null(slice); + + int m; + for (int i = 0; i < 5; i++) { + assert_uint_equal(arrayslice_next(slice, &m), ARRLIST_OK); + assert_uint_equal(m, i); + } + + assert_uint_equal(arrayslice_advance(slice, 40), ARRLIST_OUT_OF_BOUNDS); + + arrayslice_destroy(&slice); + arraylist_destroy(&arr); +} + +static void test_slice_advance_size_max(void **state) { + (void) state; + + ArrayList *arr = arraylist_init(64, sizeof(int)); + assert_non_null(arr); + + for (int i = 0; i < 10; i++) { + assert_uint_equal(arraylist_push_back(arr, &i), ARRLIST_OK); + } + + ArraySlice *slice = arraylist_slice(arr, 0, arraylist_size(arr)); + assert_non_null(slice); + + int m; + for (int i = 0; i < 5; i++) { + assert_uint_equal(arrayslice_next(slice, &m), ARRLIST_OK); + assert_uint_equal(m, i); + } + + assert_uint_equal(arrayslice_advance(slice, SIZE_MAX), ARRLIST_OUT_OF_BOUNDS); + + arrayslice_destroy(&slice); + arraylist_destroy(&arr); +} + +static void test_slice_advance_null_array(void **state) { + (void) state; + + ArraySlice *slice = NULL; + + assert_uint_equal(arrayslice_advance(slice, 56), ARRLIST_NULL_ARG); +} + int main(void) { const struct CMUnitTest init[] = { cmocka_unit_test(test_init_valid_parameters), @@ -1857,6 +1943,13 @@ int main(void) { cmocka_unit_test(test_slice_reset_null_slice), }; + const struct CMUnitTest slice_advance[] = { + cmocka_unit_test(test_slice_advance_valid_slice), + cmocka_unit_test(test_slice_advance_out_of_bounds), + cmocka_unit_test(test_slice_advance_null_array), + cmocka_unit_test(test_slice_advance_size_max), + }; + int rc = 0; rc += cmocka_run_group_tests(init, NULL, NULL); @@ -1880,6 +1973,7 @@ int main(void) { rc += cmocka_run_group_tests(slice_peek, NULL, NULL); rc += cmocka_run_group_tests(slice_next, NULL, NULL); rc += cmocka_run_group_tests(slice_reset, NULL, NULL); + rc += cmocka_run_group_tests(slice_advance, NULL, NULL); return rc; } -- 2.51.0 From d940b68eef93aa8a4c6d99ad2d88f9e8ccf0ed1f Mon Sep 17 00:00:00 2001 From: laentropia Date: Thu, 23 Apr 2026 11:22:57 -0600 Subject: [PATCH 16/16] test: tests for arrayslice to aray done --- src/arraylist.c | 13 +++++++------ test/test_arraylist.c | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 6 deletions(-) diff --git a/src/arraylist.c b/src/arraylist.c index 9b1b804..bbbaa65 100644 --- a/src/arraylist.c +++ b/src/arraylist.c @@ -579,18 +579,17 @@ ArrayListErr arrayslice_advance(ArraySlice *slice, size_t n) { } ArrayList *arrayslice_to_arraylist(const ArraySlice *slice) { - if (slice == NULL) { + if (slice == NULL || slice->arr == NULL) { return NULL; } - if (slice->current >= slice->end) { + if (slice->start >= slice->end) { return NULL; } - ArrayList *new_arr = arraylist_init( - arraylist_capacity(slice->arr), - slice->arr->elem_size); + size_t len = slice->end - slice->start; + ArrayList *new_arr = arraylist_init(arraylist_capacity(slice->arr), slice->arr->elem_size); if (new_arr == NULL) { return NULL; } @@ -598,8 +597,10 @@ ArrayList *arrayslice_to_arraylist(const ArraySlice *slice) { memcpy( new_arr->buffer, slice->arr->buffer + (slice->start * slice->arr->elem_size), - slice->arr->elem_size * (slice->end - slice->current) + slice->arr->elem_size * len ); + new_arr->len = len; + return new_arr; } diff --git a/test/test_arraylist.c b/test/test_arraylist.c index 1aa942b..1362d41 100644 --- a/test/test_arraylist.c +++ b/test/test_arraylist.c @@ -1776,6 +1776,38 @@ static void test_slice_advance_null_array(void **state) { assert_uint_equal(arrayslice_advance(slice, 56), ARRLIST_NULL_ARG); } +//Slice to Array +static void test_slice_to_array_valid(void **state) { + (void) state; + + ArrayList *arr = arraylist_init(64, sizeof(int)); + assert_non_null(arr); + + for (int i = 0; i < 10; i++) { + assert_uint_equal(arraylist_push_back(arr, &i), ARRLIST_OK); + } + + ArraySlice *slice = arraylist_slice(arr, 0, arraylist_size(arr)); + assert_non_null(slice); + + ArrayList *arr2 = arrayslice_to_arraylist(slice); + assert_non_null(arr2); + assert_uint_equal(arraylist_capacity(arr2), 64); + assert_uint_equal(arraylist_size(arr2), 10); + + arraylist_destroy(&arr2); + arrayslice_destroy(&slice); + arraylist_destroy(&arr); +} + +static void test_slice_to_array_null_slice(void **state) { + (void) state; + + ArraySlice *slice = NULL; + + assert_null(arrayslice_to_arraylist(slice)); +} + int main(void) { const struct CMUnitTest init[] = { cmocka_unit_test(test_init_valid_parameters), @@ -1950,6 +1982,11 @@ int main(void) { cmocka_unit_test(test_slice_advance_size_max), }; + const struct CMUnitTest slice_to_array[] = { + cmocka_unit_test(test_slice_to_array_valid), + cmocka_unit_test(test_slice_to_array_null_slice), + }; + int rc = 0; rc += cmocka_run_group_tests(init, NULL, NULL); @@ -1974,6 +2011,7 @@ int main(void) { rc += cmocka_run_group_tests(slice_next, NULL, NULL); rc += cmocka_run_group_tests(slice_reset, NULL, NULL); rc += cmocka_run_group_tests(slice_advance, NULL, NULL); + rc += cmocka_run_group_tests(slice_to_array, NULL, NULL); return rc; } -- 2.51.0