[glib] New API: g_sequence_lookup() and g_sequence_lookup_iter()
- From: Xavier Claessens <xclaesse src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib] New API: g_sequence_lookup() and g_sequence_lookup_iter()
- Date: Mon, 20 Dec 2010 16:31:06 +0000 (UTC)
commit 4e309043311487d66157383991373107eac1f7b9
Author: Xavier Claessens <xclaesse gmail com>
Date: Fri Apr 30 13:55:53 2010 +0200
New API: g_sequence_lookup() and g_sequence_lookup_iter()
Fixes bug #617254
docs/reference/glib/glib-sections.txt | 2 +
glib/gsequence.c | 132 ++++++++++++++++++++++++++++++++-
glib/gsequence.h | 8 ++
3 files changed, 141 insertions(+), 1 deletions(-)
---
diff --git a/docs/reference/glib/glib-sections.txt b/docs/reference/glib/glib-sections.txt
index 6540fe8..05ba4f8 100644
--- a/docs/reference/glib/glib-sections.txt
+++ b/docs/reference/glib/glib-sections.txt
@@ -2166,6 +2166,8 @@ g_sequence_remove_range
g_sequence_move_range
g_sequence_search
g_sequence_search_iter
+g_sequence_lookup
+g_sequence_lookup_iter
<SUBSECTION>
g_sequence_get
diff --git a/glib/gsequence.c b/glib/gsequence.c
index 8b28ce7..5a55bee 100644
--- a/glib/gsequence.c
+++ b/glib/gsequence.c
@@ -133,6 +133,11 @@ static GSequenceNode *node_get_next (GSequenceNode *node);
static gint node_get_pos (GSequenceNode *node);
static GSequenceNode *node_get_by_pos (GSequenceNode *node,
gint pos);
+static GSequenceNode *node_find (GSequenceNode *haystack,
+ GSequenceNode *needle,
+ GSequenceNode *end,
+ GSequenceIterCompareFunc cmp,
+ gpointer user_data);
static GSequenceNode *node_find_closest (GSequenceNode *haystack,
GSequenceNode *needle,
GSequenceNode *end,
@@ -780,6 +785,46 @@ g_sequence_search (GSequence *seq,
}
/**
+ * g_sequence_lookup:
+ * @seq: a #GSequence
+ * @data: data to lookup
+ * @cmp_func: the #GCompareDataFunc used to compare items in the sequence. It
+ * is called with two items of the @seq and @user_data. It should
+ * return 0 if the items are equal, a negative value if the first
+ * item comes before the second, and a positive value if the second
+ * item comes before the first.
+ * @cmp_data: user data passed to @cmp_func.
+ *
+ * Returns an iterator pointing to the position of the first item found
+ * equal to @data according to @cmp_func and @cmp_data. If more than one item
+ * is equal, it is not guaranteed that it is the first which is returned.
+ * In that case, you can use g_sequence_iter_next() and g_sequence_iter_prev()
+ * to get others.
+ *
+ * Return value: an #GSequenceIter pointing to the position of the first item
+ * found equal to @data according to @cmp_func and @cmp_data.
+ *
+ * Since: 2.26
+ **/
+GSequenceIter *
+g_sequence_lookup (GSequence *seq,
+ gpointer data,
+ GCompareDataFunc cmp_func,
+ gpointer cmp_data)
+{
+ SortInfo info;
+
+ g_return_val_if_fail (seq != NULL, NULL);
+
+ info.cmp_func = cmp_func;
+ info.cmp_data = cmp_data;
+ info.end_node = seq->end_node;
+ check_seq_access (seq);
+
+ return g_sequence_lookup_iter (seq, data, iter_compare, &info);
+}
+
+/**
* g_sequence_sort_iter:
* @seq: a #GSequence
* @cmp_func: the #GSequenceItercompare used to compare iterators in the
@@ -1007,6 +1052,57 @@ g_sequence_search_iter (GSequence *seq,
}
/**
+ * g_sequence_lookup_iter:
+ * @seq: a #GSequence
+ * @data: data to lookup
+ * @iter_cmp: the #GSequenceIterCompare function used to compare iterators
+ * in the sequence. It is called with two iterators pointing into @seq.
+ * It should return 0 if the iterators are equal, a negative value if the
+ * first iterator comes before the second, and a positive value if the
+ * second iterator comes before the first.
+ * @cmp_data: user data passed to @iter_cmp
+ *
+ * Like g_sequence_lookup(), but uses
+ * a #GSequenceIterCompareFunc instead of a #GCompareDataFunc as
+ * the compare function.
+ *
+ * Return value: an #GSequenceIter pointing to the position of the first item
+ * found equal to @data according to @cmp_func and @cmp_data.
+ *
+ * Since: 2.26
+ **/
+GSequenceIter *
+g_sequence_lookup_iter (GSequence *seq,
+ gpointer data,
+ GSequenceIterCompareFunc iter_cmp,
+ gpointer cmp_data)
+{
+ GSequenceNode *node;
+ GSequenceNode *dummy;
+ GSequence *tmp_seq;
+
+ g_return_val_if_fail (seq != NULL, NULL);
+
+ check_seq_access (seq);
+
+ seq->access_prohibited = TRUE;
+
+ tmp_seq = g_sequence_new (NULL);
+ tmp_seq->real_sequence = seq;
+
+ dummy = g_sequence_append (tmp_seq, data);
+
+ node = node_find (seq->end_node, dummy,
+ seq->end_node, iter_cmp, cmp_data);
+
+ g_sequence_free (tmp_seq);
+
+ seq->access_prohibited = FALSE;
+
+ return node;
+}
+
+/**
* g_sequence_iter_get_sequence:
* @iter: a #GSequenceIter
*
@@ -1549,6 +1645,40 @@ node_get_by_pos (GSequenceNode *node,
}
static GSequenceNode *
+node_find (GSequenceNode *haystack,
+ GSequenceNode *needle,
+ GSequenceNode *end,
+ GSequenceIterCompareFunc iter_cmp,
+ gpointer cmp_data)
+{
+ gint c;
+
+ haystack = find_root (haystack);
+
+ do
+ {
+ /* iter_cmp can't be passed the end node, since the function may
+ * be user-supplied
+ */
+ if (haystack == end)
+ c = 1;
+ else
+ c = iter_cmp (haystack, needle, cmp_data);
+
+ if (c == 0)
+ break;
+
+ if (c > 0)
+ haystack = haystack->left;
+ else
+ haystack = haystack->right;
+ }
+ while (haystack != NULL);
+
+ return haystack;
+}
+
+static GSequenceNode *
node_find_closest (GSequenceNode *haystack,
GSequenceNode *needle,
GSequenceNode *end,
@@ -1572,7 +1702,7 @@ node_find_closest (GSequenceNode *haystack,
else
c = iter_cmp (haystack, needle, cmp_data);
- /* In the following we don't break even if c == 0. Instaed we go on
+ /* In the following we don't break even if c == 0. Instead we go on
* searching along the 'bigger' nodes, so that we find the last one
* that is equal to the needle.
*/
diff --git a/glib/gsequence.h b/glib/gsequence.h
index fa79066..6a21c3e 100644
--- a/glib/gsequence.h
+++ b/glib/gsequence.h
@@ -99,6 +99,14 @@ GSequenceIter *g_sequence_search_iter (GSequence *seq,
gpointer data,
GSequenceIterCompareFunc iter_cmp,
gpointer cmp_data);
+GSequenceIter *g_sequence_lookup (GSequence *seq,
+ gpointer data,
+ GCompareDataFunc cmp_func,
+ gpointer cmp_data);
+GSequenceIter *g_sequence_lookup_iter (GSequence *seq,
+ gpointer data,
+ GSequenceIterCompareFunc iter_cmp,
+ gpointer cmp_data);
/* Dereferencing */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]