Graphviz 13.1.3~dev.20250831.0023
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
106#define LIST_TRY_APPEND(list, item) \
107 (((list)->impl.size < (list)->impl.capacity || \
108 gv_list_try_reserve_( \
109 &(list)->impl, \
110 (list)->impl.capacity == 0 ? 1 : ((list)->impl.capacity * 2), \
111 sizeof((list)->base[0])) || \
112 gv_list_try_reserve_(&(list)->impl, (list)->impl.capacity + 1, \
113 sizeof((list)->base[0]))) && \
114 (((list)->base[gv_list_append_slot_(&(list)->impl, \
115 sizeof((list)->base[0]))] = (item)), \
116 1))
117
132#define LIST_APPEND(list, item) \
133 do { \
134 const size_t slot_ = \
135 gv_list_append_slot_(&(list)->impl, sizeof((list)->base[0])); \
136 (list)->base[slot_] = (item); \
137 } while (0)
138
149#define LIST_PREPEND(list, item) \
150 do { \
151 const size_t slot_ = \
152 gv_list_prepend_slot_(&(list)->impl, sizeof((list)->base[0])); \
153 (list)->base[slot_] = (item); \
154 } while (0)
155
165#define LIST_GET(list, index) \
166 ((list)->base[gv_list_get_((list)->impl, (index))])
167
178#define LIST_AT(list, index) \
179 (&(list)->base[gv_list_get_((list)->impl, (index))])
180
190#define LIST_FRONT(list) LIST_AT((list), 0)
191
201#define LIST_BACK(list) LIST_AT((list), LIST_SIZE(list) - 1)
202
212#define LIST_SET(list, index, item) \
213 do { \
214 const size_t slot_ = gv_list_get_((list)->impl, (index)); \
215 LIST_DTOR_((list), slot_); \
216 (list)->base[slot_] = (item); \
217 } while (0)
218
227#define LIST_REMOVE(list, item) \
228 do { \
229 /* get something we can take the address of */ \
230 (list)->scratch = (item); \
231 \
232 const size_t found_ = gv_list_find_((list)->impl, &(list)->scratch, \
233 sizeof((list)->base[0])); \
234 if (found_ == SIZE_MAX) { /* not found */ \
235 break; \
236 } \
237 \
238 LIST_DTOR_((list), found_); \
239 gv_list_remove_(&(list)->impl, found_, sizeof((list)->base[0])); \
240 } while (0)
241
249#define LIST_CLEAR(list) \
250 do { \
251 for (size_t i_ = 0; i_ < LIST_SIZE(list); ++i_) { \
252 const size_t slot_ = gv_list_get_((list)->impl, i_); \
253 LIST_DTOR_((list), slot_); \
254 } \
255 gv_list_clear_(&(list)->impl, sizeof((list)->base[0])); \
256 } while (0)
257
266#define LIST_RESERVE(list, capacity) \
267 gv_list_reserve_(&(list)->impl, capacity, sizeof((list)->base[0]))
268
282#define LIST_CONTAINS(list, needle) \
283 gv_list_contains_((list)->impl, \
284 ((void)((list)->base == &(needle)), &(needle)), \
285 sizeof((list)->base[0]))
286
295#define LIST_COPY(dst, src) \
296 do { \
297 (void)((dst)->base == (src)->base); \
298 memset((dst), 0, sizeof(*(dst))); \
299 (dst)->impl = gv_list_copy_((src)->impl, sizeof((src)->base[0])); \
300 (dst)->dtor = (src)->dtor; \
301 } while (0)
302
324#define LIST_IS_CONTIGUOUS(list) gv_list_is_contiguous_((list)->impl);
325
336#define LIST_SYNC(list) gv_list_sync_(&(list)->impl, sizeof((list)->base[0]))
337
347#define LIST_SORT(list, cmp) \
348 gv_list_sort_(&(list)->impl, (cmp), sizeof((list)->base[0]))
349
357#define LIST_REVERSE(list) \
358 gv_list_reverse_(&(list)->impl, sizeof((list)->base[0]))
359
367#define LIST_SHRINK_TO_FIT(list) \
368 gv_list_shrink_to_fit_(&(list)->impl, sizeof((list)->base[0]))
369
379#define LIST_FREE(list) \
380 do { \
381 LIST_CLEAR(list); \
382 gv_list_free_(&(list)->impl); \
383 } while (0)
384
393#define LIST_PUSH_BACK(list, item) LIST_APPEND((list), (item))
394
403#define LIST_POP_FRONT(list) \
404 (gv_list_pop_front_(&(list)->impl, &(list)->scratch, \
405 sizeof((list)->base[0])), \
406 (list)->scratch)
407
416#define LIST_POP_BACK(list) \
417 (gv_list_pop_back_(&(list)->impl, &(list)->scratch, \
418 sizeof((list)->base[0])), \
419 (list)->scratch)
420
434#define LIST_DETACH(list, datap, sizep) \
435 do { \
436 *(datap) = (list)->base; \
437 *(sizep) = (list)->impl.size; \
438 \
439 (list)->impl = (list_t_){0}; \
440 } while (0)
441
442#ifdef __cplusplus
443}
444#endif
internal implementation details of list.h