]> git.lizzy.rs Git - nothing.git/blob - src/dynarray.c
Make Lt dynamic again
[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 #define DYNARRAY_INIT_CAPACITY 8
11
12 struct Dynarray
13 {
14     Lt *lt;
15     size_t element_size;
16     size_t capacity;
17     size_t count;
18     char *data;
19 };
20
21 Dynarray *create_dynarray(size_t element_size)
22 {
23     Lt *lt = create_lt();
24
25     Dynarray *dynarray = PUSH_LT(lt, nth_calloc(1, sizeof(Dynarray)), free);
26     if (dynarray == NULL) {
27         RETURN_LT(lt, NULL);
28     }
29     dynarray->lt = lt;
30
31     dynarray->element_size = element_size;
32     dynarray->capacity = DYNARRAY_INIT_CAPACITY;
33     dynarray->count = 0;
34
35     dynarray->data = PUSH_LT(lt, nth_calloc(DYNARRAY_INIT_CAPACITY, element_size), free);
36     if (dynarray->data == NULL) {
37         RETURN_LT(lt, NULL);
38     }
39
40     return dynarray;
41 }
42
43 void destroy_dynarray(Dynarray *dynarray)
44 {
45     trace_assert(dynarray);
46     RETURN_LT0(dynarray->lt);
47 }
48
49 size_t dynarray_count(const Dynarray *dynarray)
50 {
51     trace_assert(dynarray);
52     return dynarray->count;
53 }
54
55 void *dynarray_data(Dynarray *dynarray)
56 {
57     trace_assert(dynarray);
58     return dynarray->data;
59 }
60
61 void dynarray_clear(Dynarray *dynarray)
62 {
63     trace_assert(dynarray);
64     dynarray->count = 0;
65 }
66
67 int dynarray_push(Dynarray *dynarray, const void *element)
68 {
69     trace_assert(dynarray);
70     trace_assert(element);
71
72     if (dynarray->count >= dynarray->capacity) {
73         void *new_data = nth_realloc(
74             dynarray->data,
75             dynarray->capacity * dynarray->element_size * 2);
76         if (new_data == NULL) {
77             return -1;
78         }
79
80         dynarray->data = REPLACE_LT(dynarray->lt, dynarray->data, new_data);
81         if (dynarray->data == NULL) {
82             return -1;
83         }
84
85         dynarray->capacity *= 2;
86     }
87
88     memcpy(
89         (char*) dynarray->data + dynarray->count * dynarray->element_size,
90         element,
91         dynarray->element_size);
92
93     dynarray->count++;
94
95     return 0;
96 }
97
98 bool dynarray_contains(const Dynarray *dynarray,
99                        const void *element)
100 {
101     trace_assert(dynarray);
102     trace_assert(element);
103
104     for (size_t i = 0; i < dynarray->count; ++i) {
105         if (memcmp((const char*)dynarray->data + i * dynarray->element_size,
106                    (const char*)element,
107                    dynarray->element_size) == 0) {
108             return true;
109         }
110     }
111
112     return false;
113 }
114
115 void dynarray_delete_at(Dynarray *dynarray, size_t index)
116 {
117     trace_assert(dynarray);
118     trace_assert(index < dynarray->count);
119     memmove(
120         dynarray->data + index * dynarray->element_size,
121         dynarray->data + (index + 1) * dynarray->element_size,
122         dynarray->element_size * (dynarray->count - index - 1));
123     dynarray->count--;
124 }