Line data Source code
1 0 : /*
2 : * Copyright (c) 2016 Intel Corporation
3 : *
4 : * SPDX-License-Identifier: Apache-2.0
5 : */
6 :
7 : #ifndef ZEPHYR_INCLUDE_SYS_LIST_GEN_H_
8 : #define ZEPHYR_INCLUDE_SYS_LIST_GEN_H_
9 :
10 : #include <stddef.h>
11 : #include <stdbool.h>
12 : #include <zephyr/sys/util.h>
13 :
14 : #define Z_GENLIST_FOR_EACH_NODE(__lname, __l, __sn) \
15 : for ((__sn) = sys_ ## __lname ## _peek_head(__l); (__sn) != NULL; \
16 : (__sn) = sys_ ## __lname ## _peek_next(__sn))
17 :
18 :
19 : #define Z_GENLIST_ITERATE_FROM_NODE(__lname, __l, __sn) \
20 : for ((__sn) = (__sn) ? sys_ ## __lname ## _peek_next_no_check(__sn) \
21 : : sys_ ## __lname ## _peek_head(__l); \
22 : (__sn) != NULL; \
23 : (__sn) = sys_ ## __lname ## _peek_next(__sn))
24 :
25 : #define Z_GENLIST_FOR_EACH_NODE_SAFE(__lname, __l, __sn, __sns) \
26 : for ((__sn) = sys_ ## __lname ## _peek_head(__l), \
27 : (__sns) = sys_ ## __lname ## _peek_next(__sn); \
28 : (__sn) != NULL ; (__sn) = (__sns), \
29 : (__sns) = sys_ ## __lname ## _peek_next(__sn))
30 :
31 : #define Z_GENLIST_CONTAINER(__ln, __cn, __n) \
32 : ((__ln) ? CONTAINER_OF((__ln), __typeof__(*(__cn)), __n) : NULL)
33 :
34 : #define Z_GENLIST_PEEK_HEAD_CONTAINER(__lname, __l, __cn, __n) \
35 : Z_GENLIST_CONTAINER(sys_ ## __lname ## _peek_head(__l), __cn, __n)
36 :
37 : #define Z_GENLIST_PEEK_TAIL_CONTAINER(__lname, __l, __cn, __n) \
38 : Z_GENLIST_CONTAINER(sys_ ## __lname ## _peek_tail(__l), __cn, __n)
39 :
40 : #define Z_GENLIST_PEEK_NEXT_CONTAINER(__lname, __cn, __n) \
41 : ((__cn) ? Z_GENLIST_CONTAINER( \
42 : sys_ ## __lname ## _peek_next(&((__cn)->__n)), \
43 : __cn, __n) : NULL)
44 :
45 : #define Z_GENLIST_FOR_EACH_CONTAINER(__lname, __l, __cn, __n) \
46 : for ((__cn) = Z_GENLIST_PEEK_HEAD_CONTAINER(__lname, __l, __cn, \
47 : __n); \
48 : (__cn) != NULL; \
49 : (__cn) = Z_GENLIST_PEEK_NEXT_CONTAINER(__lname, __cn, __n))
50 :
51 : #define Z_GENLIST_FOR_EACH_CONTAINER_SAFE(__lname, __l, __cn, __cns, __n) \
52 : for ((__cn) = Z_GENLIST_PEEK_HEAD_CONTAINER(__lname, __l, __cn, __n), \
53 : (__cns) = Z_GENLIST_PEEK_NEXT_CONTAINER(__lname, __cn, __n); \
54 : (__cn) != NULL; (__cn) = (__cns), \
55 : (__cns) = Z_GENLIST_PEEK_NEXT_CONTAINER(__lname, __cn, __n))
56 :
57 : #define Z_GENLIST_IS_EMPTY(__lname) \
58 : static inline bool \
59 : sys_ ## __lname ## _is_empty(sys_ ## __lname ## _t *list) \
60 : { \
61 : return (sys_ ## __lname ## _peek_head(list) == NULL); \
62 : }
63 :
64 : #define Z_GENLIST_PEEK_NEXT_NO_CHECK(__lname, __nname) \
65 : static inline sys_ ## __nname ## _t * \
66 : sys_ ## __lname ## _peek_next_no_check(sys_ ## __nname ## _t *node) \
67 : { \
68 : return z_ ## __nname ## _next_peek(node); \
69 : }
70 :
71 : #define Z_GENLIST_PEEK_NEXT(__lname, __nname) \
72 : static inline sys_ ## __nname ## _t * \
73 : sys_ ## __lname ## _peek_next(sys_ ## __nname ## _t *node) \
74 : { \
75 : return (node != NULL) ? \
76 : sys_ ## __lname ## _peek_next_no_check(node) : \
77 : NULL; \
78 : }
79 :
80 : #define Z_GENLIST_PREPEND(__lname, __nname) \
81 : static inline void \
82 : sys_ ## __lname ## _prepend(sys_ ## __lname ## _t *list, \
83 : sys_ ## __nname ## _t *node) \
84 : { \
85 : z_ ## __nname ## _next_set(node, \
86 : sys_ ## __lname ## _peek_head(list)); \
87 : z_ ## __lname ## _head_set(list, node); \
88 : \
89 : if (sys_ ## __lname ## _peek_tail(list) == NULL) { \
90 : z_ ## __lname ## _tail_set(list, \
91 : sys_ ## __lname ## _peek_head(list)); \
92 : } \
93 : }
94 :
95 : #define Z_GENLIST_APPEND(__lname, __nname) \
96 : static inline void \
97 : sys_ ## __lname ## _append(sys_ ## __lname ## _t *list, \
98 : sys_ ## __nname ## _t *node) \
99 : { \
100 : z_ ## __nname ## _next_set(node, NULL); \
101 : \
102 : if (sys_ ## __lname ## _peek_tail(list) == NULL) { \
103 : z_ ## __lname ## _tail_set(list, node); \
104 : z_ ## __lname ## _head_set(list, node); \
105 : } else { \
106 : z_ ## __nname ## _next_set( \
107 : sys_ ## __lname ## _peek_tail(list), \
108 : node); \
109 : z_ ## __lname ## _tail_set(list, node); \
110 : } \
111 : }
112 :
113 : #define Z_GENLIST_APPEND_LIST(__lname, __nname) \
114 : static inline void \
115 : sys_ ## __lname ## _append_list(sys_ ## __lname ## _t *list, \
116 : void *head, void *tail) \
117 : { \
118 : if (head != NULL && tail != NULL) { \
119 : if (sys_ ## __lname ## _peek_tail(list) == NULL) { \
120 : z_ ## __lname ## _head_set(list, \
121 : (sys_ ## __nname ## _t *)head); \
122 : } else { \
123 : z_ ## __nname ## _next_set( \
124 : sys_ ## __lname ## _peek_tail(list), \
125 : (sys_ ## __nname ## _t *)head); \
126 : } \
127 : z_ ## __lname ## _tail_set(list, \
128 : (sys_ ## __nname ## _t *)tail); \
129 : } \
130 : }
131 :
132 : #define Z_GENLIST_MERGE_LIST(__lname, __nname) \
133 : static inline void \
134 : sys_ ## __lname ## _merge_ ## __lname ( \
135 : sys_ ## __lname ## _t *list, \
136 : sys_ ## __lname ## _t *list_to_append) \
137 : { \
138 : sys_ ## __nname ## _t *head, *tail; \
139 : head = sys_ ## __lname ## _peek_head(list_to_append); \
140 : tail = sys_ ## __lname ## _peek_tail(list_to_append); \
141 : sys_ ## __lname ## _append_list(list, head, tail); \
142 : sys_ ## __lname ## _init(list_to_append); \
143 : }
144 :
145 : #define Z_GENLIST_INSERT(__lname, __nname) \
146 : static inline void \
147 : sys_ ## __lname ## _insert(sys_ ## __lname ## _t *list, \
148 : sys_ ## __nname ## _t *prev, \
149 : sys_ ## __nname ## _t *node) \
150 : { \
151 : if (prev == NULL) { \
152 : sys_ ## __lname ## _prepend(list, node); \
153 : } else if (z_ ## __nname ## _next_peek(prev) == NULL) { \
154 : sys_ ## __lname ## _append(list, node); \
155 : } else { \
156 : z_ ## __nname ## _next_set(node, \
157 : z_ ## __nname ## _next_peek(prev)); \
158 : z_ ## __nname ## _next_set(prev, node); \
159 : } \
160 : }
161 :
162 : #define Z_GENLIST_GET_NOT_EMPTY(__lname, __nname) \
163 : static inline sys_ ## __nname ## _t * \
164 : sys_ ## __lname ## _get_not_empty(sys_ ## __lname ## _t *list) \
165 : { \
166 : sys_ ## __nname ## _t *node = \
167 : sys_ ## __lname ## _peek_head(list); \
168 : \
169 : z_ ## __lname ## _head_set(list, \
170 : z_ ## __nname ## _next_peek(node)); \
171 : if (sys_ ## __lname ## _peek_tail(list) == node) { \
172 : z_ ## __lname ## _tail_set(list, \
173 : sys_ ## __lname ## _peek_head(list)); \
174 : } \
175 : \
176 : return node; \
177 : }
178 :
179 : #define Z_GENLIST_GET(__lname, __nname) \
180 : static inline sys_ ## __nname ## _t * \
181 : sys_ ## __lname ## _get(sys_ ## __lname ## _t *list) \
182 : { \
183 : return sys_ ## __lname ## _is_empty(list) ? NULL : \
184 : sys_ ## __lname ## _get_not_empty(list); \
185 : }
186 :
187 : #define Z_GENLIST_REMOVE(__lname, __nname) \
188 : static inline void \
189 : sys_ ## __lname ## _remove(sys_ ## __lname ## _t *list, \
190 : sys_ ## __nname ## _t *prev_node, \
191 : sys_ ## __nname ## _t *node) \
192 : { \
193 : if (prev_node == NULL) { \
194 : z_ ## __lname ## _head_set(list, \
195 : z_ ## __nname ## _next_peek(node)); \
196 : \
197 : /* Was node also the tail? */ \
198 : if (sys_ ## __lname ## _peek_tail(list) == node) { \
199 : z_ ## __lname ## _tail_set(list, \
200 : sys_ ## __lname ## _peek_head(list)); \
201 : } \
202 : } else { \
203 : z_ ## __nname ## _next_set(prev_node, \
204 : z_ ## __nname ## _next_peek(node)); \
205 : \
206 : /* Was node the tail? */ \
207 : if (sys_ ## __lname ## _peek_tail(list) == node) { \
208 : z_ ## __lname ## _tail_set(list, \
209 : prev_node); \
210 : } \
211 : } \
212 : \
213 : z_ ## __nname ## _next_set(node, NULL); \
214 : }
215 :
216 : #define Z_GENLIST_FIND_AND_REMOVE(__lname, __nname) \
217 : static inline bool \
218 : sys_ ## __lname ## _find_and_remove(sys_ ## __lname ## _t *list, \
219 : sys_ ## __nname ## _t *node) \
220 : { \
221 : sys_ ## __nname ## _t *prev = NULL; \
222 : sys_ ## __nname ## _t *test; \
223 : \
224 : Z_GENLIST_FOR_EACH_NODE(__lname, list, test) { \
225 : if (test == node) { \
226 : sys_ ## __lname ## _remove(list, prev, \
227 : node); \
228 : return true; \
229 : } \
230 : \
231 : prev = test; \
232 : } \
233 : \
234 : return false; \
235 : }
236 :
237 : #define Z_GENLIST_FIND(__lname, __nname) \
238 : static inline bool sys_##__lname##_find( \
239 : sys_##__lname##_t *list, sys_##__nname##_t *node, sys_##__nname##_t **prev) \
240 : { \
241 : sys_##__nname##_t *current = NULL; \
242 : sys_##__nname##_t *previous = NULL; \
243 : \
244 : Z_GENLIST_FOR_EACH_NODE(__lname, list, current) { \
245 : if (current == node) { \
246 : if (prev != NULL) { \
247 : *prev = previous; \
248 : } \
249 : return true; \
250 : } \
251 : \
252 : previous = current; \
253 : } \
254 : \
255 : if (prev != NULL) { \
256 : *prev = previous; \
257 : } \
258 : \
259 : return false; \
260 : }
261 :
262 : #define Z_GENLIST_LEN(__lname, __nname) \
263 : static inline size_t sys_##__lname##_len(sys_##__lname##_t * list) \
264 : { \
265 : size_t len = 0; \
266 : static sys_##__nname##_t * node; \
267 : Z_GENLIST_FOR_EACH_NODE(__lname, list, node) { \
268 : len++; \
269 : } \
270 : return len; \
271 : }
272 :
273 : #endif /* ZEPHYR_INCLUDE_SYS_LIST_GEN_H_ */
|