Lely core libraries  2.3.4
sllist.h
Go to the documentation of this file.
1 
23 #ifndef LELY_UTIL_SLLIST_H_
24 #define LELY_UTIL_SLLIST_H_
25 
26 #include <lely/features.h>
27 
28 #include <assert.h>
29 #include <stddef.h>
30 
31 #ifndef LELY_UTIL_SLLIST_INLINE
32 #define LELY_UTIL_SLLIST_INLINE static inline
33 #endif
34 
40 struct slnode {
42  struct slnode *next;
43 };
44 
46 #define SLNODE_INIT \
47  { \
48  NULL \
49  }
50 
52 struct sllist {
54  struct slnode *first;
56  struct slnode **plast;
57 };
58 
59 #ifdef __cplusplus
60 extern "C" {
61 #endif
62 
64 LELY_UTIL_SLLIST_INLINE void slnode_init(struct slnode *node);
65 
74 #ifdef __COUNTER__
75 #define slnode_foreach(first, node) slnode_foreach_(__COUNTER__, first, node)
76 #else
77 #define slnode_foreach(first, node) slnode_foreach_(__LINE__, first, node)
78 #endif
79 #define slnode_foreach_(n, first, node) slnode_foreach__(n, first, node)
80 // clang-format off
81 #define slnode_foreach__(n, first, node) \
82  for (struct slnode *node = (first), \
83  *_slnode_next_##n = (node) ? (node)->next : NULL; \
84  (node); (node) = _slnode_next_##n, \
85  _slnode_next_##n = (node) ? (node)->next : NULL)
86 // clang-format on
87 
89 LELY_UTIL_SLLIST_INLINE void sllist_init(struct sllist *list);
90 
95 LELY_UTIL_SLLIST_INLINE int sllist_empty(const struct sllist *list);
96 
101 LELY_UTIL_SLLIST_INLINE size_t sllist_size(const struct sllist *list);
102 
109 LELY_UTIL_SLLIST_INLINE void sllist_push_front(
110  struct sllist *list, struct slnode *node);
111 
117 LELY_UTIL_SLLIST_INLINE void sllist_push_back(
118  struct sllist *list, struct slnode *node);
119 
126 LELY_UTIL_SLLIST_INLINE struct slnode *sllist_pop_front(struct sllist *list);
127 
133 struct slnode *sllist_pop_back(struct sllist *list);
134 
141 struct slnode *sllist_remove(struct sllist *list, struct slnode *node);
142 
148 int sllist_contains(const struct sllist *list, const struct slnode *node);
149 
156 LELY_UTIL_SLLIST_INLINE struct sllist *sllist_append(
157  struct sllist *dst, struct sllist *src);
158 
165 LELY_UTIL_SLLIST_INLINE struct slnode *sllist_first(const struct sllist *list);
166 
173 struct slnode *sllist_last(const struct sllist *list);
174 
183 #define sllist_foreach(list, node) slnode_foreach (sllist_first(list), node)
184 
185 LELY_UTIL_SLLIST_INLINE void
186 slnode_init(struct slnode *node)
187 {
188  assert(node);
189 
190  node->next = NULL;
191 }
192 
193 LELY_UTIL_SLLIST_INLINE void
194 sllist_init(struct sllist *list)
195 {
196  assert(list);
197 
198  *(list->plast = &list->first) = NULL;
199 }
200 
201 LELY_UTIL_SLLIST_INLINE int
202 sllist_empty(const struct sllist *list)
203 {
204  assert(list);
205 
206  return !list->first;
207 }
208 
209 LELY_UTIL_SLLIST_INLINE size_t
210 sllist_size(const struct sllist *list)
211 {
212  assert(list);
213 
214  size_t size = 0;
215  sllist_foreach (list, node)
216  size++;
217  return size;
218 }
219 
220 LELY_UTIL_SLLIST_INLINE void
221 sllist_push_front(struct sllist *list, struct slnode *node)
222 {
223  assert(list);
224  assert(node);
225 
226  if (!(node->next = list->first))
227  list->plast = &node->next;
228  list->first = node;
229 }
230 
231 LELY_UTIL_SLLIST_INLINE void
232 sllist_push_back(struct sllist *list, struct slnode *node)
233 {
234  assert(list);
235  assert(node);
236 
237  *list->plast = node;
238  list->plast = &(*list->plast)->next;
239  *list->plast = NULL;
240 }
241 
242 LELY_UTIL_SLLIST_INLINE struct slnode *
244 {
245  assert(list);
246 
247  struct slnode *node = list->first;
248  if (node) {
249  if (!(list->first = node->next))
250  list->plast = &list->first;
251  node->next = NULL;
252  }
253  return node;
254 }
255 
256 LELY_UTIL_SLLIST_INLINE struct sllist *
257 sllist_append(struct sllist *dst, struct sllist *src)
258 {
259  assert(dst);
260  assert(src);
261 
262  if (src->first) {
263  *dst->plast = src->first;
264  dst->plast = src->plast;
265  sllist_init(src);
266  }
267  return dst;
268 }
269 
270 LELY_UTIL_SLLIST_INLINE struct slnode *
271 sllist_first(const struct sllist *list)
272 {
273  assert(list);
274 
275  return list->first;
276 }
277 
278 #ifdef __cplusplus
279 }
280 #endif
281 
282 #endif // !LELY_UTIL_SLLIST_H_
This header file is part of the Lely libraries; it contains the compiler feature definitions.
void sllist_init(struct sllist *list)
Initializes a singly-linked list.
Definition: sllist.h:194
struct sllist * sllist_append(struct sllist *dst, struct sllist *src)
Appends the singly-linked list at src to the one at dst.
Definition: sllist.h:257
int sllist_contains(const struct sllist *list, const struct slnode *node)
Checks if a node is part of a singly-linked list.
Definition: sllist.c:64
size_t sllist_size(const struct sllist *list)
Returns the size (in number of nodes) of a singly-linked list.
Definition: sllist.h:210
void sllist_push_front(struct sllist *list, struct slnode *node)
Pushes a node to the front of a singly-linked list.
Definition: sllist.h:221
struct slnode * sllist_remove(struct sllist *list, struct slnode *node)
Removes a node from a singly-linked list.
Definition: sllist.c:46
#define sllist_foreach(list, node)
Iterates in order over each node in a singly-linked list.
Definition: sllist.h:183
void sllist_push_back(struct sllist *list, struct slnode *node)
Pushes a node to the back of a singly-linked list.
Definition: sllist.h:232
struct slnode * sllist_pop_back(struct sllist *list)
Pops a node from the back of a singly-linked list.
Definition: sllist.c:32
void slnode_init(struct slnode *node)
Initializes a node in a singly-linked list.
Definition: sllist.h:186
int sllist_empty(const struct sllist *list)
Returns 1 if the singly-linked list is empty, and 0 if not.
Definition: sllist.h:202
struct slnode * sllist_last(const struct sllist *list)
Returns a pointer to the last node in a singly-linked list.
Definition: sllist.c:80
struct slnode * sllist_pop_front(struct sllist *list)
Pops a node from the front of a singly-linked list.
Definition: sllist.h:243
struct slnode * sllist_first(const struct sllist *list)
Returns a pointer to the first node in a singly-linked list.
Definition: sllist.h:271
This header file is part of the C11 and POSIX compatibility library; it includes <stddef....
A singly-linked list.
Definition: sllist.h:52
struct slnode * first
A pointer to the first node in the list.
Definition: sllist.h:54
struct slnode ** plast
A pointer to the next field of the last node in the list.
Definition: sllist.h:56
A node in a singly-linked list.
Definition: sllist.h:40
struct slnode * next
A pointer to the next node in the list.
Definition: sllist.h:42