19 #ifndef _BOILERPLATE_PRIVATE_LIST_H
20 #define _BOILERPLATE_PRIVATE_LIST_H
22 #ifndef _BOILERPLATE_LIST_H
23 #error "Do not include this file directly. Use <boilerplate/list.h> instead."
27 struct pvholder *next;
28 struct pvholder *prev;
35 #define PRIVATE_LIST_INITIALIZER(__name) \
36 { .head = { .next = &((__name).head), .prev = &((__name).head) } }
38 #define DEFINE_PRIVATE_LIST(__name) \
39 struct pvlistobj __name = PRIVATE_LIST_INITIALIZER(__name)
41 static inline void initpvh(
struct pvholder *holder)
43 holder->next = holder;
44 holder->prev = holder;
47 static inline void atpvh(
struct pvholder *head,
struct pvholder *holder)
51 holder->next = head->next;
52 holder->next->prev = holder;
56 static inline void dtpvh(
struct pvholder *holder)
58 holder->prev->next = holder->next;
59 holder->next->prev = holder->prev;
62 static inline void pvlist_init(
struct pvlistobj *list)
67 static inline void pvholder_init(
struct pvholder *holder)
76 static inline int pvholder_linked(
const struct pvholder *holder)
78 return !(holder->prev == holder->next &&
79 holder->prev == holder);
82 static inline void pvlist_prepend(
struct pvholder *holder,
struct pvlistobj *list)
84 atpvh(&list->head, holder);
87 static inline void pvlist_append(
struct pvholder *holder,
struct pvlistobj *list)
89 atpvh(list->head.prev, holder);
92 static inline void pvlist_insert(
struct pvholder *next,
struct pvholder *prev)
97 static inline void pvlist_join(
struct pvlistobj *lsrc,
struct pvlistobj *ldst)
99 struct pvholder *headsrc = lsrc->head.next;
100 struct pvholder *tailsrc = lsrc->head.prev;
101 struct pvholder *headdst = &ldst->head;
103 headsrc->prev->next = tailsrc->next;
104 tailsrc->next->prev = headsrc->prev;
105 headsrc->prev = headdst;
106 tailsrc->next = headdst->next;
107 headdst->next->prev = tailsrc;
108 headdst->next = headsrc;
111 static inline void pvlist_remove(
struct pvholder *holder)
116 static inline void pvlist_remove_init(
struct pvholder *holder)
122 static inline int pvlist_empty(
const struct pvlistobj *list)
124 return list->head.next == &list->head;
127 static inline struct pvholder *pvlist_pop(
struct pvlistobj *list)
129 struct pvholder *holder = list->head.next;
130 pvlist_remove(holder);
134 static inline int pvlist_heading_p(
const struct pvholder *holder,
135 const struct pvlistobj *list)
137 return list->head.next == holder;
140 #define pvlist_entry(ptr, type, member) \
141 container_of(ptr, type, member)
143 #define pvlist_first_entry(list, type, member) \
144 pvlist_entry((list)->head.next, type, member)
146 #define pvlist_last_entry(list, type, member) \
147 pvlist_entry((list)->head.prev, type, member)
149 #define pvlist_pop_entry(list, type, member) ({ \
150 struct pvholder *__holder = pvlist_pop(list); \
151 pvlist_entry(__holder, type, member); })
153 #define pvlist_for_each(pos, list) \
154 for (pos = (list)->head.next; \
155 pos != &(list)->head; pos = (pos)->next)
157 #define pvlist_for_each_reverse(pos, list) \
158 for (pos = (list)->head.prev; \
159 pos != &(list)->head; pos = (pos)->prev)
161 #define pvlist_for_each_safe(pos, tmp, list) \
162 for (pos = (list)->head.next, \
164 pos != &(list)->head; \
165 pos = tmp, tmp = (pos)->next)
167 #define pvlist_for_each_entry(pos, list, member) \
168 for (pos = pvlist_entry((list)->head.next, \
169 typeof(*pos), member); \
170 &(pos)->member != &(list)->head; \
171 pos = pvlist_entry((pos)->member.next, \
172 typeof(*pos), member))
174 #define pvlist_for_each_entry_safe(pos, tmp, list, member) \
175 for (pos = pvlist_entry((list)->head.next, \
176 typeof(*pos), member), \
177 tmp = pvlist_entry((pos)->member.next, \
178 typeof(*pos), member); \
179 &(pos)->member != &(list)->head; \
180 pos = tmp, tmp = pvlist_entry((pos)->member.next, \
181 typeof(*pos), member))
183 #define pvlist_for_each_entry_reverse(pos, list, member) \
184 for (pos = pvlist_entry((list)->head.prev, \
185 typeof(*pos), member); \
186 &pos->member != &(list)->head; \
187 pos = pvlist_entry(pos->member.prev, \
188 typeof(*pos), member))
190 #define pvlist_for_each_entry_reverse_safe(pos, tmp, list, member) \
191 for (pos = pvlist_entry((list)->head.prev, \
192 typeof(*pos), member), \
193 tmp = pvlist_entry((pos)->member.prev, \
194 typeof(*pos), member); \
195 &(pos)->member != &(list)->head; \
196 pos = tmp, tmp = pvlist_entry((pos)->member.prev, \
197 typeof(*pos), member))