list.h revision 1f69aa52ea2e0a73ac502565df8c666ee49cab6a
1/*
2 * Doubly-linked list
3 * Copyright (c) 2009, Jouni Malinen <j@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 */
21struct dl_list {
22	struct dl_list *next;
23	struct dl_list *prev;
24};
25
26static inline void dl_list_init(struct dl_list *list)
27{
28	list->next = list;
29	list->prev = list;
30}
31
32static 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
40static inline void dl_list_add_tail(struct dl_list *list, struct dl_list *item)
41{
42	dl_list_add(list->prev, item);
43}
44
45static 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
53static inline int dl_list_empty(struct dl_list *list)
54{
55	return list->next == list;
56}
57
58static 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#define DEFINE_DL_LIST(name) \
99	struct dl_list name = { &(name), &(name) }
100
101#endif /* LIST_H */
102