[glib] garray: Add g_ptr_array_find[_with_equal_func]()



commit f6f6b3d83c2abae8aac55c59339adcee919ab6e5
Author: Philip Withnall <philip withnall collabora co uk>
Date:   Mon Apr 15 15:04:34 2013 +0200

    garray: Add g_ptr_array_find[_with_equal_func]()
    
    Partially based on telepathy-glib’s tp_g_ptr_array_contains(), and a
    patch by Xavier Claessens <xavier claessens collabora co uk>.
    
    Test cases included.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=698064

 docs/reference/glib/glib-sections.txt |    2 +
 glib/garray.c                         |   76 +++++++++++++++++++++++++++++++++
 glib/garray.h                         |    9 ++++
 glib/tests/array-test.c               |   55 ++++++++++++++++++++++++
 4 files changed, 142 insertions(+), 0 deletions(-)
---
diff --git a/docs/reference/glib/glib-sections.txt b/docs/reference/glib/glib-sections.txt
index 924d58f..ca9e414 100644
--- a/docs/reference/glib/glib-sections.txt
+++ b/docs/reference/glib/glib-sections.txt
@@ -2566,6 +2566,8 @@ g_ptr_array_set_size
 g_ptr_array_index
 g_ptr_array_free
 g_ptr_array_foreach
+g_ptr_array_find
+g_ptr_array_find_with_equal_func
 
 </SECTION>
 
diff --git a/glib/garray.c b/glib/garray.c
index ac7e580..e4a4546 100644
--- a/glib/garray.c
+++ b/glib/garray.c
@@ -34,6 +34,7 @@
 #include "garray.h"
 
 #include "gbytes.h"
+#include "ghash.h"
 #include "gslice.h"
 #include "gmem.h"
 #include "gtestutils.h"
@@ -1512,6 +1513,81 @@ g_ptr_array_foreach (GPtrArray *array,
 }
 
 /**
+ * g_ptr_array_find: (skip)
+ * @haystack: pointer array to be searched
+ * @needle: pointer to look for
+ * @index_: (optional) (out caller-allocates): return location for the index of
+ *    the element, if found
+ *
+ * Checks whether @needle exists in @haystack. If the element is found, %TRUE is
+ * returned and the element’s index is returned in @index_ (if non-%NULL).
+ * Otherwise, %FALSE is returned and @index_ is undefined. If @needle exists
+ * multiple times in @haystack, the index of the first instance is returned.
+ *
+ * This does pointer comparisons only. If you want to use more complex equality
+ * checks, such as string comparisons, use g_ptr_array_find_with_equal_func().
+ *
+ * Returns: %TRUE if @needle is one of the elements of @haystack
+ * Since: 2.54
+ */
+gboolean
+g_ptr_array_find (GPtrArray     *haystack,
+                  gconstpointer  needle,
+                  guint         *index_)
+{
+  return g_ptr_array_find_with_equal_func (haystack, needle, NULL, index_);
+}
+
+/**
+ * g_ptr_array_find_with_equal_func: (skip)
+ * @haystack: pointer array to be searched
+ * @needle: pointer to look for
+ * @equal_func: (nullable): the function to call for each element, which should
+ *    return %TRUE when the desired element is found; or %NULL to use pointer
+ *    equality
+ * @index_: (optional) (out caller-allocates): return location for the index of
+ *    the element, if found
+ *
+ * Checks whether @needle exists in @haystack, using the given @equal_func.
+ * If the element is found, %TRUE is returned and the element’s index is
+ * returned in @index_ (if non-%NULL). Otherwise, %FALSE is returned and @index_
+ * is undefined. If @needle exists multiple times in @haystack, the index of
+ * the first instance is returned.
+ *
+ * @equal_func is called with the element from the array as its first parameter,
+ * and @needle as its second parameter. If @equal_func is %NULL, pointer
+ * equality is used.
+ *
+ * Returns: %TRUE if @needle is one of the elements of @haystack
+ * Since: 2.54
+ */
+gboolean
+g_ptr_array_find_with_equal_func (GPtrArray     *haystack,
+                                  gconstpointer  needle,
+                                  GEqualFunc     equal_func,
+                                  guint         *index_)
+{
+  guint i;
+
+  g_return_val_if_fail (haystack != NULL, FALSE);
+
+  if (equal_func == NULL)
+    equal_func = g_direct_equal;
+
+  for (i = 0; i < haystack->len; i++)
+    {
+      if (equal_func (g_ptr_array_index (haystack, i), needle))
+        {
+          if (index_ != NULL)
+            *index_ = i;
+          return TRUE;
+        }
+    }
+
+  return FALSE;
+}
+
+/**
  * SECTION:arrays_byte
  * @title: Byte Arrays
  * @short_description: arrays of bytes
diff --git a/glib/garray.h b/glib/garray.h
index 35e298f..8b3b798 100644
--- a/glib/garray.h
+++ b/glib/garray.h
@@ -182,6 +182,15 @@ GLIB_AVAILABLE_IN_ALL
 void       g_ptr_array_foreach            (GPtrArray        *array,
                                           GFunc             func,
                                           gpointer          user_data);
+GLIB_AVAILABLE_IN_2_54
+gboolean   g_ptr_array_find               (GPtrArray        *haystack,
+                                           gconstpointer     needle,
+                                           guint            *index_);
+GLIB_AVAILABLE_IN_2_54
+gboolean   g_ptr_array_find_with_equal_func (GPtrArray     *haystack,
+                                             gconstpointer  needle,
+                                             GEqualFunc     equal_func,
+                                             guint         *index_);
 
 
 /* Byte arrays, an array of guint8.  Implemented as a GArray,
diff --git a/glib/tests/array-test.c b/glib/tests/array-test.c
index a0074d4..61851e0 100644
--- a/glib/tests/array-test.c
+++ b/glib/tests/array-test.c
@@ -548,6 +548,59 @@ pointer_array_sort_with_data (void)
 }
 
 static void
+pointer_array_find_empty (void)
+{
+  GPtrArray *array;
+  guint idx;
+
+  array = g_ptr_array_new ();
+
+  g_assert_false (g_ptr_array_find (array, "some-value", NULL));  /* NULL index */
+  g_assert_false (g_ptr_array_find (array, "some-value", &idx));  /* non-NULL index */
+  g_assert_false (g_ptr_array_find_with_equal_func (array, "some-value", g_str_equal, NULL));  /* NULL index 
*/
+  g_assert_false (g_ptr_array_find_with_equal_func (array, "some-value", g_str_equal, &idx));  /* NULL index 
*/
+
+  g_ptr_array_free (array, TRUE);
+}
+
+static void
+pointer_array_find_non_empty (void)
+{
+  GPtrArray *array;
+  guint idx;
+  const gchar *str_pointer = "static-string";
+
+  array = g_ptr_array_new ();
+
+  g_ptr_array_add (array, "some");
+  g_ptr_array_add (array, "random");
+  g_ptr_array_add (array, "values");
+  g_ptr_array_add (array, "some");
+  g_ptr_array_add (array, "duplicated");
+  g_ptr_array_add (array, (gpointer) str_pointer);
+
+  g_assert_true (g_ptr_array_find_with_equal_func (array, "random", g_str_equal, NULL));  /* NULL index */
+  g_assert_true (g_ptr_array_find_with_equal_func (array, "random", g_str_equal, &idx));  /* non-NULL index 
*/
+  g_assert_cmpuint (idx, ==, 1);
+
+  g_assert_true (g_ptr_array_find_with_equal_func (array, "some", g_str_equal, &idx));  /* duplicate element 
*/
+  g_assert_cmpuint (idx, ==, 0);
+
+  g_assert_false (g_ptr_array_find_with_equal_func (array, "nope", g_str_equal, NULL));
+
+  g_assert_true (g_ptr_array_find_with_equal_func (array, str_pointer, g_str_equal, &idx));
+  g_assert_cmpuint (idx, ==, 5);
+  idx = G_MAXUINT;
+  g_assert_true (g_ptr_array_find_with_equal_func (array, str_pointer, NULL, &idx));  /* NULL equal func */
+  g_assert_cmpuint (idx, ==, 5);
+  idx = G_MAXUINT;
+  g_assert_true (g_ptr_array_find (array, str_pointer, &idx));  /* NULL equal func */
+  g_assert_cmpuint (idx, ==, 5);
+
+  g_ptr_array_free (array, TRUE);
+}
+
+static void
 byte_array_append (void)
 {
   GByteArray *gbarray;
@@ -854,6 +907,8 @@ main (int argc, char *argv[])
   g_test_add_func ("/pointerarray/free-func", pointer_array_free_func);
   g_test_add_func ("/pointerarray/sort", pointer_array_sort);
   g_test_add_func ("/pointerarray/sort-with-data", pointer_array_sort_with_data);
+  g_test_add_func ("/pointerarray/find/empty", pointer_array_find_empty);
+  g_test_add_func ("/pointerarray/find/non-empty", pointer_array_find_non_empty);
 
   /* byte arrays */
   g_test_add_func ("/bytearray/append", byte_array_append);


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