X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=glib%2Fgqueue.c;h=3176614204be576e403b59cd2894cfe8bd2295cb;hb=2a53b4d0e2c98a14aedf31e38f0ad1fb2e8fe26f;hp=5e5535e902956aa3b2dcb289485263521b98b089;hpb=63adeda0861a26b38ec0adc76255666554c18951;p=platform%2Fupstream%2Fglib.git diff --git a/glib/gqueue.c b/glib/gqueue.c index 5e5535e..3176614 100644 --- a/glib/gqueue.c +++ b/glib/gqueue.c @@ -15,29 +15,53 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * License along with this library; if not, see . */ /* * MT safe */ +/** + * SECTION:queue + * @Title: Double-ended Queues + * @Short_description: double-ended queue data structure + * + * The #GQueue structure and its associated functions provide a standard + * queue data structure. Internally, GQueue uses the same data structure + * as #GList to store elements. + * + * The data contained in each element can be either integer values, by + * using one of the [Type Conversion Macros][glib-Type-Conversion-Macros], + * or simply pointers to any type of data. + * + * To create a new GQueue, use g_queue_new(). + * + * To initialize a statically-allocated GQueue, use #G_QUEUE_INIT or + * g_queue_init(). + * + * To add elements, use g_queue_push_head(), g_queue_push_head_link(), + * g_queue_push_tail() and g_queue_push_tail_link(). + * + * To remove elements, use g_queue_pop_head() and g_queue_pop_tail(). + * + * To free the entire queue, use g_queue_free(). + */ #include "config.h" #include "gqueue.h" #include "gtestutils.h" +#include "gslice.h" /** * g_queue_new: * * Creates a new #GQueue. * - * Returns: a new #GQueue. + * Returns: a newly allocated #GQueue **/ -GQueue* +GQueue * g_queue_new (void) { return g_slice_new0 (GQueue); @@ -45,11 +69,14 @@ g_queue_new (void) /** * g_queue_free: - * @queue: a #GQueue. + * @queue: a #GQueue * - * Frees the memory allocated for the #GQueue. Only call this function if - * @queue was created with g_queue_new(). If queue elements contain + * Frees the memory allocated for the #GQueue. Only call this function + * if @queue was created with g_queue_new(). If queue elements contain * dynamically-allocated memory, they should be freed first. + * + * If queue elements contain dynamically-allocated memory, you should + * either use g_queue_free_full() or free them manually first. **/ void g_queue_free (GQueue *queue) @@ -61,6 +88,24 @@ g_queue_free (GQueue *queue) } /** + * g_queue_free_full: + * @queue: a pointer to a #GQueue + * @free_func: the function to be called to free each element's data + * + * Convenience method, which frees all the memory used by a #GQueue, + * and calls the specified destroy function on every element's data. + * + * Since: 2.32 + */ +void +g_queue_free_full (GQueue *queue, + GDestroyNotify free_func) +{ + g_queue_foreach (queue, (GFunc) free_func, NULL); + g_queue_free (queue); +} + +/** * g_queue_init: * @queue: an uninitialized #GQueue * @@ -70,7 +115,7 @@ g_queue_free (GQueue *queue) * g_queue_new(). * * Since: 2.14 - **/ + */ void g_queue_init (GQueue *queue) { @@ -104,8 +149,8 @@ g_queue_clear (GQueue *queue) * * Returns %TRUE if the queue is empty. * - * Returns: %TRUE if the queue is empty. - **/ + * Returns: %TRUE if the queue is empty + */ gboolean g_queue_is_empty (GQueue *queue) { @@ -120,10 +165,10 @@ g_queue_is_empty (GQueue *queue) * * Returns the number of items in @queue. * - * Return value: The number of items in @queue. + * Returns: the number of items in @queue * * Since: 2.4 - **/ + */ guint g_queue_get_length (GQueue *queue) { @@ -139,7 +184,7 @@ g_queue_get_length (GQueue *queue) * Reverses the order of the items in @queue. * * Since: 2.4 - **/ + */ void g_queue_reverse (GQueue *queue) { @@ -157,10 +202,10 @@ g_queue_reverse (GQueue *queue) * queue consist of pointers to data, the pointers are copied, but the * actual data is not. * - * Return value: A copy of @queue + * Returns: a copy of @queue * * Since: 2.4 - **/ + */ GQueue * g_queue_copy (GQueue *queue) { @@ -187,11 +232,11 @@ g_queue_copy (GQueue *queue) * function. * * Since: 2.4 - **/ + */ void g_queue_foreach (GQueue *queue, - GFunc func, - gpointer user_data) + GFunc func, + gpointer user_data) { GList *list; @@ -214,13 +259,13 @@ g_queue_foreach (GQueue *queue, * * Finds the first link in @queue which contains @data. * - * Return value: The first link in @queue which contains @data. + * Returns: the first link in @queue which contains @data * * Since: 2.4 - **/ + */ GList * g_queue_find (GQueue *queue, - gconstpointer data) + gconstpointer data) { g_return_val_if_fail (queue != NULL, NULL); @@ -232,7 +277,7 @@ g_queue_find (GQueue *queue, * @queue: a #GQueue * @data: user data passed to @func * @func: a #GCompareFunc to call for each element. It should return 0 - * when the desired element is found + * when the desired element is found * * Finds an element in a #GQueue, using a supplied function to find the * desired element. It iterates over the queue, calling the given function @@ -240,14 +285,14 @@ g_queue_find (GQueue *queue, * takes two gconstpointer arguments, the #GQueue element's data as the * first argument and the given user data as the second argument. * - * Return value: The found link, or %NULL if it wasn't found + * Returns: the found link, or %NULL if it wasn't found * * Since: 2.4 - **/ + */ GList * -g_queue_find_custom (GQueue *queue, - gconstpointer data, - GCompareFunc func) +g_queue_find_custom (GQueue *queue, + gconstpointer data, + GCompareFunc func) { g_return_val_if_fail (queue != NULL, NULL); g_return_val_if_fail (func != NULL, NULL); @@ -267,11 +312,11 @@ g_queue_find_custom (GQueue *queue, * Sorts @queue using @compare_func. * * Since: 2.4 - **/ + */ void g_queue_sort (GQueue *queue, - GCompareDataFunc compare_func, - gpointer user_data) + GCompareDataFunc compare_func, + gpointer user_data) { g_return_if_fail (queue != NULL); g_return_if_fail (compare_func != NULL); @@ -286,10 +331,10 @@ g_queue_sort (GQueue *queue, * @data: the data for the new element. * * Adds a new element at the head of the queue. - **/ + */ void -g_queue_push_head (GQueue *queue, - gpointer data) +g_queue_push_head (GQueue *queue, + gpointer data) { g_return_if_fail (queue != NULL); @@ -307,14 +352,14 @@ g_queue_push_head (GQueue *queue, * larger than the number of elements in the @queue, the element is * added to the end of the queue. * - * Inserts a new element into @queue at the given position + * Inserts a new element into @queue at the given position. * * Since: 2.4 - **/ + */ void g_queue_push_nth (GQueue *queue, - gpointer data, - gint n) + gpointer data, + gint n) { g_return_if_fail (queue != NULL); @@ -329,15 +374,14 @@ g_queue_push_nth (GQueue *queue, /** * g_queue_push_head_link: - * @queue: a #GQueue. - * @link_: a single #GList element, not a list with - * more than one element. + * @queue: a #GQueue + * @link_: a single #GList element, not a list with more than one element * * Adds a new element at the head of the queue. - **/ + */ void g_queue_push_head_link (GQueue *queue, - GList *link) + GList *link) { g_return_if_fail (queue != NULL); g_return_if_fail (link != NULL); @@ -355,14 +399,14 @@ g_queue_push_head_link (GQueue *queue, /** * g_queue_push_tail: - * @queue: a #GQueue. - * @data: the data for the new element. + * @queue: a #GQueue + * @data: the data for the new element * * Adds a new element at the tail of the queue. - **/ + */ void -g_queue_push_tail (GQueue *queue, - gpointer data) +g_queue_push_tail (GQueue *queue, + gpointer data) { g_return_if_fail (queue != NULL); @@ -376,15 +420,14 @@ g_queue_push_tail (GQueue *queue, /** * g_queue_push_tail_link: - * @queue: a #GQueue. - * @link_: a single #GList element, not a list with - * more than one element. + * @queue: a #GQueue + * @link_: a single #GList element, not a list with more than one element * * Adds a new element at the tail of the queue. - **/ + */ void g_queue_push_tail_link (GQueue *queue, - GList *link) + GList *link) { g_return_if_fail (queue != NULL); g_return_if_fail (link != NULL); @@ -411,11 +454,11 @@ g_queue_push_tail_link (GQueue *queue, * Inserts @link into @queue at the given position. * * Since: 2.4 - **/ + */ void -g_queue_push_nth_link (GQueue *queue, - gint n, - GList *link_) +g_queue_push_nth_link (GQueue *queue, + gint n, + GList *link_) { GList *next; GList *prev; @@ -453,13 +496,13 @@ g_queue_push_nth_link (GQueue *queue, /** * g_queue_pop_head: - * @queue: a #GQueue. + * @queue: a #GQueue * - * Removes the first element of the queue. + * Removes the first element of the queue and returns its data. * - * Returns: the data of the first element in the queue, or %NULL if the queue - * is empty. - **/ + * Returns: the data of the first element in the queue, or %NULL + * if the queue is empty + */ gpointer g_queue_pop_head (GQueue *queue) { @@ -472,9 +515,9 @@ g_queue_pop_head (GQueue *queue) queue->head = node->next; if (queue->head) - queue->head->prev = NULL; + queue->head->prev = NULL; else - queue->tail = NULL; + queue->tail = NULL; g_list_free_1 (node); queue->length--; @@ -486,14 +529,14 @@ g_queue_pop_head (GQueue *queue) /** * g_queue_pop_head_link: - * @queue: a #GQueue. + * @queue: a #GQueue * - * Removes the first element of the queue. + * Removes and returns the first element of the queue. * - * Returns: the #GList element at the head of the queue, or %NULL if the queue - * is empty. - **/ -GList* + * Returns: the #GList element at the head of the queue, or %NULL + * if the queue is empty + */ +GList * g_queue_pop_head_link (GQueue *queue) { g_return_val_if_fail (queue != NULL, NULL); @@ -504,12 +547,12 @@ g_queue_pop_head_link (GQueue *queue) queue->head = node->next; if (queue->head) - { - queue->head->prev = NULL; - node->next = NULL; - } + { + queue->head->prev = NULL; + node->next = NULL; + } else - queue->tail = NULL; + queue->tail = NULL; queue->length--; return node; @@ -522,13 +565,13 @@ g_queue_pop_head_link (GQueue *queue) * g_queue_peek_head_link: * @queue: a #GQueue * - * Returns the first link in @queue + * Returns the first link in @queue. * - * Return value: the first link in @queue, or %NULL if @queue is empty + * Returns: the first link in @queue, or %NULL if @queue is empty * * Since: 2.4 - **/ -GList* + */ +GList * g_queue_peek_head_link (GQueue *queue) { g_return_val_if_fail (queue != NULL, NULL); @@ -540,13 +583,13 @@ g_queue_peek_head_link (GQueue *queue) * g_queue_peek_tail_link: * @queue: a #GQueue * - * Returns the last link @queue. + * Returns the last link in @queue. * - * Return value: the last link in @queue, or %NULL if @queue is empty + * Returns: the last link in @queue, or %NULL if @queue is empty * * Since: 2.4 - **/ -GList* + */ +GList * g_queue_peek_tail_link (GQueue *queue) { g_return_val_if_fail (queue != NULL, NULL); @@ -556,13 +599,13 @@ g_queue_peek_tail_link (GQueue *queue) /** * g_queue_pop_tail: - * @queue: a #GQueue. + * @queue: a #GQueue * - * Removes the last element of the queue. + * Removes the last element of the queue and returns its data. * - * Returns: the data of the last element in the queue, or %NULL if the queue - * is empty. - **/ + * Returns: the data of the last element in the queue, or %NULL + * if the queue is empty + */ gpointer g_queue_pop_tail (GQueue *queue) { @@ -575,9 +618,9 @@ g_queue_pop_tail (GQueue *queue) queue->tail = node->prev; if (queue->tail) - queue->tail->next = NULL; + queue->tail->next = NULL; else - queue->head = NULL; + queue->head = NULL; queue->length--; g_list_free_1 (node); @@ -590,17 +633,17 @@ g_queue_pop_tail (GQueue *queue) /** * g_queue_pop_nth: * @queue: a #GQueue - * @n: the position of the element. + * @n: the position of the element * - * Removes the @n'th element of @queue. + * Removes the @n'th element of @queue and returns its data. * - * Return value: the element's data, or %NULL if @n is off the end of @queue. + * Returns: the element's data, or %NULL if @n is off the end of @queue * * Since: 2.4 - **/ + */ gpointer g_queue_pop_nth (GQueue *queue, - guint n) + guint n) { GList *nth_link; gpointer result; @@ -620,14 +663,14 @@ g_queue_pop_nth (GQueue *queue, /** * g_queue_pop_tail_link: - * @queue: a #GQueue. + * @queue: a #GQueue * - * Removes the last element of the queue. + * Removes and returns the last element of the queue. * - * Returns: the #GList element at the tail of the queue, or %NULL if the queue - * is empty. - **/ -GList* + * Returns: the #GList element at the tail of the queue, or %NULL + * if the queue is empty + */ +GList * g_queue_pop_tail_link (GQueue *queue) { g_return_val_if_fail (queue != NULL, NULL); @@ -638,12 +681,12 @@ g_queue_pop_tail_link (GQueue *queue) queue->tail = node->prev; if (queue->tail) - { - queue->tail->next = NULL; - node->prev = NULL; - } + { + queue->tail->next = NULL; + node->prev = NULL; + } else - queue->head = NULL; + queue->head = NULL; queue->length--; return node; @@ -659,13 +702,13 @@ g_queue_pop_tail_link (GQueue *queue) * * Removes and returns the link at the given position. * - * Return value: The @n'th link, or %NULL if @n is off the end of @queue. + * Returns: the @n'th link, or %NULL if @n is off the end of @queue * * Since: 2.4 - **/ + */ GList* g_queue_pop_nth_link (GQueue *queue, - guint n) + guint n) { GList *link; @@ -687,14 +730,14 @@ g_queue_pop_nth_link (GQueue *queue, * * Returns the link at the given position * - * Return value: The link at the @n'th position, or %NULL if @n is off the - * end of the list + * Returns: the link at the @n'th position, or %NULL + * if @n is off the end of the list * * Since: 2.4 - **/ + */ GList * g_queue_peek_nth_link (GQueue *queue, - guint n) + guint n) { GList *link; gint i; @@ -710,13 +753,13 @@ g_queue_peek_nth_link (GQueue *queue, link = queue->tail; for (i = 0; i < n; ++i) - link = link->prev; + link = link->prev; } else { link = queue->head; for (i = 0; i < n; ++i) - link = link->next; + link = link->next; } return link; @@ -724,19 +767,19 @@ g_queue_peek_nth_link (GQueue *queue, /** * g_queue_link_index: - * @queue: a #Gqueue - * @link_: A #GList link + * @queue: a #GQueue + * @link_: a #GList link * * Returns the position of @link_ in @queue. * - * Return value: The position of @link_, or -1 if the link is - * not part of @queue + * Returns: the position of @link_, or -1 if the link is + * not part of @queue * * Since: 2.4 - **/ + */ gint g_queue_link_index (GQueue *queue, - GList *link_) + GList *link_) { g_return_val_if_fail (queue != NULL, -1); @@ -744,20 +787,20 @@ g_queue_link_index (GQueue *queue, } /** - * g_queue_unlink + * g_queue_unlink: * @queue: a #GQueue - * @link_: a #GList link that must be part of @queue + * @link_: a #GList link that must be part of @queue * - * Unlinks @link_ so that it will no longer be part of @queue. The link is - * not freed. + * Unlinks @link_ so that it will no longer be part of @queue. + * The link is not freed. * - * @link_ must be part of @queue, + * @link_ must be part of @queue. * * Since: 2.4 - **/ + */ void g_queue_unlink (GQueue *queue, - GList *link_) + GList *link_) { g_return_if_fail (queue != NULL); g_return_if_fail (link_ != NULL); @@ -772,17 +815,17 @@ g_queue_unlink (GQueue *queue, /** * g_queue_delete_link: * @queue: a #GQueue - * @link_: a #GList link that must be part of @queue + * @link_: a #GList link that must be part of @queue * * Removes @link_ from @queue and frees it. * * @link_ must be part of @queue. * * Since: 2.4 - **/ + */ void g_queue_delete_link (GQueue *queue, - GList *link_) + GList *link_) { g_return_if_fail (queue != NULL); g_return_if_fail (link_ != NULL); @@ -793,13 +836,13 @@ g_queue_delete_link (GQueue *queue, /** * g_queue_peek_head: - * @queue: a #GQueue. + * @queue: a #GQueue * * Returns the first element of the queue. * - * Returns: the data of the first element in the queue, or %NULL if the queue - * is empty. - **/ + * Returns: the data of the first element in the queue, or %NULL + * if the queue is empty + */ gpointer g_queue_peek_head (GQueue *queue) { @@ -810,13 +853,13 @@ g_queue_peek_head (GQueue *queue) /** * g_queue_peek_tail: - * @queue: a #GQueue. + * @queue: a #GQueue * * Returns the last element of the queue. * - * Returns: the data of the last element in the queue, or %NULL if the queue - * is empty. - **/ + * Returns: the data of the last element in the queue, or %NULL + * if the queue is empty + */ gpointer g_queue_peek_tail (GQueue *queue) { @@ -828,18 +871,18 @@ g_queue_peek_tail (GQueue *queue) /** * g_queue_peek_nth: * @queue: a #GQueue - * @n: the position of the element. + * @n: the position of the element * * Returns the @n'th element of @queue. * - * Return value: The data for the @n'th element of @queue, or %NULL if @n is - * off the end of @queue. + * Returns: the data for the @n'th element of @queue, + * or %NULL if @n is off the end of @queue * * Since: 2.4 - **/ + */ gpointer g_queue_peek_nth (GQueue *queue, - guint n) + guint n) { GList *link; @@ -856,17 +899,18 @@ g_queue_peek_nth (GQueue *queue, /** * g_queue_index: * @queue: a #GQueue - * @data: the data to find. + * @data: the data to find * * Returns the position of the first element in @queue which contains @data. * - * Return value: The position of the first element in @queue which contains @data, or -1 if no element in @queue contains @data. + * Returns: the position of the first element in @queue which + * contains @data, or -1 if no element in @queue contains @data * * Since: 2.4 - **/ + */ gint g_queue_index (GQueue *queue, - gconstpointer data) + gconstpointer data) { g_return_val_if_fail (queue != NULL, -1); @@ -876,42 +920,51 @@ g_queue_index (GQueue *queue, /** * g_queue_remove: * @queue: a #GQueue - * @data: data to remove. + * @data: the data to remove * * Removes the first element in @queue that contains @data. * + * Returns: %TRUE if @data was found and removed from @queue + * * Since: 2.4 - **/ -void + */ +gboolean g_queue_remove (GQueue *queue, - gconstpointer data) + gconstpointer data) { GList *link; - g_return_if_fail (queue != NULL); + g_return_val_if_fail (queue != NULL, FALSE); link = g_list_find (queue->head, data); if (link) g_queue_delete_link (queue, link); + + return (link != NULL); } /** * g_queue_remove_all: * @queue: a #GQueue - * @data: data to remove + * @data: the data to remove * - * Remove all elemeents in @queue which contains @data. + * Remove all elements whose data equals @data from @queue. * + * Returns: the number of elements removed from @queue + * * Since: 2.4 - **/ -void + */ +guint g_queue_remove_all (GQueue *queue, - gconstpointer data) + gconstpointer data) { GList *list; + guint old_length; - g_return_if_fail (queue != NULL); + g_return_val_if_fail (queue != NULL, 0); + + old_length = queue->length; list = queue->head; while (list) @@ -919,58 +972,73 @@ g_queue_remove_all (GQueue *queue, GList *next = list->next; if (list->data == data) - g_queue_delete_link (queue, list); + g_queue_delete_link (queue, list); list = next; } + + return (old_length - queue->length); } /** * g_queue_insert_before: * @queue: a #GQueue - * @sibling: a #GList link that must be part of @queue + * @sibling: (nullable): a #GList link that must be part of @queue, or %NULL to + * push at the tail of the queue. * @data: the data to insert * * Inserts @data into @queue before @sibling. * - * @sibling must be part of @queue. + * @sibling must be part of @queue. Since GLib 2.44 a %NULL sibling pushes the + * data at the tail of the queue. * * Since: 2.4 - **/ + */ void g_queue_insert_before (GQueue *queue, - GList *sibling, - gpointer data) + GList *sibling, + gpointer data) { g_return_if_fail (queue != NULL); - g_return_if_fail (sibling != NULL); - queue->head = g_list_insert_before (queue->head, sibling, data); - queue->length++; + if (sibling == NULL) + { + /* We don't use g_list_insert_before() with a NULL sibling because it + * would be a O(n) operation and we would need to update manually the tail + * pointer. + */ + g_queue_push_tail (queue, data); + } + else + { + queue->head = g_list_insert_before (queue->head, sibling, data); + queue->length++; + } } /** * g_queue_insert_after: * @queue: a #GQueue - * @sibling: a #GList link that must be part of @queue + * @sibling: (nullable): a #GList link that must be part of @queue, or %NULL to + * push at the head of the queue. * @data: the data to insert * - * Inserts @data into @queue after @sibling + * Inserts @data into @queue after @sibling. * - * @sibling must be part of @queue + * @sibling must be part of @queue. Since GLib 2.44 a %NULL sibling pushes the + * data at the head of the queue. * * Since: 2.4 - **/ + */ void g_queue_insert_after (GQueue *queue, - GList *sibling, - gpointer data) + GList *sibling, + gpointer data) { g_return_if_fail (queue != NULL); - g_return_if_fail (sibling != NULL); - if (sibling == queue->tail) - g_queue_push_tail (queue, data); + if (sibling == NULL) + g_queue_push_head (queue, data); else g_queue_insert_before (queue, sibling->next, data); } @@ -984,17 +1052,17 @@ g_queue_insert_after (GQueue *queue, * return 0 if the elements are equal, a negative value if the first * element comes before the second, and a positive value if the second * element comes before the first. - * @user_data: user data passed to @func. + * @user_data: user data passed to @func * * Inserts @data into @queue using @func to determine the new position. * * Since: 2.4 - **/ + */ void g_queue_insert_sorted (GQueue *queue, - gpointer data, - GCompareDataFunc func, - gpointer user_data) + gpointer data, + GCompareDataFunc func, + gpointer user_data) { GList *list; @@ -1004,8 +1072,5 @@ g_queue_insert_sorted (GQueue *queue, while (list && func (list->data, data, user_data) < 0) list = list->next; - if (list) - g_queue_insert_before (queue, list, data); - else - g_queue_push_tail (queue, data); + g_queue_insert_before (queue, list, data); }