GitLab repository storage has been migrated to hashed layout. Please contact Infrastructure team if you notice any issues with repositories or hooks.

Commit f6f6b3d8 authored by Philip Withnall's avatar Philip Withnall Committed by Philip Withnall

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
parent 42a8e952
......@@ -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>
......
......@@ -34,6 +34,7 @@
#include "garray.h"
#include "gbytes.h"
#include "ghash.h"
#include "gslice.h"
#include "gmem.h"
#include "gtestutils.h"
......@@ -1511,6 +1512,81 @@ g_ptr_array_foreach (GPtrArray *array,
(*func) (array->pdata[i], user_data);
}
/**
* 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
......
......@@ -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,
......
......@@ -547,6 +547,59 @@ pointer_array_sort_with_data (void)
g_ptr_array_free (gparray, TRUE);
}
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)
{
......@@ -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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment