clist.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2016 Kaspar Schleiser <kaspar@schleiser.de>
3  * 2013 Freie Universität Berlin
4  * 2017 Inria
5  *
6  * This file is subject to the terms and conditions of the GNU Lesser
7  * General Public License v2.1. See the file LICENSE in the top level
8  * directory for more details.
9  */
10 
87 #ifndef CLIST_H
88 #define CLIST_H
89 
90 #include <stddef.h>
91 #include "list.h"
92 
93 #ifdef __cplusplus
94 extern "C" {
95 #endif
96 
104 
114 static inline void clist_rpush(clist_node_t *list, clist_node_t *new_node)
115 {
116  if (list->next) {
117  new_node->next = list->next->next;
118  list->next->next = new_node;
119  }
120  else {
121  new_node->next = new_node;
122  }
123  list->next = new_node;
124 }
125 
135 static inline void clist_lpush(clist_node_t *list, clist_node_t *new_node)
136 {
137  if (list->next) {
138  new_node->next = list->next->next;
139  list->next->next = new_node;
140  }
141  else {
142  new_node->next = new_node;
143  list->next = new_node;
144  }
145 }
146 
155 static inline clist_node_t *clist_lpop(clist_node_t *list)
156 {
157  if (list->next) {
158  clist_node_t *first = list->next->next;
159  if (list->next == first) {
160  list->next = NULL;
161  }
162  else {
163  list->next->next = first->next;
164  }
165  return first;
166  }
167  else {
168  return NULL;
169  }
170 }
171 
185 static inline void clist_lpoprpush(clist_node_t *list)
186 {
187  if (list->next) {
188  list->next = list->next->next;
189  }
190 }
191 
200 static inline clist_node_t *clist_lpeek(const clist_node_t *list)
201 {
202  if (list->next) {
203  return list->next->next;
204  }
205  return NULL;
206 }
207 
216 static inline clist_node_t *clist_rpeek(const clist_node_t *list)
217 {
218  return list->next;
219 }
220 
229 static inline clist_node_t *clist_rpop(clist_node_t *list)
230 {
231  if (list->next) {
232  list_node_t *last = list->next;
233  while (list->next->next != last) {
234  clist_lpoprpush(list);
235  }
236  return clist_lpop(list);
237  }
238  else {
239  return NULL;
240  }
241 }
242 
255 static inline clist_node_t *clist_find_before(const clist_node_t *list,
256  const clist_node_t *node)
257 {
258  clist_node_t *pos = list->next;
259 
260  if (!pos) {
261  return NULL;
262  }
263  do {
264  pos = pos->next;
265  if (pos->next == node) {
266  return pos;
267  }
268  } while (pos != list->next);
269 
270  return NULL;
271 }
272 
285 static inline clist_node_t *clist_find(const clist_node_t *list,
286  const clist_node_t *node)
287 {
288  clist_node_t *tmp = clist_find_before(list, node);
289 
290  if (tmp) {
291  return tmp->next;
292  }
293  else {
294  return NULL;
295  }
296 }
297 
311 {
312  if (list->next) {
313  if (list->next->next == node) {
314  return clist_lpop(list);
315  }
316  else {
317  clist_node_t *tmp = clist_find_before(list, node);
318  if (tmp) {
319  tmp->next = tmp->next->next;
320  if (node == list->next) {
321  list->next = tmp;
322  }
323  return node;
324  }
325  }
326  }
327 
328  return NULL;
329 }
330 
346 static inline clist_node_t *clist_foreach(clist_node_t *list, int (*func)(
347  clist_node_t *,
348  void *), void *arg)
349 {
350  clist_node_t *node = list->next;
351 
352  if (node) {
353  do {
354  node = node->next;
355  if (func(node, arg)) {
356  return node;
357  }
358  } while (node != list->next);
359  }
360 
361  return NULL;
362 }
363 
369 
381 
424 static inline void clist_sort(clist_node_t *list, clist_cmp_func_t cmp)
425 {
426  if (list->next) {
427  list->next = _clist_sort(list->next->next, cmp);
428  }
429 }
430 
438 static inline size_t clist_count(clist_node_t *list)
439 {
440  clist_node_t *node = list->next;
441  size_t cnt = 0;
442 
443  if (node) {
444  do {
445  node = node->next;
446  ++cnt;
447  } while (node != list->next);
448  }
449 
450  return cnt;
451 }
452 
453 #ifdef __cplusplus
454 }
455 #endif
456 
457 #endif /* CLIST_H */
458 
clist_lpeek
static clist_node_t * clist_lpeek(const clist_node_t *list)
Returns first element in list.
Definition: clist.h:200
clist_sort
static void clist_sort(clist_node_t *list, clist_cmp_func_t cmp)
Sort a list.
Definition: clist.h:424
clist_foreach
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:346
clist_node_t
list_node_t clist_node_t
List node structure.
Definition: clist.h:103
clist_lpop
static clist_node_t * clist_lpop(clist_node_t *list)
Removes and returns first element from list.
Definition: clist.h:155
clist_find
static clist_node_t * clist_find(const clist_node_t *list, const clist_node_t *node)
Finds and returns node.
Definition: clist.h:285
clist_rpop
static clist_node_t * clist_rpop(clist_node_t *list)
Removes and returns last element from list.
Definition: clist.h:229
clist_lpoprpush
static void clist_lpoprpush(clist_node_t *list)
Advances the circle list.
Definition: clist.h:185
clist_find_before
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:255
list_node
List node structure.
Definition: list.h:40
list_node::next
struct list_node * next
pointer to next list entry
Definition: list.h:41
_clist_sort
clist_node_t * _clist_sort(clist_node_t *list_head, clist_cmp_func_t cmp)
List sorting helper function.
clist_rpush
static void clist_rpush(clist_node_t *list, clist_node_t *new_node)
Appends new_node at the end of *list.
Definition: clist.h:114
clist_count
static size_t clist_count(clist_node_t *list)
Count the number of items in the given list.
Definition: clist.h:438
list.h
Intrusive linked list.
clist_lpush
static void clist_lpush(clist_node_t *list, clist_node_t *new_node)
Inserts new_node at the beginning of *list.
Definition: clist.h:135
clist_cmp_func_t
int(* clist_cmp_func_t)(clist_node_t *a, clist_node_t *b)
Typedef for comparison function used by clist_sort()
Definition: clist.h:368
clist_remove
static clist_node_t * clist_remove(clist_node_t *list, clist_node_t *node)
Finds and removes node.
Definition: clist.h:310
clist_rpeek
static clist_node_t * clist_rpeek(const clist_node_t *list)
Returns last element in list.
Definition: clist.h:216