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