diff --git a/src/arraylist.c b/src/arraylist.c index 6e822f3..f84f414 100644 --- a/src/arraylist.c +++ b/src/arraylist.c @@ -262,7 +262,7 @@ ArrayListErr arraylist_pop_front(ArrayList *arr, void *out) { memmove( arr->buffer, arr->buffer + arr->elem_size, - arr->len * arr->elem_size); + (arr->len - 1) * arr->elem_size); arr->len--; @@ -290,13 +290,10 @@ ArrayListErr arraylist_remove_at(ArrayList *arr, size_t index, void *out) { ); } - for (size_t i = index; i < arr->len; i++) { - memcpy( - arr->buffer + (index * arr->elem_size), - arr->buffer + ((i + 1) * arr->elem_size), - arr->elem_size - ); - } + memmove( + arr->buffer + (index * arr->elem_size), + arr->buffer + ((index + 1) * arr->elem_size), + (arr->len - index) * arr->elem_size); arr->len--; diff --git a/test/test_arraylist.c b/test/test_arraylist.c index 270a48e..1108a92 100644 --- a/test/test_arraylist.c +++ b/test/test_arraylist.c @@ -601,6 +601,99 @@ static void test_pop_front_null_out(void **state) { arraylist_destroy(&arr); } +// Remove at +static void test_remove_at_beginning(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); + } + + int m; + assert_uint_equal(arraylist_size(arr), 10); + assert_uint_equal(arraylist_remove_at(arr, 0, &m), ARRLIST_OK); + assert_uint_equal(arraylist_size(arr), 9); + assert_uint_equal(m, 0); + + arraylist_destroy(&arr); +} + +static void test_remove_at_middle(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); + } + + int m; + assert_uint_equal(arraylist_size(arr), 10); + assert_uint_equal(arraylist_remove_at(arr, 5, &m), ARRLIST_OK); + assert_uint_equal(arraylist_size(arr), 9); + assert_uint_equal(m, 5); + + arraylist_destroy(&arr); +} + +static void test_remove_at_end(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); + } + + int m; + assert_uint_equal(arraylist_size(arr), 10); + assert_uint_equal(arraylist_remove_at(arr, 9, &m), ARRLIST_OK); + assert_uint_equal(arraylist_size(arr), 9); + assert_uint_equal(m, 9); + + arraylist_destroy(&arr); +} + +static void test_remove_at_invalid_index(void **state) { + (void) state; + + ArrayList *arr = arraylist_init(64, sizeof(int)); + assert_non_null(arr); + + + int n = 8; + assert_uint_equal(arraylist_remove_at(arr, 80, &n), ARRLIST_OUT_OF_BOUNDS); + + arraylist_destroy(&arr); +} + +static void test_remove_at_null_array(void **state) { + (void) state; + + ArrayList *arr = NULL; + + int n = 8; + assert_uint_equal(arraylist_remove_at(arr, 0, &n), ARRLIST_NULL_ARG); +} + +static void test_remove_at_null_data(void **state) { + (void) state; + + ArrayList *arr = arraylist_init(64, sizeof(int)); + assert_non_null(arr); + + int n = 8; + assert_uint_equal(arraylist_push_back(arr, &n), ARRLIST_OK); + + assert_uint_equal(arraylist_remove_at(arr, 0, NULL), ARRLIST_OK); + + arraylist_destroy(&arr); +} int main(void) { const struct CMUnitTest init[] = { @@ -666,6 +759,15 @@ int main(void) { cmocka_unit_test(test_pop_front_null_out), }; + const struct CMUnitTest remove_at[] = { + cmocka_unit_test(test_remove_at_beginning), + cmocka_unit_test(test_remove_at_middle), + cmocka_unit_test(test_remove_at_end), + cmocka_unit_test(test_remove_at_invalid_index), + cmocka_unit_test(test_remove_at_null_array), + cmocka_unit_test(test_remove_at_null_data), + }; + int rc = 0; rc += cmocka_run_group_tests(init, NULL, NULL); @@ -676,6 +778,7 @@ int main(void) { rc += cmocka_run_group_tests(insert, NULL, NULL); rc += cmocka_run_group_tests(pop_back, NULL, NULL); rc += cmocka_run_group_tests(pop_front, NULL, NULL); + rc += cmocka_run_group_tests(remove_at, NULL, NULL); return rc; }