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_slist_push_allocator (gpointer dummy) { /* present for binary compat only */ }
38 void g_slist_pop_allocator (void) { /* present for binary compat only */ }
40 #define _g_slist_alloc0() g_slice_new0 (GSList)
41 #define _g_slist_alloc() g_slice_new (GSList)
42 #define _g_slist_free1(slist) g_slice_free (GSList, slist)
47 return _g_slist_alloc0 ();
54 * Frees all of the memory used by a #GSList.
55 * The freed elements are returned to the slice allocator.
58 g_slist_free (GSList *list)
60 g_slice_free_chain (GSList, list, next);
65 * @list: a #GSList element
67 * Frees one #GSList element.
68 * It is usually used after g_slist_remove_link().
71 g_slist_free_1 (GSList *list)
73 _g_slist_free1 (list);
79 * @data: the data for the new element
81 * Adds a new element on to the end of the list.
84 * The return value is the new start of the list, which may
85 * have changed, so make sure you store the new value.
89 * Note that g_slist_append() has to traverse the entire list
90 * to find the end, which is inefficient when adding multiple
91 * elements. A common idiom to avoid the inefficiency is to prepend
92 * the elements and reverse the list when all elements have been added.
96 * /* Notice that these are initialized to the empty list. */
97 * GSList *list = NULL, *number_list = NULL;
99 * /* This is a list of strings. */
100 * list = g_slist_append (list, "first");
101 * list = g_slist_append (list, "second");
103 * /* This is a list of integers. */
104 * number_list = g_slist_append (number_list, GINT_TO_POINTER (27));
105 * number_list = g_slist_append (number_list, GINT_TO_POINTER (14));
108 * Returns: the new start of the #GSList
111 g_slist_append (GSList *list,
117 new_list = _g_slist_alloc ();
118 new_list->data = data;
119 new_list->next = NULL;
123 last = g_slist_last (list);
124 /* g_assert (last != NULL); */
125 last->next = new_list;
136 * @data: the data for the new element
138 * Adds a new element on to the start of the list.
141 * The return value is the new start of the list, which
142 * may have changed, so make sure you store the new value.
146 * /* Notice that it is initialized to the empty list. */
147 * GSList *list = NULL;
148 * list = g_slist_prepend (list, "last");
149 * list = g_slist_prepend (list, "first");
152 * Returns: the new start of the #GSList
155 g_slist_prepend (GSList *list,
160 new_list = _g_slist_alloc ();
161 new_list->data = data;
162 new_list->next = list;
170 * @data: the data for the new element
171 * @position: the position to insert the element.
172 * If this is negative, or is larger than the number
173 * of elements in the list, the new element is added on
174 * to the end of the list.
176 * Inserts a new element into the list at the given position.
178 * Returns: the new start of the #GSList
181 g_slist_insert (GSList *list,
190 return g_slist_append (list, data);
191 else if (position == 0)
192 return g_slist_prepend (list, data);
194 new_list = _g_slist_alloc ();
195 new_list->data = data;
199 new_list->next = NULL;
206 while ((position-- > 0) && tmp_list)
208 prev_list = tmp_list;
209 tmp_list = tmp_list->next;
214 new_list->next = prev_list->next;
215 prev_list->next = new_list;
219 new_list->next = list;
227 * g_slist_insert_before:
229 * @sibling: node to insert @data before
230 * @data: data to put in the newly-inserted node
232 * Inserts a node before @sibling containing @data.
234 * Returns: the new head of the list.
237 g_slist_insert_before (GSList *slist,
243 slist = _g_slist_alloc ();
246 g_return_val_if_fail (sibling == NULL, slist);
251 GSList *node, *last = NULL;
253 for (node = slist; node; last = node, node = last->next)
258 node = _g_slist_alloc ();
266 node = _g_slist_alloc ();
268 node->next = last->next;
279 * @list2: the #GSList to add to the end of the first #GSList
281 * Adds the second #GSList onto the end of the first #GSList.
282 * Note that the elements of the second #GSList are not copied.
283 * They are used directly.
285 * Returns: the start of the new #GSList
288 g_slist_concat (GSList *list1, GSList *list2)
293 g_slist_last (list1)->next = list2;
304 * @data: the data of the element to remove
306 * Removes an element from a #GSList.
307 * If two elements contain the same data, only the first is removed.
308 * If none of the elements contain the data, the #GSList is unchanged.
310 * Returns: the new start of the #GSList
313 g_slist_remove (GSList *list,
316 GSList *tmp, *prev = NULL;
321 if (tmp->data == data)
324 prev->next = tmp->next;
328 g_slist_free_1 (tmp);
339 * g_slist_remove_all:
341 * @data: data to remove
343 * Removes all list nodes with data equal to @data.
344 * Returns the new head of the list. Contrast with
345 * g_slist_remove() which removes only the first node
346 * matching the given data.
348 * Returns: new head of @list
351 g_slist_remove_all (GSList *list,
354 GSList *tmp, *prev = NULL;
359 if (tmp->data == data)
361 GSList *next = tmp->next;
368 g_slist_free_1 (tmp);
381 static inline GSList*
382 _g_slist_remove_link (GSList *list,
396 prev->next = tmp->next;
412 * g_slist_remove_link:
414 * @link_: an element in the #GSList
416 * Removes an element from a #GSList, without
417 * freeing the element. The removed element's next
418 * link is set to %NULL, so that it becomes a
419 * self-contained list with one element.
421 * Returns: the new start of the #GSList, without the element
424 g_slist_remove_link (GSList *list,
427 return _g_slist_remove_link (list, link_);
431 * g_slist_delete_link:
433 * @link_: node to delete
435 * Removes the node link_ from the list and frees it.
436 * Compare this to g_slist_remove_link() which removes the node
437 * without freeing it.
439 * Returns: the new head of @list
442 g_slist_delete_link (GSList *list,
445 list = _g_slist_remove_link (list, link_);
446 _g_slist_free1 (link_);
458 * Note that this is a "shallow" copy. If the list elements
459 * consist of pointers to data, the pointers are copied but
460 * the actual data isn't.
463 * Returns: a copy of @list
466 g_slist_copy (GSList *list)
468 GSList *new_list = NULL;
474 new_list = _g_slist_alloc ();
475 new_list->data = list->data;
480 last->next = _g_slist_alloc ();
482 last->data = list->data;
495 * Reverses a #GSList.
497 * Returns: the start of the reversed #GSList
500 g_slist_reverse (GSList *list)
506 GSList *next = list->next;
520 * @n: the position of the element, counting from 0
522 * Gets the element at the given position in a #GSList.
524 * Returns: the element, or %NULL if the position is off
525 * the end of the #GSList
528 g_slist_nth (GSList *list,
531 while (n-- > 0 && list)
540 * @n: the position of the element
542 * Gets the data of the element at the given position.
544 * Returns: the element's data, or %NULL if the position
545 * is off the end of the #GSList
548 g_slist_nth_data (GSList *list,
551 while (n-- > 0 && list)
554 return list ? list->data : NULL;
560 * @data: the element data to find
562 * Finds the element in a #GSList which
563 * contains the given data.
565 * Returns: the found #GSList element,
566 * or %NULL if it is not found
569 g_slist_find (GSList *list,
574 if (list->data == data)
584 * g_slist_find_custom:
586 * @data: user data passed to the function
587 * @func: the function to call for each element.
588 * It should return 0 when the desired element is found
590 * Finds an element in a #GSList, using a supplied function to
591 * find the desired element. It iterates over the list, calling
592 * the given function which should return 0 when the desired
593 * element is found. The function takes two #gconstpointer arguments,
594 * the #GSList element's data as the first argument and the
597 * Returns: the found #GSList element, or %NULL if it is not found
600 g_slist_find_custom (GSList *list,
604 g_return_val_if_fail (func != NULL, list);
608 if (! func (list->data, data))
619 * @llink: an element in the #GSList
621 * Gets the position of the given element
622 * in the #GSList (starting from 0).
624 * Returns: the position of the element in the #GSList,
625 * or -1 if the element is not found
628 g_slist_position (GSList *list,
648 * @data: the data to find
650 * Gets the position of the element containing
651 * the given data (starting from 0).
653 * Returns: the index of the element containing the data,
654 * or -1 if the data is not found
657 g_slist_index (GSList *list,
665 if (list->data == data)
678 * Gets the last element in a #GSList.
681 * This function iterates over the whole list.
684 * Returns: the last element in the #GSList,
685 * or %NULL if the #GSList has no elements
688 g_slist_last (GSList *list)
703 * Gets the number of elements in a #GSList.
706 * This function iterates over the whole list to
707 * count its elements.
710 * Returns: the number of elements in the #GSList
713 g_slist_length (GSList *list)
730 * @func: the function to call with each element's data
731 * @user_data: user data to pass to the function
733 * Calls a function for each element of a #GSList.
736 g_slist_foreach (GSList *list,
742 GSList *next = list->next;
743 (*func) (list->data, user_data);
749 g_slist_insert_sorted_real (GSList *list,
754 GSList *tmp_list = list;
755 GSList *prev_list = NULL;
759 g_return_val_if_fail (func != NULL, list);
763 new_list = _g_slist_alloc ();
764 new_list->data = data;
765 new_list->next = NULL;
769 cmp = ((GCompareDataFunc) func) (data, tmp_list->data, user_data);
771 while ((tmp_list->next) && (cmp > 0))
773 prev_list = tmp_list;
774 tmp_list = tmp_list->next;
776 cmp = ((GCompareDataFunc) func) (data, tmp_list->data, user_data);
779 new_list = _g_slist_alloc ();
780 new_list->data = data;
782 if ((!tmp_list->next) && (cmp > 0))
784 tmp_list->next = new_list;
785 new_list->next = NULL;
791 prev_list->next = new_list;
792 new_list->next = tmp_list;
797 new_list->next = list;
803 * g_slist_insert_sorted:
805 * @data: the data for the new element
806 * @func: the function to compare elements in the list.
807 * It should return a number > 0 if the first parameter
808 * comes after the second parameter in the sort order.
810 * Inserts a new element into the list, using the given
811 * comparison function to determine its position.
813 * Returns: the new start of the #GSList
816 g_slist_insert_sorted (GSList *list,
820 return g_slist_insert_sorted_real (list, data, (GFunc) func, NULL);
824 * g_slist_insert_sorted_with_data:
826 * @data: the data for the new element
827 * @func: the function to compare elements in the list.
828 * It should return a number > 0 if the first parameter
829 * comes after the second parameter in the sort order.
830 * @user_data: data to pass to comparison function
832 * Inserts a new element into the list, using the given
833 * comparison function to determine its position.
835 * Returns: the new start of the #GSList
840 g_slist_insert_sorted_with_data (GSList *list,
842 GCompareDataFunc func,
845 return g_slist_insert_sorted_real (list, data, (GFunc) func, user_data);
849 g_slist_sort_merge (GSList *l1,
861 cmp = ((GCompareDataFunc) compare_func) (l1->data, l2->data, user_data);
874 l->next= l1 ? l1 : l2;
880 g_slist_sort_real (GSList *list,
894 while ((l2 = l2->next) != NULL)
896 if ((l2 = l2->next) == NULL)
903 return g_slist_sort_merge (g_slist_sort_real (list, compare_func, user_data),
904 g_slist_sort_real (l2, compare_func, user_data),
912 * @compare_func: the comparison function used to sort the #GSList.
913 * This function is passed the data from 2 elements of the #GSList
914 * and should return 0 if they are equal, a negative value if the
915 * first element comes before the second, or a positive value if
916 * the first element comes after the second.
918 * Sorts a #GSList using the given comparison function.
920 * Returns: the start of the sorted #GSList
923 g_slist_sort (GSList *list,
924 GCompareFunc compare_func)
926 return g_slist_sort_real (list, (GFunc) compare_func, NULL);
930 * g_slist_sort_with_data:
932 * @compare_func: comparison function
933 * @user_data: data to pass to comparison function
935 * Like g_slist_sort(), but the sort function accepts a user data argument.
937 * Returns: new head of the list
940 g_slist_sort_with_data (GSList *list,
941 GCompareDataFunc compare_func,
944 return g_slist_sort_real (list, (GFunc) compare_func, user_data);
947 #define __G_SLIST_C__
948 #include "galiasdef.c"