[glib/wip/chergert/insertbeforelink: 253/254] list: add g_list_insert_before_link()
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib/wip/chergert/insertbeforelink: 253/254] list: add g_list_insert_before_link()
- Date: Mon, 7 Jan 2019 20:30:25 +0000 (UTC)
commit 2c491ac7bcd3a25bc500af5a522d6bbe5bb06209
Author: Christian Hergert <chergert redhat com>
Date: Thu Nov 15 11:43:12 2018 -0800
list: add g_list_insert_before_link()
This adds a new insertion helper using a pre-allocated link which may be
advantagous in some situations such as statically linked GList elements.
glib/glist.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++---
glib/glist.h | 4 ++++
glib/tests/list.c | 51 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 114 insertions(+), 3 deletions(-)
---
diff --git a/glib/glist.c b/glib/glist.c
index 51adeb058..f7f28cf92 100644
--- a/glib/glist.c
+++ b/glib/glist.c
@@ -367,6 +367,64 @@ g_list_insert (GList *list,
return list;
}
+/**
+ * g_list_insert_before_link:
+ * @list: a pointer to a #GList, this must point to the top of the list
+ * @sibling: the list element before which the new element
+ * is inserted or %NULL to insert at the end of the list
+ * @link_: the list element to be added, which must not be part of
+ * any other list
+ *
+ * Inserts @link_ into the list before the given position.
+ *
+ * Returns: the (possibly changed) start of the #GList
+ *
+ * Since: 2.60
+ */
+GList *
+g_list_insert_before_link (GList *list,
+ GList *sibling,
+ GList *link_)
+{
+ g_return_val_if_fail (link_ != NULL, list);
+ g_return_val_if_fail (link_->prev == NULL, list);
+ g_return_val_if_fail (link_->next == NULL, list);
+
+ if (!list)
+ {
+ g_return_val_if_fail (sibling == NULL, list);
+ return link_;
+ }
+ else if (sibling)
+ {
+ link_->prev = sibling->prev;
+ link_->next = sibling;
+ sibling->prev = link_;
+ if (link_->prev)
+ {
+ link_->prev->next = link_;
+ return list;
+ }
+ else
+ {
+ g_return_val_if_fail (sibling == list, link_);
+ return link_;
+ }
+ }
+ else
+ {
+ GList *last;
+
+ for (last = list; last->next != NULL; last = last->next) {}
+
+ last->next = link_;
+ last->next->prev = last;
+ last->next->next = NULL;
+
+ return list;
+ }
+}
+
/**
* g_list_insert_before:
* @list: a pointer to a #GList, this must point to the top of the list
@@ -414,9 +472,7 @@ g_list_insert_before (GList *list,
{
GList *last;
- last = list;
- while (last->next)
- last = last->next;
+ for (last = list; last->next != NULL; last = last->next) {}
last->next = _g_list_alloc ();
last->next->data = data;
diff --git a/glib/glist.h b/glib/glist.h
index af35cd52c..35f9cf71e 100644
--- a/glib/glist.h
+++ b/glib/glist.h
@@ -78,6 +78,10 @@ GLIB_AVAILABLE_IN_ALL
GList* g_list_insert_before (GList *list,
GList *sibling,
gpointer data) G_GNUC_WARN_UNUSED_RESULT;
+GLIB_AVAILABLE_IN_2_60
+GList* g_list_insert_before_link (GList *list,
+ GList *sibling,
+ GList *link_) G_GNUC_WARN_UNUSED_RESULT;
GLIB_AVAILABLE_IN_ALL
GList* g_list_concat (GList *list1,
GList *list2) G_GNUC_WARN_UNUSED_RESULT;
diff --git a/glib/tests/list.c b/glib/tests/list.c
index 1b5d6cadf..4d32dc17d 100644
--- a/glib/tests/list.c
+++ b/glib/tests/list.c
@@ -548,6 +548,56 @@ test_double_free (void)
g_test_trap_assert_stderr ("*corrupted double-linked list detected*");
}
+static void
+test_list_insert_before_link (void)
+{
+ GList a = {0};
+ GList b = {0};
+ GList c = {0};
+ GList d = {0};
+ GList *list;
+
+ list = g_list_insert_before_link (NULL, NULL, &a);
+ g_assert_nonnull (list);
+ g_assert_true (list == &a);
+ g_assert_null (a.prev);
+ g_assert_null (a.next);
+ g_assert_cmpint (g_list_length (list), ==, 1);
+
+ list = g_list_insert_before_link (list, &a, &b);
+ g_assert_nonnull (list);
+ g_assert_true (list == &b);
+ g_assert_null (b.prev);
+ g_assert_true (b.next == &a);
+ g_assert_true (a.prev == &b);
+ g_assert_null (a.next);
+ g_assert_cmpint (g_list_length (list), ==, 2);
+
+ list = g_list_insert_before_link (list, &a, &c);
+ g_assert_nonnull (list);
+ g_assert_true (list == &b);
+ g_assert_null (b.prev);
+ g_assert_true (b.next == &c);
+ g_assert_true (c.next == &a);
+ g_assert_true (c.prev == &b);
+ g_assert_true (a.prev == &c);
+ g_assert_null (a.next);
+ g_assert_cmpint (g_list_length (list), ==, 3);
+
+ list = g_list_insert_before_link (list, &b, &d);
+ g_assert_nonnull (list);
+ g_assert_true (list == &d);
+ g_assert_null (d.prev);
+ g_assert_true (b.prev == &d);
+ g_assert_true (c.prev == &b);
+ g_assert_true (a.prev == &c);
+ g_assert_true (d.next == &b);
+ g_assert_true (b.next == &c);
+ g_assert_true (c.next == &a);
+ g_assert_null (a.next);
+ g_assert_cmpint (g_list_length (list), ==, 4);
+}
+
int
main (int argc, char *argv[])
{
@@ -562,6 +612,7 @@ main (int argc, char *argv[])
g_test_add_func ("/list/sort", test_list_sort);
g_test_add_func ("/list/sort-with-data", test_list_sort_with_data);
g_test_add_func ("/list/sort/stable", test_list_sort_stable);
+ g_test_add_func ("/list/insert-before-link", test_list_insert_before_link);
g_test_add_func ("/list/insert-sorted", test_list_insert_sorted);
g_test_add_func ("/list/insert-sorted-with-data", test_list_insert_sorted_with_data);
g_test_add_func ("/list/reverse", test_list_reverse);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]