[glib/wip/chergert/garraylist] arraylist: add g_array_list_move()
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib/wip/chergert/garraylist] arraylist: add g_array_list_move()
- Date: Sun, 13 Sep 2015 11:58:22 +0000 (UTC)
commit 4232c04655d3eb5b2c2430e5ed6f16fcff2d7e43
Author: Christian Hergert <christian hergert me>
Date: Sun Sep 13 04:58:09 2015 -0700
arraylist: add g_array_list_move()
This function will do a more optimzed move of an item within the list
than its equivelent, g_array_list_remove() and g_array_list_prepend().
glib/garraylist.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
glib/garraylist.h | 5 +++++
glib/tests/arraylist.c | 12 +++++++++++-
3 files changed, 64 insertions(+), 1 deletions(-)
---
diff --git a/glib/garraylist.c b/glib/garraylist.c
index 1778837..9c00e30 100644
--- a/glib/garraylist.c
+++ b/glib/garraylist.c
@@ -644,3 +644,51 @@ g_array_list_copy_reversed (GArrayList *self,
return ret;
}
+
+/**
+ * g_array_list_move:
+ * @self: A #GListArray
+ * @src: the index of the item to move
+ * @dest: the new index to place the item.
+ *
+ * This function is analagous to calling g_array_list_remove_index() followed
+ * by g_array_list_insert() but allows for avoiding the need to copy the item
+ * as well as re-build the linked list twice.
+ */
+void
+g_array_list_move (GArrayList *self,
+ gsize src,
+ gsize dest)
+{
+ GArrayListAny *any = (GArrayListAny *)self;
+ GArrayListEmbed *embed = (GArrayListEmbed *)self;
+ GArrayListAlloc *alloc = (GArrayListAlloc *)self;
+ GList *items;
+ gpointer src_data;
+ gsize i;
+
+ g_return_if_fail (self != NULL);
+ g_return_if_fail (src < any->len);
+ g_return_if_fail (dest < any->len);
+
+ if (src == dest)
+ return;
+
+ items = (any->mode == MODE_EMBED) ? embed->items : alloc->items;
+
+ src_data = items [src].data;
+
+ if (dest < src)
+ {
+ for (i = src; i > dest; i--)
+ items [i].data = items [i - 1].data;
+ }
+ else
+ {
+ for (i = src; i < dest; i++)
+ items [i].data = items [i + 1].data;
+ }
+
+ items [dest].data = src_data;
+ _g_array_list_update_pointers (items, any->len);
+}
diff --git a/glib/garraylist.h b/glib/garraylist.h
index d41aac6..c078c3e 100644
--- a/glib/garraylist.h
+++ b/glib/garraylist.h
@@ -95,6 +95,11 @@ gpointer *g_array_list_copy_reversed(GArrayList *list,
GCopyFunc copy_func,
gpointer copy_data);
+GLIB_AVAILABLE_IN_2_46
+void g_array_list_move (GArrayList *list,
+ gsize src,
+ gsize dest);
+
#define g_array_list_empty(list) ((list)->len == 0)
#define g_array_list_first(list) (((list)->len == 0) ? NULL : g_array_list_index((list),0))
#define g_array_list_last(list) (((list)->len == 0) ? NULL : g_array_list_index((list),(list)->len-1))
diff --git a/glib/tests/arraylist.c b/glib/tests/arraylist.c
index 43fe8ff..6b51aa7 100644
--- a/glib/tests/arraylist.c
+++ b/glib/tests/arraylist.c
@@ -76,13 +76,23 @@ test_basic (GArrayList *al)
g_assert_cmpint (al->len, ==, 500);
g_assert_cmpint (test_basic_counter, ==, 500);
+ g_assert_cmpint (GPOINTER_TO_SIZE (g_array_list_last (al)), ==, 1000);
g_array_list_prepend (al, GSIZE_TO_POINTER (191919));
g_assert_cmpint (GPOINTER_TO_SIZE (g_array_list_index (al, 0)), ==, 191919);
+ g_assert_cmpint (GPOINTER_TO_SIZE (g_array_list_last (al)), ==, 1000);
+
+ g_array_list_move (al, 0, al->len - 1);
+ g_assert_cmpint (GPOINTER_TO_SIZE (g_array_list_index (al, 0)), ==, 501);
+ g_assert_cmpint (GPOINTER_TO_SIZE (g_array_list_last (al)), ==, 191919);
+
+ g_array_list_move (al, al->len - 1, 0);
+ g_assert_cmpint (GPOINTER_TO_SIZE (g_array_list_index (al, 0)), ==, 191919);
+ g_assert_cmpint (GPOINTER_TO_SIZE (g_array_list_last (al)), ==, 1000);
g_array_list_clear (al);
g_assert_cmpint (al->len, ==, 0);
- g_assert_cmpint (test_basic_counter, ==, 1000);
+ g_assert_cmpint (test_basic_counter, ==, 1001);
g_array_list_destroy (al);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]