PatchworkOS
Loading...
Searching...
No Matches
list.h
Go to the documentation of this file.
1#ifndef _SYS_LIST_H
2#define _SYS_LIST_H 1
3
5#include "_internal/NULL.h"
6
7#include <assert.h>
8#include <stdbool.h>
9#include <stdint.h>
10
27typedef struct list list_t;
28
37typedef struct list_entry
38{
39 struct list_entry* prev;
40 struct list_entry* next;
43
50typedef struct list
51{
55} list_t;
56
65#define LIST_FOR_EACH(elem, list, member) \
66 for ((elem) = CONTAINER_OF((list)->head.next, typeof(*elem), member); &(elem)->member != &((list)->head); \
67 (elem) = CONTAINER_OF((elem)->member.next, typeof(*elem), member))
68
81#define LIST_FOR_EACH_SAFE(elem, temp, list, member) \
82 for ((elem) = CONTAINER_OF((list)->head.next, typeof(*elem), member), \
83 (temp) = CONTAINER_OF((elem)->member.next, typeof(*elem), member); \
84 &(elem)->member != &((list)->head); \
85 (elem) = (temp), (temp) = CONTAINER_OF((elem)->member.next, typeof(*elem), member))
86
95#define LIST_FOR_EACH_REVERSE(elem, list, member) \
96 for ((elem) = CONTAINER_OF((list)->head.prev, typeof(*elem), member); &(elem)->member != &((list)->head); \
97 (elem) = CONTAINER_OF((elem)->member.prev, typeof(*elem), member))
98
110#define LIST_FOR_EACH_FROM(elem, start, list, member) \
111 for ((elem) = CONTAINER_OF(start, typeof(*elem), member); &(elem)->member != &((list)->head); \
112 (elem) = CONTAINER_OF((elem)->member.next, typeof(*elem), member))
113
123#define LIST_FOR_EACH_FROM_REVERSE(elem, start, list, member) \
124 for ((elem) = CONTAINER_OF(start, typeof(*elem), member); &(elem)->member != &((list)->head); \
125 (elem) = CONTAINER_OF((elem)->member.prev, typeof(*elem), member))
126
139#define LIST_FOR_EACH_TO(elem, end, list, member) \
140 for ((elem) = CONTAINER_OF((list)->head.next, typeof(*elem), member); \
141 &(elem)->member != &((list)->head) && &(elem)->member != (end); \
142 (elem) = CONTAINER_OF((elem)->member.next, typeof(*elem), member))
143
153#define LIST_FOR_EACH_TO_REVERSE(elem, end, list, member) \
154 for ((elem) = CONTAINER_OF((list)->head.prev, typeof(*elem), member); \
155 &(elem)->member != &((list)->head) && &(elem)->member != (end); \
156 (elem) = CONTAINER_OF((elem)->member.prev, typeof(*elem), member))
157
164#define LIST_ENTRY_CREATE(name) \
165 (list_entry_t) \
166 { \
167 .prev = &(name), .next = &(name), .list = NULL \
168 }
169
176#define LIST_CREATE(name) (list_t){.head = {.prev = &(name).head, .next = &(name).head, .list = &(name)}, .length = 0}
177
184static inline void list_entry_init(list_entry_t* entry)
185{
186 assert(entry != NULL);
187 entry->next = entry;
188 entry->prev = entry;
189 entry->list = NULL;
190}
191
198static inline void list_init(list_t* list)
199{
200 assert(list != NULL);
201 list_entry_init(&list->head);
202 list->head.next->list = list; // Also sets prev
203 list->length = 0;
204}
205
214static inline bool list_contains_entry(list_t* list, list_entry_t* entry)
215{
216 assert(list != NULL);
217 assert(entry != NULL);
218
219 return entry->list == list;
220}
221
229static inline bool list_is_empty(list_t* list)
230{
231 assert(list != NULL);
232
233 bool emptyByHead = (list->head.next == &list->head);
234 bool emptyByLength = (list->length == 0);
235
236 assert(emptyByHead == emptyByLength);
237
238 return emptyByHead;
239}
240
248static inline uint64_t list_length(list_t* list)
249{
250 assert(list != NULL);
251 return list->length;
252}
253
263static inline void list_add(list_t* list, list_entry_t* prev, list_entry_t* next, list_entry_t* entry)
264{
265 assert(list != NULL);
266 assert(prev != NULL);
267 assert(next != NULL);
268 assert(entry != NULL);
269 assert(entry->next == entry && entry->prev == entry);
270 assert(prev->next == next && next->prev == prev);
271 assert(entry->list == NULL);
272 assert(prev->list == list);
273 assert(next->list == list);
274
275 next->prev = entry;
276 entry->next = next;
277 entry->prev = prev;
278 prev->next = entry;
279
280 entry->list = list;
281 list->length++;
282}
283
292static inline void list_append(list_t* list, list_entry_t* prev, list_entry_t* entry)
293{
294 list_add(list, prev, prev->next, entry);
295}
296
305static inline void list_prepend(list_t* list, list_entry_t* head, list_entry_t* entry)
306{
307 list_add(list, head->prev, head, entry);
308}
309
317static inline void list_remove(list_t* list, list_entry_t* entry)
318{
319 if (entry->list == NULL)
320 {
321 return;
322 }
323
324 assert(list != NULL);
325 assert(entry != NULL);
326 assert(list->length > 0);
327 assert(entry != &list->head);
328 assert(entry->list == list);
329
330 entry->prev->next = entry->next;
331 entry->next->prev = entry->prev;
332 list_entry_init(entry);
333
334 entry->list = NULL;
335 list->length--;
336}
337
345static inline void list_push(list_t* list, list_entry_t* entry)
346{
347 assert(list != NULL);
348 assert(entry != NULL);
349 assert(entry->next == entry && entry->prev == entry);
350
351 list_add(list, list->head.prev, &list->head, entry);
352}
353
361static inline list_entry_t* list_pop(list_t* list)
362{
363 assert(list != NULL);
364
365 if (list_is_empty(list))
366 {
367 return NULL;
368 }
369
370 list_entry_t* entry = list->head.next;
371 list_remove(list, entry);
372 return entry;
373}
374
382static inline list_entry_t* list_first(list_t* list)
383{
384 assert(list != NULL);
385
386 if (list_is_empty(list))
387 {
388 return NULL;
389 }
390 return list->head.next;
391}
392
400static inline list_entry_t* list_last(list_t* list)
401{
402 assert(list != NULL);
403
404 if (list_is_empty(list))
405 {
406 return NULL;
407 }
408 return list->head.prev;
409}
410
411#endif
412
#define assert(expression)
Definition assert.h:29
static list_entry_t * list_first(list_t *list)
Gets the first entry in the list without removing it.
Definition list.h:382
static uint64_t list_length(list_t *list)
Gets the length of the list.
Definition list.h:248
static list_entry_t * list_last(list_t *list)
Gets the last entry in the list without removing it.
Definition list.h:400
static void list_prepend(list_t *list, list_entry_t *head, list_entry_t *entry)
Prepends an entry to the list.
Definition list.h:305
static void list_remove(list_t *list, list_entry_t *entry)
Removes a list entry from its current list.
Definition list.h:317
static void list_push(list_t *list, list_entry_t *entry)
Pushes an entry to the end of the list.
Definition list.h:345
static void list_append(list_t *list, list_entry_t *prev, list_entry_t *entry)
Appends an entry to the list.
Definition list.h:292
static bool list_is_empty(list_t *list)
Checks if a list is empty.
Definition list.h:229
static void list_entry_init(list_entry_t *entry)
Initializes a list entry.
Definition list.h:184
static void list_add(list_t *list, list_entry_t *prev, list_entry_t *next, list_entry_t *entry)
Adds a new element between two existing list entries.
Definition list.h:263
static bool list_contains_entry(list_t *list, list_entry_t *entry)
Check if an entry belongs to a specific list.
Definition list.h:214
static void list_init(list_t *list)
Initializes a list.
Definition list.h:198
static list_entry_t * list_pop(list_t *list)
Pops the first entry from the list.
Definition list.h:361
#define NULL
Pointer error value.
Definition NULL.h:23
static atomic_long next
Definition main.c:10
__UINT64_TYPE__ uint64_t
Definition stdint.h:17
A entry in a doubly linked list.
Definition list.h:38
list_t * list
The list this entry belongs to.
Definition list.h:41
struct list_entry * next
The next entry in the list.
Definition list.h:40
struct list_entry * prev
The previous entry in the list.
Definition list.h:39
A doubly linked list.
Definition list.h:51
uint64_t length
The number of elements in the list (excluding the head).
Definition list.h:54
list_entry_t head
Definition list.h:52