[glib: 4/5] Adding g_ptr_array_extend_and_steal() function to glib/garray.c



commit 0675703af08d69e2edab545bb8fa97d5cf049d42
Author: Emmanuel Fleury <emmanuel fleury u-bordeaux fr>
Date:   Wed Jun 19 12:42:08 2019 +0200

    Adding g_ptr_array_extend_and_steal() function to glib/garray.c

 docs/reference/glib/glib-sections.txt |  1 +
 glib/garray.c                         | 32 +++++++++++++++++++
 glib/garray.h                         |  3 ++
 glib/tests/array-test.c               | 58 +++++++++++++++++++++++++++++++++++
 4 files changed, 94 insertions(+)
---
diff --git a/docs/reference/glib/glib-sections.txt b/docs/reference/glib/glib-sections.txt
index a408dc238..058000e16 100644
--- a/docs/reference/glib/glib-sections.txt
+++ b/docs/reference/glib/glib-sections.txt
@@ -2645,6 +2645,7 @@ g_ptr_array_ref
 g_ptr_array_unref
 g_ptr_array_add
 g_ptr_array_extend
+g_ptr_array_extend_and_steal
 g_ptr_array_insert
 g_ptr_array_remove
 g_ptr_array_remove_index
diff --git a/glib/garray.c b/glib/garray.c
index f81b2c2c9..2b7957a92 100644
--- a/glib/garray.c
+++ b/glib/garray.c
@@ -1589,6 +1589,38 @@ g_ptr_array_extend (GPtrArray  *array_to_extend,
   rarray_to_extend->len += array->len;
 }
 
+/**
+ * g_ptr_array_extend_and_steal:
+ * @array_to_extend: (transfer none): a #GPtrArray.
+ * @array: (transfer container): a #GPtrArray to add to the end of
+ *     @array_to_extend.
+ *
+ * Adds all the pointers in @array to the end of @array_to_extend, transferring
+ * ownership of each element from @array to @array_to_extend and modifying
+ * @array_to_extend in-place. @array is then freed.
+ *
+ * As with g_ptr_array_free(), @array will be destroyed if its reference count
+ * is 1. If its reference count is higher, it will be decremented and the
+ * length of @array set to zero.
+ *
+ * Since: 2.62
+ **/
+void
+g_ptr_array_extend_and_steal (GPtrArray  *array_to_extend,
+                              GPtrArray  *array)
+{
+  gpointer *pdata;
+
+  g_ptr_array_extend (array_to_extend, array, NULL, NULL);
+
+  /* Get rid of @array without triggering the GDestroyNotify attached
+   * to the elements moved from @array to @array_to_extend. */
+  pdata = g_steal_pointer (&array->pdata);
+  array->len = 0;
+  g_ptr_array_unref (array);
+  g_free (pdata);
+}
+
 /**
  * g_ptr_array_insert:
  * @array: a #GPtrArray
diff --git a/glib/garray.h b/glib/garray.h
index bfa586e88..e97718b74 100644
--- a/glib/garray.h
+++ b/glib/garray.h
@@ -182,6 +182,9 @@ void g_ptr_array_extend                   (GPtrArray        *array_to_extend,
                                            GPtrArray        *array,
                                            GCopyFunc         func,
                                            gpointer          user_data);
+GLIB_AVAILABLE_IN_2_62
+void g_ptr_array_extend_and_steal         (GPtrArray        *array_to_extend,
+                                           GPtrArray        *array);
 GLIB_AVAILABLE_IN_2_40
 void       g_ptr_array_insert             (GPtrArray        *array,
                                            gint              index_,
diff --git a/glib/tests/array-test.c b/glib/tests/array-test.c
index e79e7e453..217ef9274 100644
--- a/glib/tests/array-test.c
+++ b/glib/tests/array-test.c
@@ -942,6 +942,63 @@ pointer_array_extend (void)
   g_free (array_test);
 }
 
+/* Test the g_ptr_array_extend_and_steal() function */
+static void
+pointer_array_extend_and_steal (void)
+{
+  GPtrArray *ptr_array, *ptr_array2, *ptr_array3;
+  gsize i;
+  const gsize array_size = 100;
+  gsize *array_test = g_malloc (array_size * sizeof (gsize));
+
+  /* Initializing array_test */
+  for (i = 0; i < array_size; i++)
+    array_test[i] = i;
+
+  /* Testing simple extend_and_steal() */
+  ptr_array = g_ptr_array_sized_new (array_size / 2);
+  ptr_array2 = g_ptr_array_sized_new (array_size / 2);
+
+  for (i = 0; i < array_size / 2; i++)
+    {
+      g_ptr_array_add (ptr_array, &array_test[i]);
+      g_ptr_array_add (ptr_array2, &array_test[i + (array_size / 2)]);
+    }
+
+  g_ptr_array_extend_and_steal (ptr_array, ptr_array2);
+
+  for (i = 0; i < array_size; i++)
+    g_assert_cmpuint (*((gsize *) g_ptr_array_index (ptr_array, i)), ==, i);
+
+  g_ptr_array_free (ptr_array, TRUE);
+
+  /* Testing extend_and_steal() with a pending reference to stolen array */
+  ptr_array = g_ptr_array_sized_new (array_size / 2);
+  ptr_array2 = g_ptr_array_sized_new (array_size / 2);
+
+  for (i = 0; i < array_size / 2; i++)
+    {
+      g_ptr_array_add (ptr_array, &array_test[i]);
+      g_ptr_array_add (ptr_array2, &array_test[i + (array_size / 2)]);
+    }
+
+  ptr_array3 = g_ptr_array_ref (ptr_array2);
+
+  g_ptr_array_extend_and_steal (ptr_array, ptr_array2);
+
+  for (i = 0; i < array_size; i++)
+    g_assert_cmpuint (*((gsize *) g_ptr_array_index (ptr_array, i)), ==, i);
+
+  g_assert_cmpuint (ptr_array3->len, ==, 0);
+  g_assert_null (ptr_array3->pdata);
+
+  g_ptr_array_free (ptr_array, TRUE);
+  g_ptr_array_free (ptr_array3, TRUE);
+
+  /* Final memory clean-up */
+  g_free (array_test);
+}
+
 static gint
 ptr_compare (gconstpointer p1, gconstpointer p2)
 {
@@ -1460,6 +1517,7 @@ main (int argc, char *argv[])
   g_test_add_func ("/pointerarray/free-func", pointer_array_free_func);
   g_test_add_func ("/pointerarray/array_copy", pointer_array_copy);
   g_test_add_func ("/pointerarray/array_extend", pointer_array_extend);
+  g_test_add_func ("/pointerarray/array_extend_and_steal", pointer_array_extend_and_steal);
   g_test_add_func ("/pointerarray/sort", pointer_array_sort);
   g_test_add_func ("/pointerarray/sort-with-data", pointer_array_sort_with_data);
   g_test_add_func ("/pointerarray/find/empty", pointer_array_find_empty);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]