#219 array list: implement insert

Thu, 17 Nov 2022 18:25:40 +0100

author
Mike Becker <universe@uap-core.de>
date
Thu, 17 Nov 2022 18:25:40 +0100
changeset 611
77efa5163ae5
parent 610
de5d3ee6435f
child 612
820ee59121b4

#219 array list: implement insert

src/array_list.c file | annotate | diff | comparison | revisions
test/test_list.cpp file | annotate | diff | comparison | revisions
--- a/src/array_list.c	Wed Nov 16 22:27:46 2022 +0100
+++ b/src/array_list.c	Thu Nov 17 18:25:40 2022 +0100
@@ -29,6 +29,7 @@
 #include "cx/array_list.h"
 #include <assert.h>
 #include <string.h>
+#include <stdint.h>
 
 /* LOW LEVEL ARRAY LIST FUNCTIONS */
 
@@ -61,6 +62,12 @@
             return CX_ARRAY_COPY_REALLOC_NOT_SUPPORTED;
         }
 
+        /* check, if we need to repair the src pointer */
+        uintptr_t targetaddr = (uintptr_t) *target;
+        uintptr_t srcaddr = (uintptr_t) src;
+        bool repairsrc = targetaddr <= srcaddr
+                         && srcaddr < targetaddr + cap * elem_size;
+
         /* increase capacity linearly */
         cap += 16;
 
@@ -72,6 +79,11 @@
             return CX_ARRAY_COPY_REALLOC_FAILED;
         }
 
+        /* repair src pointer, if necessary */
+        if (repairsrc) {
+            src = ((char *) newmem) + (srcaddr - targetaddr);
+        }
+
         /* store new pointer and capacity */
         *target = newmem;
         *capacity = cap;
@@ -82,7 +94,7 @@
     start += index * elem_size;
 
     /* copy elements and set new size */
-    memcpy(start, src, elem_count * elem_size);
+    memmove(start, src, elem_count * elem_size);
     *size = newsize;
 
     /* return successfully */
@@ -137,7 +149,33 @@
         size_t index,
         void const *elem
 ) {
-    return 1;
+    if (index > list->size) {
+        return 1;
+    } else if (index == list->size) {
+        return cx_arl_add(list, elem);
+    } else {
+        cx_array_list *arl = (cx_array_list *) list;
+
+        /* move elements starting at index to the right */
+        if (cx_array_copy(
+                &arl->data,
+                &list->size,
+                &list->capacity,
+                index + 1,
+                ((char *) arl->data) + index * list->itemsize,
+                list->itemsize,
+                list->size - index,
+                &arl->reallocator
+        )) {
+            return 1;
+        }
+
+        /* place the element */
+        memcpy(((char *) arl->data) + index * list->itemsize,
+               elem, list->itemsize);
+
+        return 0;
+    }
 }
 
 static int cx_arl_insert_iter(
--- a/test/test_list.cpp	Wed Nov 16 22:27:46 2022 +0100
+++ b/test/test_list.cpp	Thu Nov 17 18:25:40 2022 +0100
@@ -631,7 +631,7 @@
         EXPECT_EQ(list->size, 3);
         EXPECT_EQ(cxListInsert(list, 3, &d), 0);
 
-        EXPECT_EQ(list->size, 4);
+        ASSERT_EQ(list->size, 4);
         EXPECT_GE(list->capacity, list->size);
 
         EXPECT_EQ(*(int *) cxListAt(list, 0), 47);
@@ -840,7 +840,6 @@
 }
 
 TEST_F(ArrayList, cxListInsert) {
-    ASSERT_EQ(1,0); // TODO: remove when implemented
     verifyInsert(autofree(cxArrayListCreate(&testingAllocator, cx_cmp_int, sizeof(int), 2)));
 }
 

mercurial