xref: /netbsd-src/external/bsd/wpa/dist/src/utils/list.h (revision bb6183629cf165db498d8e1f4e2de129f7efb21c)
18dbcf02cSchristos /*
28dbcf02cSchristos  * Doubly-linked list
33d6c0713Schristos  * Copyright (c) 2009-2019, Jouni Malinen <j@w1.fi>
48dbcf02cSchristos  *
5e604d861Schristos  * This software may be distributed under the terms of the BSD license.
6e604d861Schristos  * See README for more details.
78dbcf02cSchristos  */
88dbcf02cSchristos 
98dbcf02cSchristos #ifndef LIST_H
108dbcf02cSchristos #define LIST_H
118dbcf02cSchristos 
128dbcf02cSchristos /**
138dbcf02cSchristos  * struct dl_list - Doubly-linked list
148dbcf02cSchristos  */
158dbcf02cSchristos struct dl_list {
168dbcf02cSchristos 	struct dl_list *next;
178dbcf02cSchristos 	struct dl_list *prev;
188dbcf02cSchristos };
198dbcf02cSchristos 
20bb610346Schristos #define DL_LIST_HEAD_INIT(l) { &(l), &(l) }
21bb610346Schristos 
228dbcf02cSchristos static inline void dl_list_init(struct dl_list *list)
238dbcf02cSchristos {
248dbcf02cSchristos 	list->next = list;
258dbcf02cSchristos 	list->prev = list;
268dbcf02cSchristos }
278dbcf02cSchristos 
288dbcf02cSchristos static inline void dl_list_add(struct dl_list *list, struct dl_list *item)
298dbcf02cSchristos {
308dbcf02cSchristos 	item->next = list->next;
318dbcf02cSchristos 	item->prev = list;
328dbcf02cSchristos 	list->next->prev = item;
338dbcf02cSchristos 	list->next = item;
348dbcf02cSchristos }
358dbcf02cSchristos 
368dbcf02cSchristos static inline void dl_list_add_tail(struct dl_list *list, struct dl_list *item)
378dbcf02cSchristos {
388dbcf02cSchristos 	dl_list_add(list->prev, item);
398dbcf02cSchristos }
408dbcf02cSchristos 
418dbcf02cSchristos static inline void dl_list_del(struct dl_list *item)
428dbcf02cSchristos {
438dbcf02cSchristos 	item->next->prev = item->prev;
448dbcf02cSchristos 	item->prev->next = item->next;
458dbcf02cSchristos 	item->next = NULL;
468dbcf02cSchristos 	item->prev = NULL;
478dbcf02cSchristos }
488dbcf02cSchristos 
49*bb618362Schristos static inline int dl_list_empty(const struct dl_list *list)
508dbcf02cSchristos {
518dbcf02cSchristos 	return list->next == list;
528dbcf02cSchristos }
538dbcf02cSchristos 
54*bb618362Schristos static inline unsigned int dl_list_len(const struct dl_list *list)
558dbcf02cSchristos {
568dbcf02cSchristos 	struct dl_list *item;
578dbcf02cSchristos 	int count = 0;
588dbcf02cSchristos 	for (item = list->next; item != list; item = item->next)
598dbcf02cSchristos 		count++;
608dbcf02cSchristos 	return count;
618dbcf02cSchristos }
628dbcf02cSchristos 
638dbcf02cSchristos #ifndef offsetof
648dbcf02cSchristos #define offsetof(type, member) ((long) &((type *) 0)->member)
658dbcf02cSchristos #endif
668dbcf02cSchristos 
678dbcf02cSchristos #define dl_list_entry(item, type, member) \
688dbcf02cSchristos 	((type *) ((char *) item - offsetof(type, member)))
698dbcf02cSchristos 
708dbcf02cSchristos #define dl_list_first(list, type, member) \
718dbcf02cSchristos 	(dl_list_empty((list)) ? NULL : \
728dbcf02cSchristos 	 dl_list_entry((list)->next, type, member))
738dbcf02cSchristos 
74111b9fd8Schristos #define dl_list_last(list, type, member) \
75111b9fd8Schristos 	(dl_list_empty((list)) ? NULL : \
76111b9fd8Schristos 	 dl_list_entry((list)->prev, type, member))
77111b9fd8Schristos 
788dbcf02cSchristos #define dl_list_for_each(item, list, type, member) \
79*bb618362Schristos 	for (item = dl_list_entry((list)->next, type, member); \
80*bb618362Schristos 	     &item->member != (list); \
818dbcf02cSchristos 	     item = dl_list_entry(item->member.next, type, member))
828dbcf02cSchristos 
838dbcf02cSchristos #define dl_list_for_each_safe(item, n, list, type, member) \
848dbcf02cSchristos 	for (item = dl_list_entry((list)->next, type, member), \
858dbcf02cSchristos 		     n = dl_list_entry(item->member.next, type, member); \
868dbcf02cSchristos 	     &item->member != (list); \
878dbcf02cSchristos 	     item = n, n = dl_list_entry(n->member.next, type, member))
888dbcf02cSchristos 
89111b9fd8Schristos #define dl_list_for_each_reverse(item, list, type, member) \
90111b9fd8Schristos 	for (item = dl_list_entry((list)->prev, type, member); \
91111b9fd8Schristos 	     &item->member != (list); \
92111b9fd8Schristos 	     item = dl_list_entry(item->member.prev, type, member))
93111b9fd8Schristos 
94111b9fd8Schristos #define DEFINE_DL_LIST(name) \
95111b9fd8Schristos 	struct dl_list name = { &(name), &(name) }
96111b9fd8Schristos 
978dbcf02cSchristos #endif /* LIST_H */
98