1 /* GLIB - Library of useful routines for C programming
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
21 * Modified by the GLib Team and others 1997-2000. See the AUTHORS
22 * file for a list of people on the GLib Team. See the ChangeLog
23 * files for a list of changes. These files are distributed with
24 * GLib at ftp://ftp.gtk.org/pub/gtk/.
37 void g_list_push_allocator (gpointer dummy) { /* present for binary compat only */ }
38 void g_list_pop_allocator (void) { /* present for binary compat only */ }
40 #define _g_list_alloc() g_slice_new (GList)
41 #define _g_list_alloc0() g_slice_new0 (GList)
42 #define _g_list_free1(list) g_slice_free (GList, list)
47 return _g_list_alloc0 ();
54 * Frees all of the memory used by a #GList.
55 * The freed elements are returned to the slice allocator.
58 * If list elements contain dynamically-allocated memory,
59 * they should be freed first.
63 g_list_free (GList *list)
65 g_slice_free_chain (GList, list, next);
70 * @list: a #GList element
72 * Frees one #GList element.
73 * It is usually used after g_list_remove_link().
76 g_list_free_1 (GList *list)
83 * @list: a pointer to a #GList
84 * @data: the data for the new element
86 * Adds a new element on to the end of the list.
89 * The return value is the new start of the list, which
90 * may have changed, so make sure you store the new value.
94 * Note that g_list_append() has to traverse the entire list
95 * to find the end, which is inefficient when adding multiple
96 * elements. A common idiom to avoid the inefficiency is to prepend
97 * the elements and reverse the list when all elements have been added.
101 * /* Notice that these are initialized to the empty list. */
102 * GList *list = NULL, *number_list = NULL;
104 * /* This is a list of strings. */
105 * list = g_list_append (list, "first");
106 * list = g_list_append (list, "second");
108 * /* This is a list of integers. */
109 * number_list = g_list_append (number_list, GINT_TO_POINTER (27));
110 * number_list = g_list_append (number_list, GINT_TO_POINTER (14));
113 * Returns: the new start of the #GList
116 g_list_append (GList *list,
122 new_list = _g_list_alloc ();
123 new_list->data = data;
124 new_list->next = NULL;
128 last = g_list_last (list);
129 /* g_assert (last != NULL); */
130 last->next = new_list;
131 new_list->prev = last;
137 new_list->prev = NULL;
144 * @list: a pointer to a #GList
145 * @data: the data for the new element
147 * Adds a new element on to the start of the list.
150 * The return value is the new start of the list, which
151 * may have changed, so make sure you store the new value.
155 * /* Notice that it is initialized to the empty list. */
156 * GList *list = NULL;
157 * list = g_list_prepend (list, "last");
158 * list = g_list_prepend (list, "first");
161 * Returns: the new start of the #GList
164 g_list_prepend (GList *list,
169 new_list = _g_list_alloc ();
170 new_list->data = data;
171 new_list->next = list;
175 new_list->prev = list->prev;
177 list->prev->next = new_list;
178 list->prev = new_list;
181 new_list->prev = NULL;
188 * @list: a pointer to a #GList
189 * @data: the data for the new element
190 * @position: the position to insert the element. If this is
191 * negative, or is larger than the number of elements in the
192 * list, the new element is added on to the end of the list.
194 * Inserts a new element into the list at the given position.
196 * Returns: the new start of the #GList
199 g_list_insert (GList *list,
207 return g_list_append (list, data);
208 else if (position == 0)
209 return g_list_prepend (list, data);
211 tmp_list = g_list_nth (list, position);
213 return g_list_append (list, data);
215 new_list = _g_list_alloc ();
216 new_list->data = data;
217 new_list->prev = tmp_list->prev;
219 tmp_list->prev->next = new_list;
220 new_list->next = tmp_list;
221 tmp_list->prev = new_list;
223 if (tmp_list == list)
230 * g_list_insert_before:
231 * @list: a pointer to a #GList
232 * @sibling: the list element before which the new element
233 * is inserted or %NULL to insert at the end of the list
234 * @data: the data for the new element
236 * Inserts a new element into the list before the given position.
238 * Returns: the new start of the #GList
241 g_list_insert_before (GList *list,
247 list = g_list_alloc ();
249 g_return_val_if_fail (sibling == NULL, list);
256 node = _g_list_alloc ();
258 node->prev = sibling->prev;
259 node->next = sibling;
260 sibling->prev = node;
263 node->prev->next = node;
268 g_return_val_if_fail (sibling == list, node);
280 last->next = _g_list_alloc ();
281 last->next->data = data;
282 last->next->prev = last;
283 last->next->next = NULL;
292 * @list2: the #GList to add to the end of the first #GList
294 * Adds the second #GList onto the end of the first #GList.
295 * Note that the elements of the second #GList are not copied.
296 * They are used directly.
298 * Returns: the start of the new #GList
301 g_list_concat (GList *list1, GList *list2)
307 tmp_list = g_list_last (list1);
309 tmp_list->next = list2;
312 list2->prev = tmp_list;
321 * @data: the data of the element to remove
323 * Removes an element from a #GList.
324 * If two elements contain the same data, only the first is removed.
325 * If none of the elements contain the data, the #GList is unchanged.
327 * Returns: the new start of the #GList
330 g_list_remove (GList *list,
338 if (tmp->data != data)
343 tmp->prev->next = tmp->next;
345 tmp->next->prev = tmp->prev;
361 * @data: data to remove
363 * Removes all list nodes with data equal to @data.
364 * Returns the new head of the list. Contrast with
365 * g_list_remove() which removes only the first node
366 * matching the given data.
368 * Returns: new head of @list
371 g_list_remove_all (GList *list,
378 if (tmp->data != data)
382 GList *next = tmp->next;
385 tmp->prev->next = next;
389 next->prev = tmp->prev;
399 _g_list_remove_link (GList *list,
405 link->prev->next = link->next;
407 link->next->prev = link->prev;
420 * g_list_remove_link:
422 * @llink: an element in the #GList
424 * Removes an element from a #GList, without freeing the element.
425 * The removed element's prev and next links are set to %NULL, so
426 * that it becomes a self-contained list with one element.
428 * Returns: the new start of the #GList, without the element
431 g_list_remove_link (GList *list,
434 return _g_list_remove_link (list, llink);
438 * g_list_delete_link:
440 * @link_: node to delete from @list
442 * Removes the node link_ from the list and frees it.
443 * Compare this to g_list_remove_link() which removes the node
444 * without freeing it.
446 * Returns: the new head of @list
449 g_list_delete_link (GList *list,
452 list = _g_list_remove_link (list, link_);
453 _g_list_free1 (link_);
465 * Note that this is a "shallow" copy. If the list elements
466 * consist of pointers to data, the pointers are copied but
467 * the actual data is not.
470 * Returns: a copy of @list
473 g_list_copy (GList *list)
475 GList *new_list = NULL;
481 new_list = _g_list_alloc ();
482 new_list->data = list->data;
483 new_list->prev = NULL;
488 last->next = _g_list_alloc ();
489 last->next->prev = last;
491 last->data = list->data;
505 * It simply switches the next and prev pointers of each element.
507 * Returns: the start of the reversed #GList
510 g_list_reverse (GList *list)
519 last->next = last->prev;
529 * @n: the position of the element, counting from 0
531 * Gets the element at the given position in a #GList.
533 * Returns: the element, or %NULL if the position is off
534 * the end of the #GList
537 g_list_nth (GList *list,
540 while ((n-- > 0) && list)
549 * @n: the position of the element, counting from 0
551 * Gets the element @n places before @list.
553 * Returns: the element, or %NULL if the position is
554 * off the end of the #GList
557 g_list_nth_prev (GList *list,
560 while ((n-- > 0) && list)
569 * @n: the position of the element
571 * Gets the data of the element at the given position.
573 * Returns: the element's data, or %NULL if the position
574 * is off the end of the #GList
577 g_list_nth_data (GList *list,
580 while ((n-- > 0) && list)
583 return list ? list->data : NULL;
589 * @data: the element data to find
591 * Finds the element in a #GList which
592 * contains the given data.
594 * Returns: the found #GList element,
595 * or %NULL if it is not found
598 g_list_find (GList *list,
603 if (list->data == data)
612 * g_list_find_custom:
614 * @data: user data passed to the function
615 * @func: the function to call for each element.
616 * It should return 0 when the desired element is found
618 * Finds an element in a #GList, using a supplied function to
619 * find the desired element. It iterates over the list, calling
620 * the given function which should return 0 when the desired
621 * element is found. The function takes two #gconstpointer arguments,
622 * the #GList element's data as the first argument and the
625 * Returns: the found #GList element, or %NULL if it is not found
628 g_list_find_custom (GList *list,
632 g_return_val_if_fail (func != NULL, list);
636 if (! func (list->data, data))
648 * @llink: an element in the #GList
650 * Gets the position of the given element
651 * in the #GList (starting from 0).
653 * Returns: the position of the element in the #GList,
654 * or -1 if the element is not found
657 g_list_position (GList *list,
677 * @data: the data to find
679 * Gets the position of the element containing
680 * the given data (starting from 0).
682 * Returns: the index of the element containing the data,
683 * or -1 if the data is not found
686 g_list_index (GList *list,
694 if (list->data == data)
707 * Gets the last element in a #GList.
709 * Returns: the last element in the #GList,
710 * or %NULL if the #GList has no elements
713 g_list_last (GList *list)
728 * Gets the first element in a #GList.
730 * Returns: the first element in the #GList,
731 * or %NULL if the #GList has no elements
734 g_list_first (GList *list)
749 * Gets the number of elements in a #GList.
752 * This function iterates over the whole list to
753 * count its elements.
756 * Returns: the number of elements in the #GList
759 g_list_length (GList *list)
776 * @func: the function to call with each element's data
777 * @user_data: user data to pass to the function
779 * Calls a function for each element of a #GList.
782 g_list_foreach (GList *list,
788 GList *next = list->next;
789 (*func) (list->data, user_data);
795 g_list_insert_sorted_real (GList *list,
800 GList *tmp_list = list;
804 g_return_val_if_fail (func != NULL, list);
808 new_list = _g_list_alloc0 ();
809 new_list->data = data;
813 cmp = ((GCompareDataFunc) func) (data, tmp_list->data, user_data);
815 while ((tmp_list->next) && (cmp > 0))
817 tmp_list = tmp_list->next;
819 cmp = ((GCompareDataFunc) func) (data, tmp_list->data, user_data);
822 new_list = _g_list_alloc0 ();
823 new_list->data = data;
825 if ((!tmp_list->next) && (cmp > 0))
827 tmp_list->next = new_list;
828 new_list->prev = tmp_list;
834 tmp_list->prev->next = new_list;
835 new_list->prev = tmp_list->prev;
837 new_list->next = tmp_list;
838 tmp_list->prev = new_list;
840 if (tmp_list == list)
847 * g_list_insert_sorted:
848 * @list: a pointer to a #GList
849 * @data: the data for the new element
850 * @func: the function to compare elements in the list. It should
851 * return a number > 0 if the first parameter comes after the
852 * second parameter in the sort order.
854 * Inserts a new element into the list, using the given comparison
855 * function to determine its position.
857 * Returns: the new start of the #GList
860 g_list_insert_sorted (GList *list,
864 return g_list_insert_sorted_real (list, data, (GFunc) func, NULL);
868 * g_list_insert_sorted_with_data:
869 * @list: a pointer to a #GList
870 * @data: the data for the new element
871 * @func: the function to compare elements in the list.
872 * It should return a number > 0 if the first parameter
873 * comes after the second parameter in the sort order.
874 * @user_data: user data to pass to comparison function.
876 * Inserts a new element into the list, using the given comparison
877 * function to determine its position.
879 * Returns: the new start of the #GList
884 g_list_insert_sorted_with_data (GList *list,
886 GCompareDataFunc func,
889 return g_list_insert_sorted_real (list, data, (GFunc) func, user_data);
893 g_list_sort_merge (GList *l1,
898 GList list, *l, *lprev;
906 cmp = ((GCompareDataFunc) compare_func) (l1->data, l2->data, user_data);
922 l->next = l1 ? l1 : l2;
929 g_list_sort_real (GList *list,
943 while ((l2 = l2->next) != NULL)
945 if ((l2 = l2->next) == NULL)
952 return g_list_sort_merge (g_list_sort_real (list, compare_func, user_data),
953 g_list_sort_real (l2, compare_func, user_data),
961 * @compare_func: the comparison function used to sort the #GList.
962 * This function is passed the data from 2 elements of the #GList
963 * and should return 0 if they are equal, a negative value if the
964 * first element comes before the second, or a positive value if
965 * the first element comes after the second.
967 * Sorts a #GList using the given comparison function.
969 * Returns: the start of the sorted #GList
972 g_list_sort (GList *list,
973 GCompareFunc compare_func)
975 return g_list_sort_real (list, (GFunc) compare_func, NULL);
980 * g_list_sort_with_data:
982 * @compare_func: comparison function
983 * @user_data: user data to pass to comparison function
985 * Like g_list_sort(), but the comparison function accepts
986 * a user data argument.
988 * Returns: the new head of @list
991 g_list_sort_with_data (GList *list,
992 GCompareDataFunc compare_func,
995 return g_list_sort_real (list, (GFunc) compare_func, user_data);
999 #include "galiasdef.c"