Sharvil Nanavati | 540e7ca | 2014-04-24 16:22:45 -0700 | [diff] [blame] | 1 | #pragma once |
| 2 | |
| 3 | #include <stdbool.h> |
| 4 | #include <stdlib.h> |
| 5 | |
| 6 | struct list_node_t; |
| 7 | typedef struct list_node_t list_node_t; |
| 8 | |
| 9 | struct list_t; |
| 10 | typedef struct list_t list_t; |
| 11 | |
| 12 | typedef void (*list_free_cb)(void *data); |
| 13 | typedef bool (*list_iter_cb)(void *data); |
| 14 | |
Zach Johnson | 8d43696 | 2015-03-02 14:42:02 -0800 | [diff] [blame] | 15 | // Returns a new, empty list. Returns NULL if not enough memory could be allocated |
| 16 | // for the list structure. The returned list must be freed with |list_free|. The |
| 17 | // |callback| specifies a function to be called whenever a list element is removed |
| 18 | // from the list. It can be used to release resources held by the list element, e.g. |
| 19 | // memory or file descriptor. |callback| may be NULL if no cleanup is necessary on |
| 20 | // element removal. |
Sharvil Nanavati | 540e7ca | 2014-04-24 16:22:45 -0700 | [diff] [blame] | 21 | list_t *list_new(list_free_cb callback); |
Zach Johnson | 8d43696 | 2015-03-02 14:42:02 -0800 | [diff] [blame] | 22 | |
| 23 | // Frees the list. This function accepts NULL as an argument, in which case it |
| 24 | // behaves like a no-op. |
Sharvil Nanavati | 540e7ca | 2014-04-24 16:22:45 -0700 | [diff] [blame] | 25 | void list_free(list_t *list); |
| 26 | |
Zach Johnson | 8d43696 | 2015-03-02 14:42:02 -0800 | [diff] [blame] | 27 | // Returns true if |list| is empty (has no elements), false otherwise. |
| 28 | // |list| may not be NULL. |
Sharvil Nanavati | 540e7ca | 2014-04-24 16:22:45 -0700 | [diff] [blame] | 29 | bool list_is_empty(const list_t *list); |
Zach Johnson | 8d43696 | 2015-03-02 14:42:02 -0800 | [diff] [blame] | 30 | |
| 31 | // Returns true if the list contains |data|, false otherwise. |
| 32 | // |list| may not be NULL. |
Sharvil Nanavati | fbf8908 | 2014-08-13 00:40:49 -0700 | [diff] [blame] | 33 | bool list_contains(const list_t *list, const void *data); |
Zach Johnson | 8d43696 | 2015-03-02 14:42:02 -0800 | [diff] [blame] | 34 | |
| 35 | // Returns the length of the |list|. |list| may not be NULL. |
Sharvil Nanavati | 540e7ca | 2014-04-24 16:22:45 -0700 | [diff] [blame] | 36 | size_t list_length(const list_t *list); |
Zach Johnson | 8d43696 | 2015-03-02 14:42:02 -0800 | [diff] [blame] | 37 | |
| 38 | // Returns the first element in the list without removing it. |list| may not |
| 39 | // be NULL or empty. |
Sharvil Nanavati | 540e7ca | 2014-04-24 16:22:45 -0700 | [diff] [blame] | 40 | void *list_front(const list_t *list); |
Zach Johnson | 8d43696 | 2015-03-02 14:42:02 -0800 | [diff] [blame] | 41 | |
| 42 | // Returns the last element in the list without removing it. |list| may not |
| 43 | // be NULL or empty. |
Sharvil Nanavati | 540e7ca | 2014-04-24 16:22:45 -0700 | [diff] [blame] | 44 | void *list_back(const list_t *list); |
| 45 | |
Zach Johnson | 8d43696 | 2015-03-02 14:42:02 -0800 | [diff] [blame] | 46 | // Inserts |data| after |prev_node| in |list|. |data|, |list|, and |prev_node| |
| 47 | // may not be NULL. This function does not make a copy of |data| so the pointer |
| 48 | // must remain valid at least until the element is removed from the list or the |
| 49 | // list is freed. Returns true if |data| could be inserted, false otherwise |
| 50 | // (e.g. out of memory). |
Sharvil Nanavati | f0e7c8b | 2014-07-01 18:42:56 -0700 | [diff] [blame] | 51 | bool list_insert_after(list_t *list, list_node_t *prev_node, void *data); |
Zach Johnson | 8d43696 | 2015-03-02 14:42:02 -0800 | [diff] [blame] | 52 | |
| 53 | // Inserts |data| at the beginning of |list|. Neither |data| nor |list| may be NULL. |
| 54 | // This function does not make a copy of |data| so the pointer must remain valid |
| 55 | // at least until the element is removed from the list or the list is freed. |
| 56 | // Returns true if |data| could be inserted, false otherwise (e.g. out of memory). |
Sharvil Nanavati | 540e7ca | 2014-04-24 16:22:45 -0700 | [diff] [blame] | 57 | bool list_prepend(list_t *list, void *data); |
Zach Johnson | 8d43696 | 2015-03-02 14:42:02 -0800 | [diff] [blame] | 58 | |
| 59 | // Inserts |data| at the end of |list|. Neither |data| nor |list| may be NULL. |
| 60 | // This function does not make a copy of |data| so the pointer must remain valid |
| 61 | // at least until the element is removed from the list or the list is freed. |
| 62 | // Returns true if |data| could be inserted, false otherwise (e.g. out of memory). |
Sharvil Nanavati | 540e7ca | 2014-04-24 16:22:45 -0700 | [diff] [blame] | 63 | bool list_append(list_t *list, void *data); |
Zach Johnson | 8d43696 | 2015-03-02 14:42:02 -0800 | [diff] [blame] | 64 | |
| 65 | // Removes |data| from the list. Neither |list| nor |data| may be NULL. If |data| |
| 66 | // is inserted multiple times in the list, this function will only remove the first |
| 67 | // instance. If a free function was specified in |list_new|, it will be called back |
| 68 | // with |data|. This function returns true if |data| was found in the list and removed, |
| 69 | // false otherwise. |
Sharvil Nanavati | 540e7ca | 2014-04-24 16:22:45 -0700 | [diff] [blame] | 70 | bool list_remove(list_t *list, void *data); |
Zach Johnson | 8d43696 | 2015-03-02 14:42:02 -0800 | [diff] [blame] | 71 | |
| 72 | // Removes all elements in the list. Calling this function will return the list to the |
| 73 | // same state it was in after |list_new|. |list| may not be NULL. |
Sharvil Nanavati | 540e7ca | 2014-04-24 16:22:45 -0700 | [diff] [blame] | 74 | void list_clear(list_t *list); |
| 75 | |
Zach Johnson | 8d43696 | 2015-03-02 14:42:02 -0800 | [diff] [blame] | 76 | // Iterates through the entire |list| and calls |callback| for each data element. |
| 77 | // If the list is empty, |callback| will never be called. It is safe to mutate the |
| 78 | // list inside the callback. If an element is added before the node being visited, |
| 79 | // there will be no callback for the newly-inserted node. Neither |list| nor |
| 80 | // |callback| may be NULL. |
Sharvil Nanavati | 540e7ca | 2014-04-24 16:22:45 -0700 | [diff] [blame] | 81 | void list_foreach(const list_t *list, list_iter_cb callback); |
| 82 | |
Zach Johnson | 8d43696 | 2015-03-02 14:42:02 -0800 | [diff] [blame] | 83 | // Returns an iterator to the first element in |list|. |list| may not be NULL. |
| 84 | // The returned iterator is valid as long as it does not equal the value returned |
| 85 | // by |list_end|. |
Sharvil Nanavati | f0e7c8b | 2014-07-01 18:42:56 -0700 | [diff] [blame] | 86 | list_node_t *list_begin(const list_t *list); |
Zach Johnson | 8d43696 | 2015-03-02 14:42:02 -0800 | [diff] [blame] | 87 | |
| 88 | // Returns an iterator that points past the end of the list. In other words, |
| 89 | // this function returns the value of an invalid iterator for the given list. |
| 90 | // When an iterator has the same value as what's returned by this function, you |
| 91 | // may no longer call |list_next| with the iterator. |list| may not be NULL. |
Sharvil Nanavati | f0e7c8b | 2014-07-01 18:42:56 -0700 | [diff] [blame] | 92 | list_node_t *list_end(const list_t *list); |
Zach Johnson | 8d43696 | 2015-03-02 14:42:02 -0800 | [diff] [blame] | 93 | |
| 94 | // Given a valid iterator |node|, this function returns the next value for the |
| 95 | // iterator. If the returned value equals the value returned by |list_end|, the |
| 96 | // iterator has reached the end of the list and may no longer be used for any |
| 97 | // purpose. |
Sharvil Nanavati | f0e7c8b | 2014-07-01 18:42:56 -0700 | [diff] [blame] | 98 | list_node_t *list_next(const list_node_t *node); |
Zach Johnson | 8d43696 | 2015-03-02 14:42:02 -0800 | [diff] [blame] | 99 | |
| 100 | // Returns the value stored at the location pointed to by the iterator |node|. |
| 101 | // |node| must not equal the value returned by |list_end|. |
Sharvil Nanavati | 540e7ca | 2014-04-24 16:22:45 -0700 | [diff] [blame] | 102 | void *list_node(const list_node_t *node); |