a6e9822412bc7d9f9aa751d15033e57015bc1045
10 #include "cgds/safe_alloc.h"
11 #include "cgds/types.h"
18 * @brief Cell of a double-linked list.
20 typedef struct ListCell
{
21 void* data
; ///< Generic data contained in this cell.
22 struct ListCell
* prev
; ///< Pointer to previous cell in the list.
23 struct ListCell
* next
; ///< Pointer to next cell in the list.
27 * @brief Double-linked list data structure.
30 UInt size
; ///< Count elements in the list.
31 size_t dataSize
; ///< Size of a list cell element in bytes.
32 ListCell
* head
; ///< Pointer to the first cell in the list.
33 ListCell
* tail
; ///< Pointer to the last cell in the list.
37 * @brief Initialize an empty list.
40 List
* list
, ///< "this" pointer.
41 size_t dataSize
///< Size of a list cell elements in bytes.
45 * @brief Return an allocated and initialized list.
46 * @param dataSize Size in bytes of a list element.
49 size_t dataSize
///< Size of a list cell elements in bytes.
53 * @brief Return an allocated and initialized list.
54 * @param type Type of a list element (int, char*, ...).
56 * Usage: List* list_new(<Type> type)
58 #define list_new(type) \
59 _list_new(sizeof(type))
62 * @brief Copy constructor (shallow copy, ok for basic types).
65 List
* list
///< "this" pointer.
69 * @brief Check if the list is empty.
72 List
* list
///< "this" pointer.
76 * @brief return the size of current list.
79 List
* list
///< "this" pointer.
83 * @brief Get data at the given list cell argument.
86 ListCell
* listCell
///< Pointer to a cell inside "this" list.
90 * @brief Get data at the given list cell argument.
91 * @param listCell Pointer to a cell inside "this" list.
92 * @param data Data to be assigned.
94 * Usage: void list_get(ListCell* listCell, void data)
96 #define list_get(listCell, data) \
98 void* pData = _list_get(listCell); \
99 data = *((typeof(&data))pData); \
103 * @brief Set data at the given list cell argument.
106 List
* list
, ///< "this" pointer.
107 ListCell
* listCell
, ///< Pointer to a cell inside "this" list.
108 void* data
///< Pointer to data to be set.
112 * @brief Set data at the given list cell argument.
113 * @param list "this" pointer.
114 * @param listCell Pointer to a cell inside "this" list.
115 * @param data Data to be set.
117 * Usage: void list_set(List* list, ListCell* listCell, void data);
119 #define list_set(list, listCell, data) \
121 typeof(data) tmp = data; \
122 _list_set(list, listCell, &tmp); \
126 * @brief Add data to the list when list is empty.
128 void _list_insert_first_element(
129 List
* list
, ///< "this" pointer.
130 void* data
///< Pointer to data to be added
134 * @brief Add data before list cell argument.
136 void _list_insert_before(
137 List
* list
, ///< "this" pointer.
138 ListCell
* listCell
, ///< Pointer to a cell inside "this" list.
139 void* data
///< Pointer to data to be added.
143 * @brief Add data before list cell argument.
144 * @param list "this" pointer.
145 * @param listCell Pointer to a cell inside "this" list.
146 * @param data Data to be inserted.
148 * Usage: void list_insert_before(List* list, ListCell* listCell, void data)
150 #define list_insert_before(list, listCell, data) \
152 typeof(data) tmp = data; \
153 _list_insert_before(list, listCell, &tmp); \
157 * @brief Add data after list cell argument.
159 void _list_insert_after(
160 List
* list
, ///< "this" pointer.
161 ListCell
* listCell
, ///< Pointer to a cell inside "this" list.
162 void* data
///< Pointer to data to be inserted.
166 * @brief Add data after list cell argument.
167 * @param list "this" pointer.
168 * @param listCell Pointer to a cell inside "this" list.
169 * @param data Data to be inserted.
171 * Usage: void list_insert_after(List* list, ListCell* listCell, void data)
173 #define list_insert_after(list, listCell, data) \
175 typeof(data) tmp = data; \
176 _list_insert_after(list, listCell, &tmp); \
180 * @brief Add data at the beginning of the list.
182 void _list_insert_front(
183 List
* list
, ///< "this" pointer.
184 void* data
///< Pointer to data to be inserted.
188 * @brief Add data at the beginning of the list.
189 * @param list "this" pointer.
190 * @param data Data to be inserted.
192 * Usage: void list_insert_front(List* list, void data)
194 #define list_insert_front(list, data) \
196 typeof(data) tmp = data; \
197 _list_insert_front(list, &tmp); \
201 * @brief Add data at the end of the list.
203 void _list_insert_back(
204 List
* list
, ///< "this" pointer.
205 void* data
///< Pointer to data to be inserted.
209 * @brief Add data at the end of the list.
210 * @param list "this" pointer.
211 * @param data Data to be inserted.
213 * Usage: void list_insert_back(List* list, void data)
215 #define list_insert_back(list, data) \
217 typeof(data) tmp = data; \
218 _list_insert_back(list, &tmp); \
222 * @brief Remove data at position given by 'listCell'.
225 List
* list
, ///< "this" pointer.
226 ListCell
* listCell
///< Pointer to a cell inside "this" list.
230 * @brief Remove data at the beginning of the list.
232 void list_remove_front(
233 List
* list
///< "this" pointer.
237 * @brief Remove data at the end of the list.
239 void list_remove_back(
240 List
* list
///< "this" pointer.
244 * @brief Clear the entire list.
247 List
* list
///< "this" pointer.
251 * @brief Destroy the list: clear it, and free 'list' pointer.
254 List
* list
///< "this" pointer.
262 * @brief Iterator on a double-linked list.
264 typedef struct ListIterator
{
265 List
* list
; ///< The list to be iterate.
266 ListCell
* current
; ///< The current iterated list cell.
270 * @brief Obtain an iterator object, starting at list beginning.
272 ListIterator
* list_get_iterator(
273 List
* list
///< Pointer to the list to be iterated over.
277 * @brief (Re)set current position inside list to head.
279 void listI_reset_head(
280 ListIterator
* listI
///< "this" pointer.
284 * @brief (Re)set current position inside list to tail.
286 void listI_reset_tail(
287 ListIterator
* listI
///< "this" pointer.
291 * @brief Tell if there is some data at the current index.
294 ListIterator
* listI
///< "this" pointer.
298 * @brief Return data contained in the current list cell.
299 * @param listI "this" pointer.
300 * @param data Data to be assigned.
302 * Usage: void listI_get(ListIterator* listI, void data)
304 #define listI_get(listI, data) \
305 list_get(listI->current, data)
308 * @brief Set data at the current iterator position.
309 * @param listI "this" pointer
310 * @param data Data to assign.
312 * Usage: void listI_set(ListIterator* listI, void data);
314 #define listI_set(listI, data) \
315 list_set(listI->list, listI->current, data)
318 * @brief Add data before current list cell.
319 * @param listI "this" pointer
320 * @param data Data to be inserted.
322 * Usage: void listI_insert_before(ListIteratorI* listI, void data)
324 #define listI_insert_before(listI, data) \
325 list_insert_before(listI->list, listI->current, data)
328 * @brief Add data after current list cell.
329 * @param listI "this" pointer
330 * @param data Data to be inserted.
332 * Usage: void listI_insert_after(ListIteratorI* listI, void data)
334 #define listI_insert_after(listI, data) \
335 list_insert_after(listI->list, listI->current, data)
338 * @brief Type to encode a direction (forward / backward).
341 BACKWARD
= -1, ///< Move toward head.
342 FORWARD
= 1 ///< Move toward tail.
346 * @brief Remove data at the current iterator position.
349 ListIterator
* listI
, ///< "this" pointer.
350 Direction direction
///< Indicate the position of iterator after removal.
354 * @brief Move current iterator position forward (toward tail).
356 void listI_move_next(
357 ListIterator
* listI
///< "this" pointer.
361 * @brief Move current iterator position backward (toward head).
363 void listI_move_prev(
364 ListIterator
* listI
///< "this" pointer.
368 * @brief Free memory allocated for the iterator.
371 ListIterator
* listI
///< "this" pointer.