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