mcchunktools
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros
list.h
Go to the documentation of this file.
1 #ifndef LIST_H
2 #define LIST_H
3 
4 #include <stddef.h>
5 
6 /*
7  * Represents a single entry in the list. This must be embedded in your linked
8  * structure.
9  */
10 struct list_head {
11  struct list_head *blink, /* back link */
12  *flink; /* front link */
13 };
14 
15 /* The first element is a sentinel. Don't access it. */
16 #define INIT_LIST_HEAD(head) (head)->flink = (head)->blink = (head)
17 
18 /* Adds a new element to the beginning of a list. Returns the head of the list
19  * so that calls may be chained. */
20 static inline struct list_head* list_add_head(struct list_head* restrict new_element,
21  struct list_head* restrict head)
22 {
23  new_element->flink = head->flink;
24  new_element->blink = head;
25 
26  new_element->flink->blink = new_element;
27  new_element->blink->flink = new_element;
28 
29  return head;
30 }
31 
32 /* Adds a new element to the end of a list. Returns the head of the list so that
33  * calls may be chained. */
34 static inline struct list_head* list_add_tail(struct list_head* restrict new_element,
35  struct list_head* restrict head)
36 {
37  new_element->flink = head;
38  new_element->blink = head->blink;
39 
40  new_element->flink->blink = new_element;
41  new_element->blink->flink = new_element;
42 
43  return head;
44 }
45 
46 /* Deletes an element from a list. NOTE: This does not free any memory. */
47 static inline void list_del(struct list_head* loc)
48 {
49  loc->flink->blink = loc->blink;
50  loc->blink->flink = loc->flink;
51 
52  loc->flink = NULL;
53  loc->blink = NULL;
54 }
55 
56 /* Tests if the list is empty */
57 #define list_empty(head) ((head)->flink == (head))
58 
59 /* Gets a pointer to the overall structure from the list member */
60 #define list_entry(ptr, type, member) \
61  ((type*)((char*)(ptr) - offsetof(type, member)))
62 
63 /*
64  * Iterates over all the elements forward. If you modify the list (such as by
65  * deleting an element), you should use list_for_each_safe instead.
66  */
67 #define list_for_each(pos, head) \
68  for((pos) = (head)->flink; \
69  (pos) != (head); \
70  (pos) = (pos)->flink)
71 
72 /* The same as list_for_each, except it traverses the list backwards. */
73 #define list_for_each_reverse(pos, head) \
74  for((pos) = (head)->blink; \
75  (pos) != (head); \
76  (pos) = (pos)->blink)
77 
78 /*
79  * Iterates over a list, where `pos' represents the current element, `n'
80  * represents temporary storage for the next element, and `head' is the start of
81  * the list.
82  *
83  * As opposed to list_for_each, it is safe to remove `pos' from the list.
84  */
85 #define list_for_each_safe(pos, n, head) \
86  for((pos) = (head)->flink, (n) = (pos)->flink; \
87  (pos) != (head); \
88  (pos) = (n), (n) = (pos)->flink)
89 
90 /* The same as list_for_each_safe, except it traverses the list backwards. */
91 #define list_for_each_reverse_safe(pos, p, head) \
92  for((pos) = (head)->blink, (p) = (pos)->blink; \
93  (pos) != (head); \
94  (pos) = (p), (p) = (pos)->blink)
95 
96 /*
97  * Returns the length of a list. WARNING: Unlike every other function, this runs
98  * in O(n). Avoid using it as much as possible, as you will have to walk the
99  * whole list.
100  */
101 static inline size_t list_length(const struct list_head* head)
102 {
103  const struct list_head* cursor;
104  size_t accum = 0;
105 
106  list_for_each(cursor, head)
107  accum++;
108 
109  return accum;
110 }
111 
112 #endif
#define list_for_each(pos, head)
Definition: list.h:67
#define restrict
Definition: mcchunk.h:25
Definition: list.h:10
struct list_head * blink
Definition: list.h:11
struct list_head * flink
Definition: list.h:11