mirror of
				https://gitlab.gnome.org/GNOME/glib.git
				synced 2025-11-04 01:58:54 +01:00 
			
		
		
		
	Adding g_ptr_array_copy() function to glib/garray.c
Related to issue #269
This commit is contained in:
		@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user