ReactOS 0.4.17-dev-966-gf06eace
list.h
Go to the documentation of this file.
1/*
2 * Linked lists support
3 *
4 * Copyright (C) 2002 Alexandre Julliard
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21#ifndef __WINE_SERVER_LIST_H
22#define __WINE_SERVER_LIST_H
23
24#include <stddef.h>
25
26#ifdef __cplusplus
27#define __WINE_SERVER_LIST_INLINE inline
28#else
29#if defined(__GNUC__)
30#define __WINE_SERVER_LIST_INLINE extern __inline__ __attribute__((__always_inline__,__gnu_inline__))
31#elif defined(_MSC_VER)
32#define __WINE_SERVER_LIST_INLINE __inline
33#else
34#define __WINE_SERVER_LIST_INLINE static
35#endif
36#endif
37
38struct list
39{
40 struct list *next;
41 struct list *prev;
42};
43
44/* Define a list like so:
45 *
46 * struct gadget
47 * {
48 * struct list entry; <-- doesn't have to be the first item in the struct
49 * int a, b;
50 * };
51 *
52 * static struct list global_gadgets = LIST_INIT( global_gadgets );
53 *
54 * or
55 *
56 * struct some_global_thing
57 * {
58 * struct list gadgets;
59 * };
60 *
61 * list_init( &some_global_thing->gadgets );
62 *
63 * Manipulate it like this:
64 *
65 * list_add_head( &global_gadgets, &new_gadget->entry );
66 * list_remove( &new_gadget->entry );
67 * list_add_after( &some_random_gadget->entry, &new_gadget->entry );
68 *
69 * And to iterate over it:
70 *
71 * struct gadget *gadget;
72 * LIST_FOR_EACH_ENTRY( gadget, &global_gadgets, struct gadget, entry )
73 * {
74 * ...
75 * }
76 *
77 */
78
79/* add an element after the specified one */
80__WINE_SERVER_LIST_INLINE void list_add_after( struct list *elem, struct list *to_add )
81{
82 to_add->next = elem->next;
83 to_add->prev = elem;
84 elem->next->prev = to_add;
85 elem->next = to_add;
86}
87
88/* add an element before the specified one */
90{
91 to_add->next = elem;
92 to_add->prev = elem->prev;
93 elem->prev->next = to_add;
94 elem->prev = to_add;
95}
96
97/* add element at the head of the list */
99{
101}
102
103/* add element at the tail of the list */
105{
107}
108
109/* remove an element from its list */
111{
112 elem->next->prev = elem->prev;
113 elem->prev->next = elem->next;
114}
115
116/* get the next element */
117__WINE_SERVER_LIST_INLINE struct list *list_next( const struct list *list, const struct list *elem )
118{
119 struct list *ret = elem->next;
120 if (elem->next == list) ret = NULL;
121 return ret;
122}
123
124/* get the previous element */
125__WINE_SERVER_LIST_INLINE struct list *list_prev( const struct list *list, const struct list *elem )
126{
127 struct list *ret = elem->prev;
128 if (elem->prev == list) ret = NULL;
129 return ret;
130}
131
132/* get the first element */
134{
135 return list_next( list, list );
136}
137
138/* get the last element */
140{
141 return list_prev( list, list );
142}
143
144/* check if a list is empty */
146{
147 return list->next == list;
148}
149
150/* initialize a list */
152{
153 list->next = list->prev = list;
154}
155
156/* count the elements of a list */
157__WINE_SERVER_LIST_INLINE unsigned int list_count( const struct list *list )
158{
159 unsigned count = 0;
160 const struct list *ptr;
161 for (ptr = list->next; ptr != list; ptr = ptr->next) count++;
162 return count;
163}
164
165/* move all elements from src to before the specified element */
167{
168 if (list_empty(src)) return;
169
170 dst->prev->next = src->next;
171 src->next->prev = dst->prev;
172 dst->prev = src->prev;
173 src->prev->next = dst;
174 list_init(src);
175}
176
177/* move all elements from src to after the specified element */
179{
180 if (list_empty(src)) return;
181
182 dst->next->prev = src->prev;
183 src->prev->next = dst->next;
184 dst->next = src->next;
185 src->next->prev = dst;
186 list_init(src);
187}
188
189/* move all elements from src to the tail of dst */
191{
193}
194
195/* move all elements from src to the head of dst */
197{
199}
200
201/* move the slice of elements from begin to end inclusive to the head of dst */
202__WINE_SERVER_LIST_INLINE void list_move_slice_head( struct list *dst, struct list *begin, struct list *end )
203{
204 struct list *dst_next = dst->next;
205 begin->prev->next = end->next;
206 end->next->prev = begin->prev;
207 dst->next = begin;
208 dst_next->prev = end;
209 begin->prev = dst;
210 end->next = dst_next;
211}
212
213/* move the slice of elements from begin to end inclusive to the tail of dst */
214__WINE_SERVER_LIST_INLINE void list_move_slice_tail( struct list *dst, struct list *begin, struct list *end )
215{
216 struct list *dst_prev = dst->prev;
217 begin->prev->next = end->next;
218 end->next->prev = begin->prev;
219 dst_prev->next = begin;
220 dst->prev = end;
221 begin->prev = dst_prev;
222 end->next = dst;
223}
224
225/* iterate through the list */
226#define LIST_FOR_EACH(cursor,list) \
227 for ((cursor) = (list)->next; (cursor) != (list); (cursor) = (cursor)->next)
228
229/* iterate through the list, with safety against removal */
230#define LIST_FOR_EACH_SAFE(cursor, cursor2, list) \
231 for ((cursor) = (list)->next, (cursor2) = (cursor)->next; \
232 (cursor) != (list); \
233 (cursor) = (cursor2), (cursor2) = (cursor)->next)
234
235/* iterate through the list using a list entry */
236#define LIST_FOR_EACH_ENTRY(elem, list, type, field) \
237 for ((elem) = LIST_ENTRY((list)->next, type, field); \
238 &(elem)->field != (list); \
239 (elem) = LIST_ENTRY((elem)->field.next, type, field))
240
241/* iterate through the list using a list entry, with safety against removal */
242#define LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, list, type, field) \
243 for ((cursor) = LIST_ENTRY((list)->next, type, field), \
244 (cursor2) = LIST_ENTRY((cursor)->field.next, type, field); \
245 &(cursor)->field != (list); \
246 (cursor) = (cursor2), \
247 (cursor2) = LIST_ENTRY((cursor)->field.next, type, field))
248
249/* iterate through the list in reverse order */
250#define LIST_FOR_EACH_REV(cursor,list) \
251 for ((cursor) = (list)->prev; (cursor) != (list); (cursor) = (cursor)->prev)
252
253/* iterate through the list in reverse order, with safety against removal */
254#define LIST_FOR_EACH_SAFE_REV(cursor, cursor2, list) \
255 for ((cursor) = (list)->prev, (cursor2) = (cursor)->prev; \
256 (cursor) != (list); \
257 (cursor) = (cursor2), (cursor2) = (cursor)->prev)
258
259/* iterate through the list in reverse order using a list entry */
260#define LIST_FOR_EACH_ENTRY_REV(elem, list, type, field) \
261 for ((elem) = LIST_ENTRY((list)->prev, type, field); \
262 &(elem)->field != (list); \
263 (elem) = LIST_ENTRY((elem)->field.prev, type, field))
264
265/* iterate through the list in reverse order using a list entry, with safety against removal */
266#define LIST_FOR_EACH_ENTRY_SAFE_REV(cursor, cursor2, list, type, field) \
267 for ((cursor) = LIST_ENTRY((list)->prev, type, field), \
268 (cursor2) = LIST_ENTRY((cursor)->field.prev, type, field); \
269 &(cursor)->field != (list); \
270 (cursor) = (cursor2), \
271 (cursor2) = LIST_ENTRY((cursor)->field.prev, type, field))
272
273/* macros for statically initialized lists */
274#define LIST_INIT(list) { &(list), &(list) }
275
276/* get pointer to object containing list element */
277#ifdef _WIN64
278#define LIST_ENTRY(elem, type, field) \
279 ((type *)((char *)(elem) - (unsigned long long)(&((type *)0)->field)))
280#else
281#define LIST_ENTRY(elem, type, field) \
282 ((type *)((char *)(elem) - (unsigned long)(&((type *)0)->field)))
283#endif
284
285#endif /* __WINE_SERVER_LIST_H */
static void list_remove(struct list_entry *entry)
Definition: list.h:90
static int list_empty(struct list_entry *head)
Definition: list.h:58
static void list_add_tail(struct list_entry *head, struct list_entry *entry)
Definition: list.h:83
static void list_add_head(struct list_entry *head, struct list_entry *entry)
Definition: list.h:76
static void list_init(struct list_entry *head)
Definition: list.h:51
Definition: list.h:39
struct list * next
Definition: list.h:40
struct list * prev
Definition: list.h:41
#define NULL
Definition: types.h:112
static void list_move_tail(struct list_head *list, struct list_head *head)
Definition: list.h:122
return ret
Definition: mutex.c:147
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLuint GLuint end
Definition: gl.h:1545
GLenum src
Definition: glext.h:6340
GLenum GLenum dst
Definition: glext.h:6340
static PVOID ptr
Definition: dispmode.c:27
static size_t elem
Definition: string.c:71
#define list
Definition: rosglue.h:35
__WINE_SERVER_LIST_INLINE unsigned int list_count(const struct list *list)
Definition: list.h:157
__WINE_SERVER_LIST_INLINE void list_move_after(struct list *dst, struct list *src)
Definition: list.h:178
__WINE_SERVER_LIST_INLINE struct list * list_prev(const struct list *list, const struct list *elem)
Definition: list.h:125
__WINE_SERVER_LIST_INLINE void list_move_slice_head(struct list *dst, struct list *begin, struct list *end)
Definition: list.h:202
#define __WINE_SERVER_LIST_INLINE
Definition: list.h:34
__WINE_SERVER_LIST_INLINE void list_move_head(struct list *dst, struct list *src)
Definition: list.h:196
__WINE_SERVER_LIST_INLINE struct list * list_next(const struct list *list, const struct list *elem)
Definition: list.h:117
__WINE_SERVER_LIST_INLINE void list_move_before(struct list *dst, struct list *src)
Definition: list.h:166
__WINE_SERVER_LIST_INLINE void list_add_before(struct list *elem, struct list *to_add)
Definition: list.h:89
__WINE_SERVER_LIST_INLINE void list_add_after(struct list *elem, struct list *to_add)
Definition: list.h:80
__WINE_SERVER_LIST_INLINE void list_move_slice_tail(struct list *dst, struct list *begin, struct list *end)
Definition: list.h:214
__WINE_SERVER_LIST_INLINE struct list * list_tail(const struct list *list)
Definition: list.h:139
Definition: list.h:15