[glib/wip/chergert/garraylist] arraylist: add g_array_list_move()



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]