1 // ============================================================================
3 // ============================================================================
5 /* GLIB - Library of useful routines for C programming
6 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
8 * SPDX-License-Identifier: LGPL-2.1-or-later
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
25 * Modified by the GLib Team and others 1997-2000. See the AUTHORS
26 * file for a list of people on the GLib Team. See the ChangeLog
27 * files for a list of changes. These files are distributed with
28 * GLib at ftp://ftp.gtk.org/pub/gtk/.
39 * @data: holds the element's data, which can be a pointer to any kind
40 * of data, or any integer value using the
41 * [Type Conversion Macros][glib-Type-Conversion-Macros]
42 * @next: contains the link to the next element in the list
43 * @prev: contains the link to the previous element in the list
45 * The #List struct is used for each element in a doubly-linked list.
50 * @list: an element in a #List
52 * A convenience macro to get the previous element in a #List.
53 * Note that it is considered perfectly acceptable to access
54 * @list->prev directly.
56 * Returns: the previous element, or %NULL if there are no previous
62 * @list: an element in a #List
64 * A convenience macro to get the next element in a #List.
65 * Note that it is considered perfectly acceptable to access
66 * @list->next directly.
68 * Returns: the next element, or %NULL if there are no more elements
74 * Allocates space for one #List element. It is called by
75 * list_append(), list_prepend(), list_insert() and
76 * list_insert_sorted() and so is rarely used on its own.
78 * Returns: a pointer to the newly-allocated #List element
83 return checked_calloc(sizeof(List));
88 * @list: the first link of a #List
90 * Frees all of the memory used by a #List.
91 * The freed elements are returned to the slice allocator.
93 * If list elements contain dynamically-allocated memory, you should
94 * either use list_free_full() or free them manually first.
96 * It can be combined with steal_pointer() to ensure the list head pointer
97 * is not left dangling:
98 * |[<!-- language="C" -->
99 * List *list_of_borrowed_things = …; /<!-- -->* (transfer container) *<!-- -->/
100 * list_free (steal_pointer (&list_of_borrowed_things));
104 list_free (List *list)
107 size_t next_offset = offsetof(List, next);
111 void *current = slice;
112 slice = *(void**) (current + next_offset);
113 checked_free(current);
119 * @list: a #List element
121 * Frees one #List element, but does not update links from the next and
122 * previous elements in the list, so you should not call this function on an
123 * element that is currently part of a list.
125 * It is usually used after list_remove_link().
130 * Another name for list_free_1().
133 list_free_1 (List *list)
140 * @list: a pointer to a #List
141 * @data: the data for the new element
143 * Adds a new element on to the end of the list.
145 * Note that the return value is the new start of the list,
146 * if @list was empty; make sure you store the new value.
148 * list_append() has to traverse the entire list to find the end,
149 * which is inefficient when adding multiple elements. A common idiom
150 * to avoid the inefficiency is to use list_prepend() and reverse
151 * the list with list_reverse() when all elements have been added.
153 * |[<!-- language="C" -->
154 * // Notice that these are initialized to the empty list.
155 * List *strinlist = NULL, *number_list = NULL;
157 * // This is a list of strings.
158 * strinlist = list_append (strinlist, "first");
159 * strinlist = list_append (strinlist, "second");
161 * // This is a list of integers.
162 * number_list = list_append (number_list, INT_TO_PTR (27));
163 * number_list = list_append (number_list, INT_TO_PTR (14));
166 * Returns: either @list or the new start of the #List if @list was %NULL
169 list_append (List *list, void *data)
174 new_list = checked_malloc(sizeof(List));
175 new_list->data = data;
176 new_list->next = NULL;
180 last = list_last(list);
181 last->next = new_list;
182 new_list->prev = last;
188 new_list->prev = NULL;
196 * @list: a pointer to a #List, this must point to the top of the list
197 * @data: the data for the new element
199 * Prepends a new element on to the start of the list.
201 * Note that the return value is the new start of the list,
202 * which will have changed, so make sure you store the new value.
204 * |[<!-- language="C" -->
205 * // Notice that it is initialized to the empty list.
208 * list = list_prepend (list, "last");
209 * list = list_prepend (list, "first");
212 * Do not use this function to prepend a new element to a different
213 * element than the start of the list. Use list_insert_before() instead.
215 * Returns: a pointer to the newly prepended element, which is the new
219 list_prepend (List *list, void *data)
223 new_list = checked_malloc(sizeof(List));
224 new_list->data = data;
225 new_list->next = list;
229 new_list->prev = list->prev;
231 list->prev->next = new_list;
232 list->prev = new_list;
236 new_list->prev = NULL;
244 * @list: a pointer to a #List, this must point to the top of the list
245 * @data: the data for the new element
246 * @position: the position to insert the element. If this is
247 * negative, or is larger than the number of elements in the
248 * list, the new element is added on to the end of the list.
250 * Inserts a new element into the list at the given position.
252 * Returns: the (possibly changed) start of the #List
255 list_insert (List *list, void *data, int position)
261 return list_append(list, data);
262 else if (position == 0)
263 return list_prepend(list, data);
265 tmp_list = list_nth(list, position);
267 return list_append(list, data);
269 new_list = checked_malloc(sizeof(List));
270 new_list->data = data;
271 new_list->prev = tmp_list->prev;
272 tmp_list->prev->next = new_list;
273 new_list->next = tmp_list;
274 tmp_list->prev = new_list;
280 _list_remove_link (List *list, List *link)
287 if (link->prev->next == link)
288 link->prev->next = link->next;
290 Warn("corrupted double-linked list detected");
295 if (link->next->prev == link)
296 link->next->prev = link->prev;
298 Warn("corrupted double-linked list detected");
312 * @list: a #List, this must point to the top of the list
313 * @data: the data of the element to remove
315 * Removes an element from a #List.
316 * If two elements contain the same data, only the first is removed.
317 * If none of the elements contain the data, the #List is unchanged.
319 * Returns: the (possibly changed) start of the #List
322 list_remove (List *list, const void *data)
329 if (tmp->data != data)
335 list = _list_remove_link (list, tmp);
347 * @list: a #List, this must point to the top of the list
348 * @data: data to remove
350 * Removes all list nodes with data equal to @data.
351 * Returns the new head of the list. Contrast with
352 * list_remove() which removes only the first node
353 * matching the given data.
355 * Returns: the (possibly changed) start of the #List
358 list_remove_all (List *list, const void *data)
364 if (tmp->data != data)
370 List *next = tmp->next;
373 tmp->prev->next = next;
378 next->prev = tmp->prev;
390 * @list: a #List, this must point to the top of the list
391 * @llink: an element in the #List
393 * Removes an element from a #List, without freeing the element.
394 * The removed element's prev and next links are set to %NULL, so
395 * that it becomes a self-contained list with one element.
397 * This function is for example used to move an element in the list
398 * (see the example for list_concat()) or to remove an element in
399 * the list before freeing its data:
400 * |[<!-- language="C" -->
401 * list = list_remove_link (list, llink);
402 * free_some_data_that_may_access_the_list_again (llink->data);
406 * Returns: the (possibly changed) start of the #List
409 list_remove_link (List *list, List *llink)
411 return _list_remove_link(list, llink);
416 * @list: a #List, this must point to the top of the list
417 * @link_: node to delete from @list
419 * Removes the node link_ from the list and frees it.
420 * Compare this to list_remove_link() which removes the node
421 * without freeing it.
423 * Returns: the (possibly changed) start of the #List
426 list_delete_link (List *list, List *link_)
428 list = _list_remove_link(list, link_);
436 * @list: a #List, this must point to the top of the list
440 * Note that this is a "shallow" copy. If the list elements
441 * consist of pointers to data, the pointers are copied but
442 * the actual data is not. See list_copy_deep() if you need
443 * to copy the data as well.
445 * Returns: the start of the new list that holds the same data as @list
448 list_copy (List *list)
450 return list_copy_deep(list, NULL, NULL);
455 * @list: a #List, this must point to the top of the list
456 * @func: (scope call): a copy function used to copy every element in the list
457 * @user_data: user data passed to the copy function @func, or %NULL
459 * Makes a full (deep) copy of a #List.
461 * In contrast with g_list_copy(), this function uses @func to make
462 * a copy of each list element, in addition to copying the list
465 * @func, as a #GCopyFunc, takes two arguments, the data to be copied
466 * and a @user_data pointer. On common processor architectures, it's safe to
467 * pass %NULL as @user_data if the copy function takes only one argument. You
468 * may get compiler warnings from this though if compiling with GCC’s
469 * `-Wcast-function-type` warning.
471 * For instance, if @list holds a list of GObjects, you can do:
472 * |[<!-- language="C" -->
473 * another_list = g_list_copy_deep (list, (GCopyFunc) g_object_ref, NULL);
476 * And, to entirely free the new list, you could do:
477 * |[<!-- language="C" -->
478 * g_list_free_full (another_list, g_object_unref);
481 * Returns: the start of the new list that holds a full copy of @list,
482 * use g_list_free_full() to free it
487 list_copy_deep (List *list, list_copy_fn func, void *user_data)
489 List *new_list = NULL;
495 new_list = checked_malloc(sizeof(List));
498 new_list->data = func (list->data, user_data);
500 new_list->data = list->data;
502 new_list->prev = NULL;
508 last->next = checked_malloc(sizeof(List));
509 last->next->prev = last;
513 last->data = func (list->data, user_data);
515 last->data = list->data;
528 * @list: a #List, this must point to the top of the list
531 * It simply switches the next and prev pointers of each element.
533 * Returns: the start of the reversed #List
536 list_reverse (List *list)
546 last->next = last->prev;
555 * @list: a #List, this must point to the top of the list
556 * @n: the position of the element, counting from 0
558 * Gets the element at the given position in a #List.
560 * This iterates over the list until it reaches the @n-th position. If you
561 * intend to iterate over every element, it is better to use a for-loop as
562 * described in the #List introduction.
564 * Returns: the element, or %NULL if the position is off
565 * the end of the #List
568 list_nth (List *list, unsigned int n)
570 while ((n-- > 0) && list)
579 * @n: the position of the element, counting from 0
581 * Gets the element @n places before @list.
583 * Returns: the element, or %NULL if the position is
584 * off the end of the #List
587 list_nth_prev (List *list, unsigned int n)
589 while ((n-- > 0) && list)
597 * @list: a #List, this must point to the top of the list
598 * @n: the position of the element
600 * Gets the data of the element at the given position.
602 * This iterates over the list until it reaches the @n-th position. If you
603 * intend to iterate over every element, it is better to use a for-loop as
604 * described in the #List introduction.
606 * Returns: the element's data, or %NULL if the position
607 * is off the end of the #List
610 list_nth_data (List *list, unsigned int n)
612 while ((n-- > 0) && list)
615 return list ? list->data : NULL;
620 * @list: a #List, this must point to the top of the list
621 * @llink: an element in the #List
623 * Gets the position of the given element
624 * in the #List (starting from 0).
626 * Returns: the position of the element in the #List,
627 * or -1 if the element is not found
630 list_position (List *list, List *llink)
649 * @list: a #List, this must point to the top of the list
650 * @data: the data to find
652 * Gets the position of the element containing
653 * the given data (starting from 0).
655 * Returns: the index of the element containing the data,
656 * or -1 if the data is not found
659 list_index (List *list, const void *data)
666 if (list->data == data)
678 * @list: any #List element
680 * Gets the last element in a #List.
682 * Returns: the last element in the #List,
683 * or %NULL if the #List has no elements
686 list_last (List *list)
699 * @list: any #List element
701 * Gets the first element in a #List.
703 * Returns: the first element in the #List,
704 * or %NULL if the #List has no elements
707 list_first (List *list)
720 * @list: a #List, this must point to the top of the list
722 * Gets the number of elements in a #List.
724 * This function iterates over the whole list to count its elements.
725 * Use a #GQueue instead of a List if you regularly need the number
726 * of items. To check whether the list is non-empty, it is faster to check
727 * @list against %NULL.
729 * Returns: the number of elements in the #List
732 list_length (List *list)
748 * @list: a #List, this must point to the top of the list
749 * @func: (scope call): the function to call with each element's data
750 * @user_data: user data to pass to the function
752 * Calls a function for each element of a #List.
754 * It is safe for @func to remove the element from @list, but it must
755 * not modify any part of the list after that element.
759 * @data: the element's data
760 * @user_data: user data passed to list_foreach() or slist_foreach()
762 * Specifies the type of functions passed to list_foreach() and
766 list_foreach (List *list, list_fn func, void *user_data)
770 List *next = list->next;
772 (*func) (list->data, user_data);