]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/basic/list.h
Merge pull request #653 from dvdhrm/bus-gold
[thirdparty/systemd.git] / src / basic / list.h
CommitLineData
c2f1db8f 1#pragma once
60918275 2
a7334b09
LP
3/***
4 This file is part of systemd.
5
6 Copyright 2010 Lennart Poettering
7
8 systemd is free software; you can redistribute it and/or modify it
5430f7f2
LP
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
a7334b09
LP
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5430f7f2 16 Lesser General Public License for more details.
a7334b09 17
5430f7f2 18 You should have received a copy of the GNU Lesser General Public License
a7334b09
LP
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20***/
21
60918275
LP
22/* The head of the linked list. Use this in the structure that shall
23 * contain the head of the linked list */
24#define LIST_HEAD(t,name) \
034c6ed7 25 t *name
60918275
LP
26
27/* The pointers in the linked list's items. Use this in the item structure */
034c6ed7
LP
28#define LIST_FIELDS(t,name) \
29 t *name##_next, *name##_prev
60918275
LP
30
31/* Initialize the list's head */
71fda00f 32#define LIST_HEAD_INIT(head) \
60918275 33 do { \
034c6ed7 34 (head) = NULL; } \
9ed794a3 35 while (false)
60918275
LP
36
37/* Initialize a list item */
71fda00f 38#define LIST_INIT(name,item) \
60918275 39 do { \
71fda00f 40 typeof(*(item)) *_item = (item); \
60918275 41 assert(_item); \
034c6ed7 42 _item->name##_prev = _item->name##_next = NULL; \
9ed794a3 43 } while (false)
60918275
LP
44
45/* Prepend an item to the list */
71fda00f 46#define LIST_PREPEND(name,head,item) \
60918275 47 do { \
71fda00f 48 typeof(*(head)) **_head = &(head), *_item = (item); \
60918275 49 assert(_item); \
034c6ed7
LP
50 if ((_item->name##_next = *_head)) \
51 _item->name##_next->name##_prev = _item; \
52 _item->name##_prev = NULL; \
60918275 53 *_head = _item; \
9ed794a3 54 } while (false)
60918275 55
502f1733
ZJS
56/* Append an item to the list */
57#define LIST_APPEND(name,head,item) \
58 do { \
59 typeof(*(head)) *_tail; \
60 LIST_FIND_TAIL(name,head,_tail); \
61 LIST_INSERT_AFTER(name,head,_tail,item); \
9ed794a3 62 } while (false)
502f1733 63
60918275 64/* Remove an item from the list */
71fda00f 65#define LIST_REMOVE(name,head,item) \
60918275 66 do { \
71fda00f 67 typeof(*(head)) **_head = &(head), *_item = (item); \
60918275 68 assert(_item); \
034c6ed7
LP
69 if (_item->name##_next) \
70 _item->name##_next->name##_prev = _item->name##_prev; \
71 if (_item->name##_prev) \
72 _item->name##_prev->name##_next = _item->name##_next; \
60918275
LP
73 else { \
74 assert(*_head == _item); \
034c6ed7 75 *_head = _item->name##_next; \
60918275 76 } \
034c6ed7 77 _item->name##_next = _item->name##_prev = NULL; \
9ed794a3 78 } while (false)
60918275
LP
79
80/* Find the head of the list */
71fda00f 81#define LIST_FIND_HEAD(name,item,head) \
60918275 82 do { \
71fda00f 83 typeof(*(item)) *_item = (item); \
376cd3b8
LP
84 if (!_item) \
85 (head) = NULL; \
86 else { \
87 while (_item->name##_prev) \
88 _item = _item->name##_prev; \
89 (head) = _item; \
90 } \
034c6ed7
LP
91 } while (false)
92
3b18ae68 93/* Find the tail of the list */
71fda00f 94#define LIST_FIND_TAIL(name,item,tail) \
034c6ed7 95 do { \
71fda00f 96 typeof(*(item)) *_item = (item); \
376cd3b8
LP
97 if (!_item) \
98 (tail) = NULL; \
99 else { \
100 while (_item->name##_next) \
101 _item = _item->name##_next; \
102 (tail) = _item; \
103 } \
60918275
LP
104 } while (false)
105
106/* Insert an item after another one (a = where, b = what) */
71fda00f 107#define LIST_INSERT_AFTER(name,head,a,b) \
60918275 108 do { \
71fda00f 109 typeof(*(head)) **_head = &(head), *_a = (a), *_b = (b); \
60918275
LP
110 assert(_b); \
111 if (!_a) { \
034c6ed7
LP
112 if ((_b->name##_next = *_head)) \
113 _b->name##_next->name##_prev = _b; \
114 _b->name##_prev = NULL; \
60918275
LP
115 *_head = _b; \
116 } else { \
034c6ed7
LP
117 if ((_b->name##_next = _a->name##_next)) \
118 _b->name##_next->name##_prev = _b; \
119 _b->name##_prev = _a; \
120 _a->name##_next = _b; \
60918275 121 } \
9ed794a3 122 } while (false)
60918275 123
dbe465c9
AC
124/* Insert an item before another one (a = where, b = what) */
125#define LIST_INSERT_BEFORE(name,head,a,b) \
126 do { \
127 typeof(*(head)) **_head = &(head), *_a = (a), *_b = (b); \
128 assert(_b); \
129 if (!_a) { \
130 if (!*_head) { \
131 _b->name##_next = NULL; \
132 _b->name##_prev = NULL; \
133 *_head = _b; \
134 } else { \
135 typeof(*(head)) *_tail = (head); \
136 while (_tail->name##_next) \
137 _tail = _tail->name##_next; \
138 _b->name##_next = NULL; \
139 _b->name##_prev = _tail; \
140 _tail->name##_next = _b; \
141 } \
142 } else { \
143 if ((_b->name##_prev = _a->name##_prev)) \
144 _b->name##_prev->name##_next = _b; \
5076f421
MO
145 else \
146 *_head = _b; \
dbe465c9
AC
147 _b->name##_next = _a; \
148 _a->name##_prev = _b; \
149 } \
9ed794a3 150 } while (false)
dbe465c9 151
6210e7fc
LP
152#define LIST_JUST_US(name,item) \
153 (!(item)->name##_prev && !(item)->name##_next) \
154
034c6ed7
LP
155#define LIST_FOREACH(name,i,head) \
156 for ((i) = (head); (i); (i) = (i)->name##_next)
60918275 157
034c6ed7
LP
158#define LIST_FOREACH_SAFE(name,i,n,head) \
159 for ((i) = (head); (i) && (((n) = (i)->name##_next), 1); (i) = (n))
60918275 160
e04aad61
LP
161#define LIST_FOREACH_BEFORE(name,i,p) \
162 for ((i) = (p)->name##_prev; (i); (i) = (i)->name##_prev)
163
164#define LIST_FOREACH_AFTER(name,i,p) \
165 for ((i) = (p)->name##_next; (i); (i) = (i)->name##_next)
2bc8ca0c 166
7663df37
LP
167/* Iterate through all the members of the list p is included in, but skip over p */
168#define LIST_FOREACH_OTHERS(name,i,p) \
169 for (({ \
170 (i) = (p); \
171 while ((i) && (i)->name##_prev) \
172 (i) = (i)->name##_prev; \
cdda4aa8
LP
173 if ((i) == (p)) \
174 (i) = (p)->name##_next; \
7663df37
LP
175 }); \
176 (i); \
177 (i) = (i)->name##_next == (p) ? (p)->name##_next : (i)->name##_next)
178
2bc8ca0c
ZJS
179/* Loop starting from p->next until p->prev.
180 p can be adjusted meanwhile. */
181#define LIST_LOOP_BUT_ONE(name,i,head,p) \
182 for ((i) = (p)->name##_next ? (p)->name##_next : (head); \
183 (i) != (p); \
184 (i) = (i)->name##_next ? (i)->name##_next : (head))