xref: /kvm-unit-tests/lib/list.h (revision 4fa2b92f995761575305d80fc10368277e2c2c75)
1*4fa2b92fSClaudio Imbrenda #ifndef LIST_H
2*4fa2b92fSClaudio Imbrenda #define LIST_H
3*4fa2b92fSClaudio Imbrenda 
4*4fa2b92fSClaudio Imbrenda #include <stdbool.h>
5*4fa2b92fSClaudio Imbrenda 
6*4fa2b92fSClaudio Imbrenda /*
7*4fa2b92fSClaudio Imbrenda  * Circular doubly-linked list. The pointer to the list is a list item itself,
8*4fa2b92fSClaudio Imbrenda  * like in the kernel implementation.
9*4fa2b92fSClaudio Imbrenda  */
10*4fa2b92fSClaudio Imbrenda struct linked_list {
11*4fa2b92fSClaudio Imbrenda 	struct linked_list *prev;
12*4fa2b92fSClaudio Imbrenda 	struct linked_list *next;
13*4fa2b92fSClaudio Imbrenda };
14*4fa2b92fSClaudio Imbrenda 
15*4fa2b92fSClaudio Imbrenda /*
16*4fa2b92fSClaudio Imbrenda  * An empty list is a list item whose prev and next both point to itself.
17*4fa2b92fSClaudio Imbrenda  * Returns true if the list is empty.
18*4fa2b92fSClaudio Imbrenda  */
19*4fa2b92fSClaudio Imbrenda static inline bool is_list_empty(struct linked_list *p)
20*4fa2b92fSClaudio Imbrenda {
21*4fa2b92fSClaudio Imbrenda 	return !p->next || !p->prev || p == p->next || p == p->prev;
22*4fa2b92fSClaudio Imbrenda }
23*4fa2b92fSClaudio Imbrenda 
24*4fa2b92fSClaudio Imbrenda /*
25*4fa2b92fSClaudio Imbrenda  * Remove the given element from the list, if the list is not already empty.
26*4fa2b92fSClaudio Imbrenda  * The removed element is returned.
27*4fa2b92fSClaudio Imbrenda  */
28*4fa2b92fSClaudio Imbrenda static inline struct linked_list *list_remove(struct linked_list *l)
29*4fa2b92fSClaudio Imbrenda {
30*4fa2b92fSClaudio Imbrenda 	if (is_list_empty(l))
31*4fa2b92fSClaudio Imbrenda 		return NULL;
32*4fa2b92fSClaudio Imbrenda 
33*4fa2b92fSClaudio Imbrenda 	l->prev->next = l->next;
34*4fa2b92fSClaudio Imbrenda 	l->next->prev = l->prev;
35*4fa2b92fSClaudio Imbrenda 	l->prev = l->next = NULL;
36*4fa2b92fSClaudio Imbrenda 
37*4fa2b92fSClaudio Imbrenda 	return l;
38*4fa2b92fSClaudio Imbrenda }
39*4fa2b92fSClaudio Imbrenda 
40*4fa2b92fSClaudio Imbrenda /*
41*4fa2b92fSClaudio Imbrenda  * Add the given element after the given list head.
42*4fa2b92fSClaudio Imbrenda  */
43*4fa2b92fSClaudio Imbrenda static inline void list_add(struct linked_list *head, struct linked_list *li)
44*4fa2b92fSClaudio Imbrenda {
45*4fa2b92fSClaudio Imbrenda 	assert(li);
46*4fa2b92fSClaudio Imbrenda 	assert(head);
47*4fa2b92fSClaudio Imbrenda 	li->prev = head;
48*4fa2b92fSClaudio Imbrenda 	li->next = head->next;
49*4fa2b92fSClaudio Imbrenda 	head->next->prev = li;
50*4fa2b92fSClaudio Imbrenda 	head->next = li;
51*4fa2b92fSClaudio Imbrenda }
52*4fa2b92fSClaudio Imbrenda 
53*4fa2b92fSClaudio Imbrenda #endif
54