ReactOS
0.4.16-dev-1946-g52006dd
dynamic_array.h
Go to the documentation of this file.
1
#pragma once
2
3
#include <
uacpi/types.h
>
4
#include <
uacpi/internal/stdlib.h
>
5
#include <
uacpi/kernel_api.h
>
6
7
#define DYNAMIC_ARRAY_WITH_INLINE_STORAGE(name, type, inline_capacity) \
8
struct name { \
9
type inline_storage[inline_capacity]; \
10
type *dynamic_storage; \
11
uacpi_size dynamic_capacity; \
12
uacpi_size size_including_inline; \
13
}; \
14
15
#define DYNAMIC_ARRAY_SIZE(arr) ((arr)->size_including_inline)
16
17
#define DYNAMIC_ARRAY_WITH_INLINE_STORAGE_EXPORTS(name, type, prefix) \
18
prefix uacpi_size name##_inline_capacity(struct name *arr); \
19
prefix type *name##_at(struct name *arr, uacpi_size idx); \
20
prefix type *name##_alloc(struct name *arr); \
21
prefix type *name##_calloc(struct name *arr); \
22
prefix void name##_pop(struct name *arr); \
23
prefix uacpi_size name##_size(struct name *arr); \
24
prefix type *name##_last(struct name *arr) \
25
prefix void name##_clear(struct name *arr);
26
27
#ifndef UACPI_BAREBONES_MODE
28
#define DYNAMIC_ARRAY_ALLOC_FN(name, type, prefix) \
29
UACPI_MAYBE_UNUSED \
30
prefix type *name##_alloc(struct name *arr) \
31
{ \
32
uacpi_size inline_cap; \
33
type *out_ptr; \
34
\
35
inline_cap = name##_inline_capacity(arr); \
36
\
37
if (arr->size_including_inline >= inline_cap) { \
38
uacpi_size dynamic_size; \
39
\
40
dynamic_size = arr->size_including_inline - inline_cap; \
41
if (dynamic_size == arr->dynamic_capacity) { \
42
uacpi_size bytes, type_size; \
43
void *new_buf; \
44
\
45
type_size = sizeof(*arr->dynamic_storage); \
46
\
47
if (arr->dynamic_capacity == 0) { \
48
bytes = type_size * inline_cap; \
49
} else { \
50
bytes = (arr->dynamic_capacity / 2) * type_size; \
51
if (bytes == 0) \
52
bytes += type_size; \
53
\
54
bytes += arr->dynamic_capacity * type_size; \
55
} \
56
\
57
new_buf = uacpi_kernel_alloc(bytes); \
58
if (uacpi_unlikely(new_buf == UACPI_NULL)) \
59
return UACPI_NULL; \
60
\
61
arr->dynamic_capacity = bytes / type_size; \
62
\
63
if (arr->dynamic_storage) { \
64
uacpi_memcpy(new_buf, arr->dynamic_storage, \
65
dynamic_size * type_size); \
66
} \
67
uacpi_free(arr->dynamic_storage, dynamic_size * type_size); \
68
arr->dynamic_storage = new_buf; \
69
} \
70
\
71
out_ptr = &arr->dynamic_storage[dynamic_size]; \
72
goto ret; \
73
} \
74
out_ptr = &arr->inline_storage[arr->size_including_inline]; \
75
ret: \
76
arr->size_including_inline++; \
77
return out_ptr; \
78
}
79
80
#define DYNAMIC_ARRAY_CLEAR_FN(name, type, prefix) \
81
prefix void name##_clear(struct name *arr) \
82
{ \
83
uacpi_free( \
84
arr->dynamic_storage, \
85
arr->dynamic_capacity * sizeof(*arr->dynamic_storage) \
86
); \
87
arr->size_including_inline = 0; \
88
arr->dynamic_capacity = 0; \
89
arr->dynamic_storage = UACPI_NULL; \
90
}
91
#else
92
#define DYNAMIC_ARRAY_ALLOC_FN(name, type, prefix) \
93
UACPI_MAYBE_UNUSED \
94
prefix type *name##_alloc(struct name *arr) \
95
{ \
96
uacpi_size inline_cap; \
97
type *out_ptr; \
98
\
99
inline_cap = name##_inline_capacity(arr); \
100
\
101
if (arr->size_including_inline >= inline_cap) { \
102
uacpi_size dynamic_size; \
103
\
104
dynamic_size = arr->size_including_inline - inline_cap; \
105
if (uacpi_unlikely(dynamic_size == arr->dynamic_capacity)) \
106
return UACPI_NULL; \
107
\
108
out_ptr = &arr->dynamic_storage[dynamic_size]; \
109
goto ret; \
110
} \
111
out_ptr = &arr->inline_storage[arr->size_including_inline]; \
112
ret: \
113
arr->size_including_inline++; \
114
return out_ptr; \
115
}
116
117
#define DYNAMIC_ARRAY_CLEAR_FN(name, type, prefix) \
118
prefix void name##_clear(struct name *arr) \
119
{ \
120
arr->size_including_inline = 0; \
121
arr->dynamic_capacity = 0; \
122
arr->dynamic_storage = UACPI_NULL; \
123
}
124
#endif
125
126
#define DYNAMIC_ARRAY_WITH_INLINE_STORAGE_IMPL(name, type, prefix) \
127
UACPI_MAYBE_UNUSED \
128
prefix uacpi_size name##_inline_capacity(struct name *arr) \
129
{ \
130
return sizeof(arr->inline_storage) / sizeof(arr->inline_storage[0]); \
131
} \
132
\
133
UACPI_MAYBE_UNUSED \
134
prefix uacpi_size name##_capacity(struct name *arr) \
135
{ \
136
return name##_inline_capacity(arr) + arr->dynamic_capacity; \
137
} \
138
\
139
prefix type *name##_at(struct name *arr, uacpi_size idx) \
140
{ \
141
if (idx >= arr->size_including_inline) \
142
return UACPI_NULL; \
143
\
144
if (idx < name##_inline_capacity(arr)) \
145
return &arr->inline_storage[idx]; \
146
\
147
return &arr->dynamic_storage[idx - name##_inline_capacity(arr)]; \
148
} \
149
\
150
DYNAMIC_ARRAY_ALLOC_FN(name, type, prefix) \
151
\
152
UACPI_MAYBE_UNUSED \
153
prefix type *name##_calloc(struct name *arr) \
154
{ \
155
type *ret; \
156
\
157
ret = name##_alloc(arr); \
158
if (ret) \
159
uacpi_memzero(ret, sizeof(*ret)); \
160
\
161
return ret; \
162
} \
163
\
164
UACPI_MAYBE_UNUSED \
165
prefix void name##_pop(struct name *arr) \
166
{ \
167
if (arr->size_including_inline == 0) \
168
return; \
169
\
170
arr->size_including_inline--; \
171
} \
172
\
173
UACPI_MAYBE_UNUSED \
174
prefix uacpi_size name##_size(struct name *arr) \
175
{ \
176
return arr->size_including_inline; \
177
} \
178
\
179
UACPI_MAYBE_UNUSED \
180
prefix type *name##_last(struct name *arr) \
181
{ \
182
return name##_at(arr, arr->size_including_inline - 1); \
183
} \
184
\
185
DYNAMIC_ARRAY_CLEAR_FN(name, type, prefix)
stdlib.h
types.h
kernel_api.h
drivers
bus
acpi_new
uacpi
include
uacpi
internal
dynamic_array.h
Generated on Thu Dec 4 2025 06:06:01 for ReactOS by
1.9.6