[glib: 1/2] gio: Add g_list_store_find_with_equal_func_full()




commit a85246af3be7afd253727d811e4ce719b77e633e
Author: Jason Francis <jafrancis999 gmail com>
Date:   Sat Mar 12 22:09:29 2022 -0500

    gio: Add g_list_store_find_with_equal_func_full()
    
    Fixes: #2447

 docs/reference/gio/gio-sections-common.txt |  1 +
 docs/reference/glib/glib-sections.txt      |  1 +
 gio/gliststore.c                           | 41 ++++++++++++++++++++++++++++--
 gio/gliststore.h                           |  7 +++++
 gio/tests/glistmodel.c                     | 23 +++++++++++++++++
 glib/gtypes.h                              | 21 +++++++++++++++
 6 files changed, 92 insertions(+), 2 deletions(-)
---
diff --git a/docs/reference/gio/gio-sections-common.txt b/docs/reference/gio/gio-sections-common.txt
index 4e88a597e2..383cfd1a16 100644
--- a/docs/reference/gio/gio-sections-common.txt
+++ b/docs/reference/gio/gio-sections-common.txt
@@ -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>
diff --git a/docs/reference/glib/glib-sections.txt b/docs/reference/glib/glib-sections.txt
index 3532d28cb0..2932313cd0 100644
--- a/docs/reference/glib/glib-sections.txt
+++ b/docs/reference/glib/glib-sections.txt
@@ -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
diff --git a/gio/gliststore.c b/gio/gliststore.c
index da7d12ce57..65ff5d4e94 100644
--- a/gio/gliststore.c
+++ b/gio/gliststore.c
@@ -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);
diff --git a/gio/gliststore.h b/gio/gliststore.h
index ef3b839511..aa5a7331ce 100644
--- a/gio/gliststore.h
+++ b/gio/gliststore.h
@@ -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__ */
diff --git a/gio/tests/glistmodel.c b/gio/tests/glistmodel.c
index e50969eadf..a65c2f3b11 100644
--- a/gio/tests/glistmodel.c
+++ b/gio/tests/glistmodel.c
@@ -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);
diff --git a/glib/gtypes.h b/glib/gtypes.h
index ea2a49057a..3d8763df55 100644
--- a/glib/gtypes.h
+++ b/glib/gtypes.h
@@ -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);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]