| 8 | 8 | 
| 9 UCX already comes with two common list implementations ([linked list](linked_list.h.md) and [array list](array_list.h.md)) | 9 UCX already comes with two common list implementations ([linked list](linked_list.h.md) and [array list](array_list.h.md)) | 
| 10 that should cover most use cases. | 10 that should cover most use cases. | 
| 11 But if you feel the need to implement an own list, you will find instructions [below](#implement-own-list-structures). | 11 But if you feel the need to implement an own list, you will find instructions [below](#implement-own-list-structures). | 
| 12 | 12 | 
|  | 13 ```C | 
|  | 14 #include <cx/linked_list.h> | 
|  | 15 | 
|  | 16 CxList *cxLinkedListCreate(const CxAllocator *allocator, | 
|  | 17         cx_compare_func comparator, size_t elem_size); | 
|  | 18 | 
|  | 19 CxList *cxLinkedListCreateSimple(size_t elem_size); | 
|  | 20 | 
|  | 21 #include <cx/array_list.h> | 
|  | 22 | 
|  | 23 CxList *cxArrayListCreate(const CxAllocator *allocator, | 
|  | 24         cx_compare_func comparator, size_t elem_size, | 
|  | 25         size_t initial_capacity); | 
|  | 26 | 
|  | 27 CxList *cxArrayListCreateSimple(size_t elem_size, | 
|  | 28         size_t initial_capacity); | 
|  | 29 ``` | 
|  | 30 | 
|  | 31 The function `cxLinkedListCreate()` creates a new linked list with the specified `allocator` which stores elements of size `elem_size`. | 
|  | 32 The elements are supposed to be compared with the specified `comparator` (cf. [](#access-and-find)). | 
|  | 33 The function `cxLinkedListCreateSimple()` will use the stdlib default allocator and does not specify a compare function. | 
|  | 34 | 
|  | 35 Array lists can be created with `cxArrayListCreate()` where the additional argument `initial_capacity` specifies for how many elements the underlying array shall be initially allocated. | 
|  | 36 | 
|  | 37 If `CX_STORE_POINTERS` is used as `elem_size`, the actual element size will be `sizeof(void*)` and the list will behave slightly differently when accessing elements. | 
|  | 38 Lists that are storing pointers will always return the stored pointer directly, instead of returning a pointer into the list's memory, thus saving you from unnecessary dereferencing. | 
|  | 39 Conversely, when adding elements to the list, the pointers you specify (e.g. in `cxListAdd()` or `cxListInsert()`) are directly added to the list, instead of copying the contents pointed to by the argument. | 
|  | 40 | 
|  | 41 > When you create a list which is storing pointers and do not specify a compare function, `cx_cmp_ptr` will be used by default. | 
|  | 42 | 
| 13 ## Example | 43 ## Example | 
| 14 | 44 | 
| 15 <warning> | 45 <warning> | 
| 16 TODO: add example how to work with lists | 46 TODO: add example how to work with lists | 
| 17 </warning> | 47 </warning> | 
| 18 | 48 | 
| 19 > If you want to lazy-initialize lists, you can use the global `cxEmptyList` symbol as a placeholder instead of using a `NULL`-pointer. | 49 > If you want to lazy-initialize lists, you can use the global `cxEmptyList` symbol as a placeholder instead of using a `NULL`-pointer. | 
| 20 > While you *must not* insert items into that list, you can safely access this list or create iterators. | 50 > While you *must not* insert elements into that list, you can safely access this list or create iterators. | 
| 21 > This allows you to write clean code without checking for `NULL`-pointer everywhere. | 51 > This allows you to write clean code without checking for `NULL`-pointer everywhere. | 
| 22 > You still need to make sure that the placeholder is replaced with an actual list before inserting items. | 52 > You still need to make sure that the placeholder is replaced with an actual list before inserting elements. | 
| 23 | 53 | 
| 24 ## Insert | 54 ## Insert | 
| 25 | 55 | 
| 26 ```C | 56 ```C | 
|  | 57 #include <cx/list.h> | 
|  | 58 | 
| 27 int cxListAdd(CxList *list, const void *elem); | 59 int cxListAdd(CxList *list, const void *elem); | 
| 28 | 60 | 
|  | 61 int cxListInsert(CxList *list, size_t index, const void *elem); | 
|  | 62 | 
|  | 63 int cxListInsertSorted(CxList *list, const void *elem); | 
|  | 64 | 
| 29 size_t cxListAddArray(CxList *list, const void *array, size_t n); | 65 size_t cxListAddArray(CxList *list, const void *array, size_t n); | 
| 30 |  | 
| 31 int cxListInsert(CxList *list, size_t index, const void *elem); |  | 
| 32 |  | 
| 33 int cxListInsertSorted(CxList *list, const void *elem); |  | 
| 34 | 66 | 
| 35 size_t cxListInsertArray(CxList *list, size_t index, | 67 size_t cxListInsertArray(CxList *list, size_t index, | 
| 36         const void *array, size_t n); | 68         const void *array, size_t n); | 
| 37 | 69 | 
| 38 size_t cxListInsertSortedArray(CxList *list, | 70 size_t cxListInsertSortedArray(CxList *list, | 
| 41 int cxListInsertAfter(CxIterator *iter, const void *elem); | 73 int cxListInsertAfter(CxIterator *iter, const void *elem); | 
| 42 | 74 | 
| 43 int cxListInsertBefore(CxIterator *iter, const void *elem); | 75 int cxListInsertBefore(CxIterator *iter, const void *elem); | 
| 44 ``` | 76 ``` | 
| 45 | 77 | 
| 46 <warning> | 78 The function `cxListAdd()` appends the element `elem` to the list and returns zero on success or non-zero when allocating the memory for the element fails. | 
| 47 TODO: add documentation | 79 Similarly, `cxListInsert()` adds the element at the specified `index`, | 
| 48 </warning> | 80 and `cxListInsertSorted()` adds the element at the correct position so that the list remains sorted according to the list's compare function. | 
|  | 81 | 
|  | 82 When you are currently iterating through a list, you can insert items before or after the current position of the iterator | 
|  | 83 with `cxListInsertBefore()` or `cxListInsertAfter()`, respectively. | 
|  | 84 This _should_ be done with [mutating iterators](iterator.h.md#mutating-iterators) only, but is also defined for normal iterators. | 
|  | 85 | 
|  | 86 If the list is storing pointers (cf. `cxCollectionStoresPointers()`), the pointer `elem` is directly added to the list. | 
|  | 87 Otherwise, the contents at the location pointed to by `elem` are copied to the list's memory with the element size specified during creation of the list. | 
|  | 88 | 
|  | 89 On the other hand the `array` argument for `cxListAddArray()`, `cxListInsertArray()`, and `cxListInsertSortedArray()` | 
|  | 90 must always point to an array of elements to be added (i.e. either an array of pointers, or an array of actual elements). | 
|  | 91 | 
|  | 92 A special requirement for `cxListInsertSortedArray()` is, that the `array` must already be sorted. | 
|  | 93 | 
|  | 94 > Implementations are required to optimize the insertion of a sorted array into a sorted list in linear time, | 
|  | 95 > while inserting each element separately via `cxListInsertSorted()` may take quadratic time. | 
|  | 96 | 
|  | 97 > The functions `cxListInsertSorted()` and `cxListInsertSortedArray()` do neither check if the list is already sorted, nor do they actively sort the list. | 
|  | 98 > {style="note"} | 
| 49 | 99 | 
| 50 ## Access and Find | 100 ## Access and Find | 
| 51 | 101 | 
| 52 ```C | 102 <link-summary>Functions for searching and accessing elements.</link-summary> | 
|  | 103 | 
|  | 104 ```C | 
|  | 105 #include <cx/list.h> | 
|  | 106 | 
|  | 107 void *cxListAt(const CxList *list, size_t index); | 
|  | 108 | 
|  | 109 size_t cxListFind(const CxList *list, const void *elem); | 
|  | 110 | 
|  | 111 size_t cxListFindRemove(CxList *list, const void *elem); | 
|  | 112 | 
|  | 113 bool cxListIndexValid(const CxList *list, size_t index); | 
|  | 114 | 
| 53 size_t cxListSize(const CxList *list); | 115 size_t cxListSize(const CxList *list); | 
| 54 | 116 ``` | 
| 55 void *cxListAt(const CxList *list, size_t index); | 117 | 
| 56 | 118 The function `cxListAt()` accesses the element at the specified `index`. | 
| 57 size_t cxListFind(const CxList *list, const void *elem); | 119 If the list is storing pointers (i.e. `cxCollectionStoresPointers()` returns `true`), the pointer at the specified index is directly returned. | 
| 58 | 120 Otherwise, a pointer to element at the specified index is returned. | 
| 59 size_t cxListFindRemove(CxList *list, const void *elem); | 121 If the index is out-of-bounds, the function returns `NULL`. | 
| 60 | 122 | 
| 61 bool cxListIndexValid(const CxList *list, size_t index); | 123 On the other hand, `cxListFind()` searches for the element pointed to by `elem` by comparing each element in the list with the list`s compare function, | 
| 62 ``` | 124 and returns the first index when the element was found. | 
| 63 | 125 Otherwise, the function returns the list size. | 
| 64 <warning> | 126 | 
| 65 TODO: add documentation | 127 The function `cxListFindRemove()` behaves like `cxListFind()`, except that it also removes the first occurrence of the element from the list. | 
| 66 </warning> | 128 This will _also_ call destructor functions, if specified, so take special care when you continue to use `elem`, or when the list is storing pointers and the element appears more than once in the list. | 
|  | 129 | 
|  | 130 With `cxListIndexValid()` you can check the index returned by `cxListFind()` or `cxListFindRemove()`, | 
|  | 131 which is more convenient than comparing the return value if the return value of `cxListSize()`. | 
| 67 | 132 | 
| 68 ## Remove | 133 ## Remove | 
| 69 | 134 | 
| 70 ```C | 135 ```C | 
|  | 136 #include <cx/list.h> | 
|  | 137 | 
| 71 int cxListRemove(CxList *list, size_t index); | 138 int cxListRemove(CxList *list, size_t index); | 
| 72 | 139 | 
|  | 140 size_t cxListRemoveArray(CxList *list, size_t index, size_t num); | 
|  | 141 | 
| 73 int cxListRemoveAndGet(CxList *list, size_t index, void *targetbuf); | 142 int cxListRemoveAndGet(CxList *list, size_t index, void *targetbuf); | 
| 74 |  | 
| 75 size_t cxListRemoveArray(CxList *list, size_t index, size_t num); |  | 
| 76 | 143 | 
| 77 size_t cxListRemoveArrayAndGet(CxList *list, size_t index, size_t num, | 144 size_t cxListRemoveArrayAndGet(CxList *list, size_t index, size_t num, | 
| 78         void *targetbuf); | 145         void *targetbuf); | 
|  | 146 | 
|  | 147 size_t cxListFindRemove(CxList *list, const void *elem); | 
| 79 | 148 | 
| 80 void cxListClear(CxList *list); | 149 void cxListClear(CxList *list); | 
| 81 ``` | 150 ``` | 
| 82 | 151 | 
| 83 <warning> | 152 The function `cxListRemove()` removes the element at the specified index and returns zero, | 
| 84 TODO: add documentation | 153 or returns non-zero if the index is out-of-bounds. | 
| 85 </warning> | 154 The function `cxListRemoveArray()` removes `num` elements starting at `index` and returns the number of elements that have been removed. | 
|  | 155 For each removed element, the [destructor functions](collection.h.md#destructor-functions) are called. | 
|  | 156 | 
|  | 157 On the other hand, `cxListRemoveAndGet()` and `cxListRemoveArrayAndGet()` do not invoke the destructor functions | 
|  | 158 and instead copy the elements into the `targetbuf`, which must be large enough to hold the removed elements. | 
|  | 159 | 
|  | 160 The function `cxListFindRemove()` finds the first element within the list that is equivalent to the element pointed to by `elem` and removes it from the list. | 
|  | 161 This will _also_ call destructor functions, if specified, so take special care when you continue to use `elem`. | 
|  | 162 | 
|  | 163 The function `cxListClear()` simply removes all elements from the list, invoking the destructor functions. | 
|  | 164 It behaves equivalently, but is usually more efficient than calling `cxListRemove()` for every index. | 
| 86 | 165 | 
| 87 ## Iterators | 166 ## Iterators | 
| 88 | 167 | 
| 89 ```C | 168 ```C | 
|  | 169 #include <cx/list.h> | 
|  | 170 | 
| 90 CxIterator cxListIterator(const CxList *list); | 171 CxIterator cxListIterator(const CxList *list); | 
| 91 | 172 | 
|  | 173 CxIterator cxListBackwardsIterator(const CxList *list); | 
|  | 174 | 
|  | 175 CxIterator cxListIteratorAt(const CxList *list, size_t index); | 
|  | 176 | 
|  | 177 CxIterator cxListBackwardsIteratorAt(const CxList *list, size_t index); | 
|  | 178 | 
| 92 CxIterator cxListMutIterator(CxList *list); | 179 CxIterator cxListMutIterator(CxList *list); | 
| 93 | 180 | 
| 94 CxIterator cxListBackwardsIterator(const CxList *list); |  | 
| 95 |  | 
| 96 CxIterator cxListMutBackwardsIterator(CxList *list); | 181 CxIterator cxListMutBackwardsIterator(CxList *list); | 
| 97 | 182 | 
| 98 CxIterator cxListIteratorAt(const CxList *list, size_t index); |  | 
| 99 |  | 
| 100 CxIterator cxListBackwardsIteratorAt(const CxList *list, size_t index); |  | 
| 101 |  | 
| 102 CxIterator cxListMutIteratorAt(CxList *list, size_t index); | 183 CxIterator cxListMutIteratorAt(CxList *list, size_t index); | 
| 103 | 184 | 
| 104 CxIterator cxListMutBackwardsIteratorAt(CxList *list, size_t index); | 185 CxIterator cxListMutBackwardsIteratorAt(CxList *list, size_t index); | 
| 105 ``` | 186 ``` | 
| 106 | 187 | 
| 107 <warning> | 188 The functions `cxListIterator()` and `cxListBackwardsIterator()` create iterators | 
| 108 TODO: add documentation | 189 that start and the first or the last element in the list and iterate through the entire list. | 
| 109 </warning> | 190 | 
|  | 191 The functions `cxListIteratorAt()` and `cxListBackwardsIteratorAt()` start with the element at the specified index | 
|  | 192 and iterate until the end, or the beginning of the list, respectively. | 
|  | 193 | 
|  | 194 The functions with `Mut` in are equivalently, except that they create a [mutating iterator](iterator.h.md#mutating-iterators). | 
|  | 195 Removing elements via a mutating iterator will cause an invocation of the [destructor functions](collection.h.md#destructor-functions) for the removed element. | 
|  | 196 | 
|  | 197 If is safe to specify an out-of-bounds index in which case an iterator is returned for which `cxIteratorValid()` returns `false`, immediately. | 
| 110 | 198 | 
| 111 ## Reorder | 199 ## Reorder | 
| 112 | 200 | 
| 113 ```C | 201 ```C | 
|  | 202 #include <cx/list.h> | 
|  | 203 | 
| 114 int cxListSwap(CxList *list, size_t i, size_t j); | 204 int cxListSwap(CxList *list, size_t i, size_t j); | 
| 115 | 205 | 
|  | 206 void cxListReverse(CxList *list); | 
|  | 207 | 
| 116 void cxListSort(CxList *list); | 208 void cxListSort(CxList *list); | 
| 117 | 209 ``` | 
| 118 void cxListReverse(CxList *list); | 210 | 
| 119 ``` | 211 The function `cxListSwap()` swaps two elements specified by the indices `i` and `j`. | 
| 120 | 212 The return value is non-zero if one of the indices is out-of-bounds. | 
| 121 <warning> | 213 | 
| 122 TODO: add documentation | 214 The function `cxListReverse()` reorders all elements, so that they appear in exactly the opposite order after invoking this function. | 
| 123 </warning> | 215 | 
|  | 216 The function `cxListSort()` sorts all elements with respect to the list's compare function, | 
|  | 217 unless the list is already sorted (cf. `cxCollectionSorted()`), in which case the function immediately returns. | 
|  | 218 | 
|  | 219 Default UCX implementations of the list interface make use of [small buffer optimizations](install.md#small-buffer-optimizations) when swapping elements. | 
|  | 220 | 
|  | 221 > An invocation of `cxListSort` sets the `sorted` flag of the [collection](collection.h.md). | 
|  | 222 > Implementations usually make use of this flag to optimize search operations, if possible. | 
|  | 223 > For example the [array list](array_list.h.md) implementation will use binary search | 
|  | 224 > for `cxListFind()` and similar operations, when the list is sorted. | 
| 124 | 225 | 
| 125 ## Compare | 226 ## Compare | 
| 126 | 227 | 
| 127 ```C | 228 ```C | 
|  | 229 #include <cx/list.h> | 
|  | 230 | 
| 128 int cxListCompare(const CxList *list, const CxList *other); | 231 int cxListCompare(const CxList *list, const CxList *other); | 
| 129 ``` | 232 ``` | 
| 130 | 233 | 
| 131 Arbitrary lists can be compared item-wise with `cxListCompare()`, as long as the compare functions of both lists are equivalent. | 234 Arbitrary lists can be compared element-wise with `cxListCompare()`, as long as the compare functions of both lists are equivalent. | 
| 132 | 235 | 
| 133 That means, you can compare an UCX [array list](array_list.h.md) with a [linked list](linked_list.h.md), | 236 That means, you can compare an UCX [array list](array_list.h.md) with a [linked list](linked_list.h.md), | 
| 134 and you could even compare lists that are storing pointers with lists that are not storing pointers. | 237 and you could even compare lists that are storing pointers with lists that are not storing pointers. | 
| 135 | 238 | 
| 136 However, the optimized list-internal compare implementation is only used, when both the compare functions and the list classes are identical. | 239 However, the optimized list-internal compare implementation is only used, when both the compare functions and the list classes are identical. | 
| 137 Otherwise, `cxListCompare()` will behave as if you were iterating through both lists and manually comparing the items. | 240 Otherwise, `cxListCompare()` will behave as if you were iterating through both lists and manually comparing the elements. | 
| 138 | 241 | 
| 139 The return value of `cxListCompare()` is zero, if the lists are item-wise equivalent. | 242 The return value of `cxListCompare()` is zero, if the lists are element-wise equivalent. | 
| 140 If they are not, the non-zero return value equals the return value of the used compare function for the first pair of elements that are not equal. | 243 If they are not, the non-zero return value equals the return value of the used compare function for the first pair of elements that are not equal. | 
| 141 | 244 | 
| 142 ## Dispose | 245 ## Dispose | 
| 143 | 246 | 
| 144 ```C | 247 ```C | 
|  | 248 #include <cx/list.h> | 
|  | 249 | 
| 145 void cxListFree(CxList *list); | 250 void cxListFree(CxList *list); | 
| 146 ``` | 251 ``` | 
| 147 | 252 | 
| 148 No matter with which function a `CxList` has been created, you can _always_ deallocate the entire memory with a call to `cxListFree()`. | 253 No matter with which function a `CxList` has been created, you can _always_ deallocate the entire memory with a call to `cxListFree()`. | 
| 149 | 254 | 
| 150 The effect is equivalent to invoking `cxListClear()` plus deallocating the memory for the list structure. | 255 The effect is equivalent to invoking `cxListClear()` plus deallocating the memory for the list structure. | 
| 151 That means, for each item in the list, the destructor functions defined by `cxDefineDestructor()` or `cxDefineAdvancedDestructor()` are called, | 256 That means, for each element in the list, the [destructor functions](collection.h.md#destructor-functions) are called before deallocating the list. | 
| 152 before deallocating the list. |  | 
| 153 | 257 | 
| 154 When the list has been storing pointers, make sure that either another reference to the same memory exist in your program, | 258 When the list has been storing pointers, make sure that either another reference to the same memory exist in your program, | 
| 155 or any of the destructor functions deallocates the memory. | 259 or any of the destructor functions deallocates the memory. | 
| 156 Otherwise, there is a risk of a memory leak. | 260 Otherwise, there is a risk of a memory leak. | 
| 157 | 261 |