Graphviz 14.0.2~dev.20251008.0253
Loading...
Searching...
No Matches
list.h
Go to the documentation of this file.
1
34
35#pragma once
36
37#include <assert.h>
38#include <stdint.h>
39#include <string.h>
40#include <util/list-private.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46static_assert(
47 offsetof(list_t_, base) == 0,
48 "LIST(<type>).base and LIST(<type>).impl.base will not alias each other");
49
55#define LIST(type) \
56 struct { \
57 union { \
58 type *base; \
59 list_t_ impl; \
60 }; \
61 void (*dtor)(type); \
62 type scratch; \
63 }
64
70#define LIST_DTOR_FREE ((void *)1)
71
80#define LIST_SIZE(list) gv_list_size_((list)->impl)
81
90#define LIST_IS_EMPTY(list) (LIST_SIZE(list) == 0)
91
101#define LIST_TRY_APPEND(list, item) \
102 gv_list_try_append_(&(list)->impl, \
103 ((list)->scratch = (item), &(list)->scratch), \
104 sizeof((list)->base[0]))
105
120#define LIST_APPEND(list, item) \
121 do { \
122 (list)->scratch = (item); \
123 const size_t slot_ = \
124 gv_list_append_slot_(&(list)->impl, sizeof((list)->base[0])); \
125 (list)->base[slot_] = (list)->scratch; \
126 } while (0)
127
138#define LIST_PREPEND(list, item) \
139 do { \
140 (list)->scratch = (item); \
141 const size_t slot_ = \
142 gv_list_prepend_slot_(&(list)->impl, sizeof((list)->base[0])); \
143 (list)->base[slot_] = (list)->scratch; \
144 } while (0)
145
155#define LIST_GET(list, index) \
156 ((list)->base[gv_list_get_((list)->impl, (index))])
157
168#define LIST_AT(list, index) \
169 (&(list)->base[gv_list_get_((list)->impl, (index))])
170
180#define LIST_FRONT(list) LIST_AT((list), 0)
181
191#define LIST_BACK(list) LIST_AT((list), LIST_SIZE(list) - 1)
192
202#define LIST_SET(list, index, item) \
203 do { \
204 (list)->scratch = (item); \
205 const size_t slot_ = gv_list_get_((list)->impl, (index)); \
206 LIST_DTOR_((list), slot_); \
207 (list)->base[slot_] = (list)->scratch; \
208 } while (0)
209
218#define LIST_REMOVE(list, item) \
219 do { \
220 /* get something we can take the address of */ \
221 (list)->scratch = (item); \
222 \
223 const size_t found_ = gv_list_find_((list)->impl, &(list)->scratch, \
224 sizeof((list)->base[0])); \
225 if (found_ == SIZE_MAX) { /* not found */ \
226 break; \
227 } \
228 \
229 LIST_DTOR_((list), found_); \
230 gv_list_remove_(&(list)->impl, found_, sizeof((list)->base[0])); \
231 } while (0)
232
240#define LIST_CLEAR(list) \
241 do { \
242 for (size_t i_ = 0; i_ < LIST_SIZE(list); ++i_) { \
243 const size_t slot_ = gv_list_get_((list)->impl, i_); \
244 LIST_DTOR_((list), slot_); \
245 } \
246 gv_list_clear_(&(list)->impl, sizeof((list)->base[0])); \
247 } while (0)
248
257#define LIST_RESERVE(list, capacity) \
258 gv_list_reserve_(&(list)->impl, capacity, sizeof((list)->base[0]))
259
273#define LIST_CONTAINS(list, needle) \
274 gv_list_contains_((list)->impl, \
275 ((void)((list)->base == &(needle)), &(needle)), \
276 sizeof((list)->base[0]))
277
286#define LIST_COPY(dst, src) \
287 do { \
288 memset((dst), 0, sizeof(*(dst))); \
289 (void)((dst)->base == (src)->base); \
290 (dst)->impl = gv_list_copy_((src)->impl, sizeof((src)->base[0])); \
291 (dst)->dtor = (src)->dtor; \
292 } while (0)
293
315#define LIST_IS_CONTIGUOUS(list) gv_list_is_contiguous_((list)->impl);
316
327#define LIST_SYNC(list) gv_list_sync_(&(list)->impl, sizeof((list)->base[0]))
328
338#define LIST_SORT(list, cmp) \
339 gv_list_sort_(&(list)->impl, (cmp), sizeof((list)->base[0]))
340
348#define LIST_REVERSE(list) \
349 gv_list_reverse_(&(list)->impl, sizeof((list)->base[0]))
350
358#define LIST_SHRINK_TO_FIT(list) \
359 gv_list_shrink_to_fit_(&(list)->impl, sizeof((list)->base[0]))
360
370#define LIST_FREE(list) \
371 do { \
372 LIST_CLEAR(list); \
373 gv_list_free_(&(list)->impl); \
374 } while (0)
375
384#define LIST_PUSH_BACK(list, item) LIST_APPEND((list), (item))
385
394#define LIST_POP_FRONT(list) \
395 (gv_list_pop_front_(&(list)->impl, &(list)->scratch, \
396 sizeof((list)->base[0])), \
397 (list)->scratch)
398
407#define LIST_POP_BACK(list) \
408 (gv_list_pop_back_(&(list)->impl, &(list)->scratch, \
409 sizeof((list)->base[0])), \
410 (list)->scratch)
411
422#define LIST_DROP_BACK(list) \
423 do { \
424 const size_t slot_ = gv_list_get_((list)->impl, LIST_SIZE(list) - 1); \
425 LIST_DTOR_((list), slot_); \
426 gv_list_pop_back_(&(list)->impl, &(list)->scratch, \
427 sizeof((list)->base[0])); \
428 } while (0)
429
443#define LIST_DETACH(list, datap, sizep) \
444 gv_list_detach_(&(list)->impl, ((void)((list)->base == *(datap)), (datap)), \
445 (sizep), sizeof((list)->base[0]))
446
447#ifdef __cplusplus
448}
449#endif
internal implementation details of list.h