diff --git a/docs/reference/glib/glib-sections.txt b/docs/reference/glib/glib-sections.txt index c8681fa2f..ff080f711 100644 --- a/docs/reference/glib/glib-sections.txt +++ b/docs/reference/glib/glib-sections.txt @@ -2851,6 +2851,7 @@ g_trash_stack_height GHashTable g_hash_table_new g_hash_table_new_full +g_hash_table_new_similar GHashFunc GEqualFunc g_hash_table_insert diff --git a/glib/ghash.c b/glib/ghash.c index 48a7db0e2..3d71643c7 100644 --- a/glib/ghash.c +++ b/glib/ghash.c @@ -1085,6 +1085,33 @@ g_hash_table_new_full (GHashFunc hash_func, return hash_table; } +/** + * g_hash_table_new_similar: + * @other_hash_table: (not nullable) (transfer none): Another #GHashTable + * + * Creates a new #GHashTable like g_hash_table_new_full() with a reference + * count of 1. + * + * It inherits the hash function, the key equal function, the key destroy function, + * as well as the value destroy function, from @other_hash_table. + * + * The returned hash table will be empty; it will not contain the keys + * or values from @other_hash_table. + * + * Returns: (transfer full) (not nullable): a new #GHashTable + * Since: 2.72 + */ +GHashTable * +g_hash_table_new_similar (GHashTable *other_hash_table) +{ + g_return_val_if_fail (other_hash_table, NULL); + + return g_hash_table_new_full (other_hash_table->hash_func, + other_hash_table->key_equal_func, + other_hash_table->key_destroy_func, + other_hash_table->value_destroy_func); +} + /** * g_hash_table_iter_init: * @iter: an uninitialized #GHashTableIter diff --git a/glib/ghash.h b/glib/ghash.h index e9ce64505..4e81d6263 100644 --- a/glib/ghash.h +++ b/glib/ghash.h @@ -61,6 +61,8 @@ GHashTable* g_hash_table_new_full (GHashFunc hash_func, GEqualFunc key_equal_func, GDestroyNotify key_destroy_func, GDestroyNotify value_destroy_func); +GLIB_AVAILABLE_IN_2_72 +GHashTable *g_hash_table_new_similar (GHashTable *other_hash_table); GLIB_AVAILABLE_IN_ALL void g_hash_table_destroy (GHashTable *hash_table); GLIB_AVAILABLE_IN_ALL diff --git a/glib/tests/hash.c b/glib/tests/hash.c index fe72606f8..fe0811aff 100644 --- a/glib/tests/hash.c +++ b/glib/tests/hash.c @@ -1345,6 +1345,49 @@ test_lookup_extended (void) g_hash_table_unref (hash); } +static void +inc_state (gpointer user_data) +{ + int *state = user_data; + g_assert_cmpint (*state, ==, 0); + *state = 1; +} + +static void +test_new_similar (void) +{ + GHashTable *hash1; + GHashTable *hash2; + int state1; + int state2; + + hash1 = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, inc_state); + state1 = 0; + g_hash_table_insert (hash1, + g_strdup ("test"), + &state1); + g_assert_true (g_hash_table_lookup (hash1, "test") == &state1); + + hash2 = g_hash_table_new_similar (hash1); + + g_assert_true (g_hash_table_lookup (hash1, "test") == &state1); + g_assert_null (g_hash_table_lookup (hash2, "test")); + + state2 = 0; + g_hash_table_insert (hash2, g_strdup ("test"), &state2); + g_assert_true (g_hash_table_lookup (hash2, "test") == &state2); + g_hash_table_remove (hash2, "test"); + g_assert_cmpint (state2, ==, 1); + + g_assert_cmpint (state1, ==, 0); + g_hash_table_remove (hash1, "test"); + g_assert_cmpint (state1, ==, 1); + + g_hash_table_unref (hash1); + g_hash_table_unref (hash2); +} + struct _GHashTable { gsize size; @@ -1685,6 +1728,7 @@ main (int argc, char *argv[]) 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/lookup-extended", test_lookup_extended); + g_test_add_func ("/hash/new-similar", test_new_similar); /* tests for individual bugs */ g_test_add_func ("/hash/lookup-null-key", test_lookup_null_key);