gio: Add g_list_store_find_with_equal_func_full()

Fixes: #2447
This commit is contained in:
Jason Francis 2022-03-12 22:09:29 -05:00 committed by Philip Withnall
parent 28add9abfe
commit a85246af3b
6 changed files with 92 additions and 2 deletions

View File

@ -4765,6 +4765,7 @@ g_list_store_splice
g_list_store_sort
g_list_store_find
g_list_store_find_with_equal_func
g_list_store_find_with_equal_func_full
<SUBSECTION Standard>
G_TYPE_LIST_STORE
<SUBSECTION Private>

View File

@ -2875,6 +2875,7 @@ g_hash_table_new_full
g_hash_table_new_similar
GHashFunc
GEqualFunc
GEqualFuncFull
g_hash_table_insert
g_hash_table_replace
g_hash_table_add

View File

@ -495,6 +495,14 @@ g_list_store_splice (GListStore *store,
g_list_store_items_changed (store, position, n_removals, n_additions);
}
static gboolean
simple_equal (gconstpointer a,
gconstpointer b,
gpointer equal_func)
{
return ((GEqualFunc) equal_func) (a, b);
}
/**
* g_list_store_find_with_equal_func:
* @store: a #GListStore
@ -503,7 +511,7 @@ g_list_store_splice (GListStore *store,
* @position: (out) (optional): the first position of @item, if it was found.
*
* Looks up the given @item in the list store by looping over the items and
* comparing them with @compare_func until the first occurrence of @item which
* comparing them with @equal_func until the first occurrence of @item which
* matches. If @item was not found, then @position will not be set, and this
* method will return %FALSE.
*
@ -517,6 +525,35 @@ g_list_store_find_with_equal_func (GListStore *store,
gpointer item,
GEqualFunc equal_func,
guint *position)
{
g_return_val_if_fail (equal_func != NULL, FALSE);
return g_list_store_find_with_equal_func_full (store, item, simple_equal,
equal_func, position);
}
/**
* g_list_store_find_with_equal_func_full:
* @store: a #GListStore
* @item: (type GObject): an item
* @equal_func: (scope call): A custom equality check function
* @user_data: (closure): user data for @equal_func
* @position: (out) (optional): the first position of @item, if it was found.
*
* Like g_list_store_find_with_equal_func() but with an additional @user_data
* that is passed to @equal_func.
*
* Returns: Whether @store contains @item. If it was found, @position will be
* set to the position where @item occurred for the first time.
*
* Since: 2.74
*/
gboolean
g_list_store_find_with_equal_func_full (GListStore *store,
gpointer item,
GEqualFuncFull equal_func,
gpointer user_data,
guint *position)
{
GSequenceIter *iter, *begin, *end;
@ -536,7 +573,7 @@ g_list_store_find_with_equal_func (GListStore *store,
gpointer iter_item;
iter_item = g_sequence_get (iter);
if (equal_func (iter_item, item))
if (equal_func (iter_item, item, user_data))
{
if (position)
*position = g_sequence_iter_get_position (iter);

View File

@ -83,6 +83,13 @@ gboolean g_list_store_find_with_equal_func (GListSt
GEqualFunc equal_func,
guint *position);
GLIB_AVAILABLE_IN_2_74
gboolean g_list_store_find_with_equal_func_full (GListStore *store,
gpointer item,
GEqualFuncFull equal_func,
gpointer user_data,
guint *position);
G_END_DECLS
#endif /* __G_LIST_STORE_H__ */

View File

@ -813,6 +813,18 @@ list_model_casecmp_action_by_name (gconstpointer a,
g_action_get_name (G_ACTION (b))) == 0;
}
static gboolean
list_model_casecmp_action_by_name_full (gconstpointer a,
gconstpointer b,
gpointer user_data)
{
char buf[4];
const char *suffix = user_data;
g_snprintf (buf, sizeof buf, "%s%s", g_action_get_name (G_ACTION (b)), suffix);
return g_strcmp0 (g_action_get_name (G_ACTION (a)), buf) == 0;
}
/* Test if find() and find_with_equal_func() works */
static void
test_store_find (void)
@ -866,6 +878,17 @@ test_store_find (void)
g_assert_cmpint (position, ==, 2);
g_clear_object (&other_item);
/* try to find element which should only work with custom equality check and string concat */
other_item = g_simple_action_new ("c", NULL);
g_assert_false (g_list_store_find (store, other_item, NULL));
g_assert_true (g_list_store_find_with_equal_func_full (store,
other_item,
list_model_casecmp_action_by_name_full,
"cc",
&position));
g_assert_cmpint (position, ==, 3);
g_clear_object (&other_item);
for (i = 0; i < G_N_ELEMENTS (item_strs); i++)
g_clear_object(&items[i]);
g_clear_object (&store);

View File

@ -110,6 +110,27 @@ typedef gint (*GCompareDataFunc) (gconstpointer a,
gpointer user_data);
typedef gboolean (*GEqualFunc) (gconstpointer a,
gconstpointer b);
/**
* GEqualFuncFull:
* @a: a value
* @b: a value to compare with
* @user_data: user data provided by the caller
*
* Specifies the type of a function used to test two values for
* equality. The function should return %TRUE if both values are equal
* and %FALSE otherwise.
*
* This is a version of #GEqualFunc which provides a @user_data closure from
* the caller.
*
* Returns: %TRUE if @a = @b; %FALSE otherwise
* Since: 2.74
*/
typedef gboolean (*GEqualFuncFull) (gconstpointer a,
gconstpointer b,
gpointer user_data);
typedef void (*GDestroyNotify) (gpointer data);
typedef void (*GFunc) (gpointer data,
gpointer user_data);