Imported Upstream version 2.55.0
[platform/upstream/glib.git] / glib / gslist.c
1 /* GLIB - Library of useful routines for C programming
2  * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
3  *
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.1 of the License, or (at your option) any later version.
8  *
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.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
16  */
17
18 /*
19  * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
20  * file for a list of people on the GLib Team.  See the ChangeLog
21  * files for a list of changes.  These files are distributed with
22  * GLib at ftp://ftp.gtk.org/pub/gtk/.
23  */
24
25 /*
26  * MT safe
27  */
28
29 #include "config.h"
30
31 #include "gslist.h"
32
33 #include "gtestutils.h"
34 #include "gslice.h"
35
36 /**
37  * SECTION:linked_lists_single
38  * @title: Singly-Linked Lists
39  * @short_description: linked lists that can be iterated in one direction
40  *
41  * The #GSList structure and its associated functions provide a
42  * standard singly-linked list data structure.
43  *
44  * Each element in the list contains a piece of data, together with a
45  * pointer which links to the next element in the list. Using this
46  * pointer it is possible to move through the list in one direction
47  * only (unlike the [double-linked lists][glib-Doubly-Linked-Lists],
48  * which allow movement in both directions).
49  *
50  * The data contained in each element can be either integer values, by
51  * using one of the [Type Conversion Macros][glib-Type-Conversion-Macros],
52  * or simply pointers to any type of data.
53  *
54  * List elements are allocated from the [slice allocator][glib-Memory-Slices],
55  * which is more efficient than allocating elements individually.
56  *
57  * Note that most of the #GSList functions expect to be passed a
58  * pointer to the first element in the list. The functions which insert
59  * elements return the new start of the list, which may have changed.
60  *
61  * There is no function to create a #GSList. %NULL is considered to be
62  * the empty list so you simply set a #GSList* to %NULL.
63  *
64  * To add elements, use g_slist_append(), g_slist_prepend(),
65  * g_slist_insert() and g_slist_insert_sorted().
66  *
67  * To remove elements, use g_slist_remove().
68  *
69  * To find elements in the list use g_slist_last(), g_slist_next(),
70  * g_slist_nth(), g_slist_nth_data(), g_slist_find() and
71  * g_slist_find_custom().
72  *
73  * To find the index of an element use g_slist_position() and
74  * g_slist_index().
75  *
76  * To call a function for each element in the list use
77  * g_slist_foreach().
78  *
79  * To free the entire list, use g_slist_free().
80  **/
81
82 /**
83  * GSList:
84  * @data: holds the element's data, which can be a pointer to any kind
85  *        of data, or any integer value using the
86  *        [Type Conversion Macros][glib-Type-Conversion-Macros]
87  * @next: contains the link to the next element in the list.
88  *
89  * The #GSList struct is used for each element in the singly-linked
90  * list.
91  **/
92
93 /**
94  * g_slist_next:
95  * @slist: an element in a #GSList.
96  *
97  * A convenience macro to get the next element in a #GSList.
98  * Note that it is considered perfectly acceptable to access
99  * @slist->next directly.
100  *
101  * Returns: the next element, or %NULL if there are no more elements.
102  **/
103
104 #define _g_slist_alloc0()       g_slice_new0 (GSList)
105 #define _g_slist_alloc()        g_slice_new (GSList)
106 #define _g_slist_free1(slist)   g_slice_free (GSList, slist)
107
108 /**
109  * g_slist_alloc:
110  *
111  * Allocates space for one #GSList element. It is called by the
112  * g_slist_append(), g_slist_prepend(), g_slist_insert() and
113  * g_slist_insert_sorted() functions and so is rarely used on its own.
114  *
115  * Returns: a pointer to the newly-allocated #GSList element.
116  **/
117 GSList*
118 g_slist_alloc (void)
119 {
120   return _g_slist_alloc0 ();
121 }
122
123 /**
124  * g_slist_free:
125  * @list: a #GSList
126  *
127  * Frees all of the memory used by a #GSList.
128  * The freed elements are returned to the slice allocator.
129  *
130  * If list elements contain dynamically-allocated memory,
131  * you should either use g_slist_free_full() or free them manually
132  * first.
133  */
134 void
135 g_slist_free (GSList *list)
136 {
137   g_slice_free_chain (GSList, list, next);
138 }
139
140 /**
141  * g_slist_free_1:
142  * @list: a #GSList element
143  *
144  * Frees one #GSList element.
145  * It is usually used after g_slist_remove_link().
146  */
147 /**
148  * g_slist_free1:
149  *
150  * A macro which does the same as g_slist_free_1().
151  *
152  * Since: 2.10
153  **/
154 void
155 g_slist_free_1 (GSList *list)
156 {
157   _g_slist_free1 (list);
158 }
159
160 /**
161  * g_slist_free_full:
162  * @list: a pointer to a #GSList
163  * @free_func: the function to be called to free each element's data
164  *
165  * Convenience method, which frees all the memory used by a #GSList, and
166  * calls the specified destroy function on every element's data.
167  *
168  * Since: 2.28
169  **/
170 void
171 g_slist_free_full (GSList         *list,
172                    GDestroyNotify  free_func)
173 {
174   g_slist_foreach (list, (GFunc) free_func, NULL);
175   g_slist_free (list);
176 }
177
178 /**
179  * g_slist_append:
180  * @list: a #GSList
181  * @data: the data for the new element
182  *
183  * Adds a new element on to the end of the list.
184  *
185  * The return value is the new start of the list, which may
186  * have changed, so make sure you store the new value.
187  *
188  * Note that g_slist_append() has to traverse the entire list
189  * to find the end, which is inefficient when adding multiple
190  * elements. A common idiom to avoid the inefficiency is to prepend
191  * the elements and reverse the list when all elements have been added.
192  *
193  * |[<!-- language="C" --> 
194  * // Notice that these are initialized to the empty list.
195  * GSList *list = NULL, *number_list = NULL;
196  *
197  * // This is a list of strings.
198  * list = g_slist_append (list, "first");
199  * list = g_slist_append (list, "second");
200  *
201  * // This is a list of integers.
202  * number_list = g_slist_append (number_list, GINT_TO_POINTER (27));
203  * number_list = g_slist_append (number_list, GINT_TO_POINTER (14));
204  * ]|
205  *
206  * Returns: the new start of the #GSList
207  */
208 GSList*
209 g_slist_append (GSList   *list,
210                 gpointer  data)
211 {
212   GSList *new_list;
213   GSList *last;
214
215   new_list = _g_slist_alloc ();
216   new_list->data = data;
217   new_list->next = NULL;
218
219   if (list)
220     {
221       last = g_slist_last (list);
222       /* g_assert (last != NULL); */
223       last->next = new_list;
224
225       return list;
226     }
227   else
228     return new_list;
229 }
230
231 /**
232  * g_slist_prepend:
233  * @list: a #GSList
234  * @data: the data for the new element
235  *
236  * Adds a new element on to the start of the list.
237  *
238  * The return value is the new start of the list, which
239  * may have changed, so make sure you store the new value.
240  *
241  * |[<!-- language="C" --> 
242  * // Notice that it is initialized to the empty list.
243  * GSList *list = NULL;
244  * list = g_slist_prepend (list, "last");
245  * list = g_slist_prepend (list, "first");
246  * ]|
247  *
248  * Returns: the new start of the #GSList
249  */
250 GSList*
251 g_slist_prepend (GSList   *list,
252                  gpointer  data)
253 {
254   GSList *new_list;
255
256   new_list = _g_slist_alloc ();
257   new_list->data = data;
258   new_list->next = list;
259
260   return new_list;
261 }
262
263 /**
264  * g_slist_insert:
265  * @list: a #GSList
266  * @data: the data for the new element
267  * @position: the position to insert the element.
268  *     If this is negative, or is larger than the number
269  *     of elements in the list, the new element is added on
270  *     to the end of the list.
271  *
272  * Inserts a new element into the list at the given position.
273  *
274  * Returns: the new start of the #GSList
275  */
276 GSList*
277 g_slist_insert (GSList   *list,
278                 gpointer  data,
279                 gint      position)
280 {
281   GSList *prev_list;
282   GSList *tmp_list;
283   GSList *new_list;
284
285   if (position < 0)
286     return g_slist_append (list, data);
287   else if (position == 0)
288     return g_slist_prepend (list, data);
289
290   new_list = _g_slist_alloc ();
291   new_list->data = data;
292
293   if (!list)
294     {
295       new_list->next = NULL;
296       return new_list;
297     }
298
299   prev_list = NULL;
300   tmp_list = list;
301
302   while ((position-- > 0) && tmp_list)
303     {
304       prev_list = tmp_list;
305       tmp_list = tmp_list->next;
306     }
307
308   new_list->next = prev_list->next;
309   prev_list->next = new_list;
310
311   return list;
312 }
313
314 /**
315  * g_slist_insert_before:
316  * @slist: a #GSList
317  * @sibling: node to insert @data before
318  * @data: data to put in the newly-inserted node
319  *
320  * Inserts a node before @sibling containing @data.
321  *
322  * Returns: the new head of the list.
323  */
324 GSList*
325 g_slist_insert_before (GSList  *slist,
326                        GSList  *sibling,
327                        gpointer data)
328 {
329   if (!slist)
330     {
331       slist = _g_slist_alloc ();
332       slist->data = data;
333       slist->next = NULL;
334       g_return_val_if_fail (sibling == NULL, slist);
335       return slist;
336     }
337   else
338     {
339       GSList *node, *last = NULL;
340
341       for (node = slist; node; last = node, node = last->next)
342         if (node == sibling)
343           break;
344       if (!last)
345         {
346           node = _g_slist_alloc ();
347           node->data = data;
348           node->next = slist;
349
350           return node;
351         }
352       else
353         {
354           node = _g_slist_alloc ();
355           node->data = data;
356           node->next = last->next;
357           last->next = node;
358
359           return slist;
360         }
361     }
362 }
363
364 /**
365  * g_slist_concat:
366  * @list1: a #GSList
367  * @list2: the #GSList to add to the end of the first #GSList
368  *
369  * Adds the second #GSList onto the end of the first #GSList.
370  * Note that the elements of the second #GSList are not copied.
371  * They are used directly.
372  *
373  * Returns: the start of the new #GSList
374  */
375 GSList *
376 g_slist_concat (GSList *list1, GSList *list2)
377 {
378   if (list2)
379     {
380       if (list1)
381         g_slist_last (list1)->next = list2;
382       else
383         list1 = list2;
384     }
385
386   return list1;
387 }
388
389 static GSList*
390 _g_slist_remove_data (GSList        *list,
391                       gconstpointer  data,
392                       gboolean       all)
393 {
394   GSList *tmp = NULL;
395   GSList **previous_ptr = &list;
396
397   while (*previous_ptr)
398     {
399       tmp = *previous_ptr;
400       if (tmp->data == data)
401         {
402           *previous_ptr = tmp->next;
403           g_slist_free_1 (tmp);
404           if (!all)
405             break;
406         }
407       else
408         {
409           previous_ptr = &tmp->next;
410         }
411     }
412
413   return list;
414 }
415 /**
416  * g_slist_remove:
417  * @list: a #GSList
418  * @data: the data of the element to remove
419  *
420  * Removes an element from a #GSList.
421  * If two elements contain the same data, only the first is removed.
422  * If none of the elements contain the data, the #GSList is unchanged.
423  *
424  * Returns: the new start of the #GSList
425  */
426 GSList*
427 g_slist_remove (GSList        *list,
428                 gconstpointer  data)
429 {
430   return _g_slist_remove_data (list, data, FALSE);
431 }
432
433 /**
434  * g_slist_remove_all:
435  * @list: a #GSList
436  * @data: data to remove
437  *
438  * Removes all list nodes with data equal to @data.
439  * Returns the new head of the list. Contrast with
440  * g_slist_remove() which removes only the first node
441  * matching the given data.
442  *
443  * Returns: new head of @list
444  */
445 GSList*
446 g_slist_remove_all (GSList        *list,
447                     gconstpointer  data)
448 {
449   return _g_slist_remove_data (list, data, TRUE);
450 }
451
452 static inline GSList*
453 _g_slist_remove_link (GSList *list,
454                       GSList *link)
455 {
456   GSList *tmp = NULL;
457   GSList **previous_ptr = &list;
458
459   while (*previous_ptr)
460     {
461       tmp = *previous_ptr;
462       if (tmp == link)
463         {
464           *previous_ptr = tmp->next;
465           tmp->next = NULL;
466           break;
467         }
468
469       previous_ptr = &tmp->next;
470     }
471
472   return list;
473 }
474
475 /**
476  * g_slist_remove_link:
477  * @list: a #GSList
478  * @link_: an element in the #GSList
479  *
480  * Removes an element from a #GSList, without
481  * freeing the element. The removed element's next
482  * link is set to %NULL, so that it becomes a
483  * self-contained list with one element.
484  *
485  * Removing arbitrary nodes from a singly-linked list
486  * requires time that is proportional to the length of the list
487  * (ie. O(n)). If you find yourself using g_slist_remove_link()
488  * frequently, you should consider a different data structure,
489  * such as the doubly-linked #GList.
490  *
491  * Returns: the new start of the #GSList, without the element
492  */
493 GSList*
494 g_slist_remove_link (GSList *list,
495                      GSList *link_)
496 {
497   return _g_slist_remove_link (list, link_);
498 }
499
500 /**
501  * g_slist_delete_link:
502  * @list: a #GSList
503  * @link_: node to delete
504  *
505  * Removes the node link_ from the list and frees it.
506  * Compare this to g_slist_remove_link() which removes the node
507  * without freeing it.
508  *
509  * Removing arbitrary nodes from a singly-linked list requires time
510  * that is proportional to the length of the list (ie. O(n)). If you
511  * find yourself using g_slist_delete_link() frequently, you should
512  * consider a different data structure, such as the doubly-linked
513  * #GList.
514  *
515  * Returns: the new head of @list
516  */
517 GSList*
518 g_slist_delete_link (GSList *list,
519                      GSList *link_)
520 {
521   list = _g_slist_remove_link (list, link_);
522   _g_slist_free1 (link_);
523
524   return list;
525 }
526
527 /**
528  * g_slist_copy:
529  * @list: a #GSList
530  *
531  * Copies a #GSList.
532  *
533  * Note that this is a "shallow" copy. If the list elements
534  * consist of pointers to data, the pointers are copied but
535  * the actual data isn't. See g_slist_copy_deep() if you need
536  * to copy the data as well.
537  *
538  * Returns: a copy of @list
539  */
540 GSList*
541 g_slist_copy (GSList *list)
542 {
543   return g_slist_copy_deep (list, NULL, NULL);
544 }
545
546 /**
547  * g_slist_copy_deep:
548  * @list: a #GSList
549  * @func: a copy function used to copy every element in the list
550  * @user_data: user data passed to the copy function @func, or #NULL
551  *
552  * Makes a full (deep) copy of a #GSList.
553  *
554  * In contrast with g_slist_copy(), this function uses @func to make a copy of
555  * each list element, in addition to copying the list container itself.
556  *
557  * @func, as a #GCopyFunc, takes two arguments, the data to be copied and a user
558  * pointer. It's safe to pass #NULL as user_data, if the copy function takes only
559  * one argument.
560  *
561  * For instance, if @list holds a list of GObjects, you can do:
562  * |[<!-- language="C" --> 
563  * another_list = g_slist_copy_deep (list, (GCopyFunc) g_object_ref, NULL);
564  * ]|
565  *
566  * And, to entirely free the new list, you could do:
567  * |[<!-- language="C" --> 
568  * g_slist_free_full (another_list, g_object_unref);
569  * ]|
570  *
571  * Returns: a full copy of @list, use #g_slist_free_full to free it
572  *
573  * Since: 2.34
574  */
575 GSList*
576 g_slist_copy_deep (GSList *list, GCopyFunc func, gpointer user_data)
577 {
578   GSList *new_list = NULL;
579
580   if (list)
581     {
582       GSList *last;
583
584       new_list = _g_slist_alloc ();
585       if (func)
586         new_list->data = func (list->data, user_data);
587       else
588         new_list->data = list->data;
589       last = new_list;
590       list = list->next;
591       while (list)
592         {
593           last->next = _g_slist_alloc ();
594           last = last->next;
595           if (func)
596             last->data = func (list->data, user_data);
597           else
598             last->data = list->data;
599           list = list->next;
600         }
601       last->next = NULL;
602     }
603
604   return new_list;
605 }
606
607 /**
608  * g_slist_reverse:
609  * @list: a #GSList
610  *
611  * Reverses a #GSList.
612  *
613  * Returns: the start of the reversed #GSList
614  */
615 GSList*
616 g_slist_reverse (GSList *list)
617 {
618   GSList *prev = NULL;
619
620   while (list)
621     {
622       GSList *next = list->next;
623
624       list->next = prev;
625
626       prev = list;
627       list = next;
628     }
629
630   return prev;
631 }
632
633 /**
634  * g_slist_nth:
635  * @list: a #GSList
636  * @n: the position of the element, counting from 0
637  *
638  * Gets the element at the given position in a #GSList.
639  *
640  * Returns: the element, or %NULL if the position is off
641  *     the end of the #GSList
642  */
643 GSList*
644 g_slist_nth (GSList *list,
645              guint   n)
646 {
647   while (n-- > 0 && list)
648     list = list->next;
649
650   return list;
651 }
652
653 /**
654  * g_slist_nth_data:
655  * @list: a #GSList
656  * @n: the position of the element
657  *
658  * Gets the data of the element at the given position.
659  *
660  * Returns: the element's data, or %NULL if the position
661  *     is off the end of the #GSList
662  */
663 gpointer
664 g_slist_nth_data (GSList   *list,
665                   guint     n)
666 {
667   while (n-- > 0 && list)
668     list = list->next;
669
670   return list ? list->data : NULL;
671 }
672
673 /**
674  * g_slist_find:
675  * @list: a #GSList
676  * @data: the element data to find
677  *
678  * Finds the element in a #GSList which
679  * contains the given data.
680  *
681  * Returns: the found #GSList element,
682  *     or %NULL if it is not found
683  */
684 GSList*
685 g_slist_find (GSList        *list,
686               gconstpointer  data)
687 {
688   while (list)
689     {
690       if (list->data == data)
691         break;
692       list = list->next;
693     }
694
695   return list;
696 }
697
698
699 /**
700  * g_slist_find_custom:
701  * @list: a #GSList
702  * @data: user data passed to the function
703  * @func: the function to call for each element.
704  *     It should return 0 when the desired element is found
705  *
706  * Finds an element in a #GSList, using a supplied function to
707  * find the desired element. It iterates over the list, calling
708  * the given function which should return 0 when the desired
709  * element is found. The function takes two #gconstpointer arguments,
710  * the #GSList element's data as the first argument and the
711  * given user data.
712  *
713  * Returns: the found #GSList element, or %NULL if it is not found
714  */
715 GSList*
716 g_slist_find_custom (GSList        *list,
717                      gconstpointer  data,
718                      GCompareFunc   func)
719 {
720   g_return_val_if_fail (func != NULL, list);
721
722   while (list)
723     {
724       if (! func (list->data, data))
725         return list;
726       list = list->next;
727     }
728
729   return NULL;
730 }
731
732 /**
733  * g_slist_position:
734  * @list: a #GSList
735  * @llink: an element in the #GSList
736  *
737  * Gets the position of the given element
738  * in the #GSList (starting from 0).
739  *
740  * Returns: the position of the element in the #GSList,
741  *     or -1 if the element is not found
742  */
743 gint
744 g_slist_position (GSList *list,
745                   GSList *llink)
746 {
747   gint i;
748
749   i = 0;
750   while (list)
751     {
752       if (list == llink)
753         return i;
754       i++;
755       list = list->next;
756     }
757
758   return -1;
759 }
760
761 /**
762  * g_slist_index:
763  * @list: a #GSList
764  * @data: the data to find
765  *
766  * Gets the position of the element containing
767  * the given data (starting from 0).
768  *
769  * Returns: the index of the element containing the data,
770  *     or -1 if the data is not found
771  */
772 gint
773 g_slist_index (GSList        *list,
774                gconstpointer  data)
775 {
776   gint i;
777
778   i = 0;
779   while (list)
780     {
781       if (list->data == data)
782         return i;
783       i++;
784       list = list->next;
785     }
786
787   return -1;
788 }
789
790 /**
791  * g_slist_last:
792  * @list: a #GSList
793  *
794  * Gets the last element in a #GSList.
795  *
796  * This function iterates over the whole list.
797  *
798  * Returns: the last element in the #GSList,
799  *     or %NULL if the #GSList has no elements
800  */
801 GSList*
802 g_slist_last (GSList *list)
803 {
804   if (list)
805     {
806       while (list->next)
807         list = list->next;
808     }
809
810   return list;
811 }
812
813 /**
814  * g_slist_length:
815  * @list: a #GSList
816  *
817  * Gets the number of elements in a #GSList.
818  *
819  * This function iterates over the whole list to
820  * count its elements. To check whether the list is non-empty, it is faster to
821  * check @list against %NULL.
822  *
823  * Returns: the number of elements in the #GSList
824  */
825 guint
826 g_slist_length (GSList *list)
827 {
828   guint length;
829
830   length = 0;
831   while (list)
832     {
833       length++;
834       list = list->next;
835     }
836
837   return length;
838 }
839
840 /**
841  * g_slist_foreach:
842  * @list: a #GSList
843  * @func: the function to call with each element's data
844  * @user_data: user data to pass to the function
845  *
846  * Calls a function for each element of a #GSList.
847  */
848 void
849 g_slist_foreach (GSList   *list,
850                  GFunc     func,
851                  gpointer  user_data)
852 {
853   while (list)
854     {
855       GSList *next = list->next;
856       (*func) (list->data, user_data);
857       list = next;
858     }
859 }
860
861 static GSList*
862 g_slist_insert_sorted_real (GSList   *list,
863                             gpointer  data,
864                             GFunc     func,
865                             gpointer  user_data)
866 {
867   GSList *tmp_list = list;
868   GSList *prev_list = NULL;
869   GSList *new_list;
870   gint cmp;
871
872   g_return_val_if_fail (func != NULL, list);
873
874   if (!list)
875     {
876       new_list = _g_slist_alloc ();
877       new_list->data = data;
878       new_list->next = NULL;
879       return new_list;
880     }
881
882   cmp = ((GCompareDataFunc) func) (data, tmp_list->data, user_data);
883
884   while ((tmp_list->next) && (cmp > 0))
885     {
886       prev_list = tmp_list;
887       tmp_list = tmp_list->next;
888
889       cmp = ((GCompareDataFunc) func) (data, tmp_list->data, user_data);
890     }
891
892   new_list = _g_slist_alloc ();
893   new_list->data = data;
894
895   if ((!tmp_list->next) && (cmp > 0))
896     {
897       tmp_list->next = new_list;
898       new_list->next = NULL;
899       return list;
900     }
901
902   if (prev_list)
903     {
904       prev_list->next = new_list;
905       new_list->next = tmp_list;
906       return list;
907     }
908   else
909     {
910       new_list->next = list;
911       return new_list;
912     }
913 }
914
915 /**
916  * g_slist_insert_sorted:
917  * @list: a #GSList
918  * @data: the data for the new element
919  * @func: the function to compare elements in the list.
920  *     It should return a number > 0 if the first parameter
921  *     comes after the second parameter in the sort order.
922  *
923  * Inserts a new element into the list, using the given
924  * comparison function to determine its position.
925  *
926  * Returns: the new start of the #GSList
927  */
928 GSList*
929 g_slist_insert_sorted (GSList       *list,
930                        gpointer      data,
931                        GCompareFunc  func)
932 {
933   return g_slist_insert_sorted_real (list, data, (GFunc) func, NULL);
934 }
935
936 /**
937  * g_slist_insert_sorted_with_data:
938  * @list: a #GSList
939  * @data: the data for the new element
940  * @func: the function to compare elements in the list.
941  *     It should return a number > 0 if the first parameter
942  *     comes after the second parameter in the sort order.
943  * @user_data: data to pass to comparison function
944  *
945  * Inserts a new element into the list, using the given
946  * comparison function to determine its position.
947  *
948  * Returns: the new start of the #GSList
949  *
950  * Since: 2.10
951  */
952 GSList*
953 g_slist_insert_sorted_with_data (GSList           *list,
954                                  gpointer          data,
955                                  GCompareDataFunc  func,
956                                  gpointer          user_data)
957 {
958   return g_slist_insert_sorted_real (list, data, (GFunc) func, user_data);
959 }
960
961 static GSList *
962 g_slist_sort_merge (GSList   *l1,
963                     GSList   *l2,
964                     GFunc     compare_func,
965                     gpointer  user_data)
966 {
967   GSList list, *l;
968   gint cmp;
969
970   l=&list;
971
972   while (l1 && l2)
973     {
974       cmp = ((GCompareDataFunc) compare_func) (l1->data, l2->data, user_data);
975
976       if (cmp <= 0)
977         {
978           l=l->next=l1;
979           l1=l1->next;
980         }
981       else
982         {
983           l=l->next=l2;
984           l2=l2->next;
985         }
986     }
987   l->next= l1 ? l1 : l2;
988
989   return list.next;
990 }
991
992 static GSList *
993 g_slist_sort_real (GSList   *list,
994                    GFunc     compare_func,
995                    gpointer  user_data)
996 {
997   GSList *l1, *l2;
998
999   if (!list)
1000     return NULL;
1001   if (!list->next)
1002     return list;
1003
1004   l1 = list;
1005   l2 = list->next;
1006
1007   while ((l2 = l2->next) != NULL)
1008     {
1009       if ((l2 = l2->next) == NULL)
1010         break;
1011       l1=l1->next;
1012     }
1013   l2 = l1->next;
1014   l1->next = NULL;
1015
1016   return g_slist_sort_merge (g_slist_sort_real (list, compare_func, user_data),
1017                              g_slist_sort_real (l2, compare_func, user_data),
1018                              compare_func,
1019                              user_data);
1020 }
1021
1022 /**
1023  * g_slist_sort:
1024  * @list: a #GSList
1025  * @compare_func: the comparison function used to sort the #GSList.
1026  *     This function is passed the data from 2 elements of the #GSList
1027  *     and should return 0 if they are equal, a negative value if the
1028  *     first element comes before the second, or a positive value if
1029  *     the first element comes after the second.
1030  *
1031  * Sorts a #GSList using the given comparison function.
1032  *
1033  * Returns: the start of the sorted #GSList
1034  */
1035 GSList *
1036 g_slist_sort (GSList       *list,
1037               GCompareFunc  compare_func)
1038 {
1039   return g_slist_sort_real (list, (GFunc) compare_func, NULL);
1040 }
1041
1042 /**
1043  * g_slist_sort_with_data:
1044  * @list: a #GSList
1045  * @compare_func: comparison function
1046  * @user_data: data to pass to comparison function
1047  *
1048  * Like g_slist_sort(), but the sort function accepts a user data argument.
1049  *
1050  * Returns: new head of the list
1051  */
1052 GSList *
1053 g_slist_sort_with_data (GSList           *list,
1054                         GCompareDataFunc  compare_func,
1055                         gpointer          user_data)
1056 {
1057   return g_slist_sort_real (list, (GFunc) compare_func, user_data);
1058 }