Merge branch 'ghash-keys+values-arrays' into 'main'

ghash: Add APIs to get (and steal) hash table keys and values as GPtrArray

See merge request GNOME/glib!3130
This commit is contained in:
Philip Withnall 2022-12-16 18:32:10 +00:00
commit abd76e0286
11 changed files with 394 additions and 84 deletions

View File

@ -2578,13 +2578,17 @@ GHFunc
g_hash_table_remove
g_hash_table_steal
g_hash_table_steal_extended
g_hash_table_steal_all_keys
g_hash_table_steal_all_values
g_hash_table_foreach_remove
g_hash_table_foreach_steal
g_hash_table_remove_all
g_hash_table_steal_all
g_hash_table_get_keys
g_hash_table_get_values
g_hash_table_get_values_as_ptr_array
g_hash_table_get_keys_as_array
g_hash_table_get_keys_as_ptr_array
GHRFunc
g_hash_table_freeze
g_hash_table_thaw

View File

@ -317,6 +317,12 @@ print_paths (GDBusConnection *c,
;
}
static gint
ptr_strcmp0 (const gchar **a, const gchar **b)
{
return g_strcmp0 (*a, *b);
}
static void
print_names (GDBusConnection *c,
gboolean include_unique_names)
@ -326,8 +332,7 @@ print_names (GDBusConnection *c,
GVariantIter *iter;
gchar *str;
GHashTable *name_set;
GList *keys;
GList *l;
GPtrArray *keys;
name_set = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
@ -379,17 +384,17 @@ print_names (GDBusConnection *c,
g_variant_iter_free (iter);
g_variant_unref (result);
keys = g_hash_table_get_keys (name_set);
keys = g_list_sort (keys, (GCompareFunc) g_strcmp0);
for (l = keys; l != NULL; l = l->next)
keys = g_hash_table_steal_all_keys (name_set);
g_ptr_array_sort (keys, (GCompareFunc) ptr_strcmp0);
for (guint i = 0; i < keys->len; ++i)
{
const gchar *name = l->data;
const gchar *name = g_ptr_array_index (keys, i);
if (!include_unique_names && g_str_has_prefix (name, ":"))
continue;
g_print ("%s \n", name);
}
g_list_free (keys);
g_clear_pointer (&keys, g_ptr_array_unref);
out:
g_hash_table_unref (name_set);

View File

@ -130,24 +130,22 @@ is_valid_unix (const gchar *address_entry,
GError **error)
{
gboolean ret;
GList *keys;
GList *l;
GPtrArray *keys;
const gchar *path;
const gchar *dir;
const gchar *tmpdir;
const gchar *abstract;
ret = FALSE;
keys = NULL;
path = NULL;
dir = NULL;
tmpdir = NULL;
abstract = NULL;
keys = g_hash_table_get_keys (key_value_pairs);
for (l = keys; l != NULL; l = l->next)
keys = g_hash_table_get_keys_as_ptr_array (key_value_pairs);
for (guint i = 0; i < keys->len; ++i)
{
const gchar *key = l->data;
const gchar *key = g_ptr_array_index (keys, i);
if (g_strcmp0 (key, "path") == 0)
path = g_hash_table_lookup (key_value_pairs, key);
else if (g_strcmp0 (key, "dir") == 0)
@ -191,7 +189,7 @@ is_valid_unix (const gchar *address_entry,
ret = TRUE;
out:
g_list_free (keys);
g_ptr_array_unref (keys);
return ret;
}
@ -202,8 +200,7 @@ is_valid_nonce_tcp (const gchar *address_entry,
GError **error)
{
gboolean ret;
GList *keys;
GList *l;
GPtrArray *keys;
const gchar *host;
const gchar *port;
const gchar *family;
@ -212,16 +209,15 @@ is_valid_nonce_tcp (const gchar *address_entry,
gchar *endp;
ret = FALSE;
keys = NULL;
host = NULL;
port = NULL;
family = NULL;
nonce_file = NULL;
keys = g_hash_table_get_keys (key_value_pairs);
for (l = keys; l != NULL; l = l->next)
keys = g_hash_table_get_keys_as_ptr_array (key_value_pairs);
for (guint i = 0; i < keys->len; ++i)
{
const gchar *key = l->data;
const gchar *key = g_ptr_array_index (keys, i);
if (g_strcmp0 (key, "host") == 0)
host = g_hash_table_lookup (key_value_pairs, key);
else if (g_strcmp0 (key, "port") == 0)
@ -284,7 +280,7 @@ is_valid_nonce_tcp (const gchar *address_entry,
ret = TRUE;
out:
g_list_free (keys);
g_ptr_array_unref (keys);
return ret;
}
@ -295,8 +291,7 @@ is_valid_tcp (const gchar *address_entry,
GError **error)
{
gboolean ret;
GList *keys;
GList *l;
GPtrArray *keys;
const gchar *host;
const gchar *port;
const gchar *family;
@ -304,15 +299,14 @@ is_valid_tcp (const gchar *address_entry,
gchar *endp;
ret = FALSE;
keys = NULL;
host = NULL;
port = NULL;
family = NULL;
keys = g_hash_table_get_keys (key_value_pairs);
for (l = keys; l != NULL; l = l->next)
keys = g_hash_table_get_keys_as_ptr_array (key_value_pairs);
for (guint i = 0; i < keys->len; ++i)
{
const gchar *key = l->data;
const gchar *key = g_ptr_array_index (keys, i);
if (g_strcmp0 (key, "host") == 0)
host = g_hash_table_lookup (key_value_pairs, key);
else if (g_strcmp0 (key, "port") == 0)
@ -363,7 +357,7 @@ is_valid_tcp (const gchar *address_entry,
ret= TRUE;
out:
g_list_free (keys);
g_ptr_array_unref (keys);
return ret;
}

View File

@ -4870,8 +4870,6 @@ g_dbus_connection_list_registered_unlocked (GDBusConnection *connection,
const gchar *object_path;
gsize path_len;
GHashTable *set;
GList *keys;
GList *l;
CONNECTION_ENSURE_LOCK (connection);
@ -4889,12 +4887,8 @@ g_dbus_connection_list_registered_unlocked (GDBusConnection *connection,
while (g_hash_table_iter_next (&hash_iter, (gpointer) &object_path, NULL))
maybe_add_path (path, path_len, object_path, set);
p = g_ptr_array_new ();
keys = g_hash_table_get_keys (set);
for (l = keys; l != NULL; l = l->next)
g_ptr_array_add (p, l->data);
p = g_hash_table_steal_all_keys (set);
g_hash_table_unref (set);
g_list_free (keys);
g_ptr_array_add (p, NULL);
ret = (gchar **) g_ptr_array_free (p, FALSE);

View File

@ -1087,29 +1087,13 @@ handle_list_names (_GFreedesktopDBus *object,
{
GDBusDaemon *daemon = G_DBUS_DAEMON (object);
GPtrArray *array;
GList *clients, *names, *l;
GPtrArray *clients, *names;
array = g_ptr_array_new ();
clients = g_hash_table_get_values_as_ptr_array (daemon->clients);
array = g_steal_pointer (&clients);
clients = g_hash_table_get_values (daemon->clients);
for (l = clients; l != NULL; l = l->next)
{
Client *client = l->data;
g_ptr_array_add (array, client->id);
}
g_list_free (clients);
names = g_hash_table_get_values (daemon->names);
for (l = names; l != NULL; l = l->next)
{
Name *name = l->data;
g_ptr_array_add (array, name->name);
}
g_list_free (names);
names = g_hash_table_get_values_as_ptr_array (daemon->names);
g_ptr_array_extend_and_steal (array, g_steal_pointer (&names));
g_ptr_array_add (array, NULL);

View File

@ -1094,24 +1094,27 @@ g_dbus_message_set_header (GDBusMessage *message,
guchar *
g_dbus_message_get_header_fields (GDBusMessage *message)
{
GList *keys;
guchar *ret;
guint num_keys;
GList *l;
guint n;
GPtrArray *keys;
GArray *array;
g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
keys = g_hash_table_get_keys (message->headers);
num_keys = g_list_length (keys);
ret = g_new (guchar, num_keys + 1);
for (l = keys, n = 0; l != NULL; l = l->next, n++)
ret[n] = GPOINTER_TO_UINT (l->data);
g_assert (n == num_keys);
ret[n] = G_DBUS_MESSAGE_HEADER_FIELD_INVALID;
g_list_free (keys);
keys = g_hash_table_get_keys_as_ptr_array (message->headers);
array = g_array_sized_new (FALSE, FALSE, sizeof (guchar), keys->len + 1);
return ret;
for (guint i = 0; i < keys->len; ++i)
{
guchar val = GPOINTER_TO_UINT (g_ptr_array_index (keys, i));
g_array_append_val (array, val);
}
g_assert (array->len == keys->len);
g_clear_pointer (&keys, g_ptr_array_unref);
guchar invalid_field = G_DBUS_MESSAGE_HEADER_FIELD_INVALID;
g_array_append_val (array, invalid_field);
return (guchar *) g_array_free (array, FALSE);
}
/* ---------------------------------------------------------------------------------------------------- */

View File

@ -1355,13 +1355,11 @@ on_notify_g_name_owner (GObject *object,
if (g_strcmp0 (old_name_owner, new_name_owner) != 0)
{
GList *l;
GList *proxies;
GPtrArray *proxies;
/* remote manager changed; nuke all local proxies */
proxies = g_hash_table_get_values (manager->priv->map_object_path_to_object_proxy);
g_list_foreach (proxies, (GFunc) g_object_ref, NULL);
g_hash_table_remove_all (manager->priv->map_object_path_to_object_proxy);
proxies = g_hash_table_steal_all_values (
manager->priv->map_object_path_to_object_proxy);
g_mutex_unlock (&manager->priv->lock);
@ -1371,12 +1369,13 @@ on_notify_g_name_owner (GObject *object,
*/
g_object_notify (G_OBJECT (manager), "name-owner");
for (l = proxies; l != NULL; l = l->next)
for (guint i = 0; i < proxies->len; ++i)
{
GDBusObjectProxy *object_proxy = G_DBUS_OBJECT_PROXY (l->data);
GDBusObjectProxy *object_proxy =
G_DBUS_OBJECT_PROXY (g_ptr_array_index (proxies, i));
g_signal_emit_by_name (manager, "object-removed", object_proxy);
}
g_list_free_full (proxies, g_object_unref);
g_clear_pointer (&proxies, g_ptr_array_unref);
/* nuke local filter */
maybe_unsubscribe_signals (manager);

View File

@ -473,17 +473,21 @@ g_dbus_object_skeleton_get_interfaces (GDBusObject *_object)
void
g_dbus_object_skeleton_flush (GDBusObjectSkeleton *object)
{
GList *to_flush, *l;
GPtrArray *to_flush;
g_mutex_lock (&object->priv->lock);
to_flush = g_hash_table_get_values (object->priv->map_name_to_iface);
g_list_foreach (to_flush, (GFunc) g_object_ref, NULL);
to_flush = g_hash_table_get_values_as_ptr_array (object->priv->map_name_to_iface);
g_ptr_array_foreach (to_flush, (GFunc) g_object_ref, NULL);
g_ptr_array_set_free_func (to_flush, g_object_unref);
g_mutex_unlock (&object->priv->lock);
for (l = to_flush; l != NULL; l = l->next)
g_dbus_interface_skeleton_flush (G_DBUS_INTERFACE_SKELETON (l->data));
for (guint i = 0; i < to_flush->len; ++i)
{
g_dbus_interface_skeleton_flush (
G_DBUS_INTERFACE_SKELETON (g_ptr_array_index (to_flush, i)));
}
g_list_free_full (to_flush, g_object_unref);
g_clear_pointer (&to_flush, g_ptr_array_unref);
}
static void

View File

@ -1942,6 +1942,80 @@ g_hash_table_steal_all (GHashTable *hash_table)
g_hash_table_maybe_resize (hash_table);
}
/**
* g_hash_table_steal_all_keys: (skip)
* @hash_table: a #GHashTable
*
* Removes all keys and their associated values from a #GHashTable
* without calling the key destroy functions, returning the keys
* as a #GPtrArray with the free func set to the @hash_table key
* destroy function.
*
* Returns: (transfer container): a #GPtrArray containing each key of
* the table. Unref with with g_ptr_array_unref() when done.
*
* Since: 2.76
*/
GPtrArray *
g_hash_table_steal_all_keys (GHashTable *hash_table)
{
GPtrArray *array;
GDestroyNotify key_destroy_func;
g_return_val_if_fail (hash_table != NULL, NULL);
array = g_hash_table_get_keys_as_ptr_array (hash_table);
/* Ignore the key destroy notify calls during removal, and use it for the
* array elements instead, but restore it after the hash table has been
* cleared, so that newly added keys will continue using it.
*/
key_destroy_func = g_steal_pointer (&hash_table->key_destroy_func);
g_ptr_array_set_free_func (array, key_destroy_func);
g_hash_table_remove_all (hash_table);
hash_table->key_destroy_func = g_steal_pointer (&key_destroy_func);
return array;
}
/**
* g_hash_table_steal_all_values: (skip)
* @hash_table: a #GHashTable
*
* Removes all keys and their associated values from a #GHashTable
* without calling the value destroy functions, returning the values
* as a #GPtrArray with the free func set to the @hash_table value
* destroy function.
*
* Returns: (transfer container): a #GPtrArray containing each value of
* the table. Unref with with g_ptr_array_unref() when done.
*
* Since: 2.76
*/
GPtrArray *
g_hash_table_steal_all_values (GHashTable *hash_table)
{
GPtrArray *array;
GDestroyNotify value_destroy_func;
g_return_val_if_fail (hash_table != NULL, NULL);
array = g_hash_table_get_values_as_ptr_array (hash_table);
/* Ignore the value destroy notify calls during removal, and use it for the
* array elements instead, but restore it after the hash table has been
* cleared, so that newly added values will continue using it.
*/
value_destroy_func = g_steal_pointer (&hash_table->value_destroy_func);
g_ptr_array_set_free_func (array, value_destroy_func);
g_hash_table_remove_all (hash_table);
hash_table->value_destroy_func = g_steal_pointer (&value_destroy_func);
return array;
}
/*
* g_hash_table_foreach_remove_or_steal:
* @hash_table: a #GHashTable
@ -2273,6 +2347,45 @@ g_hash_table_get_keys_as_array (GHashTable *hash_table,
return result;
}
/**
* g_hash_table_get_keys_as_ptr_array: (skip)
* @hash_table: a #GHashTable
*
* Retrieves every key inside @hash_table, as a #GPtrArray.
* The returned data is valid until changes to the hash release those keys.
*
* This iterates over every entry in the hash table to build its return value.
* To iterate over the entries in a #GHashTable more efficiently, use a
* #GHashTableIter.
*
* You should always unref the returned array with g_ptr_array_unref().
*
* Returns: (transfer container): a #GPtrArray containing each key from
* the table. Unref with with g_ptr_array_unref() when done.
*
* Since: 2.76
**/
GPtrArray *
g_hash_table_get_keys_as_ptr_array (GHashTable *hash_table)
{
GPtrArray *array;
g_return_val_if_fail (hash_table != NULL, NULL);
array = g_ptr_array_sized_new (hash_table->size);
for (gsize i = 0; i < hash_table->size; ++i)
{
if (HASH_IS_REAL (hash_table->hashes[i]))
{
g_ptr_array_add (array, g_hash_table_fetch_key_or_value (
hash_table->keys, i, hash_table->have_big_keys));
}
}
g_assert (array->len == (guint) hash_table->nnodes);
return array;
}
/**
* g_hash_table_get_values:
* @hash_table: a #GHashTable
@ -2309,6 +2422,45 @@ g_hash_table_get_values (GHashTable *hash_table)
return retval;
}
/**
* g_hash_table_get_values_as_ptr_array: (skip)
* @hash_table: a #GHashTable
*
* Retrieves every value inside @hash_table, as a #GPtrArray.
* The returned data is valid until changes to the hash release those values.
*
* This iterates over every entry in the hash table to build its return value.
* To iterate over the entries in a #GHashTable more efficiently, use a
* #GHashTableIter.
*
* You should always unref the returned array with g_ptr_array_unref().
*
* Returns: (transfer container): a #GPtrArray containing each value from
* the table. Unref with with g_ptr_array_unref() when done.
*
* Since: 2.76
**/
GPtrArray *
g_hash_table_get_values_as_ptr_array (GHashTable *hash_table)
{
GPtrArray *array;
g_return_val_if_fail (hash_table != NULL, NULL);
array = g_ptr_array_sized_new (hash_table->size);
for (gsize i = 0; i < hash_table->size; ++i)
{
if (HASH_IS_REAL (hash_table->hashes[i]))
{
g_ptr_array_add (array, g_hash_table_fetch_key_or_value (
hash_table->values, i, hash_table->have_big_values));
}
}
g_assert (array->len == (guint) hash_table->nnodes);
return array;
}
/* Hash functions.
*/

View File

@ -32,6 +32,7 @@
#endif
#include <glib/gtypes.h>
#include <glib/garray.h>
#include <glib/glist.h>
G_BEGIN_DECLS
@ -93,6 +94,10 @@ gboolean g_hash_table_steal_extended (GHashTable *hash_table,
gpointer *stolen_value);
GLIB_AVAILABLE_IN_ALL
void g_hash_table_steal_all (GHashTable *hash_table);
GLIB_AVAILABLE_IN_2_76
GPtrArray * g_hash_table_steal_all_keys (GHashTable *hash_table);
GLIB_AVAILABLE_IN_2_76
GPtrArray * g_hash_table_steal_all_values (GHashTable *hash_table);
GLIB_AVAILABLE_IN_ALL
gpointer g_hash_table_lookup (GHashTable *hash_table,
gconstpointer key);
@ -129,6 +134,11 @@ GList * g_hash_table_get_values (GHashTable *hash_table);
GLIB_AVAILABLE_IN_2_40
gpointer * g_hash_table_get_keys_as_array (GHashTable *hash_table,
guint *length);
GLIB_AVAILABLE_IN_2_76
GPtrArray * g_hash_table_get_keys_as_ptr_array (GHashTable *hash_table);
GLIB_AVAILABLE_IN_2_76
GPtrArray * g_hash_table_get_values_as_ptr_array (GHashTable *hash_table);
GLIB_AVAILABLE_IN_ALL
void g_hash_table_iter_init (GHashTableIter *iter,

View File

@ -1692,6 +1692,163 @@ test_set_to_strv (void)
g_strfreev (strv);
}
static void
test_set_get_keys_as_ptr_array (void)
{
GHashTable *set;
GPtrArray *array;
set = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
g_hash_table_add (set, g_strdup ("xyz"));
g_hash_table_add (set, g_strdup ("xyz"));
g_hash_table_add (set, g_strdup ("abc"));
array = g_hash_table_get_keys_as_ptr_array (set);
g_hash_table_steal_all (set);
g_hash_table_unref (set);
g_ptr_array_set_free_func (array, g_free);
g_assert_cmpint (array->len, ==, 2);
g_ptr_array_add (array, NULL);
g_assert_true (
g_strv_equal ((const gchar * const[]) { "xyz", "abc", NULL },
(const gchar * const*) array->pdata) ||
g_strv_equal ((const gchar * const[]) { "abc", "xyz", NULL },
(const gchar * const*) array->pdata)
);
g_clear_pointer (&array, g_ptr_array_unref);
}
static void
test_set_get_values_as_ptr_array (void)
{
GHashTable *table;
GPtrArray *array;
table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
g_hash_table_insert (table, g_strdup ("xyz"), GUINT_TO_POINTER (0));
g_hash_table_insert (table, g_strdup ("xyz"), GUINT_TO_POINTER (1));
g_hash_table_insert (table, g_strdup ("abc"), GUINT_TO_POINTER (2));
array = g_hash_table_get_values_as_ptr_array (table);
g_clear_pointer (&table, g_hash_table_unref);
g_assert_cmpint (array->len, ==, 2);
g_assert_true (g_ptr_array_find (array, GUINT_TO_POINTER (1), NULL));
g_assert_true (g_ptr_array_find (array, GUINT_TO_POINTER (2), NULL));
g_assert_true (
memcmp ((gpointer []) { GUINT_TO_POINTER (1), GUINT_TO_POINTER (2) },
array->pdata, array->len * sizeof (gpointer)) == 0 ||
memcmp ((gpointer []) { GUINT_TO_POINTER (2), GUINT_TO_POINTER (1) },
array->pdata, array->len * sizeof (gpointer)) == 0
);
g_clear_pointer (&array, g_ptr_array_unref);
}
static void
test_steal_all_keys (void)
{
GHashTable *table;
GPtrArray *array;
table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
g_hash_table_insert (table, g_strdup ("xyz"), GUINT_TO_POINTER (0));
g_hash_table_insert (table, g_strdup ("xyz"), GUINT_TO_POINTER (1));
g_hash_table_insert (table, g_strdup ("abc"), GUINT_TO_POINTER (2));
array = g_hash_table_steal_all_keys (table);
g_assert_cmpuint (g_hash_table_size (table), ==, 0);
g_hash_table_insert (table, g_strdup ("do-not-leak-me"), GUINT_TO_POINTER (5));
g_clear_pointer (&table, g_hash_table_unref);
g_assert_cmpint (array->len, ==, 2);
g_ptr_array_add (array, NULL);
g_assert_true (
g_strv_equal ((const gchar * const[]) { "xyz", "abc", NULL },
(const gchar * const*) array->pdata) ||
g_strv_equal ((const gchar * const[]) { "abc", "xyz", NULL },
(const gchar * const*) array->pdata)
);
g_clear_pointer (&array, g_ptr_array_unref);
table = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free);
g_hash_table_insert (table, GUINT_TO_POINTER (0), g_strdup ("xyz"));
g_hash_table_insert (table, GUINT_TO_POINTER (1), g_strdup ("xyz"));
g_hash_table_insert (table, GUINT_TO_POINTER (2), g_strdup ("abc"));
array = g_hash_table_steal_all_keys (table);
g_assert_cmpuint (g_hash_table_size (table), ==, 0);
g_hash_table_insert (table, GUINT_TO_POINTER (5), g_strdup ("do-not-leak-me"));
g_clear_pointer (&table, g_hash_table_unref);
g_assert_cmpint (array->len, ==, 3);
g_assert_true (g_ptr_array_find (array, GUINT_TO_POINTER (0), NULL));
g_assert_true (g_ptr_array_find (array, GUINT_TO_POINTER (1), NULL));
g_assert_true (g_ptr_array_find (array, GUINT_TO_POINTER (2), NULL));
g_clear_pointer (&array, g_ptr_array_unref);
}
static void
test_steal_all_values (void)
{
GHashTable *table;
GPtrArray *array;
table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
g_hash_table_insert (table, g_strdup ("xyz"), GUINT_TO_POINTER (0));
g_hash_table_insert (table, g_strdup ("xyz"), GUINT_TO_POINTER (1));
g_hash_table_insert (table, g_strdup ("abc"), GUINT_TO_POINTER (2));
array = g_hash_table_steal_all_values (table);
g_assert_cmpuint (g_hash_table_size (table), ==, 0);
g_hash_table_insert (table, g_strdup ("do-not-leak-me"), GUINT_TO_POINTER (5));
g_clear_pointer (&table, g_hash_table_unref);
g_assert_cmpint (array->len, ==, 2);
g_assert_true (g_ptr_array_find (array, GUINT_TO_POINTER (1), NULL));
g_assert_true (g_ptr_array_find (array, GUINT_TO_POINTER (2), NULL));
g_assert_true (
memcmp ((gpointer []) { GUINT_TO_POINTER (1), GUINT_TO_POINTER (2) },
array->pdata, array->len * sizeof (gpointer)) == 0 ||
memcmp ((gpointer []) { GUINT_TO_POINTER (2), GUINT_TO_POINTER (1) },
array->pdata, array->len * sizeof (gpointer)) == 0
);
g_clear_pointer (&array, g_ptr_array_unref);
table = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free);
g_hash_table_insert (table, GUINT_TO_POINTER (0), g_strdup ("xyz"));
g_hash_table_insert (table, GUINT_TO_POINTER (1), g_strdup ("foo"));
g_hash_table_insert (table, GUINT_TO_POINTER (2), g_strdup ("abc"));
array = g_hash_table_steal_all_values (table);
g_assert_cmpuint (g_hash_table_size (table), ==, 0);
g_hash_table_insert (table, GUINT_TO_POINTER (5), g_strdup ("do-not-leak-me"));
g_clear_pointer (&table, g_hash_table_unref);
g_assert_cmpint (array->len, ==, 3);
g_assert_true (
g_ptr_array_find_with_equal_func (array, "xyz", g_str_equal, NULL));
g_assert_true (
g_ptr_array_find_with_equal_func (array, "foo", g_str_equal, NULL));
g_assert_true (
g_ptr_array_find_with_equal_func (array, "abc", g_str_equal, NULL));
g_clear_pointer (&array, g_ptr_array_unref);
}
static gboolean
is_prime (guint p)
{
@ -1764,6 +1921,8 @@ main (int argc, char *argv[])
g_test_add_func ("/hash/foreach-steal", test_foreach_steal);
g_test_add_func ("/hash/steal-extended", test_steal_extended);
g_test_add_func ("/hash/steal-extended/optional", test_steal_extended_optional);
g_test_add_func ("/hash/steal-all-keys", test_steal_all_keys);
g_test_add_func ("/hash/steal-all-values", test_steal_all_values);
g_test_add_func ("/hash/lookup-extended", test_lookup_extended);
g_test_add_func ("/hash/new-similar", test_new_similar);
@ -1774,6 +1933,8 @@ main (int argc, char *argv[])
g_test_add_func ("/hash/iter-replace", test_iter_replace);
g_test_add_func ("/hash/set-insert-corruption", test_set_insert_corruption);
g_test_add_func ("/hash/set-to-strv", test_set_to_strv);
g_test_add_func ("/hash/get-keys-as-ptr-array", test_set_get_keys_as_ptr_array);
g_test_add_func ("/hash/get-values-as-ptr-array", test_set_get_values_as_ptr_array);
g_test_add_func ("/hash/primes", test_primes);
return g_test_run ();