]> git.proxmox.com Git - mirror_lxc.git/blob - src/lxc/list.h
overlay: rewrite and simplify
[mirror_lxc.git] / src / lxc / list.h
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2
3 #ifndef __LXC_LIST_H
4 #define __LXC_LIST_H
5
6 #include <stdio.h>
7
8 struct lxc_list {
9 void *elem;
10 struct lxc_list *next;
11 struct lxc_list *prev;
12 };
13
14 #define lxc_init_list(l) \
15 { \
16 .next = l, .prev = l \
17 }
18
19 /*
20 * Iterate through an lxc list. An example for an idiom would be:
21 *
22 * struct lxc_list *iterator;
23 * lxc_list_for_each(iterator, list) {
24 * type *tmp;
25 * tmp = iterator->elem;
26 * }
27 */
28 #define lxc_list_for_each(__iterator, __list) \
29 for (__iterator = (__list)->next; __iterator != __list; \
30 __iterator = __iterator->next)
31
32 /* Iterate safely through an lxc list. An example for an appropriate use case
33 * would be:
34 *
35 * struct lxc_list *cur, *next;
36 * lxc_list_for_each_safe(cur, list, next) {
37 * type *tmp;
38 * tmp = cur->elem;
39 * }
40 */
41 #define lxc_list_for_each_safe(__iterator, __list, __next) \
42 for (__iterator = (__list)->next, __next = __iterator->next; \
43 __iterator != __list; __iterator = __next, __next = __next->next)
44
45 /* Initialize list. */
46 static inline void lxc_list_init(struct lxc_list *list)
47 {
48 list->elem = NULL;
49 list->next = list->prev = list;
50 }
51
52 /* Add an element to a list. See lxc_list_add() and lxc_list_add_tail() for an
53 * idiom.
54 */
55 static inline void lxc_list_add_elem(struct lxc_list *list, void *elem)
56 {
57 list->elem = elem;
58 }
59
60 /* Retrieve first element of list. */
61 static inline void *lxc_list_first_elem(const struct lxc_list *list)
62 {
63 return list->next->elem;
64 }
65
66 /* Retrieve last element of list. */
67 static inline void *lxc_list_last_elem(const struct lxc_list *list)
68 {
69 return list->prev->elem;
70 }
71
72 /* Determine if list is empty. */
73 static inline int lxc_list_empty(const struct lxc_list *list)
74 {
75 return list == list->next;
76 }
77
78 /* Workhorse to be called from lxc_list_add() and lxc_list_add_tail(). */
79 static inline void __lxc_list_add(struct lxc_list *new, struct lxc_list *prev,
80 struct lxc_list *next)
81 {
82 next->prev = new;
83 new->next = next;
84 new->prev = prev;
85 prev->next = new;
86 }
87
88 /* Idiom to add an element to the beginning of an lxc list:
89 *
90 * struct lxc_list *tmp = malloc(sizeof(*tmp));
91 * if (tmp == NULL)
92 * return 1;
93 * lxc_list_add_elem(tmp, elem);
94 * lxc_list_add(list, tmp);
95 */
96 static inline void lxc_list_add(struct lxc_list *head, struct lxc_list *list)
97 {
98 __lxc_list_add(list, head, head->next);
99 }
100
101 /* Idiom to add an element to the end of an lxc list:
102 *
103 * struct lxc_list *tmp = malloc(sizeof(*tmp));
104 * if (tmp == NULL)
105 * return 1;
106 * lxc_list_add_elem(tmp, elem);
107 * lxc_list_add_tail(list, tmp);
108 */
109 static inline void lxc_list_add_tail(struct lxc_list *head,
110 struct lxc_list *list)
111 {
112 __lxc_list_add(list, head->prev, head);
113 }
114
115 /* Idiom to remove an element from a list:
116 * struct lxc_list *cur, *next;
117 * lxc_list_for_each_safe(cur, list, next) {
118 * lxc_list_del(cur);
119 * free(cur->elem);
120 * free(cur);
121 * }
122 */
123 static inline void lxc_list_del(struct lxc_list *list)
124 {
125 struct lxc_list *next, *prev;
126
127 next = list->next;
128 prev = list->prev;
129 next->prev = prev;
130 prev->next = next;
131 }
132
133 /* Return length of the list. */
134 static inline size_t lxc_list_len(struct lxc_list *list)
135 {
136 size_t i = 0;
137 struct lxc_list *iter;
138
139 lxc_list_for_each(iter, list) {
140 i++;
141 }
142
143 return i;
144 }
145
146 #endif /* __LXC_LIST_H */