diff --git a/docs/reference/glib/glib-sections.txt b/docs/reference/glib/glib-sections.txt index 5ea5b9b8f..ee1defd9e 100644 --- a/docs/reference/glib/glib-sections.txt +++ b/docs/reference/glib/glib-sections.txt @@ -2363,6 +2363,7 @@ g_queue_free_full G_QUEUE_INIT g_queue_init g_queue_clear +g_queue_clear_full g_queue_is_empty g_queue_get_length g_queue_reverse diff --git a/glib/gqueue.c b/glib/gqueue.c index 9f34790b9..76541f493 100644 --- a/glib/gqueue.c +++ b/glib/gqueue.c @@ -149,6 +149,28 @@ g_queue_clear (GQueue *queue) g_queue_init (queue); } +/** + * g_queue_clear_full: + * @queue: a pointer to a #GQueue + * @free_func: (nullable): the function to be called to free memory allocated + * + * Convenience method, which frees all the memory used by a #GQueue, + * and calls the provided @free_func on each item in the #GQueue. + * + * Since: 2.60 + */ +void +g_queue_clear_full (GQueue *queue, + GDestroyNotify free_func) +{ + g_return_if_fail (queue != NULL); + + if (free_func != NULL) + g_queue_foreach (queue, (GFunc) free_func, NULL); + + g_queue_clear (queue); +} + /** * g_queue_is_empty: * @queue: a #GQueue. diff --git a/glib/gqueue.h b/glib/gqueue.h index f81f5fb4e..2c836553b 100644 --- a/glib/gqueue.h +++ b/glib/gqueue.h @@ -82,6 +82,9 @@ GLIB_AVAILABLE_IN_ALL void g_queue_clear (GQueue *queue); GLIB_AVAILABLE_IN_ALL gboolean g_queue_is_empty (GQueue *queue); +GLIB_AVAILABLE_IN_2_60 +void g_queue_clear_full (GQueue *queue, + GDestroyNotify free_func); GLIB_AVAILABLE_IN_ALL guint g_queue_get_length (GQueue *queue); GLIB_AVAILABLE_IN_ALL diff --git a/glib/tests/queue.c b/glib/tests/queue.c index 9f4d3c2ca..46839790f 100644 --- a/glib/tests/queue.c +++ b/glib/tests/queue.c @@ -1058,6 +1058,43 @@ new_item (int x) return item; } +static void +test_clear_full (void) +{ + QueueItem *one, *two, *three, *four; + GQueue *queue; + + queue = g_queue_new (); + g_queue_push_tail (queue, one = new_item (1)); + g_queue_push_tail (queue, two = new_item (2)); + g_queue_push_tail (queue, three = new_item (3)); + g_queue_push_tail (queue, four = new_item (4)); + + g_assert_cmpint (g_queue_get_length (queue), ==, 4); + g_assert_false (one->freed); + g_assert_false (two->freed); + g_assert_false (three->freed); + g_assert_false (four->freed); + + g_queue_clear_full (queue, free_func); + + g_assert_true (one->freed); + g_assert_true (two->freed); + g_assert_true (three->freed); + g_assert_true (four->freed); + + check_integrity (queue); + + g_slice_free (QueueItem, one); + g_slice_free (QueueItem, two); + g_slice_free (QueueItem, three); + g_slice_free (QueueItem, four); + + g_assert_true (g_queue_is_empty (queue)); + + g_queue_free (queue); +} + static void test_free_full (void) { @@ -1095,6 +1132,7 @@ int main (int argc, char *argv[]) g_test_add_func ("/queue/static", test_static); g_test_add_func ("/queue/clear", test_clear); g_test_add_func ("/queue/free-full", test_free_full); + g_test_add_func ("/queue/clear-full", test_clear_full); seed = g_test_rand_int_range (0, G_MAXINT); path = g_strdup_printf ("/queue/random/seed:%u", seed);