clist.h
Go to the documentation of this file.
1 /*
2  * SPDX-FileCopyrightText: 2016 Kaspar Schleiser <kaspar@schleiser.de>
3  * SPDX-FileCopyrightText: 2013 Freie Universität Berlin
4  * SPDX-FileCopyrightText: 2017 Inria
5  * SPDX-License-Identifier: LGPL-2.1-only
6  */
7 
8 #pragma once
9 
90 #include <stdbool.h>
91 #include <stddef.h>
92 #include "list.h"
93 
94 #ifdef __cplusplus
95 extern "C" {
96 #endif
97 
105 
115 static inline bool clist_is_empty(const clist_node_t *list)
116 {
117  return list->next == NULL;
118 }
119 
129 static inline void clist_rpush(clist_node_t *list, clist_node_t *new_node)
130 {
131  if (list->next) {
132  new_node->next = list->next->next;
133  list->next->next = new_node;
134  }
135  else {
136  new_node->next = new_node;
137  }
138  list->next = new_node;
139 }
140 
150 static inline void clist_lpush(clist_node_t *list, clist_node_t *new_node)
151 {
152  if (list->next) {
153  new_node->next = list->next->next;
154  list->next->next = new_node;
155  }
156  else {
157  new_node->next = new_node;
158  list->next = new_node;
159  }
160 }
161 
170 static inline clist_node_t *clist_lpop(clist_node_t *list)
171 {
172  if (list->next) {
173  clist_node_t *first = list->next->next;
174  if (list->next == first) {
175  list->next = NULL;
176  }
177  else {
178  list->next->next = first->next;
179  }
180  return first;
181  }
182  else {
183  return NULL;
184  }
185 }
186 
200 static inline void clist_lpoprpush(clist_node_t *list)
201 {
202  if (list->next) {
203  list->next = list->next->next;
204  }
205 }
206 
215 static inline clist_node_t *clist_lpeek(const clist_node_t *list)
216 {
217  if (list->next) {
218  return list->next->next;
219  }
220  return NULL;
221 }
222 
231 static inline clist_node_t *clist_rpeek(const clist_node_t *list)
232 {
233  return list->next;
234 }
235 
244 static inline clist_node_t *clist_rpop(clist_node_t *list)
245 {
246  if (list->next) {
247  list_node_t *last = list->next;
248  while (list->next->next != last) {
249  clist_lpoprpush(list);
250  }
251  return clist_lpop(list);
252  }
253  else {
254  return NULL;
255  }
256 }
257 
270 static inline clist_node_t *clist_find_before(const clist_node_t *list,
271  const clist_node_t *node)
272 {
273  clist_node_t *pos = list->next;
274 
275  if (!pos) {
276  return NULL;
277  }
278  do {
279  pos = pos->next;
280  if (pos->next == node) {
281  return pos;
282  }
283  } while (pos != list->next);
284 
285  return NULL;
286 }
287 
300 static inline clist_node_t *clist_find(const clist_node_t *list,
301  const clist_node_t *node)
302 {
303  clist_node_t *tmp = clist_find_before(list, node);
304 
305  if (tmp) {
306  return tmp->next;
307  }
308  else {
309  return NULL;
310  }
311 }
312 
326 {
327  if (list->next) {
328  if (list->next->next == node) {
329  return clist_lpop(list);
330  }
331  else {
332  clist_node_t *tmp = clist_find_before(list, node);
333  if (tmp) {
334  tmp->next = tmp->next->next;
335  if (node == list->next) {
336  list->next = tmp;
337  }
338  return node;
339  }
340  }
341  }
342 
343  return NULL;
344 }
345 
361 static inline clist_node_t *clist_foreach(clist_node_t *list, int (*func)(
362  clist_node_t *,
363  void *), void *arg)
364 {
365  clist_node_t *node = list->next;
366 
367  if (node) {
368  do {
369  node = node->next;
370  if (func(node, arg)) {
371  return node;
372  }
373  } while (node != list->next);
374  }
375 
376  return NULL;
377 }
378 
384 
396 
439 static inline void clist_sort(clist_node_t *list, clist_cmp_func_t cmp)
440 {
441  if (list->next) {
442  list->next = _clist_sort(list->next->next, cmp);
443  }
444 }
445 
453 static inline size_t clist_count(clist_node_t *list)
454 {
455  clist_node_t *node = list->next;
456  size_t cnt = 0;
457 
458  if (node) {
459  do {
460  node = node->next;
461  ++cnt;
462  } while (node != list->next);
463  }
464 
465  return cnt;
466 }
467 
477 static inline bool clist_exactly_one(clist_node_t *list)
478 {
479  return !clist_is_empty(list) && (list->next == list->next->next);
480 }
481 
491 static inline bool clist_more_than_one(clist_node_t *list)
492 {
493  return !clist_is_empty(list) && (list->next != list->next->next);
494 }
495 
496 #ifdef __cplusplus
497 }
498 #endif
499 
static size_t clist_count(clist_node_t *list)
Count the number of items in the given list.
Definition: clist.h:453
static bool clist_more_than_one(clist_node_t *list)
Tells if a list has more than one element.
Definition: clist.h:491
static clist_node_t * clist_remove(clist_node_t *list, clist_node_t *node)
Finds and removes node.
Definition: clist.h:325
static void clist_sort(clist_node_t *list, clist_cmp_func_t cmp)
Sort a list.
Definition: clist.h:439
static clist_node_t * clist_rpeek(const clist_node_t *list)
Returns last element in list.
Definition: clist.h:231
clist_node_t * _clist_sort(clist_node_t *list_head, clist_cmp_func_t cmp)
List sorting helper function.
static void clist_rpush(clist_node_t *list, clist_node_t *new_node)
Appends new_node at the end of *list.
Definition: clist.h:129
list_node_t clist_node_t
List node structure.
Definition: clist.h:104
static bool clist_is_empty(const clist_node_t *list)
Checks if *list is empty.
Definition: clist.h:115
static void clist_lpush(clist_node_t *list, clist_node_t *new_node)
Inserts new_node at the beginning of *list.
Definition: clist.h:150
static clist_node_t * clist_lpeek(const clist_node_t *list)
Returns first element in list.
Definition: clist.h:215
static clist_node_t * clist_rpop(clist_node_t *list)
Removes and returns last element from list.
Definition: clist.h:244
static void clist_lpoprpush(clist_node_t *list)
Advances the circle list.
Definition: clist.h:200
int(* clist_cmp_func_t)(clist_node_t *a, clist_node_t *b)
Typedef for comparison function used by clist_sort()
Definition: clist.h:383
static bool clist_exactly_one(clist_node_t *list)
Tells if a list has exactly one element.
Definition: clist.h:477
static clist_node_t * clist_find_before(const clist_node_t *list, const clist_node_t *node)
Finds node and returns its predecessor.
Definition: clist.h:270
static clist_node_t * clist_find(const clist_node_t *list, const clist_node_t *node)
Finds and returns node.
Definition: clist.h:300
static clist_node_t * clist_foreach(clist_node_t *list, int(*func)(clist_node_t *, void *), void *arg)
Traverse clist, call function for each member.
Definition: clist.h:361
static clist_node_t * clist_lpop(clist_node_t *list)
Removes and returns first element from list.
Definition: clist.h:170
Intrusive linked list.
List node structure.
Definition: list.h:36
struct list_node * next
pointer to next list entry
Definition: list.h:37