1 /* 2 * Doubly-linked list 3 * Copyright (c) 2009, Jouni Malinen <j (at) w1.fi> 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License version 2 as 7 * published by the Free Software Foundation. 8 * 9 * Alternatively, this software may be distributed under the terms of BSD 10 * license. 11 * 12 * See README and COPYING for more details. 13 */ 14 15 #ifndef LIST_H 16 #define LIST_H 17 18 /** 19 * struct dl_list - Doubly-linked list 20 */ 21 struct dl_list { 22 struct dl_list *next; 23 struct dl_list *prev; 24 }; 25 26 static inline void dl_list_init(struct dl_list *list) 27 { 28 list->next = list; 29 list->prev = list; 30 } 31 32 static inline void dl_list_add(struct dl_list *list, struct dl_list *item) 33 { 34 item->next = list->next; 35 item->prev = list; 36 list->next->prev = item; 37 list->next = item; 38 } 39 40 static inline void dl_list_add_tail(struct dl_list *list, struct dl_list *item) 41 { 42 dl_list_add(list->prev, item); 43 } 44 45 static inline void dl_list_del(struct dl_list *item) 46 { 47 item->next->prev = item->prev; 48 item->prev->next = item->next; 49 item->next = NULL; 50 item->prev = NULL; 51 } 52 53 static inline int dl_list_empty(struct dl_list *list) 54 { 55 return list->next == list; 56 } 57 58 static inline unsigned int dl_list_len(struct dl_list *list) 59 { 60 struct dl_list *item; 61 int count = 0; 62 for (item = list->next; item != list; item = item->next) 63 count++; 64 return count; 65 } 66 67 #ifndef offsetof 68 #define offsetof(type, member) ((long) &((type *) 0)->member) 69 #endif 70 71 #define dl_list_entry(item, type, member) \ 72 ((type *) ((char *) item - offsetof(type, member))) 73 74 #define dl_list_first(list, type, member) \ 75 (dl_list_empty((list)) ? NULL : \ 76 dl_list_entry((list)->next, type, member)) 77 78 #define dl_list_last(list, type, member) \ 79 (dl_list_empty((list)) ? NULL : \ 80 dl_list_entry((list)->prev, type, member)) 81 82 #define dl_list_for_each(item, list, type, member) \ 83 for (item = dl_list_entry((list)->next, type, member); \ 84 &item->member != (list); \ 85 item = dl_list_entry(item->member.next, type, member)) 86 87 #define dl_list_for_each_safe(item, n, list, type, member) \ 88 for (item = dl_list_entry((list)->next, type, member), \ 89 n = dl_list_entry(item->member.next, type, member); \ 90 &item->member != (list); \ 91 item = n, n = dl_list_entry(n->member.next, type, member)) 92 93 #define dl_list_for_each_reverse(item, list, type, member) \ 94 for (item = dl_list_entry((list)->prev, type, member); \ 95 &item->member != (list); \ 96 item = dl_list_entry(item->member.prev, type, member)) 97 98 #endif /* LIST_H */ 99