]> git.lizzy.rs Git - nothing.git/blob - src/dynarray.c
Make Dynarray fixed
[nothing.git] / src / dynarray.c
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <string.h>
4
5 #include "system/stacktrace.h"
6 #include "system/lt.h"
7 #include "system/nth_alloc.h"
8 #include "dynarray.h"
9
10 void *dynarray_pointer_at(const Dynarray *dynarray, size_t index)
11 {
12     trace_assert(index < dynarray->count);
13     return (uint8_t *)dynarray->data + index * dynarray->element_size;
14 }
15
16 void dynarray_clear(Dynarray *dynarray)
17 {
18     trace_assert(dynarray);
19     dynarray->count = 0;
20 }
21
22 int dynarray_push(Dynarray *dynarray, const void *element)
23 {
24     trace_assert(dynarray);
25     trace_assert(element);
26     trace_assert(dynarray->count < DYNARRAY_CAPACITY);
27
28     memcpy(
29         (char*) dynarray->data + dynarray->count * dynarray->element_size,
30         element,
31         dynarray->element_size);
32
33     dynarray->count++;
34
35     return 0;
36 }
37
38 bool dynarray_contains(const Dynarray *dynarray,
39                        const void *element)
40 {
41     trace_assert(dynarray);
42     trace_assert(element);
43
44     for (size_t i = 0; i < dynarray->count; ++i) {
45         if (memcmp((const char*)dynarray->data + i * dynarray->element_size,
46                    (const char*)element,
47                    dynarray->element_size) == 0) {
48             return true;
49         }
50     }
51
52     return false;
53 }
54
55 void dynarray_delete_at(Dynarray *dynarray, size_t index)
56 {
57     trace_assert(dynarray);
58     trace_assert(index < dynarray->count);
59     memmove(
60         (uint8_t *) dynarray->data + index * dynarray->element_size,
61         (uint8_t *) dynarray->data + (index + 1) * dynarray->element_size,
62         dynarray->element_size * (dynarray->count - index - 1));
63     dynarray->count--;
64 }
65
66 void dynarray_insert_before(Dynarray *dynarray, size_t index, void *element)
67 {
68     trace_assert(dynarray);
69     trace_assert(element);
70     trace_assert(index < dynarray->count);
71
72     memmove(
73         (uint8_t*) dynarray->data + (index + 1) * dynarray->element_size,
74         (uint8_t*) dynarray->data + index * dynarray->element_size,
75         dynarray->element_size * (dynarray->count - index));
76
77     memcpy(
78         (uint8_t*) dynarray->data + index * dynarray->element_size,
79         element,
80         dynarray->element_size);
81
82     dynarray->count++;
83 }
84
85 int dynarray_push_empty(Dynarray *dynarray)
86 {
87     trace_assert(dynarray);
88     trace_assert(dynarray->count < DYNARRAY_CAPACITY);
89
90     memset(
91         (char*) dynarray->data + dynarray->count * dynarray->element_size,
92         0,
93         dynarray->element_size);
94
95     dynarray->count++;
96
97     return 0;
98 }
99
100 // TODO(#980): dynarray_push and dynarray_push_empty have duplicate codez
101
102 void dynarray_pop(Dynarray *dynarray, void *element)
103 {
104     trace_assert(dynarray);
105     trace_assert(dynarray->count > 0);
106
107     dynarray->count--;
108
109     if (element) {
110         memcpy(
111             element,
112             (uint8_t*) dynarray->data + dynarray->count * dynarray->element_size,
113             dynarray->element_size);
114     }
115 }
116
117 void dynarray_replace_at(Dynarray *dynarray, size_t index, void *element)
118 {
119     trace_assert(dynarray);
120     trace_assert(element);
121     trace_assert(index < dynarray->count);
122
123     memcpy(
124         (uint8_t*) dynarray->data + index * dynarray->element_size,
125         element,
126         dynarray->element_size);
127 }
128
129 void dynarray_copy_to(Dynarray *dynarray, void *dest, size_t index)
130 {
131     trace_assert(dynarray);
132     trace_assert(dest);
133     trace_assert(index < dynarray->count);
134
135     memcpy(dest, (uint8_t*) dynarray->data + index * dynarray->element_size, dynarray->element_size);
136 }
137
138 void dynarray_swap(Dynarray *dynarray, size_t i, size_t j)
139 {
140     trace_assert(dynarray);
141     trace_assert(i < dynarray->count);
142     trace_assert(j < dynarray->count);
143
144     if (i == j) return;
145
146     char *a = dynarray_pointer_at(dynarray, i);
147     char *b = dynarray_pointer_at(dynarray, j);
148
149     for (size_t k = 0; k < dynarray->element_size; ++k) {
150         char t = a[k];
151         a[k] = b[k];
152         b[k] = t;
153     }
154 }