- Increase version to 0.1.9.
[sliver-openvswitch.git] / include / list.h
1 #ifndef LIST_H
2 #define LIST_H 1
3
4 /* Doubly linked list. */
5
6 #include <stdbool.h>
7 #include <stddef.h>
8 #include "util.h"
9
10 /* Doubly linked list head or element. */
11 struct list
12   {
13     struct list *prev;     /* Previous list element. */
14     struct list *next;     /* Next list element. */
15   };
16
17 #define LIST_INITIALIZER(LIST) { LIST, LIST }
18
19 void list_init(struct list *);
20
21 /* List insertion. */
22 void list_insert(struct list *, struct list *);
23 void list_splice(struct list *before, struct list *first, struct list *last);
24 void list_push_front(struct list *, struct list *);
25 void list_push_back(struct list *, struct list *);
26
27 /* List removal. */
28 struct list *list_remove(struct list *);
29 struct list *list_pop_front(struct list *);
30 struct list *list_pop_back(struct list *);
31
32 /* List elements. */
33 struct list *list_front(struct list *);
34 struct list *list_back(struct list *);
35
36 /* List properties. */
37 size_t list_size(const struct list *);
38 bool list_is_empty(const struct list *);
39
40 #define LIST_ELEM__(ELEM, STRUCT, MEMBER, LIST)                 \
41         (ELEM != LIST ? CONTAINER_OF(ELEM, STRUCT, MEMBER) : NULL)
42 #define LIST_FOR_EACH(ITER, STRUCT, MEMBER, LIST)                   \
43     for (ITER = LIST_ELEM__((LIST)->next, STRUCT, MEMBER, LIST);    \
44          ITER != NULL;                                              \
45          ITER = LIST_ELEM__((ITER)->MEMBER.next, STRUCT, MEMBER, LIST))
46 #define LIST_FOR_EACH_SAFE(ITER, NEXT, STRUCT, MEMBER, LIST)            \
47     for (ITER = LIST_ELEM__((LIST)->next, STRUCT, MEMBER, LIST);        \
48          (ITER != NULL                                                  \
49           ? (NEXT = LIST_ELEM__((ITER)->MEMBER.next, STRUCT, MEMBER, LIST), 1) \
50           : 0),                                                         \
51          ITER = NEXT)
52
53 #endif /* list.h */