mirror of
				https://gitlab.gnome.org/GNOME/glib.git
				synced 2025-11-04 01:58:54 +01:00 
			
		
		
		
	Merge branch 'wsign-conversion' into 'main'
gqsort: Add g_sort_array() and deprecate g_qsort_with_data() See merge request GNOME/glib!4127
This commit is contained in:
		@@ -925,11 +925,11 @@ g_array_sort (GArray       *farray,
 | 
			
		||||
 | 
			
		||||
  /* Don't use qsort as we want a guaranteed stable sort */
 | 
			
		||||
  if (array->len > 0)
 | 
			
		||||
    g_qsort_with_data (array->data,
 | 
			
		||||
                       array->len,
 | 
			
		||||
                       array->elt_size,
 | 
			
		||||
                       (GCompareDataFunc)compare_func,
 | 
			
		||||
                       NULL);
 | 
			
		||||
    g_sort_array (array->data,
 | 
			
		||||
                  array->len,
 | 
			
		||||
                  array->elt_size,
 | 
			
		||||
                  (GCompareDataFunc) compare_func,
 | 
			
		||||
                  NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -957,11 +957,11 @@ g_array_sort_with_data (GArray           *farray,
 | 
			
		||||
  g_return_if_fail (array != NULL);
 | 
			
		||||
 | 
			
		||||
  if (array->len > 0)
 | 
			
		||||
    g_qsort_with_data (array->data,
 | 
			
		||||
                       array->len,
 | 
			
		||||
                       array->elt_size,
 | 
			
		||||
                       compare_func,
 | 
			
		||||
                       user_data);
 | 
			
		||||
    g_sort_array (array->data,
 | 
			
		||||
                  array->len,
 | 
			
		||||
                  array->elt_size,
 | 
			
		||||
                  compare_func,
 | 
			
		||||
                  user_data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -2338,23 +2338,23 @@ g_ptr_array_insert (GPtrArray *array,
 | 
			
		||||
                    gpointer   data)
 | 
			
		||||
{
 | 
			
		||||
  GRealPtrArray *rarray = (GRealPtrArray *)array;
 | 
			
		||||
  guint real_index;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (rarray);
 | 
			
		||||
  g_return_if_fail (index_ >= -1);
 | 
			
		||||
  g_return_if_fail (index_ <= (gint)rarray->len);
 | 
			
		||||
  g_return_if_fail (index_ < 0 || (guint) index_ <= rarray->len);
 | 
			
		||||
 | 
			
		||||
  g_ptr_array_maybe_expand (rarray, 1u + rarray->null_terminated);
 | 
			
		||||
 | 
			
		||||
  if (index_ < 0)
 | 
			
		||||
    index_ = rarray->len;
 | 
			
		||||
  real_index = (index_ >= 0) ? (guint) index_ : rarray->len;
 | 
			
		||||
 | 
			
		||||
  if ((guint) index_ < rarray->len)
 | 
			
		||||
    memmove (&(rarray->pdata[index_ + 1]),
 | 
			
		||||
             &(rarray->pdata[index_]),
 | 
			
		||||
             (rarray->len - index_) * sizeof (gpointer));
 | 
			
		||||
  if (real_index < rarray->len)
 | 
			
		||||
    memmove (&(rarray->pdata[real_index + 1]),
 | 
			
		||||
             &(rarray->pdata[real_index]),
 | 
			
		||||
             (rarray->len - real_index) * sizeof (gpointer));
 | 
			
		||||
 | 
			
		||||
  rarray->len++;
 | 
			
		||||
  rarray->pdata[index_] = data;
 | 
			
		||||
  rarray->pdata[real_index] = data;
 | 
			
		||||
 | 
			
		||||
  ptr_array_maybe_null_terminate (rarray);
 | 
			
		||||
}
 | 
			
		||||
@@ -2413,11 +2413,11 @@ g_ptr_array_sort (GPtrArray    *array,
 | 
			
		||||
 | 
			
		||||
  /* Don't use qsort as we want a guaranteed stable sort */
 | 
			
		||||
  if (array->len > 0)
 | 
			
		||||
    g_qsort_with_data (array->pdata,
 | 
			
		||||
                       array->len,
 | 
			
		||||
                       sizeof (gpointer),
 | 
			
		||||
                       (GCompareDataFunc)compare_func,
 | 
			
		||||
                       NULL);
 | 
			
		||||
    g_sort_array (array->pdata,
 | 
			
		||||
                  array->len,
 | 
			
		||||
                  sizeof (gpointer),
 | 
			
		||||
                  (GCompareDataFunc) compare_func,
 | 
			
		||||
                  NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Please keep this doc-comment in sync with
 | 
			
		||||
@@ -2493,11 +2493,11 @@ g_ptr_array_sort_with_data (GPtrArray        *array,
 | 
			
		||||
  g_return_if_fail (array != NULL);
 | 
			
		||||
 | 
			
		||||
  if (array->len > 0)
 | 
			
		||||
    g_qsort_with_data (array->pdata,
 | 
			
		||||
                       array->len,
 | 
			
		||||
                       sizeof (gpointer),
 | 
			
		||||
                       compare_func,
 | 
			
		||||
                       user_data);
 | 
			
		||||
    g_sort_array (array->pdata,
 | 
			
		||||
                  array->len,
 | 
			
		||||
                  sizeof (gpointer),
 | 
			
		||||
                  compare_func,
 | 
			
		||||
                  user_data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline gint
 | 
			
		||||
 
 | 
			
		||||
@@ -289,10 +289,14 @@ msort_r (void *b, size_t n, size_t s, GCompareDataFunc cmp, void *arg)
 | 
			
		||||
 * @compare_func: (scope call): function to compare elements
 | 
			
		||||
 * @user_data: data to pass to @compare_func
 | 
			
		||||
 *
 | 
			
		||||
 * This is just like the standard C qsort() function, but
 | 
			
		||||
 * the comparison routine accepts a user data argument.
 | 
			
		||||
 * This is just like the standard C [`qsort()`](man:qsort(3)) function, but
 | 
			
		||||
 * the comparison routine accepts a user data argument
 | 
			
		||||
 * (like [`qsort_r()`](man:qsort_r(3))).
 | 
			
		||||
 *
 | 
			
		||||
 * This is guaranteed to be a stable sort since version 2.32.
 | 
			
		||||
 * Unlike `qsort()`, this is guaranteed to be a stable sort (since GLib 2.32).
 | 
			
		||||
 *
 | 
			
		||||
 * Deprecated: 2.82: `total_elems` is too small to represent larger arrays; use
 | 
			
		||||
 *   [func@GLib.sort_array] instead
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
g_qsort_with_data (gconstpointer    pbase,
 | 
			
		||||
@@ -301,5 +305,29 @@ g_qsort_with_data (gconstpointer    pbase,
 | 
			
		||||
                   GCompareDataFunc compare_func,
 | 
			
		||||
                   gpointer         user_data)
 | 
			
		||||
{
 | 
			
		||||
  msort_r ((gpointer)pbase, total_elems, size, compare_func, user_data);
 | 
			
		||||
  g_sort_array (pbase, total_elems, size, compare_func, user_data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_sort_array:
 | 
			
		||||
 * @array: (not nullable) (array length=n_elements): start of array to sort
 | 
			
		||||
 * @n_elements: number of elements in the array
 | 
			
		||||
 * @element_size: size of each element
 | 
			
		||||
 * @compare_func: (scope call): function to compare elements
 | 
			
		||||
 * @user_data: data to pass to @compare_func
 | 
			
		||||
 *
 | 
			
		||||
 * This is just like the standard C [`qsort()`](man:qsort(3)) function, but
 | 
			
		||||
 * the comparison routine accepts a user data argument
 | 
			
		||||
 * (like [`qsort_r()`](man:qsort_r(3))).
 | 
			
		||||
 *
 | 
			
		||||
 * Unlike `qsort()`, this is guaranteed to be a stable sort.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
g_sort_array (const void       *array,
 | 
			
		||||
              size_t            n_elements,
 | 
			
		||||
              size_t            element_size,
 | 
			
		||||
              GCompareDataFunc  compare_func,
 | 
			
		||||
              void             *user_data)
 | 
			
		||||
{
 | 
			
		||||
  msort_r ((void *) array, n_elements, element_size, compare_func, user_data);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -35,13 +35,20 @@
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
GLIB_AVAILABLE_IN_ALL
 | 
			
		||||
GLIB_DEPRECATED_IN_2_82_FOR(g_sort_array)
 | 
			
		||||
void g_qsort_with_data (gconstpointer    pbase,
 | 
			
		||||
			gint             total_elems,
 | 
			
		||||
			gsize            size,
 | 
			
		||||
			GCompareDataFunc compare_func,
 | 
			
		||||
			gpointer         user_data);
 | 
			
		||||
 | 
			
		||||
GLIB_AVAILABLE_IN_2_82
 | 
			
		||||
void g_sort_array (const void       *array,
 | 
			
		||||
                   size_t            n_elements,
 | 
			
		||||
                   size_t            element_size,
 | 
			
		||||
                   GCompareDataFunc  compare_func,
 | 
			
		||||
                   void             *user_data);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __G_QSORT_H__ */
 | 
			
		||||
 
 | 
			
		||||
@@ -40,7 +40,7 @@ test_sort_basic (void)
 | 
			
		||||
      data[i] = g_random_int_range (0, 10000);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  g_qsort_with_data (data, 10000, sizeof (int), int_compare_data, NULL);
 | 
			
		||||
  g_sort_array (data, 10000, sizeof (int), int_compare_data, NULL);
 | 
			
		||||
 | 
			
		||||
  for (i = 1; i < 10000; i++)
 | 
			
		||||
    g_assert_cmpint (data[i -1], <=, data[i]);
 | 
			
		||||
@@ -63,7 +63,7 @@ test_sort_zero_elements (void)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  /* 0 elements is a valid case */
 | 
			
		||||
  g_qsort_with_data (data, 0, sizeof (int), int_compare_data, NULL);
 | 
			
		||||
  g_sort_array (data, 0, sizeof (int), int_compare_data, NULL);
 | 
			
		||||
 | 
			
		||||
  for (i = 0; i < 100; i++)
 | 
			
		||||
    g_assert_cmpint (data[i], ==, data_copy[i]);
 | 
			
		||||
@@ -105,7 +105,7 @@ test_sort_stable (void)
 | 
			
		||||
      data[i].i = i;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  g_qsort_with_data (data, 10000, sizeof (SortItem), item_compare_data, NULL);
 | 
			
		||||
  g_sort_array (data, 10000, sizeof (SortItem), item_compare_data, NULL);
 | 
			
		||||
 | 
			
		||||
  for (i = 1; i < 10000; i++)
 | 
			
		||||
    {
 | 
			
		||||
@@ -129,7 +129,7 @@ test_sort_big (void)
 | 
			
		||||
      data[i].i = i;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  g_qsort_with_data (data, 10000, sizeof (BigItem), item_compare_data, NULL);
 | 
			
		||||
  g_sort_array (data, 10000, sizeof (BigItem), item_compare_data, NULL);
 | 
			
		||||
 | 
			
		||||
  for (i = 1; i < 10000; i++)
 | 
			
		||||
    {
 | 
			
		||||
@@ -140,6 +140,28 @@ test_sort_big (void)
 | 
			
		||||
  g_free (data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
test_sort_deprecated (void)
 | 
			
		||||
{
 | 
			
		||||
  gint *data;
 | 
			
		||||
  gint i;
 | 
			
		||||
 | 
			
		||||
  data = g_malloc (10000 * sizeof (int));
 | 
			
		||||
  for (i = 0; i < 10000; i++)
 | 
			
		||||
    {
 | 
			
		||||
      data[i] = g_random_int_range (0, 10000);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
 | 
			
		||||
  g_qsort_with_data (data, 10000, sizeof (int), int_compare_data, NULL);
 | 
			
		||||
G_GNUC_END_IGNORE_DEPRECATIONS
 | 
			
		||||
 | 
			
		||||
  for (i = 1; i < 10000; i++)
 | 
			
		||||
    g_assert_cmpint (data[i -1], <=, data[i]);
 | 
			
		||||
 | 
			
		||||
  g_free (data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
main (int argc, char *argv[])
 | 
			
		||||
{
 | 
			
		||||
@@ -149,6 +171,7 @@ main (int argc, char *argv[])
 | 
			
		||||
  g_test_add_func ("/sort/zero-elements", test_sort_zero_elements);
 | 
			
		||||
  g_test_add_func ("/sort/stable", test_sort_stable);
 | 
			
		||||
  g_test_add_func ("/sort/big", test_sort_big);
 | 
			
		||||
  g_test_add_func ("/sort/deprecated", test_sort_deprecated);
 | 
			
		||||
 | 
			
		||||
  return g_test_run ();
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -364,9 +364,9 @@ g_value_array_sort_with_data (GValueArray     *value_array,
 | 
			
		||||
  g_return_val_if_fail (compare_func != NULL, NULL);
 | 
			
		||||
 | 
			
		||||
  if (value_array->n_values)
 | 
			
		||||
    g_qsort_with_data (value_array->values,
 | 
			
		||||
		       value_array->n_values,
 | 
			
		||||
		       sizeof (value_array->values[0]),
 | 
			
		||||
		       compare_func, user_data);
 | 
			
		||||
    g_sort_array (value_array->values,
 | 
			
		||||
		  value_array->n_values,
 | 
			
		||||
		  sizeof (value_array->values[0]),
 | 
			
		||||
		  compare_func, user_data);
 | 
			
		||||
  return value_array;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -664,6 +664,52 @@ test_valuearray_basic (void)
 | 
			
		||||
  g_value_array_free (a2);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gint
 | 
			
		||||
cmpint_with_data (gconstpointer a,
 | 
			
		||||
                  gconstpointer b,
 | 
			
		||||
                  gpointer      user_data)
 | 
			
		||||
{
 | 
			
		||||
  const GValue *aa = a;
 | 
			
		||||
  const GValue *bb = b;
 | 
			
		||||
 | 
			
		||||
  g_assert_cmpuint (GPOINTER_TO_UINT (user_data), ==, 123);
 | 
			
		||||
 | 
			
		||||
  return g_value_get_int (aa) - g_value_get_int (bb);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
test_value_array_sort_with_data (void)
 | 
			
		||||
{
 | 
			
		||||
  GValueArray *a, *a2;
 | 
			
		||||
  GValue v = G_VALUE_INIT;
 | 
			
		||||
 | 
			
		||||
  a = g_value_array_new (20);
 | 
			
		||||
 | 
			
		||||
  /* Try sorting an empty array. */
 | 
			
		||||
  a2 = g_value_array_sort_with_data (a, cmpint_with_data, GUINT_TO_POINTER (456));
 | 
			
		||||
  g_assert_cmpuint (a->n_values, ==, 0);
 | 
			
		||||
  g_assert_true (a2 == a);
 | 
			
		||||
 | 
			
		||||
  /* Add some values and try sorting them. */
 | 
			
		||||
  g_value_init (&v, G_TYPE_INT);
 | 
			
		||||
  for (unsigned int i = 0; i < 100; i++)
 | 
			
		||||
    {
 | 
			
		||||
      g_value_set_int (&v, 100 - i);
 | 
			
		||||
      g_value_array_append (a, &v);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  g_assert_cmpint (a->n_values, ==, 100);
 | 
			
		||||
 | 
			
		||||
  a2 = g_value_array_sort_with_data (a, cmpint_with_data, GUINT_TO_POINTER (123));
 | 
			
		||||
 | 
			
		||||
  for (unsigned int i = 0; i < a->n_values - 1; i++)
 | 
			
		||||
    g_assert_cmpint (g_value_get_int (&a->values[i]), <=, g_value_get_int (&a->values[i+1]));
 | 
			
		||||
 | 
			
		||||
  g_assert_true (a2 == a);
 | 
			
		||||
 | 
			
		||||
  g_value_array_free (a);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* We create some dummy objects with this relationship:
 | 
			
		||||
 *
 | 
			
		||||
 *               GObject           TestInterface
 | 
			
		||||
@@ -765,6 +811,7 @@ main (int argc, char *argv[])
 | 
			
		||||
 | 
			
		||||
  g_test_add_func ("/value/basic", test_value_basic);
 | 
			
		||||
  g_test_add_func ("/value/array/basic", test_valuearray_basic);
 | 
			
		||||
  g_test_add_func ("/value/array/sort-with-data", test_value_array_sort_with_data);
 | 
			
		||||
  g_test_add_func ("/value/collection", test_collection);
 | 
			
		||||
  g_test_add_func ("/value/copying", test_copying);
 | 
			
		||||
  g_test_add_func ("/value/enum-transformation", test_enum_transformation);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user