Merge remote branch 'gvdb/master'
[platform/upstream/glib.git] / glib / gqueue.c
1 /* GLIB - Library of useful routines for C programming
2  * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
3  *
4  * GQueue: Double ended queue implementation, piggy backed on GList.
5  * Copyright (C) 1998 Tim Janik
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
22
23 /*
24  * MT safe
25  */
26
27 #include "config.h"
28
29 #include "glib.h"
30 #include "galias.h"
31
32 /**
33  * g_queue_new:
34  *
35  * Creates a new #GQueue. 
36  *
37  * Returns: a new #GQueue.
38  **/
39 GQueue*
40 g_queue_new (void)
41 {
42   return g_slice_new0 (GQueue);
43 }
44
45 /**
46  * g_queue_free:
47  * @queue: a #GQueue.
48  *
49  * Frees the memory allocated for the #GQueue. Only call this function if
50  * @queue was created with g_queue_new(). If queue elements contain
51  * dynamically-allocated memory, they should be freed first.
52  **/
53 void
54 g_queue_free (GQueue *queue)
55 {
56   g_return_if_fail (queue != NULL);
57
58   g_list_free (queue->head);
59   g_slice_free (GQueue, queue);
60 }
61
62 /**
63  * g_queue_init:
64  * @queue: an uninitialized #GQueue
65  *
66  * A statically-allocated #GQueue must be initialized with this function
67  * before it can be used. Alternatively you can initialize it with
68  * #G_QUEUE_INIT. It is not necessary to initialize queues created with
69  * g_queue_new().
70  *
71  * Since: 2.14
72  **/
73 void
74 g_queue_init (GQueue *queue)
75 {
76   g_return_if_fail (queue != NULL);
77
78   queue->head = queue->tail = NULL;
79   queue->length = 0;
80 }
81
82 /**
83  * g_queue_clear:
84  * @queue: a #GQueue
85  *
86  * Removes all the elements in @queue. If queue elements contain
87  * dynamically-allocated memory, they should be freed first.
88  *
89  * Since: 2.14
90  */
91 void
92 g_queue_clear (GQueue *queue)
93 {
94   g_return_if_fail (queue != NULL);
95
96   g_list_free (queue->head);
97   g_queue_init (queue);
98 }
99
100 /**
101  * g_queue_is_empty:
102  * @queue: a #GQueue.
103  *
104  * Returns %TRUE if the queue is empty.
105  *
106  * Returns: %TRUE if the queue is empty.
107  **/
108 gboolean
109 g_queue_is_empty (GQueue *queue)
110 {
111   g_return_val_if_fail (queue != NULL, TRUE);
112
113   return queue->head == NULL;
114 }
115
116 /**
117  * g_queue_get_length:
118  * @queue: a #GQueue
119  * 
120  * Returns the number of items in @queue.
121  * 
122  * Return value: The number of items in @queue.
123  * 
124  * Since: 2.4
125  **/
126 guint
127 g_queue_get_length (GQueue *queue)
128 {
129   g_return_val_if_fail (queue != NULL, 0);
130
131   return queue->length;
132 }
133
134 /**
135  * g_queue_reverse:
136  * @queue: a #GQueue
137  * 
138  * Reverses the order of the items in @queue.
139  * 
140  * Since: 2.4
141  **/
142 void
143 g_queue_reverse (GQueue *queue)
144 {
145   g_return_if_fail (queue != NULL);
146
147   queue->tail = queue->head;
148   queue->head = g_list_reverse (queue->head);
149 }
150
151 /**
152  * g_queue_copy:
153  * @queue: a #GQueue
154  * 
155  * Copies a @queue. Note that is a shallow copy. If the elements in the
156  * queue consist of pointers to data, the pointers are copied, but the
157  * actual data is not.
158  * 
159  * Return value: A copy of @queue
160  * 
161  * Since: 2.4
162  **/
163 GQueue *
164 g_queue_copy (GQueue *queue)
165 {
166   GQueue *result;
167   GList *list;
168
169   g_return_val_if_fail (queue != NULL, NULL);
170
171   result = g_queue_new ();
172
173   for (list = queue->head; list != NULL; list = list->next)
174     g_queue_push_tail (result, list->data);
175
176   return result;
177 }
178
179 /**
180  * g_queue_foreach:
181  * @queue: a #GQueue
182  * @func: the function to call for each element's data
183  * @user_data: user data to pass to @func
184  * 
185  * Calls @func for each element in the queue passing @user_data to the
186  * function.
187  * 
188  * Since: 2.4
189  **/
190 void
191 g_queue_foreach (GQueue   *queue,
192                  GFunc     func,
193                  gpointer  user_data)
194 {
195   GList *list;
196
197   g_return_if_fail (queue != NULL);
198   g_return_if_fail (func != NULL);
199   
200   list = queue->head;
201   while (list)
202     {
203       GList *next = list->next;
204       func (list->data, user_data);
205       list = next;
206     }
207 }
208
209 /**
210  * g_queue_find:
211  * @queue: a #GQueue
212  * @data: data to find
213  * 
214  * Finds the first link in @queue which contains @data.
215  * 
216  * Return value: The first link in @queue which contains @data.
217  * 
218  * Since: 2.4
219  **/
220 GList *
221 g_queue_find (GQueue        *queue,
222               gconstpointer  data)
223 {
224   g_return_val_if_fail (queue != NULL, NULL);
225
226   return g_list_find (queue->head, data);
227 }
228
229 /**
230  * g_queue_find_custom:
231  * @queue: a #GQueue
232  * @data: user data passed to @func
233  * @func: a #GCompareFunc to call for each element. It should return 0
234  * when the desired element is found
235  *
236  * Finds an element in a #GQueue, using a supplied function to find the
237  * desired element. It iterates over the queue, calling the given function
238  * which should return 0 when the desired element is found. The function
239  * takes two gconstpointer arguments, the #GQueue element's data as the
240  * first argument and the given user data as the second argument.
241  * 
242  * Return value: The found link, or %NULL if it wasn't found
243  * 
244  * Since: 2.4
245  **/
246 GList *
247 g_queue_find_custom    (GQueue        *queue,
248                         gconstpointer  data,
249                         GCompareFunc   func)
250 {
251   g_return_val_if_fail (queue != NULL, NULL);
252   g_return_val_if_fail (func != NULL, NULL);
253
254   return g_list_find_custom (queue->head, data, func);
255 }
256
257 /**
258  * g_queue_sort:
259  * @queue: a #GQueue
260  * @compare_func: the #GCompareDataFunc used to sort @queue. This function
261  *     is passed two elements of the queue and should return 0 if they are
262  *     equal, a negative value if the first comes before the second, and
263  *     a positive value if the second comes before the first.
264  * @user_data: user data passed to @compare_func
265  * 
266  * Sorts @queue using @compare_func. 
267  * 
268  * Since: 2.4
269  **/
270 void
271 g_queue_sort (GQueue           *queue,
272               GCompareDataFunc  compare_func,
273               gpointer          user_data)
274 {
275   g_return_if_fail (queue != NULL);
276   g_return_if_fail (compare_func != NULL);
277
278   queue->head = g_list_sort_with_data (queue->head, compare_func, user_data);
279   queue->tail = g_list_last (queue->head);
280 }
281
282 /**
283  * g_queue_push_head:
284  * @queue: a #GQueue.
285  * @data: the data for the new element.
286  *
287  * Adds a new element at the head of the queue.
288  **/
289 void
290 g_queue_push_head (GQueue  *queue,
291                    gpointer data)
292 {
293   g_return_if_fail (queue != NULL);
294
295   queue->head = g_list_prepend (queue->head, data);
296   if (!queue->tail)
297     queue->tail = queue->head;
298   queue->length++;
299 }
300
301 /**
302  * g_queue_push_nth:
303  * @queue: a #GQueue
304  * @data: the data for the new element
305  * @n: the position to insert the new element. If @n is negative or
306  *     larger than the number of elements in the @queue, the element is
307  *     added to the end of the queue.
308  * 
309  * Inserts a new element into @queue at the given position
310  * 
311  * Since: 2.4
312  **/
313 void
314 g_queue_push_nth (GQueue   *queue,
315                   gpointer  data,
316                   gint      n)
317 {
318   g_return_if_fail (queue != NULL);
319
320   if (n < 0 || n >= queue->length)
321     {
322       g_queue_push_tail (queue, data);
323       return;
324     }
325
326   g_queue_insert_before (queue, g_queue_peek_nth_link (queue, n), data);
327 }
328
329 /**
330  * g_queue_push_head_link:
331  * @queue: a #GQueue.
332  * @link_: a single #GList element, <emphasis>not</emphasis> a list with
333  *     more than one element.
334  *
335  * Adds a new element at the head of the queue.
336  **/
337 void
338 g_queue_push_head_link (GQueue *queue,
339                         GList  *link)
340 {
341   g_return_if_fail (queue != NULL);
342   g_return_if_fail (link != NULL);
343   g_return_if_fail (link->prev == NULL);
344   g_return_if_fail (link->next == NULL);
345
346   link->next = queue->head;
347   if (queue->head)
348     queue->head->prev = link;
349   else
350     queue->tail = link;
351   queue->head = link;
352   queue->length++;
353 }
354
355 /**
356  * g_queue_push_tail:
357  * @queue: a #GQueue.
358  * @data: the data for the new element.
359  *
360  * Adds a new element at the tail of the queue.
361  **/
362 void
363 g_queue_push_tail (GQueue  *queue,
364                    gpointer data)
365 {
366   g_return_if_fail (queue != NULL);
367
368   queue->tail = g_list_append (queue->tail, data);
369   if (queue->tail->next)
370     queue->tail = queue->tail->next;
371   else
372     queue->head = queue->tail;
373   queue->length++;
374 }
375
376 /**
377  * g_queue_push_tail_link:
378  * @queue: a #GQueue.
379  * @link_: a single #GList element, <emphasis>not</emphasis> a list with
380  *   more than one element.
381  *
382  * Adds a new element at the tail of the queue.
383  **/
384 void
385 g_queue_push_tail_link (GQueue *queue,
386                         GList  *link)
387 {
388   g_return_if_fail (queue != NULL);
389   g_return_if_fail (link != NULL);
390   g_return_if_fail (link->prev == NULL);
391   g_return_if_fail (link->next == NULL);
392
393   link->prev = queue->tail;
394   if (queue->tail)
395     queue->tail->next = link;
396   else
397     queue->head = link;
398   queue->tail = link;
399   queue->length++;
400 }
401
402 /**
403  * g_queue_push_nth_link:
404  * @queue: a #GQueue
405  * @n: the position to insert the link. If this is negative or larger than
406  *     the number of elements in @queue, the link is added to the end of
407  *     @queue.
408  * @link_: the link to add to @queue
409  * 
410  * Inserts @link into @queue at the given position.
411  * 
412  * Since: 2.4
413  **/
414 void
415 g_queue_push_nth_link  (GQueue  *queue,
416                         gint     n,
417                         GList   *link_)
418 {
419   GList *next;
420   GList *prev;
421   
422   g_return_if_fail (queue != NULL);
423   g_return_if_fail (link_ != NULL);
424
425   if (n < 0 || n >= queue->length)
426     {
427       g_queue_push_tail_link (queue, link_);
428       return;
429     }
430
431   g_assert (queue->head);
432   g_assert (queue->tail);
433
434   next = g_queue_peek_nth_link (queue, n);
435   prev = next->prev;
436
437   if (prev)
438     prev->next = link_;
439   next->prev = link_;
440
441   link_->next = next;
442   link_->prev = prev;
443
444   if (queue->head->prev)
445     queue->head = queue->head->prev;
446
447   if (queue->tail->next)
448     queue->tail = queue->tail->next;
449   
450   queue->length++;
451 }
452
453 /**
454  * g_queue_pop_head:
455  * @queue: a #GQueue.
456  *
457  * Removes the first element of the queue.
458  *
459  * Returns: the data of the first element in the queue, or %NULL if the queue
460  *   is empty.
461  **/
462 gpointer
463 g_queue_pop_head (GQueue *queue)
464 {
465   g_return_val_if_fail (queue != NULL, NULL);
466
467   if (queue->head)
468     {
469       GList *node = queue->head;
470       gpointer data = node->data;
471
472       queue->head = node->next;
473       if (queue->head)
474         queue->head->prev = NULL;
475       else
476         queue->tail = NULL;
477       g_list_free_1 (node);
478       queue->length--;
479
480       return data;
481     }
482
483   return NULL;
484 }
485
486 /**
487  * g_queue_pop_head_link:
488  * @queue: a #GQueue.
489  *
490  * Removes the first element of the queue.
491  *
492  * Returns: the #GList element at the head of the queue, or %NULL if the queue
493  *   is empty.
494  **/
495 GList*
496 g_queue_pop_head_link (GQueue *queue)
497 {
498   g_return_val_if_fail (queue != NULL, NULL);
499
500   if (queue->head)
501     {
502       GList *node = queue->head;
503
504       queue->head = node->next;
505       if (queue->head)
506         {
507           queue->head->prev = NULL;
508           node->next = NULL;
509         }
510       else
511         queue->tail = NULL;
512       queue->length--;
513
514       return node;
515     }
516
517   return NULL;
518 }
519
520 /**
521  * g_queue_peek_head_link:
522  * @queue: a #GQueue
523  * 
524  * Returns the first link in @queue
525  * 
526  * Return value: the first link in @queue, or %NULL if @queue is empty
527  * 
528  * Since: 2.4
529  **/
530 GList*
531 g_queue_peek_head_link (GQueue *queue)
532 {
533   g_return_val_if_fail (queue != NULL, NULL);
534
535   return queue->head;
536 }
537
538 /**
539  * g_queue_peek_tail_link:
540  * @queue: a #GQueue
541  * 
542  * Returns the last link @queue.
543  * 
544  * Return value: the last link in @queue, or %NULL if @queue is empty
545  * 
546  * Since: 2.4
547  **/
548 GList*
549 g_queue_peek_tail_link (GQueue *queue)
550 {
551   g_return_val_if_fail (queue != NULL, NULL);
552
553   return queue->tail;
554 }
555
556 /**
557  * g_queue_pop_tail:
558  * @queue: a #GQueue.
559  *
560  * Removes the last element of the queue.
561  *
562  * Returns: the data of the last element in the queue, or %NULL if the queue
563  *   is empty.
564  **/
565 gpointer
566 g_queue_pop_tail (GQueue *queue)
567 {
568   g_return_val_if_fail (queue != NULL, NULL);
569
570   if (queue->tail)
571     {
572       GList *node = queue->tail;
573       gpointer data = node->data;
574
575       queue->tail = node->prev;
576       if (queue->tail)
577         queue->tail->next = NULL;
578       else
579         queue->head = NULL;
580       queue->length--;
581       g_list_free_1 (node);
582
583       return data;
584     }
585   
586   return NULL;
587 }
588
589 /**
590  * g_queue_pop_nth:
591  * @queue: a #GQueue
592  * @n: the position of the element.
593  * 
594  * Removes the @n'th element of @queue.
595  * 
596  * Return value: the element's data, or %NULL if @n is off the end of @queue.
597  * 
598  * Since: 2.4
599  **/
600 gpointer
601 g_queue_pop_nth (GQueue *queue,
602                  guint   n)
603 {
604   GList *nth_link;
605   gpointer result;
606   
607   g_return_val_if_fail (queue != NULL, NULL);
608
609   if (n >= queue->length)
610     return NULL;
611   
612   nth_link = g_queue_peek_nth_link (queue, n);
613   result = nth_link->data;
614
615   g_queue_delete_link (queue, nth_link);
616
617   return result;
618 }
619
620 /**
621  * g_queue_pop_tail_link:
622  * @queue: a #GQueue.
623  *
624  * Removes the last element of the queue.
625  *
626  * Returns: the #GList element at the tail of the queue, or %NULL if the queue
627  *   is empty.
628  **/
629 GList*
630 g_queue_pop_tail_link (GQueue *queue)
631 {
632   g_return_val_if_fail (queue != NULL, NULL);
633   
634   if (queue->tail)
635     {
636       GList *node = queue->tail;
637       
638       queue->tail = node->prev;
639       if (queue->tail)
640         {
641           queue->tail->next = NULL;
642           node->prev = NULL;
643         }
644       else
645         queue->head = NULL;
646       queue->length--;
647       
648       return node;
649     }
650   
651   return NULL;
652 }
653
654 /**
655  * g_queue_pop_nth_link:
656  * @queue: a #GQueue
657  * @n: the link's position
658  * 
659  * Removes and returns the link at the given position.
660  * 
661  * Return value: The @n'th link, or %NULL if @n is off the end of @queue.
662  * 
663  * Since: 2.4
664  **/
665 GList*
666 g_queue_pop_nth_link (GQueue *queue,
667                       guint   n)
668 {
669   GList *link;
670   
671   g_return_val_if_fail (queue != NULL, NULL);
672
673   if (n >= queue->length)
674     return NULL;
675   
676   link = g_queue_peek_nth_link (queue, n);
677   g_queue_unlink (queue, link);
678
679   return link;
680 }
681
682 /**
683  * g_queue_peek_nth_link:
684  * @queue: a #GQueue
685  * @n: the position of the link
686  * 
687  * Returns the link at the given position
688  * 
689  * Return value: The link at the @n'th position, or %NULL if @n is off the
690  * end of the list
691  * 
692  * Since: 2.4
693  **/
694 GList *
695 g_queue_peek_nth_link (GQueue *queue,
696                        guint   n)
697 {
698   GList *link;
699   gint i;
700   
701   g_return_val_if_fail (queue != NULL, NULL);
702
703   if (n >= queue->length)
704     return NULL;
705   
706   if (n > queue->length / 2)
707     {
708       n = queue->length - n - 1;
709
710       link = queue->tail;
711       for (i = 0; i < n; ++i)
712         link = link->prev;
713     }
714   else
715     {
716       link = queue->head;
717       for (i = 0; i < n; ++i)
718         link = link->next;
719     }
720
721   return link;
722 }
723
724 /**
725  * g_queue_link_index:
726  * @queue: a #Gqueue
727  * @link_: A #GList link
728  * 
729  * Returns the position of @link_ in @queue.
730  * 
731  * Return value: The position of @link_, or -1 if the link is
732  * not part of @queue
733  * 
734  * Since: 2.4
735  **/
736 gint
737 g_queue_link_index (GQueue *queue,
738                     GList  *link_)
739 {
740   g_return_val_if_fail (queue != NULL, -1);
741
742   return g_list_position (queue->head, link_);
743 }
744
745 /**
746  * g_queue_unlink
747  * @queue: a #GQueue
748  * @link_: a #GList link that <emphasis>must</emphasis> be part of @queue
749  *
750  * Unlinks @link_ so that it will no longer be part of @queue. The link is
751  * not freed.
752  *
753  * @link_ must be part of @queue,
754  * 
755  * Since: 2.4
756  **/
757 void
758 g_queue_unlink (GQueue *queue,
759                 GList  *link_)
760 {
761   g_return_if_fail (queue != NULL);
762   g_return_if_fail (link_ != NULL);
763
764   if (link_ == queue->tail)
765     queue->tail = queue->tail->prev;
766   
767   queue->head = g_list_remove_link (queue->head, link_);
768   queue->length--;
769 }
770
771 /**
772  * g_queue_delete_link:
773  * @queue: a #GQueue
774  * @link_: a #GList link that <emphasis>must</emphasis> be part of @queue
775  *
776  * Removes @link_ from @queue and frees it.
777  *
778  * @link_ must be part of @queue.
779  * 
780  * Since: 2.4
781  **/
782 void
783 g_queue_delete_link (GQueue *queue,
784                      GList  *link_)
785 {
786   g_return_if_fail (queue != NULL);
787   g_return_if_fail (link_ != NULL);
788
789   g_queue_unlink (queue, link_);
790   g_list_free (link_);
791 }
792
793 /**
794  * g_queue_peek_head:
795  * @queue: a #GQueue.
796  *
797  * Returns the first element of the queue.
798  *
799  * Returns: the data of the first element in the queue, or %NULL if the queue
800  *   is empty.
801  **/
802 gpointer
803 g_queue_peek_head (GQueue *queue)
804 {
805   g_return_val_if_fail (queue != NULL, NULL);
806
807   return queue->head ? queue->head->data : NULL;
808 }
809
810 /**
811  * g_queue_peek_tail:
812  * @queue: a #GQueue.
813  *
814  * Returns the last element of the queue.
815  *
816  * Returns: the data of the last element in the queue, or %NULL if the queue
817  *   is empty.
818  **/
819 gpointer
820 g_queue_peek_tail (GQueue *queue)
821 {
822   g_return_val_if_fail (queue != NULL, NULL);
823
824   return queue->tail ? queue->tail->data : NULL;
825 }
826
827 /**
828  * g_queue_peek_nth:
829  * @queue: a #GQueue
830  * @n: the position of the element.
831  * 
832  * Returns the @n'th element of @queue. 
833  * 
834  * Return value: The data for the @n'th element of @queue, or %NULL if @n is
835  *   off the end of @queue.
836  * 
837  * Since: 2.4
838  **/
839 gpointer
840 g_queue_peek_nth (GQueue *queue,
841                   guint   n)
842 {
843   GList *link;
844   
845   g_return_val_if_fail (queue != NULL, NULL);
846
847   link = g_queue_peek_nth_link (queue, n);
848
849   if (link)
850     return link->data;
851
852   return NULL;
853 }
854
855 /**
856  * g_queue_index:
857  * @queue: a #GQueue
858  * @data: the data to find.
859  * 
860  * Returns the position of the first element in @queue which contains @data.
861  * 
862  * Return value: The position of the first element in @queue which contains @data, or -1 if no element in @queue contains @data.
863  * 
864  * Since: 2.4
865  **/
866 gint
867 g_queue_index (GQueue        *queue,
868                gconstpointer  data)
869 {
870   g_return_val_if_fail (queue != NULL, -1);
871
872   return g_list_index (queue->head, data);
873 }
874
875 /**
876  * g_queue_remove:
877  * @queue: a #GQueue
878  * @data: data to remove.
879  * 
880  * Removes the first element in @queue that contains @data. 
881  * 
882  * Since: 2.4
883  **/
884 void
885 g_queue_remove (GQueue        *queue,
886                 gconstpointer  data)
887 {
888   GList *link;
889   
890   g_return_if_fail (queue != NULL);
891
892   link = g_list_find (queue->head, data);
893
894   if (link)
895     g_queue_delete_link (queue, link);
896 }
897
898 /**
899  * g_queue_remove_all:
900  * @queue: a #GQueue
901  * @data: data to remove
902  * 
903  * Remove all elemeents in @queue which contains @data.
904  * 
905  * Since: 2.4
906  **/
907 void
908 g_queue_remove_all (GQueue        *queue,
909                     gconstpointer  data)
910 {
911   GList *list;
912   
913   g_return_if_fail (queue != NULL);
914
915   list = queue->head;
916   while (list)
917     {
918       GList *next = list->next;
919
920       if (list->data == data)
921         g_queue_delete_link (queue, list);
922       
923       list = next;
924     }
925 }
926
927 /**
928  * g_queue_insert_before:
929  * @queue: a #GQueue
930  * @sibling: a #GList link that <emphasis>must</emphasis> be part of @queue
931  * @data: the data to insert
932  * 
933  * Inserts @data into @queue before @sibling.
934  *
935  * @sibling must be part of @queue.
936  * 
937  * Since: 2.4
938  **/
939 void
940 g_queue_insert_before (GQueue   *queue,
941                        GList    *sibling,
942                        gpointer  data)
943 {
944   g_return_if_fail (queue != NULL);
945   g_return_if_fail (sibling != NULL);
946
947   queue->head = g_list_insert_before (queue->head, sibling, data);
948   queue->length++;
949 }
950
951 /**
952  * g_queue_insert_after:
953  * @queue: a #GQueue
954  * @sibling: a #GList link that <emphasis>must</emphasis> be part of @queue
955  * @data: the data to insert
956  *
957  * Inserts @data into @queue after @sibling
958  *
959  * @sibling must be part of @queue
960  * 
961  * Since: 2.4
962  **/
963 void
964 g_queue_insert_after (GQueue   *queue,
965                       GList    *sibling,
966                       gpointer  data)
967 {
968   g_return_if_fail (queue != NULL);
969   g_return_if_fail (sibling != NULL);
970
971   if (sibling == queue->tail)
972     g_queue_push_tail (queue, data);
973   else
974     g_queue_insert_before (queue, sibling->next, data);
975 }
976
977 /**
978  * g_queue_insert_sorted:
979  * @queue: a #GQueue
980  * @data: the data to insert
981  * @func: the #GCompareDataFunc used to compare elements in the queue. It is
982  *     called with two elements of the @queue and @user_data. It should
983  *     return 0 if the elements are equal, a negative value if the first
984  *     element comes before the second, and a positive value if the second
985  *     element comes before the first.
986  * @user_data: user data passed to @func.
987  * 
988  * Inserts @data into @queue using @func to determine the new position.
989  * 
990  * Since: 2.4
991  **/
992 void
993 g_queue_insert_sorted (GQueue           *queue,
994                        gpointer          data,
995                        GCompareDataFunc  func,
996                        gpointer          user_data)
997 {
998   GList *list;
999   
1000   g_return_if_fail (queue != NULL);
1001
1002   list = queue->head;
1003   while (list && func (list->data, data, user_data) < 0)
1004     list = list->next;
1005
1006   if (list)
1007     g_queue_insert_before (queue, list, data);
1008   else
1009     g_queue_push_tail (queue, data);
1010 }
1011
1012 #define __G_QUEUE_C__
1013 #include "galiasdef.c"