mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-06-29 07:34:57 +02:00
ghash: Add g_hash_table_steal_extended()
This is a combination of g_hash_table_lookup_extended() and g_hash_table_steal(), so that users can combine the two to reduce code and eliminate a pointless second hash table lookup by g_hash_table_steal(). Signed-off-by: Philip Withnall <withnall@endlessm.com> https://bugzilla.gnome.org/show_bug.cgi?id=795302
This commit is contained in:
parent
864cb71524
commit
6acece5074
@ -2453,6 +2453,7 @@ g_hash_table_find
|
|||||||
GHFunc
|
GHFunc
|
||||||
g_hash_table_remove
|
g_hash_table_remove
|
||||||
g_hash_table_steal
|
g_hash_table_steal
|
||||||
|
g_hash_table_steal_extended
|
||||||
g_hash_table_foreach_remove
|
g_hash_table_foreach_remove
|
||||||
g_hash_table_foreach_steal
|
g_hash_table_foreach_steal
|
||||||
g_hash_table_remove_all
|
g_hash_table_remove_all
|
||||||
|
61
glib/ghash.c
61
glib/ghash.c
@ -1421,6 +1421,67 @@ g_hash_table_steal (GHashTable *hash_table,
|
|||||||
return g_hash_table_remove_internal (hash_table, key, FALSE);
|
return g_hash_table_remove_internal (hash_table, key, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* g_hash_table_steal_extended:
|
||||||
|
* @hash_table: a #GHashTable
|
||||||
|
* @lookup_key: the key to look up
|
||||||
|
* @stolen_key: (out) (optional) (transfer full): return location for the
|
||||||
|
* original key
|
||||||
|
* @stolen_value: (out) (optional) (nullable) (transfer full): return location
|
||||||
|
* for the value associated with the key
|
||||||
|
*
|
||||||
|
* Looks up a key in the #GHashTable, stealing the original key and the
|
||||||
|
* associated value and returning %TRUE if the key was found. If the key was
|
||||||
|
* not found, %FALSE is returned.
|
||||||
|
*
|
||||||
|
* If found, the stolen key and value are removed from the hash table without
|
||||||
|
* calling the key and value destroy functions, and ownership is transferred to
|
||||||
|
* the caller of this method; as with g_hash_table_steal().
|
||||||
|
*
|
||||||
|
* You can pass %NULL for @lookup_key, provided the hash and equal functions
|
||||||
|
* of @hash_table are %NULL-safe.
|
||||||
|
*
|
||||||
|
* Returns: %TRUE if the key was found in the #GHashTable
|
||||||
|
* Since: 2.58
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
g_hash_table_steal_extended (GHashTable *hash_table,
|
||||||
|
gconstpointer lookup_key,
|
||||||
|
gpointer *stolen_key,
|
||||||
|
gpointer *stolen_value)
|
||||||
|
{
|
||||||
|
guint node_index;
|
||||||
|
guint node_hash;
|
||||||
|
|
||||||
|
g_return_val_if_fail (hash_table != NULL, FALSE);
|
||||||
|
|
||||||
|
node_index = g_hash_table_lookup_node (hash_table, lookup_key, &node_hash);
|
||||||
|
|
||||||
|
if (!HASH_IS_REAL (hash_table->hashes[node_index]))
|
||||||
|
{
|
||||||
|
if (stolen_key != NULL)
|
||||||
|
*stolen_key = NULL;
|
||||||
|
if (stolen_value != NULL)
|
||||||
|
*stolen_value = NULL;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stolen_key != NULL)
|
||||||
|
*stolen_key = g_steal_pointer (&hash_table->keys[node_index]);
|
||||||
|
|
||||||
|
if (stolen_value != NULL)
|
||||||
|
*stolen_value = g_steal_pointer (&hash_table->values[node_index]);
|
||||||
|
|
||||||
|
g_hash_table_remove_node (hash_table, node_index, FALSE);
|
||||||
|
g_hash_table_maybe_resize (hash_table);
|
||||||
|
|
||||||
|
#ifndef G_DISABLE_ASSERT
|
||||||
|
hash_table->version++;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* g_hash_table_remove_all:
|
* g_hash_table_remove_all:
|
||||||
* @hash_table: a #GHashTable
|
* @hash_table: a #GHashTable
|
||||||
|
@ -82,6 +82,11 @@ void g_hash_table_remove_all (GHashTable *hash_table);
|
|||||||
GLIB_AVAILABLE_IN_ALL
|
GLIB_AVAILABLE_IN_ALL
|
||||||
gboolean g_hash_table_steal (GHashTable *hash_table,
|
gboolean g_hash_table_steal (GHashTable *hash_table,
|
||||||
gconstpointer key);
|
gconstpointer key);
|
||||||
|
GLIB_AVAILABLE_IN_2_58
|
||||||
|
gboolean g_hash_table_steal_extended (GHashTable *hash_table,
|
||||||
|
gconstpointer lookup_key,
|
||||||
|
gpointer *stolen_key,
|
||||||
|
gpointer *stolen_value);
|
||||||
GLIB_AVAILABLE_IN_ALL
|
GLIB_AVAILABLE_IN_ALL
|
||||||
void g_hash_table_steal_all (GHashTable *hash_table);
|
void g_hash_table_steal_all (GHashTable *hash_table);
|
||||||
GLIB_AVAILABLE_IN_ALL
|
GLIB_AVAILABLE_IN_ALL
|
||||||
|
@ -1189,6 +1189,50 @@ test_foreach_steal (void)
|
|||||||
g_hash_table_unref (hash2);
|
g_hash_table_unref (hash2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Test g_hash_table_steal_extended() works properly with existing and
|
||||||
|
* non-existing keys. */
|
||||||
|
static void
|
||||||
|
test_steal_extended (void)
|
||||||
|
{
|
||||||
|
GHashTable *hash;
|
||||||
|
gchar *stolen_key = NULL, *stolen_value = NULL;
|
||||||
|
|
||||||
|
hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
|
||||||
|
|
||||||
|
g_hash_table_insert (hash, g_strdup ("a"), g_strdup ("A"));
|
||||||
|
g_hash_table_insert (hash, g_strdup ("b"), g_strdup ("B"));
|
||||||
|
g_hash_table_insert (hash, g_strdup ("c"), g_strdup ("C"));
|
||||||
|
g_hash_table_insert (hash, g_strdup ("d"), g_strdup ("D"));
|
||||||
|
g_hash_table_insert (hash, g_strdup ("e"), g_strdup ("E"));
|
||||||
|
g_hash_table_insert (hash, g_strdup ("f"), g_strdup ("F"));
|
||||||
|
|
||||||
|
g_assert_true (g_hash_table_steal_extended (hash, "a",
|
||||||
|
(gpointer *) &stolen_key,
|
||||||
|
(gpointer *) &stolen_value));
|
||||||
|
g_assert_cmpstr (stolen_key, ==, "a");
|
||||||
|
g_assert_cmpstr (stolen_value, ==, "A");
|
||||||
|
g_clear_pointer (&stolen_key, g_free);
|
||||||
|
g_clear_pointer (&stolen_value, g_free);
|
||||||
|
|
||||||
|
g_assert_cmpuint (g_hash_table_size (hash), ==, 5);
|
||||||
|
|
||||||
|
g_assert_false (g_hash_table_steal_extended (hash, "a",
|
||||||
|
(gpointer *) &stolen_key,
|
||||||
|
(gpointer *) &stolen_value));
|
||||||
|
g_assert_null (stolen_key);
|
||||||
|
g_assert_null (stolen_value);
|
||||||
|
|
||||||
|
g_assert_false (g_hash_table_steal_extended (hash, "never a key",
|
||||||
|
(gpointer *) &stolen_key,
|
||||||
|
(gpointer *) &stolen_value));
|
||||||
|
g_assert_null (stolen_key);
|
||||||
|
g_assert_null (stolen_value);
|
||||||
|
|
||||||
|
g_assert_cmpuint (g_hash_table_size (hash), ==, 5);
|
||||||
|
|
||||||
|
g_hash_table_unref (hash);
|
||||||
|
}
|
||||||
|
|
||||||
struct _GHashTable
|
struct _GHashTable
|
||||||
{
|
{
|
||||||
gint size;
|
gint size;
|
||||||
@ -1513,6 +1557,7 @@ main (int argc, char *argv[])
|
|||||||
g_test_add_func ("/hash/find", test_find);
|
g_test_add_func ("/hash/find", test_find);
|
||||||
g_test_add_func ("/hash/foreach", test_foreach);
|
g_test_add_func ("/hash/foreach", test_foreach);
|
||||||
g_test_add_func ("/hash/foreach-steal", test_foreach_steal);
|
g_test_add_func ("/hash/foreach-steal", test_foreach_steal);
|
||||||
|
g_test_add_func ("/hash/steal-extended", test_steal_extended);
|
||||||
|
|
||||||
/* tests for individual bugs */
|
/* tests for individual bugs */
|
||||||
g_test_add_func ("/hash/lookup-null-key", test_lookup_null_key);
|
g_test_add_func ("/hash/lookup-null-key", test_lookup_null_key);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user