Thu, 17 Nov 2022 18:25:40 +0100
#219 array list: implement insert
src/array_list.c | file | annotate | diff | comparison | revisions | |
test/test_list.cpp | file | annotate | diff | comparison | revisions |
1.1 --- a/src/array_list.c Wed Nov 16 22:27:46 2022 +0100 1.2 +++ b/src/array_list.c Thu Nov 17 18:25:40 2022 +0100 1.3 @@ -29,6 +29,7 @@ 1.4 #include "cx/array_list.h" 1.5 #include <assert.h> 1.6 #include <string.h> 1.7 +#include <stdint.h> 1.8 1.9 /* LOW LEVEL ARRAY LIST FUNCTIONS */ 1.10 1.11 @@ -61,6 +62,12 @@ 1.12 return CX_ARRAY_COPY_REALLOC_NOT_SUPPORTED; 1.13 } 1.14 1.15 + /* check, if we need to repair the src pointer */ 1.16 + uintptr_t targetaddr = (uintptr_t) *target; 1.17 + uintptr_t srcaddr = (uintptr_t) src; 1.18 + bool repairsrc = targetaddr <= srcaddr 1.19 + && srcaddr < targetaddr + cap * elem_size; 1.20 + 1.21 /* increase capacity linearly */ 1.22 cap += 16; 1.23 1.24 @@ -72,6 +79,11 @@ 1.25 return CX_ARRAY_COPY_REALLOC_FAILED; 1.26 } 1.27 1.28 + /* repair src pointer, if necessary */ 1.29 + if (repairsrc) { 1.30 + src = ((char *) newmem) + (srcaddr - targetaddr); 1.31 + } 1.32 + 1.33 /* store new pointer and capacity */ 1.34 *target = newmem; 1.35 *capacity = cap; 1.36 @@ -82,7 +94,7 @@ 1.37 start += index * elem_size; 1.38 1.39 /* copy elements and set new size */ 1.40 - memcpy(start, src, elem_count * elem_size); 1.41 + memmove(start, src, elem_count * elem_size); 1.42 *size = newsize; 1.43 1.44 /* return successfully */ 1.45 @@ -137,7 +149,33 @@ 1.46 size_t index, 1.47 void const *elem 1.48 ) { 1.49 - return 1; 1.50 + if (index > list->size) { 1.51 + return 1; 1.52 + } else if (index == list->size) { 1.53 + return cx_arl_add(list, elem); 1.54 + } else { 1.55 + cx_array_list *arl = (cx_array_list *) list; 1.56 + 1.57 + /* move elements starting at index to the right */ 1.58 + if (cx_array_copy( 1.59 + &arl->data, 1.60 + &list->size, 1.61 + &list->capacity, 1.62 + index + 1, 1.63 + ((char *) arl->data) + index * list->itemsize, 1.64 + list->itemsize, 1.65 + list->size - index, 1.66 + &arl->reallocator 1.67 + )) { 1.68 + return 1; 1.69 + } 1.70 + 1.71 + /* place the element */ 1.72 + memcpy(((char *) arl->data) + index * list->itemsize, 1.73 + elem, list->itemsize); 1.74 + 1.75 + return 0; 1.76 + } 1.77 } 1.78 1.79 static int cx_arl_insert_iter(
2.1 --- a/test/test_list.cpp Wed Nov 16 22:27:46 2022 +0100 2.2 +++ b/test/test_list.cpp Thu Nov 17 18:25:40 2022 +0100 2.3 @@ -631,7 +631,7 @@ 2.4 EXPECT_EQ(list->size, 3); 2.5 EXPECT_EQ(cxListInsert(list, 3, &d), 0); 2.6 2.7 - EXPECT_EQ(list->size, 4); 2.8 + ASSERT_EQ(list->size, 4); 2.9 EXPECT_GE(list->capacity, list->size); 2.10 2.11 EXPECT_EQ(*(int *) cxListAt(list, 0), 47); 2.12 @@ -840,7 +840,6 @@ 2.13 } 2.14 2.15 TEST_F(ArrayList, cxListInsert) { 2.16 - ASSERT_EQ(1,0); // TODO: remove when implemented 2.17 verifyInsert(autofree(cxArrayListCreate(&testingAllocator, cx_cmp_int, sizeof(int), 2))); 2.18 } 2.19