6150d2bb466f2df365eb0832c8521efa396fb344
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) \
60 _list_new(sizeof(type)); \
64 * @brief Copy constructor (shallow copy, ok for basic types).
67 List
* list
///< "this" pointer.
71 * @brief Check if the list is empty.
74 List
* list
///< "this" pointer.
78 * @brief return the size of current list.
81 List
* list
///< "this" pointer.
85 * @brief Get data at the given list cell argument.
88 ListCell
* listCell
///< Pointer to a cell inside "this" list.
92 * @brief Get data at the given list cell argument.
93 * @param listCell Pointer to a cell inside "this" list.
94 * @param data Data to be assigned.
96 * Usage: void list_get(ListCell* listCell, void data)
98 #define list_get(listCell, data) \
100 void* pData = _list_get(listCell); \
101 data = *((typeof(&data))pData); \
105 * @brief Set data at the given list cell argument.
108 List
* list
, ///< "this" pointer.
109 ListCell
* listCell
, ///< Pointer to a cell inside "this" list.
110 void* data
///< Pointer to data to be set.
114 * @brief Set data at the given list cell argument.
115 * @param list "this" pointer.
116 * @param listCell Pointer to a cell inside "this" list.
117 * @param data Data to be set.
119 * Usage: void list_set(List* list, ListCell* listCell, void data);
121 #define list_set(list, listCell, data) \
123 typeof((data)) tmp = data; \
124 _list_set(list, listCell, &tmp); \
128 * @brief Add data to the list when list is empty.
130 void _list_insert_first_element(
131 List
* list
, ///< "this" pointer.
132 void* data
///< Pointer to data to be added
136 * @brief Add data before list cell argument.
138 void _list_insert_before(
139 List
* list
, ///< "this" pointer.
140 ListCell
* listCell
, ///< Pointer to a cell inside "this" list.
141 void* data
///< Pointer to data to be added.
145 * @brief Add data before list cell argument.
146 * @param list "this" pointer.
147 * @param listCell Pointer to a cell inside "this" list.
148 * @param data Data to be inserted.
150 * Usage: void list_insert_before(List* list, ListCell* listCell, void data)
152 #define list_insert_before(list, listCell, data) \
154 typeof((data)) tmp = data; \
155 _list_insert_before(list, listCell, &tmp); \
159 * @brief Add data after list cell argument.
161 void _list_insert_after(
162 List
* list
, ///< "this" pointer.
163 ListCell
* listCell
, ///< Pointer to a cell inside "this" list.
164 void* data
///< Pointer to data to be inserted.
168 * @brief Add data after list cell argument.
169 * @param list "this" pointer.
170 * @param listCell Pointer to a cell inside "this" list.
171 * @param data Data to be inserted.
173 * Usage: void list_insert_after(List* list, ListCell* listCell, void data)
175 #define list_insert_after(list, listCell, data) \
177 typeof((data)) tmp = data; \
178 _list_insert_after(list, listCell, &tmp); \
182 * @brief Add data at the beginning of the list.
184 void _list_insert_front(
185 List
* list
, ///< "this" pointer.
186 void* data
///< Pointer to data to be inserted.
190 * @brief Add data at the beginning of the list.
191 * @param list "this" pointer.
192 * @param data Data to be inserted.
194 * Usage: void list_insert_front(List* list, void data)
196 #define list_insert_front(list, data) \
198 typeof((data)) tmp = data; \
199 _list_insert_front(list, &tmp); \
203 * @brief Add data at the end of the list.
205 void _list_insert_back(
206 List
* list
, ///< "this" pointer.
207 void* data
///< Pointer to data to be inserted.
211 * @brief Add data at the end of the list.
212 * @param list "this" pointer.
213 * @param data Data to be inserted.
215 * Usage: void list_insert_back(List* list, void data)
217 #define list_insert_back(list, data) \
219 typeof((data)) tmp = data; \
220 _list_insert_back(list, &tmp); \
224 * @brief Remove data at position given by 'listCell'.
227 List
* list
, ///< "this" pointer.
228 ListCell
* listCell
///< Pointer to a cell inside "this" list.
232 * @brief Remove data at the beginning of the list.
234 void list_remove_front(
235 List
* list
///< "this" pointer.
239 * @brief Remove data at the end of the list.
241 void list_remove_back(
242 List
* list
///< "this" pointer.
246 * @brief Clear the entire list.
249 List
* list
///< "this" pointer.
253 * @brief Destroy the list: clear it, and free 'list' pointer.
256 List
* list
///< "this" pointer.
264 * @brief Iterator on a double-linked list.
266 typedef struct ListIterator
{
267 List
* list
; ///< The list to be iterate.
268 ListCell
* current
; ///< The current iterated list cell.
272 * @brief Obtain an iterator object, starting at list beginning.
274 ListIterator
* list_get_iterator(
275 List
* list
///< Pointer to the list to be iterated over.
279 * @brief (Re)set current position inside list to head.
281 void listI_reset_head(
282 ListIterator
* listI
///< "this" pointer.
286 * @brief (Re)set current position inside list to tail.
288 void listI_reset_tail(
289 ListIterator
* listI
///< "this" pointer.
293 * @brief Tell if there is some data at the current index.
296 ListIterator
* listI
///< "this" pointer.
300 * @brief Return data contained in the current list cell.
301 * @param listI "this" pointer.
302 * @param data Data to be assigned.
304 * Usage: void listI_get(ListIterator* listI, void data)
306 #define listI_get(listI, data) \
307 list_get(listI->current, data)
310 * @brief Set data at the current iterator position.
311 * @param listI "this" pointer
312 * @param data Data to assign.
314 * Usage: void listI_set(ListIterator* listI, void data);
316 #define listI_set(listI, data) \
317 list_set(listI->list, listI->current, data)
320 * @brief Add data before current list cell.
321 * @param listI "this" pointer
322 * @param data Data to be inserted.
324 * Usage: void listI_insert_before(ListIteratorI* listI, void data)
326 #define listI_insert_before(listI, data) \
327 list_insert_before(listI->list, listI->current, data)
330 * @brief Add data after current list cell.
331 * @param listI "this" pointer
332 * @param data Data to be inserted.
334 * Usage: void listI_insert_after(ListIteratorI* listI, void data)
336 #define listI_insert_after(listI, data) \
337 list_insert_after(listI->list, listI->current, data)
340 * @brief Type to encode a direction (forward / backward).
343 BACKWARD
= -1, ///< Move toward head.
344 FORWARD
= 1 ///< Move toward tail.
348 * @brief Remove data at the current iterator position.
351 ListIterator
* listI
, ///< "this" pointer.
352 Direction direction
///< Indicate the position of iterator after removal.
356 * @brief Move current iterator position forward (toward tail).
358 void listI_move_next(
359 ListIterator
* listI
///< "this" pointer.
363 * @brief Move current iterator position backward (toward head).
365 void listI_move_prev(
366 ListIterator
* listI
///< "this" pointer.
370 * @brief Free memory allocated for the iterator.
373 ListIterator
* listI
///< "this" pointer.