[glib: 2/5] Adding g_ptr_array_copy() function to glib/garray.c
- From: Philip Withnall <pwithnall src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib: 2/5] Adding g_ptr_array_copy() function to glib/garray.c
- Date: Thu, 27 Jun 2019 11:12:02 +0000 (UTC)
commit 86bcc5c94295d4af4b4830f0c7b4ba30acdbfc84
Author: Emmanuel Fleury <emmanuel fleury u-bordeaux fr>
Date: Wed Jun 19 12:36:06 2019 +0200
Adding g_ptr_array_copy() function to glib/garray.c
Related to issue #269
docs/reference/glib/glib-sections.txt | 1 +
glib/garray.c | 46 ++++++++++++++++++++
glib/garray.h | 4 ++
glib/tests/array-test.c | 81 ++++++++++++++++++++++++++++++++++-
4 files changed, 131 insertions(+), 1 deletion(-)
---
diff --git a/docs/reference/glib/glib-sections.txt b/docs/reference/glib/glib-sections.txt
index 888886aba..0be2e5244 100644
--- a/docs/reference/glib/glib-sections.txt
+++ b/docs/reference/glib/glib-sections.txt
@@ -2638,6 +2638,7 @@ GPtrArray
g_ptr_array_new
g_ptr_array_sized_new
g_ptr_array_new_with_free_func
+g_ptr_array_copy
g_ptr_array_new_full
g_ptr_array_set_free_func
g_ptr_array_ref
diff --git a/glib/garray.c b/glib/garray.c
index 84c816da6..b4773721a 100644
--- a/glib/garray.c
+++ b/glib/garray.c
@@ -922,6 +922,52 @@ g_ptr_array_new (void)
return g_ptr_array_sized_new (0);
}
+/**
+ * g_ptr_array_copy:
+ * @array: #GPtrArray to duplicate
+ * @func: (nullable): a copy function used to copy every element in the array
+ * @user_data: user data passed to the copy function @func, or %NULL
+ *
+ * Makes a full (deep) copy of a #GPtrArray.
+ *
+ * @func, as a #GCopyFunc, takes two arguments, the data to be copied
+ * and a @user_data pointer. On common processor architectures, it's safe to
+ * pass %NULL as @user_data if the copy function takes only one argument. You
+ * may get compiler warnings from this though if compiling with GCC’s
+ * `-Wcast-function-type` warning.
+ *
+ * If @func is %NULL, then only the pointers (and not what they are
+ * pointing to) are copied to the new #GPtrArray.
+ *
+ * Returns: (transfer full): a deep copy of the initial #GPtrArray.
+ *
+ * Since: 2.62
+ **/
+GPtrArray *
+g_ptr_array_copy (GPtrArray *array,
+ GCopyFunc func,
+ gpointer user_data)
+{
+ gsize i;
+ GPtrArray *new_array;
+
+ g_return_val_if_fail (array != NULL, NULL);
+
+ new_array = g_ptr_array_sized_new (array->len);
+ if (func != NULL)
+ {
+ for (i = 0; i < array->len; i++)
+ new_array->pdata[i] = func (array->pdata[i], user_data);
+ }
+ else
+ {
+ memcpy (new_array->pdata, array->pdata,
+ array->len * sizeof (*array->pdata));
+ }
+
+ return new_array;
+}
+
/**
* g_ptr_array_sized_new:
* @reserved_size: number of pointers preallocated
diff --git a/glib/garray.h b/glib/garray.h
index 6c8c2c363..a92c7cd66 100644
--- a/glib/garray.h
+++ b/glib/garray.h
@@ -130,6 +130,10 @@ GLIB_AVAILABLE_IN_ALL
GPtrArray* g_ptr_array_new (void);
GLIB_AVAILABLE_IN_ALL
GPtrArray* g_ptr_array_new_with_free_func (GDestroyNotify element_free_func);
+GLIB_AVAILABLE_IN_2_62
+GPtrArray *g_ptr_array_copy (GPtrArray *array,
+ GCopyFunc func,
+ gpointer user_data);
GLIB_AVAILABLE_IN_ALL
GPtrArray* g_ptr_array_sized_new (guint reserved_size);
GLIB_AVAILABLE_IN_ALL
diff --git a/glib/tests/array-test.c b/glib/tests/array-test.c
index e0a6109eb..a07ff2a28 100644
--- a/glib/tests/array-test.c
+++ b/glib/tests/array-test.c
@@ -23,7 +23,6 @@
*/
#undef G_DISABLE_ASSERT
-#undef G_LOG_DOMAIN
#include <stdio.h>
#include <stdlib.h>
@@ -746,6 +745,85 @@ pointer_array_free_func (void)
g_assert_cmpint (num_free_func_invocations, ==, 0);
}
+static gpointer
+ptr_array_copy_func (gconstpointer src, gpointer userdata)
+{
+ gsize *dst = g_malloc (sizeof (gsize));
+ *dst = *((gsize *) src);
+ return dst;
+}
+
+/* Test the g_ptr_array_copy() function */
+static void
+pointer_array_copy (void)
+{
+ GPtrArray *ptr_array, *ptr_array2;
+ gsize i;
+ const gsize array_size = 100;
+ gsize *array_test = g_malloc (array_size * sizeof (gsize));
+
+ g_test_summary ("Check all normal behaviour of stealing elements from one "
+ "array to append to another, covering different array sizes "
+ "and element copy functions");
+
+ if (g_test_undefined ())
+ {
+ /* Testing degenerated cases */
+ g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
+ "*assertion*!= NULL*");
+ ptr_array = g_ptr_array_copy (NULL, NULL, NULL);
+ g_test_assert_expected_messages ();
+ g_assert_cmpuint ((gsize) ptr_array, ==, (gsize) NULL);
+ }
+
+ /* Initializing array_test */
+ for (i = 0; i < array_size; i++)
+ array_test[i] = i;
+
+ /* Test copy an empty array */
+ ptr_array = g_ptr_array_sized_new (0);
+ ptr_array2 = g_ptr_array_copy (ptr_array, NULL, NULL);
+
+ g_ptr_array_unref (ptr_array);
+ g_ptr_array_unref (ptr_array2);
+
+ /* Test simple copy */
+ ptr_array = g_ptr_array_sized_new (array_size);
+
+ for (i = 0; i < array_size; i++)
+ g_ptr_array_add (ptr_array, &array_test[i]);
+
+ ptr_array2 = g_ptr_array_copy (ptr_array, NULL, NULL);
+
+ for (i = 0; i < array_size; i++)
+ g_assert_cmpuint (*((gsize *) g_ptr_array_index (ptr_array2, i)), ==, i);
+
+ for (i = 0; i < array_size; i++)
+ g_assert_cmpuint ((gsize) g_ptr_array_index (ptr_array, i), ==,
+ (gsize) g_ptr_array_index (ptr_array2, i));
+
+ g_ptr_array_free (ptr_array2, TRUE);
+
+ /* Test copy through GCopyFunc */
+ ptr_array2 = g_ptr_array_copy (ptr_array, ptr_array_copy_func, NULL);
+
+ for (i = 0; i < array_size; i++)
+ g_assert_cmpuint (*((gsize *) g_ptr_array_index (ptr_array2, i)), ==, i);
+
+ for (i = 0; i < array_size; i++)
+ g_assert_cmpuint ((gsize) g_ptr_array_index (ptr_array, i), !=,
+ (gsize) g_ptr_array_index (ptr_array2, i));
+
+ for (i = 0; i < array_size; i++)
+ free(ptr_array2->pdata[i]);
+
+ g_ptr_array_free (ptr_array2, TRUE);
+
+ /* Final cleanup */
+ g_ptr_array_free (ptr_array, TRUE);
+ g_free (array_test);
+}
+
static gint
ptr_compare (gconstpointer p1, gconstpointer p2)
{
@@ -1262,6 +1340,7 @@ main (int argc, char *argv[])
g_test_add_func ("/pointerarray/insert", pointer_array_insert);
g_test_add_func ("/pointerarray/ref-count", pointer_array_ref_count);
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/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]