diff --git a/CMakeLists.txt b/CMakeLists.txt index ae8d2c9..4983ec7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 4.2) project(dynamic_array LANGUAGES C) -set(CMAKE_C_STANDARD 23) +set(CMAKE_C_STANDARD 11) # Configures Testing Framework diff --git a/src/dynamic_array.c b/src/dynamic_array.c index 06839c9..4cc5798 100644 --- a/src/dynamic_array.c +++ b/src/dynamic_array.c @@ -7,7 +7,7 @@ Array *array_create(const ArrayCreateOptions *options) { const ArrayCreateOptions opt = options != NULL ? *options : DEFAULT_ARRAY_CREATE_OPTIONS; - const auto array = (Array*) malloc(sizeof(Array)); + Array *array = (Array*) malloc(sizeof(Array)); array->capacity = opt.initial_size; array->value = (int*) calloc(array->capacity, sizeof(int)); @@ -20,7 +20,7 @@ void array_deconstructor(Array **pp_array) { free((*pp_array)->value); free(*pp_array); - *pp_array = nullptr; + *pp_array = NULL; } void array_resize(Array *p_array, const int new_size) { @@ -39,15 +39,29 @@ void array_resize(Array *p_array, const int new_size) { int *array_get_value(const Array *array, const int index) { if (index > array->capacity) { - return nullptr; + return NULL; } return &array->value[index]; } void array_set_value(Array *p_array, const int index, const int value) { if (index > p_array->capacity) { - const int new_size = (index - p_array->capacity) * 2 + p_array->capacity; + int new_size = p_array->capacity; + while (index >= new_size) { + new_size *= 2; + } array_resize(p_array, new_size); } + if (index >= p_array->size) { + p_array->size = index + 1; + } p_array->value[index] = value; } + +int array_get_size(const Array *p_array) { + return p_array->size; +} + +int array_get_capacity(const Array *p_array) { + return p_array->capacity; +} diff --git a/src/dynamic_array.h b/src/dynamic_array.h index 8fe8297..ca8e334 100644 --- a/src/dynamic_array.h +++ b/src/dynamic_array.h @@ -30,4 +30,10 @@ void array_resize(Array *p_array, int new_size); int *array_get_value(const Array *p_array, int index); -void array_set_value(Array *p_array, int index, int value); \ No newline at end of file +void array_set_value(Array *p_array, int index, int value); + + +int array_get_size(const Array *p_array); + + +int array_get_capacity(const Array *p_array); diff --git a/src/test_dynamic_array.c b/src/test_dynamic_array.c index f5ab602..a23568f 100644 --- a/src/test_dynamic_array.c +++ b/src/test_dynamic_array.c @@ -11,7 +11,7 @@ void tearDown() { void test_array_create_without_options(void) { - Array *array = array_create(nullptr); + const Array *array = array_create(NULL); TEST_ASSERT_EQUAL(DEFAULT_ARRAY_SIZE, array->capacity); } @@ -27,12 +27,245 @@ void test_array_create_with_options(void) { void test_array_deconstruct(void) { - Array *array = array_create(nullptr); + Array *array = array_create(NULL); array_deconstructor(&array); TEST_ASSERT_NULL(array); } +void test_array_resize_expand(void) { + Array *array = array_create(NULL); + const int ORIGINAL_CAPACITY = array->capacity; + const int NEW_CAPACITY = 30; + + array_resize(array, NEW_CAPACITY); + + TEST_ASSERT_EQUAL(NEW_CAPACITY, array->capacity); + TEST_ASSERT_GREATER_THAN(ORIGINAL_CAPACITY, array->capacity); + + array_deconstructor(&array); +} + + +void test_array_resize_shrink(void) { + Array *array = array_create(&(ArrayCreateOptions){.initial_size = 50}); + const int NEW_CAPACITY = 20; + + array_resize(array, NEW_CAPACITY); + + TEST_ASSERT_EQUAL(NEW_CAPACITY, array->capacity); + + array_deconstructor(&array); +} + + +void test_array_set_value_within_capacity(void) { + Array *array = array_create(NULL); + const int INDEX = 5; + const int VALUE = 42; + + array_set_value(array, INDEX, VALUE); + + TEST_ASSERT_EQUAL(VALUE, array->value[INDEX]); + + array_deconstructor(&array); +} + + +void test_array_set_value_beyond_capacity(void) { + Array *array = array_create(NULL); + const int INDEX = 50; + const int VALUE = 99; + const int ORIGINAL_CAPACITY = array->capacity; + + array_set_value(array, INDEX, VALUE); + + TEST_ASSERT_GREATER_THAN(ORIGINAL_CAPACITY, array->capacity); + TEST_ASSERT_EQUAL(VALUE, array->value[INDEX]); + + array_deconstructor(&array); +} + + +void test_array_get_value_valid_index(void) { + Array *array = array_create(NULL); + const int INDEX = 3; + const int VALUE = 77; + + array->value[INDEX] = VALUE; + int *result = array_get_value(array, INDEX); + + TEST_ASSERT_NOT_NULL(result); + TEST_ASSERT_EQUAL(VALUE, *result); + + array_deconstructor(&array); +} + + +void test_array_get_value_zero_index(void) { + Array *array = array_create(NULL); + const int VALUE = 100; + + array->value[0] = VALUE; + int *result = array_get_value(array, 0); + + TEST_ASSERT_NOT_NULL(result); + TEST_ASSERT_EQUAL(VALUE, *result); + + array_deconstructor(&array); +} + + +void test_array_get_value_beyond_capacity(void) { + Array *array = array_create(NULL); + + int *result = array_get_value(array, array->capacity + 1); + + TEST_ASSERT_NULL(result); + + array_deconstructor(&array); +} + + +void test_array_multiple_operations(void) { + Array *array = array_create(&(ArrayCreateOptions){.initial_size = 5}); + + array_set_value(array, 0, 10); + array_set_value(array, 1, 20); + array_set_value(array, 2, 30); + + TEST_ASSERT_EQUAL(10, *array_get_value(array, 0)); + TEST_ASSERT_EQUAL(20, *array_get_value(array, 1)); + TEST_ASSERT_EQUAL(30, *array_get_value(array, 2)); + + array_set_value(array, 10, 100); + TEST_ASSERT_EQUAL(100, *array_get_value(array, 10)); + + array_deconstructor(&array); +} + + +void test_array_get_capacity_default(void) { + Array *array = array_create(NULL); + + int capacity = array_get_capacity(array); + + TEST_ASSERT_EQUAL(DEFAULT_ARRAY_SIZE, capacity); + + array_deconstructor(&array); +} + + +void test_array_get_capacity_custom_size(void) { + const int EXPECTED_CAPACITY = 25; + Array *array = array_create(&(ArrayCreateOptions){.initial_size = EXPECTED_CAPACITY}); + + int capacity = array_get_capacity(array); + + TEST_ASSERT_EQUAL(EXPECTED_CAPACITY, capacity); + + array_deconstructor(&array); +} + + +void test_array_get_capacity_after_resize(void) { + Array *array = array_create(NULL); + const int ORIGINAL_CAPACITY = array_get_capacity(array); + const int NEW_CAPACITY = 50; + + array_resize(array, NEW_CAPACITY); + int capacity = array_get_capacity(array); + + TEST_ASSERT_EQUAL(NEW_CAPACITY, capacity); + TEST_ASSERT_NOT_EQUAL(ORIGINAL_CAPACITY, capacity); + + array_deconstructor(&array); +} + + +void test_array_get_size_initial(void) { + Array *array = array_create(NULL); + + int size = array_get_size(array); + + TEST_ASSERT_EQUAL(0, size); + + array_deconstructor(&array); +} + + +void test_array_get_size_after_single_set(void) { + Array *array = array_create(NULL); + + array_set_value(array, 0, 42); + int size = array_get_size(array); + + TEST_ASSERT_EQUAL(1, size); + + array_deconstructor(&array); +} + + +void test_array_get_size_after_multiple_sets(void) { + Array *array = array_create(NULL); + + array_set_value(array, 0, 10); + array_set_value(array, 1, 20); + array_set_value(array, 2, 30); + int size = array_get_size(array); + + TEST_ASSERT_EQUAL(3, size); + + array_deconstructor(&array); +} + + +void test_array_get_size_with_gap_in_indices(void) { + Array *array = array_create(NULL); + + array_set_value(array, 0, 10); + array_set_value(array, 5, 50); + int size = array_get_size(array); + + TEST_ASSERT_EQUAL(6, size); + + array_deconstructor(&array); +} + + +void test_array_get_size_capacity_relationship(void) { + Array *array = array_create(&(ArrayCreateOptions){.initial_size = 10}); + + array_set_value(array, 0, 1); + array_set_value(array, 1, 2); + array_set_value(array, 2, 3); + + int size = array_get_size(array); + int capacity = array_get_capacity(array); + + TEST_ASSERT_LESS_OR_EQUAL(capacity, size); + TEST_ASSERT_EQUAL(3, size); + TEST_ASSERT_EQUAL(10, capacity); + + array_deconstructor(&array); +} + + +void test_array_get_size_after_resize_beyond_capacity(void) { + Array *array = array_create(&(ArrayCreateOptions){.initial_size = 5}); + + array_set_value(array, 0, 10); + array_set_value(array, 15, 100); + int size = array_get_size(array); + int capacity = array_get_capacity(array); + + TEST_ASSERT_EQUAL(16, size); + TEST_ASSERT_LESS_OR_EQUAL(capacity, size); + + array_deconstructor(&array); +} + + int main(void) { UNITY_BEGIN(); @@ -40,6 +273,23 @@ int main(void) RUN_TEST(test_array_create_without_options); RUN_TEST(test_array_create_with_options); RUN_TEST(test_array_deconstruct); + RUN_TEST(test_array_resize_expand); + RUN_TEST(test_array_resize_shrink); + RUN_TEST(test_array_set_value_within_capacity); + RUN_TEST(test_array_set_value_beyond_capacity); + RUN_TEST(test_array_get_value_valid_index); + RUN_TEST(test_array_get_value_zero_index); + RUN_TEST(test_array_get_value_beyond_capacity); + RUN_TEST(test_array_multiple_operations); + RUN_TEST(test_array_get_capacity_default); + RUN_TEST(test_array_get_capacity_custom_size); + RUN_TEST(test_array_get_capacity_after_resize); + RUN_TEST(test_array_get_size_initial); + RUN_TEST(test_array_get_size_after_single_set); + RUN_TEST(test_array_get_size_after_multiple_sets); + RUN_TEST(test_array_get_size_with_gap_in_indices); + RUN_TEST(test_array_get_size_capacity_relationship); + RUN_TEST(test_array_get_size_after_resize_beyond_capacity); return UNITY_END(); } \ No newline at end of file