]> git.lizzy.rs Git - nothing.git/blobdiff - src/dynarray.c
(#1139) Add labels to the test level
[nothing.git] / src / dynarray.c
index 2ae688349b170f8974f69d6d13a69f92ae64d289..5cda6bdfc4851a66f5a7b1754abf3662cda8a622 100644 (file)
@@ -46,6 +46,11 @@ void destroy_dynarray(Dynarray *dynarray)
     RETURN_LT0(dynarray->lt);
 }
 
+void *dynarray_pointer_at(Dynarray *dynarray, size_t index) {
+    trace_assert(index < dynarray->count);
+    return dynarray->data + index * dynarray->element_size;
+}
+
 size_t dynarray_count(const Dynarray *dynarray)
 {
     trace_assert(dynarray);
@@ -64,25 +69,37 @@ void dynarray_clear(Dynarray *dynarray)
     dynarray->count = 0;
 }
 
+static
+int dynarray_grow(Dynarray *dynarray)
+{
+    if (dynarray->count < dynarray->capacity) {
+        return 0;
+    }
+
+    void *new_data = nth_realloc(
+        dynarray->data,
+        dynarray->capacity * dynarray->element_size * 2);
+    if (new_data == NULL) {
+        return -1;
+    }
+
+    dynarray->data = REPLACE_LT(dynarray->lt, dynarray->data, new_data);
+    if (dynarray->data == NULL) {
+        return -1;
+    }
+
+    dynarray->capacity *= 2;
+
+    return 0;
+}
+
 int dynarray_push(Dynarray *dynarray, const void *element)
 {
     trace_assert(dynarray);
     trace_assert(element);
 
-    if (dynarray->count >= dynarray->capacity) {
-        void *new_data = nth_realloc(
-            dynarray->data,
-            dynarray->capacity * dynarray->element_size * 2);
-        if (new_data == NULL) {
-            return -1;
-        }
-
-        dynarray->data = REPLACE_LT(dynarray->lt, dynarray->data, new_data);
-        if (dynarray->data == NULL) {
-            return -1;
-        }
-
-        dynarray->capacity *= 2;
+    if (dynarray_grow(dynarray) < 0) {
+        return -1;
     }
 
     memcpy(
@@ -123,24 +140,33 @@ void dynarray_delete_at(Dynarray *dynarray, size_t index)
     dynarray->count--;
 }
 
-int dynarray_push_empty(Dynarray *dynarray)
+void dynarray_insert_before(Dynarray *dynarray, size_t index, void *element)
 {
     trace_assert(dynarray);
+    trace_assert(element);
+    trace_assert(index <= dynarray->count);
 
-    if (dynarray->count >= dynarray->capacity) {
-        void *new_data = nth_realloc(
-            dynarray->data,
-            dynarray->capacity * dynarray->element_size * 2);
-        if (new_data == NULL) {
-            return -1;
-        }
+    dynarray_grow(dynarray);
 
-        dynarray->data = REPLACE_LT(dynarray->lt, dynarray->data, new_data);
-        if (dynarray->data == NULL) {
-            return -1;
-        }
+    memmove(
+        dynarray->data + (index + 1) * dynarray->element_size,
+        dynarray->data + index * dynarray->element_size,
+        dynarray->element_size * (dynarray->count - index));
+
+    memcpy(
+        dynarray->data + index * dynarray->element_size,
+        element,
+        dynarray->element_size);
 
-        dynarray->capacity *= 2;
+    dynarray->count++;
+}
+
+int dynarray_push_empty(Dynarray *dynarray)
+{
+    trace_assert(dynarray);
+
+    if (dynarray_grow(dynarray) < 0) {
+        return -1;
     }
 
     memset(
@@ -154,3 +180,57 @@ int dynarray_push_empty(Dynarray *dynarray)
 }
 
 // TODO(#980): dynarray_push and dynarray_push_empty have duplicate codez
+
+void dynarray_pop(Dynarray *dynarray, void *element)
+{
+    trace_assert(dynarray);
+    trace_assert(dynarray->count > 0);
+
+    dynarray->count--;
+
+    if (element) {
+        memcpy(
+            element,
+            dynarray->data + dynarray->count * dynarray->element_size,
+            dynarray->element_size);
+    }
+}
+
+void dynarray_replace_at(Dynarray *dynarray, size_t index, void *element)
+{
+    trace_assert(dynarray);
+    trace_assert(element);
+    trace_assert(index < dynarray->count);
+
+    memcpy(
+        dynarray->data + index * dynarray->element_size,
+        element,
+        dynarray->element_size);
+}
+
+void dynarray_copy_to(Dynarray *dynarray, void *dest, size_t index)
+{
+    trace_assert(dynarray);
+    trace_assert(dest);
+    trace_assert(index < dynarray->count);
+
+    memcpy(dest, dynarray->data + index * dynarray->element_size, dynarray->element_size);
+}
+
+void dynarray_swap(Dynarray *dynarray, size_t i, size_t j)
+{
+    trace_assert(dynarray);
+    trace_assert(i < dynarray->count);
+    trace_assert(j < dynarray->count);
+
+    if (i == j) return;
+
+    char *a = dynarray_pointer_at(dynarray, i);
+    char *b = dynarray_pointer_at(dynarray, j);
+
+    for (size_t k = 0; k < dynarray->element_size; ++k) {
+        char t = a[k];
+        a[k] = b[k];
+        b[k] = t;
+    }
+}