PipeWire  0.3.66
list.h
Go to the documentation of this file.
1 /* Simple Plugin API */
2 /* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */
3 /* SPDX-License-Identifier: MIT */
4 
5 #ifndef SPA_LIST_H
6 #define SPA_LIST_H
7 
8 #ifdef __cplusplus
9 extern "C" {
10 #endif
11 
22 struct spa_list {
23  struct spa_list *next;
24  struct spa_list *prev;
25 };
26 
27 #define SPA_LIST_INIT(list) ((struct spa_list){ (list), (list) })
28 
29 static inline void spa_list_init(struct spa_list *list)
30 {
31  *list = SPA_LIST_INIT(list);
32 }
33 
34 static inline int spa_list_is_initialized(struct spa_list *list)
35 {
36  return !!list->prev;
37 }
38 
39 #define spa_list_is_empty(l) ((l)->next == (l))
40 
41 static inline void spa_list_insert(struct spa_list *list, struct spa_list *elem)
42 {
43  elem->prev = list;
44  elem->next = list->next;
45  list->next = elem;
46  elem->next->prev = elem;
47 }
48 
49 static inline void spa_list_insert_list(struct spa_list *list, struct spa_list *other)
50 {
51  if (spa_list_is_empty(other))
52  return;
53  other->next->prev = list;
54  other->prev->next = list->next;
55  list->next->prev = other->prev;
56  list->next = other->next;
57 }
58 
59 static inline void spa_list_remove(struct spa_list *elem)
60 {
61  elem->prev->next = elem->next;
62  elem->next->prev = elem->prev;
63 }
64 
65 #define spa_list_first(head, type, member) \
66  SPA_CONTAINER_OF((head)->next, type, member)
67 
68 #define spa_list_last(head, type, member) \
69  SPA_CONTAINER_OF((head)->prev, type, member)
70 
71 #define spa_list_append(list, item) \
72  spa_list_insert((list)->prev, item)
73 
74 #define spa_list_prepend(list, item) \
75  spa_list_insert(list, item)
76 
77 #define spa_list_is_end(pos, head, member) \
78  (&(pos)->member == (head))
79 
80 #define spa_list_next(pos, member) \
81  SPA_CONTAINER_OF((pos)->member.next, __typeof__(*(pos)), member)
82 
83 #define spa_list_prev(pos, member) \
84  SPA_CONTAINER_OF((pos)->member.prev, __typeof__(*(pos)), member)
85 
86 #define spa_list_consume(pos, head, member) \
87  for ((pos) = spa_list_first(head, __typeof__(*(pos)), member); \
88  !spa_list_is_empty(head); \
89  (pos) = spa_list_first(head, __typeof__(*(pos)), member))
90 
91 #define spa_list_for_each_next(pos, head, curr, member) \
92  for ((pos) = spa_list_first(curr, __typeof__(*(pos)), member); \
93  !spa_list_is_end(pos, head, member); \
94  (pos) = spa_list_next(pos, member))
95 
96 #define spa_list_for_each_prev(pos, head, curr, member) \
97  for ((pos) = spa_list_last(curr, __typeof__(*(pos)), member); \
98  !spa_list_is_end(pos, head, member); \
99  (pos) = spa_list_prev(pos, member))
100 
101 #define spa_list_for_each(pos, head, member) \
102  spa_list_for_each_next(pos, head, head, member)
103 
104 #define spa_list_for_each_reverse(pos, head, member) \
105  spa_list_for_each_prev(pos, head, head, member)
106 
107 #define spa_list_for_each_safe_next(pos, tmp, head, curr, member) \
108  for ((pos) = spa_list_first(curr, __typeof__(*(pos)), member); \
109  (tmp) = spa_list_next(pos, member), \
110  !spa_list_is_end(pos, head, member); \
111  (pos) = (tmp))
112 
113 #define spa_list_for_each_safe_prev(pos, tmp, head, curr, member) \
114  for ((pos) = spa_list_last(curr, __typeof__(*(pos)), member); \
115  (tmp) = spa_list_prev(pos, member), \
116  !spa_list_is_end(pos, head, member); \
117  (pos) = (tmp))
118 
119 #define spa_list_for_each_safe(pos, tmp, head, member) \
120  spa_list_for_each_safe_next(pos, tmp, head, head, member)
121 
122 #define spa_list_for_each_safe_reverse(pos, tmp, head, member) \
123  spa_list_for_each_safe_prev(pos, tmp, head, head, member)
124 
125 #define spa_list_cursor_start(cursor, head, member) \
126  spa_list_prepend(head, &(cursor).member)
127 
128 #define spa_list_for_each_cursor(pos, cursor, head, member) \
129  for((pos) = spa_list_first(&(cursor).member, __typeof__(*(pos)), member); \
130  spa_list_remove(&(pos)->member), \
131  spa_list_append(&(cursor).member, &(pos)->member), \
132  !spa_list_is_end(pos, head, member); \
133  (pos) = spa_list_next(&(cursor), member))
134 
135 #define spa_list_cursor_end(cursor, member) \
136  spa_list_remove(&(cursor).member)
137 
142 #ifdef __cplusplus
143 } /* extern "C" */
144 #endif
145 
146 #endif /* SPA_LIST_H */
static void spa_list_insert(struct spa_list *list, struct spa_list *elem)
Definition: list.h:47
static int spa_list_is_initialized(struct spa_list *list)
Definition: list.h:40
static void spa_list_init(struct spa_list *list)
Definition: list.h:35
static void spa_list_remove(struct spa_list *elem)
Definition: list.h:65
#define spa_list_is_empty(l)
Definition: list.h:45
#define SPA_LIST_INIT(list)
Definition: list.h:33
static void spa_list_insert_list(struct spa_list *list, struct spa_list *other)
Definition: list.h:55
Definition: list.h:27
struct spa_list * prev
Definition: list.h:29
struct spa_list * next
Definition: list.h:28