1 /*
2 * Copyright (C) 2019 - 2020 Intel Corporation
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6 #ifndef _USFSTL_LIST_H_
7 #define _USFSTL_LIST_H_
8 #include <stddef.h>
9 #include <stdbool.h>
10
11 #ifndef offsetof
12 #define offsetof __builtin_offsetof
13 #endif
14
15 #ifndef container_of
16 #define container_of(ptr, type, member) ((type *)(void *)((char *)ptr - offsetof(type, member)))
17 #endif
18
19 struct usfstl_list_entry {
20 struct usfstl_list_entry *next, *prev;
21 };
22
23 struct usfstl_list {
24 struct usfstl_list_entry list;
25 };
26
27 #define USFSTL_LIST_INIT(name) { \
28 .list.next = &(name).list, \
29 .list.prev = &(name).list, \
30 }
31 #define USFSTL_LIST(name) struct usfstl_list name = USFSTL_LIST_INIT(name)
32
usfstl_list_init(struct usfstl_list * list)33 static inline void usfstl_list_init(struct usfstl_list *list)
34 {
35 list->list.next = &list->list;
36 list->list.prev = &list->list;
37 }
38
usfstl_list_insert_before(struct usfstl_list_entry * existing,struct usfstl_list_entry * new_entry)39 static inline void usfstl_list_insert_before(struct usfstl_list_entry *existing,
40 struct usfstl_list_entry *new_entry)
41 {
42 new_entry->prev = existing->prev;
43 existing->prev->next = new_entry;
44 existing->prev = new_entry;
45 new_entry->next = existing;
46 }
47
usfstl_list_append(struct usfstl_list * list,struct usfstl_list_entry * new_entry)48 static inline void usfstl_list_append(struct usfstl_list *list,
49 struct usfstl_list_entry *new_entry)
50 {
51 usfstl_list_insert_before(&list->list, new_entry);
52 }
53
54 #define usfstl_list_item(element, type, member) \
55 ((type *)container_of(element, type, member))
56
57 #define usfstl_next_item(_list, entry, type, member) \
58 ((entry)->member.next != &(_list)->list ? \
59 usfstl_list_item((entry)->member.next, type, member) :\
60 NULL)
61
62 #define usfstl_for_each_list_item(item, _list, member) \
63 for (item = usfstl_list_first_item(_list, typeof(*item), member); \
64 item; \
65 item = usfstl_next_item(_list, item, typeof(*item), member))
66
67 #define usfstl_for_each_list_item_safe(item, next, _list, member) \
68 for (item = usfstl_list_first_item(_list, typeof(*item), member), \
69 next = item ? usfstl_next_item(_list, item, typeof(*next), member) : NULL; \
70 item; \
71 item = next, \
72 next = item ? usfstl_next_item(_list, next, typeof(*next), member) : NULL)
73
74 #define usfstl_for_each_list_item_continue_safe(item, next, _list, member) \
75 for (item = item ? usfstl_next_item(_list, item, typeof(*item), member) : \
76 usfstl_list_first_item(_list, typeof(*item), member), \
77 next = item ? usfstl_next_item(_list, item, typeof(*item), member) : NULL; \
78 item; \
79 item = next, next = item ? usfstl_next_item(_list, next, typeof(*item), member) : NULL)
80
usfstl_list_empty(const struct usfstl_list * list)81 static inline bool usfstl_list_empty(const struct usfstl_list *list)
82 {
83 return list->list.next == &list->list;
84 }
85
86 #define usfstl_list_first_item(_list, type, member) \
87 (usfstl_list_empty(_list) ? NULL : usfstl_list_item((_list)->list.next, type, member))
88
usfstl_list_item_remove(struct usfstl_list_entry * entry)89 static inline void usfstl_list_item_remove(struct usfstl_list_entry *entry)
90 {
91 entry->next->prev = entry->prev;
92 entry->prev->next = entry->next;
93 entry->next = NULL;
94 entry->prev = NULL;
95 }
96
97 #endif // _USFSTL_LIST_H_
98