NeoMutt
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
array.h
Go to the documentation of this file.
1
29#ifndef MUTT_MUTT_ARRAY_H
30#define MUTT_MUTT_ARRAY_H
31
32#include <stdbool.h>
33#include <string.h>
34#include "memory.h"
35
39#define ARRAY_HEADROOM 25
40
46#define ARRAY_HEAD(name, type) \
47 struct name \
48 { \
49 size_t size; \
50 size_t capacity; \
51 type *entries; \
52 }
53
57#define ARRAY_HEAD_INITIALIZER \
58 { 0, 0, NULL }
59
64#define ARRAY_INIT(head) \
65 memset((head), 0, sizeof(*(head)))
66
73#define ARRAY_EMPTY(head) \
74 ((head)->size == 0)
75
86#define ARRAY_SIZE(head) \
87 ((head)->size)
88
94#define ARRAY_CAPACITY(head) \
95 ((head)->capacity)
96
108#define ARRAY_GET(head, idx) \
109 ((head)->size > (idx) ? &(head)->entries[(idx)] : NULL)
110
122#define ARRAY_SET(head, idx, elem) \
123 (((head)->capacity > (idx) \
124 ? true \
125 : ARRAY_RESERVE((head), (idx) + 1)), \
126 ARRAY_SET_NORESERVE((head), (idx), (elem)))
127
134#define ARRAY_FIRST(head) \
135 ARRAY_GET((head), 0)
136
143#define ARRAY_LAST(head) \
144 (ARRAY_EMPTY((head)) \
145 ? NULL \
146 : ARRAY_GET((head), ARRAY_SIZE((head)) - 1))
147
155#define ARRAY_ADD(head, elem) \
156 (((head)->capacity > (head)->size \
157 ? true \
158 : ARRAY_RESERVE((head), (head)->size + 1)), \
159 ARRAY_ADD_NORESERVE((head), (elem)))
160
171#define ARRAY_SHRINK(head, num) \
172 ((head)->size -= MIN((num), (head)->size))
173
179#define ARRAY_ELEM_SIZE(head) \
180 (sizeof(*(head)->entries))
181
188#define ARRAY_RESERVE(head, num) \
189 (((head)->capacity > (num)) ? \
190 (head)->capacity : \
191 ((mutt_mem_realloc( \
192 &(head)->entries, ((num) + ARRAY_HEADROOM) * ARRAY_ELEM_SIZE(head))), \
193 (memset((head)->entries + (head)->capacity, 0, \
194 ((num) + ARRAY_HEADROOM - (head)->capacity) * \
195 ARRAY_ELEM_SIZE(head))), \
196 ((head)->capacity = (num) + ARRAY_HEADROOM)))
197
203#define ARRAY_FREE(head) \
204 (FREE(&(head)->entries), (head)->size = (head)->capacity = 0)
205
211#define ARRAY_FOREACH(elem, head) \
212 ARRAY_FOREACH_FROM_TO((elem), (head), 0, (head)->size)
213
222#define ARRAY_FOREACH_FROM(elem, head, from) \
223 ARRAY_FOREACH_FROM_TO((elem), (head), (from), (head)->size)
224
233#define ARRAY_FOREACH_TO(elem, head, to) \
234 ARRAY_FOREACH_FROM_TO((elem), (head), 0, (to))
235
246#define ARRAY_FOREACH_FROM_TO(elem, head, from, to) \
247 for (size_t ARRAY_FOREACH_IDX = (from); \
248 (ARRAY_FOREACH_IDX < (to)) && \
249 ((elem) = ARRAY_GET((head), ARRAY_FOREACH_IDX)); \
250 ARRAY_FOREACH_IDX++)
251
258#define ARRAY_IDX(head, elem) \
259 (elem - (head)->entries)
260
266#define ARRAY_REMOVE(head, elem) \
267 (memmove((elem), (elem) + 1, \
268 ARRAY_ELEM_SIZE((head)) * \
269 MAX(0, (ARRAY_SIZE((head)) - ARRAY_IDX((head), (elem)) - 1))), \
270 ARRAY_SHRINK((head), 1))
271
278#define ARRAY_SORT(head, fn, sdata) \
279 ((head)->entries && \
280 (mutt_qsort_r((head)->entries, ARRAY_SIZE(head), ARRAY_ELEM_SIZE(head), (fn), (sdata)), true))
281
282/******************************************************************************
283 * Internal APIs
284 *****************************************************************************/
285#define ARRAY_SET_NORESERVE(head, idx, elem) \
286 ((head)->capacity > (idx) \
287 ? (((head)->size = MAX((head)->size, ((idx) + 1))), \
288 ((head)->entries[(idx)] = (elem)), \
289 true) \
290 : false)
291
292#define ARRAY_ADD_NORESERVE(head, elem) \
293 ((head)->capacity > (head)->size \
294 ? (((head)->entries[(head)->size++] = (elem)), \
295 true) \
296 : false)
297
298#endif /* MUTT_MUTT_ARRAY_H */
Memory management wrappers.