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