ucx/list.h

changeset 5
88625853ae74
parent 1
1bcaac272cdf
child 17
11dffb40cd91
equal deleted inserted replaced
4:ae5a98f0545c 5:88625853ae74
1 /* 1 /*
2 * 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3 */ 3 *
4 4 * Copyright 2013 Olaf Wintermann. All rights reserved.
5 #ifndef LIST_H 5 *
6 #define LIST_H 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28 /**
29 * Doubly linked list implementation.
30 *
31 * @file list.h
32 * @author Mike Becker
33 * @author Olaf Wintermann
34 */
35
36 #ifndef UCX_LIST_H
37 #define UCX_LIST_H
7 38
8 #include "ucx.h" 39 #include "ucx.h"
9 #include <stddef.h> 40 #include "allocator.h"
10 41
11 #ifdef __cplusplus 42 #ifdef __cplusplus
12 extern "C" { 43 extern "C" {
13 #endif 44 #endif
14 45
46 /**
47 * Loop statement for UCX lists.
48 *
49 * The first argument is a pointer to the list. In most cases this will be the
50 * pointer to the first element of the list, but it may also be an arbitrary
51 * element of the list. The iteration will then start with that element.
52 *
53 * The second argument is the name of the iteration variable. The scope of
54 * this variable is limited to the <code>UCX_FOREACH</code> statement.
55 *
56 * @param list The first element of the list
57 * @param elem The variable name of the element
58 */
59 #define UCX_FOREACH(elem,list) \
60 for (UcxList* elem = list ; elem != NULL ; elem = elem->next)
61
62 /**
63 * UCX list type.
64 * @see UcxList
65 */
15 typedef struct UcxList UcxList; 66 typedef struct UcxList UcxList;
67 /**
68 * UCX list structure.
69 */
16 struct UcxList { 70 struct UcxList {
71 /**
72 * List element payload.
73 */
17 void *data; 74 void *data;
75 /**
76 * Pointer to the next list element or <code>NULL</code>, if this is the
77 * last element.
78 */
18 UcxList *next; 79 UcxList *next;
80 /**
81 * Pointer to the previous list element or <code>NULL</code>, if this is
82 * the first element.
83 */
84 UcxList *prev;
19 }; 85 };
20 86
21 UcxList *restrict ucx_list_clone(UcxList *restrict l, 87 /**
22 copy_func fnc, void *data); 88 * Creates an element-wise copy of a list.
23 int ucx_list_equals(const UcxList *l1, const UcxList *l2, 89 *
24 cmp_func fnc, void *data); 90 * This function clones the specified list by creating new list elements and
25 91 * copying the data with the specified copy_func(). If no copy_func() is
26 void ucx_list_free(UcxList *l); 92 * specified, a shallow copy is created and the new list will reference the
27 UcxList *ucx_list_append(UcxList *l, void *data); 93 * same data as the source list.
28 UcxList *ucx_list_prepend(UcxList *l, void *data); 94 *
29 UcxList *ucx_list_concat(UcxList *restrict l1, UcxList *restrict l2); 95 * @param list the list to copy
30 UcxList *ucx_list_last(const UcxList *l); 96 * @param cpyfnc a pointer to the function that shall copy an element (may be
31 UcxList *ucx_list_get(const UcxList *l, int index); 97 * <code>NULL</code>)
32 size_t ucx_list_size(const UcxList *l); 98 * @param data additional data for the copy_func()
33 99 * @return a pointer to the copy
34 UcxList *ucx_list_sort(UcxList *l, cmp_func fnc, void *data); 100 */
35 101 UcxList *ucx_list_clone(UcxList *list, copy_func cpyfnc, void* data);
36 /* list specific functions */ 102 /**
37 UcxList *ucx_list_remove(UcxList *l, UcxList *e); 103 * Creates an element-wise copy of a list using an UcxAllocator.
104 *
105 * See ucx_list_clone() for details.
106 *
107 * Keep in mind, that you might want to pass the allocator as an (part of the)
108 * argument for the <code>data</code> parameter, if you want the copy_func() to
109 * make use of the allocator.
110 *
111 * @param allocator the allocator to use
112 * @param list the list to copy
113 * @param cpyfnc a pointer to the function that shall copy an element (may be
114 * <code>NULL</code>)
115 * @param data additional data for the copy_func()
116 * @return a pointer to the copy
117 * @see ucx_list_clone()
118 */
119 UcxList *ucx_list_clone_a(UcxAllocator *allocator, UcxList *list,
120 copy_func cpyfnc, void* data);
121
122 /**
123 * Compares two UCX lists element-wise by using a compare function.
124 *
125 * Each element of the two specified lists are compared by using the specified
126 * compare function and the additional data. The type and content of this
127 * additional data depends on the cmp_func() used.
128 *
129 * If the list pointers denote elements within a list, the lists are compared
130 * starting with the denoted elements. Thus any previous elements are not taken
131 * into account. This might be useful to check, if certain list tails match
132 * each other.
133 *
134 * @param list1 the first list
135 * @param list2 the second list
136 * @param cmpfnc the compare function
137 * @param data additional data for the compare function
138 * @return 1, if and only if the two lists equal element-wise, 0 otherwise
139 */
140 int ucx_list_equals(const UcxList *list1, const UcxList *list2,
141 cmp_func cmpfnc, void* data);
142
143 /**
144 * Destroys the entire list.
145 *
146 * The members of the list are not automatically freed, so ensure they are
147 * otherwise referenced or a memory leak will occur.
148 *
149 * <b>Caution:</b> the argument <b>MUST</b> denote an entire list (i.e. a call
150 * to ucx_list_first() on the argument must return the argument itself)
151 *
152 * @param list the list to free
153 */
154 void ucx_list_free(UcxList *list);
155 /**
156 * Destroys the entire list using an UcxAllocator.
157 *
158 * See ucx_list_free() for details.
159 *
160 * @param allocator the allocator to use
161 * @param list the list to free
162 * @see ucx_list_free()
163 */
164 void ucx_list_free_a(UcxAllocator *allocator, UcxList *list);
165 /**
166 * Inserts an element at the end of the list.
167 *
168 * This is generally an O(n) operation, as the end of the list is seeked with
169 * ucx_list_last().
170 *
171 * @param list the list where to append the data, or <code>NULL</code> to
172 * create a new list
173 * @param data the data to insert
174 * @return <code>list</code>, if it is not <code>NULL</code> or a pointer to
175 * the newly created list otherwise
176 */
177 UcxList *ucx_list_append(UcxList *list, void *data);
178 /**
179 * Inserts an element at the end of the list using an UcxAllocator.
180 *
181 * See ucx_list_append() for details.
182 *
183 * @param allocator the allocator to use
184 * @param list the list where to append the data, or <code>NULL</code> to
185 * create a new list
186 * @param data the data to insert
187 * @return <code>list</code>, if it is not <code>NULL</code> or a pointer to
188 * the newly created list otherwise
189 * @see ucx_list_append()
190 */
191 UcxList *ucx_list_append_a(UcxAllocator *allocator, UcxList *list, void *data);
192 /**
193 * Inserts an element at the beginning of the list.
194 *
195 * You <i>should</i> overwrite the old list pointer by calling
196 * <code>mylist = ucx_list_prepend(mylist, mydata);</code>. However, you may
197 * also perform successive calls of ucx_list_prepend() on the same list pointer,
198 * as this function always searchs for the head of the list with
199 * ucx_list_first().
200 *
201 * @param list the list where to insert the data or <code>NULL</code> to create
202 * a new list
203 * @param data the data to insert
204 * @return a pointer to the new list head
205 */
206 UcxList *ucx_list_prepend(UcxList *list, void *data);
207 /**
208 * Inserts an element at the beginning of the list using an UcxAllocator.
209 *
210 * See ucx_list_prepend() for details.
211 *
212 * @param allocator the allocator to use
213 * @param list the list where to insert the data or <code>NULL</code> to create
214 * a new list
215 * @param data the data to insert
216 * @return a pointer to the new list head
217 * @see ucx_list_prepend()
218 */
219 UcxList *ucx_list_prepend_a(UcxAllocator *allocator, UcxList *list, void *data);
220 /**
221 * Concatenates two lists.
222 *
223 * Either of the two arguments may be <code>NULL</code>.
224 *
225 * This function modifies the references to the next/previous element of
226 * the last/first element of <code>list1</code>/<code>
227 * list2</code>.
228 *
229 * @param list1 first list
230 * @param list2 second list
231 * @return if <code>list1</code> is <code>NULL</code>, <code>list2</code> is
232 * returned, otherwise <code>list1</code> is returned
233 */
234 UcxList *ucx_list_concat(UcxList *list1, UcxList *list2);
235 /**
236 * Returns the first element of a list.
237 *
238 * If the argument is the list pointer, it is directly returned. Otherwise
239 * this function traverses to the first element of the list and returns the
240 * list pointer.
241 *
242 * @param elem one element of the list
243 * @return the first element of the list, the specified element is a member of
244 */
245 UcxList *ucx_list_first(const UcxList *elem);
246 /**
247 * Returns the last element of a list.
248 *
249 * If the argument has no successor, it is the last element and therefore
250 * directly returned. Otherwise this function traverses to the last element of
251 * the list and returns it.
252 *
253 * @param elem one element of the list
254 * @return the last element of the list, the specified element is a member of
255 */
256 UcxList *ucx_list_last(const UcxList *elem);
257 /**
258 * Returns the list element at the specified index.
259 *
260 * @param list the list to retrieve the element from
261 * @param index index of the element to return
262 * @return the element at the specified index or <code>NULL</code>, if the
263 * index is greater than the list size
264 */
265 UcxList *ucx_list_get(const UcxList *list, int index);
266 /**
267 * Returns the index of an element.
268 *
269 * @param list the list where to search for the element
270 * @param elem the element to find
271 * @return the index of the element or -1 if the list does not contain the
272 * element
273 */
274 ssize_t ucx_list_indexof(const UcxList *list, const UcxList *elem);
275 /**
276 * Returns the element count of the list.
277 *
278 * @param list the list whose elements are counted
279 * @return the element count
280 */
281 size_t ucx_list_size(const UcxList *list);
282 /**
283 * Returns the index of an element containing the specified data.
284 *
285 * This function uses a cmp_func() to compare the data of each list element
286 * with the specified data. If no cmp_func is provided, the pointers are
287 * compared.
288 *
289 * If the list contains the data more than once, the index of the first
290 * occurrence is returned.
291 *
292 * @param list the list where to search for the data
293 * @param elem the element data
294 * @param cmpfnc the compare function
295 * @param data additional data for the compare function
296 * @return the index of the element containing the specified data or -1 if the
297 * data is not found in this list
298 */
299 ssize_t ucx_list_find(UcxList *list, void *elem, cmp_func cmpfnc, void *data);
300 /**
301 * Checks, if a list contains a specific element.
302 *
303 * An element is found, if ucx_list_find() returns a value greater than -1.
304 *
305 * @param list the list where to search for the data
306 * @param elem the element data
307 * @param cmpfnc the compare function
308 * @param data additional data for the compare function
309 * @return 1, if and only if the list contains the specified element data
310 * @see ucx_list_find()
311 */
312 int ucx_list_contains(UcxList *list, void *elem, cmp_func cmpfnc, void *data);
313
314 /**
315 * Sorts an UcxList with natural merge sort.
316 *
317 * This function uses O(n) additional temporary memory for merge operations
318 * that is automatically freed after each merge.
319 *
320 * As the head of the list might change, you <b>MUST</b> call this function
321 * as follows: <code>mylist = ucx_list_sort(mylist, mycmpfnc, mydata);</code>.
322 *
323 * @param list the list to sort
324 * @param cmpfnc the function that shall be used to compare the element data
325 * @param data additional data for the cmp_func()
326 * @return the sorted list
327 */
328 UcxList *ucx_list_sort(UcxList *list, cmp_func cmpfnc, void *data);
329
330 /**
331 * Removes an element from the list.
332 *
333 * If the first element is removed, the list pointer changes. So it is
334 * <i>highly recommended</i> to <i>always</i> update the pointer by calling
335 * <code>mylist = ucx_list_remove(mylist, myelem);</code>.
336 *
337 * @param list the list from which the element shall be removed
338 * @param element the element to removed
339 * @return returns the updated list pointer or <code>NULL</code>, if the list
340 * is now empty
341 */
342 UcxList *ucx_list_remove(UcxList *list, UcxList *element);
343 /**
344 * Removes an element from the list using an UcxAllocator.
345 *
346 * See ucx_list_remove() for details.
347 *
348 * @param allocator the allocator to use
349 * @param list the list from which the element shall be removed
350 * @param element the element to removed
351 * @return returns the updated list pointer or <code>NULL</code>, if the list
352 * @see ucx_list_remove()
353 */
354 UcxList *ucx_list_remove_a(UcxAllocator *allocator, UcxList *list,
355 UcxList *element);
38 356
39 #ifdef __cplusplus 357 #ifdef __cplusplus
40 } 358 }
41 #endif 359 #endif
42 360
43 #endif /* LIST_H */ 361 #endif /* UCX_LIST_H */
44 362

mercurial