Lines Matching refs:list

3 #include "list.h"
18 static list_node_t *list_free_node_(list_t *list, list_node_t *node);
20 // Returns a new, empty list. Returns NULL if not enough memory could be allocated
21 // for the list structure. The returned list must be freed with |list_free|. The
22 // |callback| specifies a function to be called whenever a list element is removed
23 // from the list. It can be used to release resources held by the list element, e.g.
27 list_t *list = (list_t *)calloc(sizeof(list_t), 1);
28 if (list)
29 list->free_cb = callback;
30 return list;
33 // Frees the list. This function accepts NULL as an argument, in which case it
35 void list_free(list_t *list) {
36 if (list != NULL)
37 list_clear(list);
39 free(list);
42 // Returns true if the list is empty (has no elements), false otherwise.
43 // Note that a NULL list is not the same as an empty list. This function
44 // does not accept a NULL list.
45 bool list_is_empty(const list_t *list) {
46 assert(list != NULL);
47 return (list->length == 0);
50 // Returns the length of the list. This function does not accept a NULL list.
51 size_t list_length(const list_t *list) {
52 assert(list != NULL);
53 return list->length;
56 // Returns the first element in the list without removing it. |list| may not
58 void *list_front(const list_t *list) {
59 assert(list != NULL);
60 assert(!list_is_empty(list));
62 return list->head->data;
65 // Returns the last element in the list without removing it. |list| may not
67 void *list_back(const list_t *list) {
68 assert(list != NULL);
69 assert(!list_is_empty(list));
71 return list->tail->data;
74 bool list_insert_after(list_t *list, list_node_t *prev_node, void *data) {
75 assert(list != NULL);
86 if (list->tail == prev_node)
87 list->tail = node;
88 ++list->length;
92 // Inserts |data| at the beginning of |list|. Neither |data| nor |list| may be NULL.
94 // at least until the element is removed from the list or the list is freed.
96 bool list_prepend(list_t *list, void *data) {
97 assert(list != NULL);
103 node->next = list->head;
105 list->head = node;
106 if (list->tail == NULL)
107 list->tail = list->head;
108 ++list->length;
112 // Inserts |data| at the end of |list|. Neither |data| nor |list| may be NULL.
114 // at least until the element is removed from the list or the list is freed.
116 bool list_append(list_t *list, void *data) {
117 assert(list != NULL);
125 if (list->tail == NULL) {
126 list->head = node;
127 list->tail = node;
129 list->tail->next = node;
130 list->tail = node;
132 ++list->length;
136 // Removes |data| from the list. Neither |list| nor |data| may be NULL. If |data|
137 // is inserted multiple times in the list, this function will only remove the first
139 // with |data|. This function returns true if |data| was found in the list and removed,
141 bool list_remove(list_t *list, void *data) {
142 assert(list != NULL);
145 if (list_is_empty(list))
148 if (list->head->data == data) {
149 list_node_t *next = list_free_node_(list, list->head);
150 if (list->tail == list->head)
151 list->tail = next;
152 list->head = next;
156 for (list_node_t *prev = list->head, *node = list->head->next; node; prev = node, node = node->next)
158 prev->next = list_free_node_(list, node);
159 if (list->tail == node)
160 list->tail = prev;
167 // Removes all elements in the list. Calling this function will return the list to the
168 // same state it was in after |list_new|. |list| may not be NULL.
169 void list_clear(list_t *list) {
170 assert(list != NULL);
171 for (list_node_t *node = list->head; node; )
172 node = list_free_node_(list, node);
173 list->head = NULL;
174 list->tail = NULL;
175 list->length = 0;
178 // Iterates through the entire |list| and calls |callback| for each data element.
179 // If the list is empty, |callback| will never be called. It is safe to mutate the
180 // list inside the callback. If an element is added before the node being visited,
181 // there will be no callback for the newly-inserted node. Neither |list| nor
183 void list_foreach(const list_t *list, list_iter_cb callback) {
184 assert(list != NULL);
187 for (list_node_t *node = list->head; node; ) {
194 // Returns an iterator to the first element in |list|. |list| may not be NULL.
197 list_node_t *list_begin(const list_t *list) {
198 assert(list != NULL);
199 return list->head;
202 // Returns an iterator that points past the end of the list. In other words,
203 // this function returns the value of an invalid iterator for the given list.
205 // may no longer call |list_next| with the iterator. |list| may not be NULL.
206 list_node_t *list_end(UNUSED_ATTR const list_t *list) {
207 assert(list != NULL);
213 // iterator has reached the end of the list and may no longer be used for any
227 static list_node_t *list_free_node_(list_t *list, list_node_t *node) {
228 assert(list != NULL);
233 if (list->free_cb)
234 list->free_cb(node->data);
236 --list->length;