[glib/wip/chergert/garraylist] arraylist: add find, copy and copy_reverse



commit 2f272a2c0bb2ca6d241a950395083d03488840d1
Author: Christian Hergert <christian hergert me>
Date:   Sun Sep 13 04:35:58 2015 -0700

    arraylist: add find, copy and copy_reverse
    
    Some more common helpers for GArrayList migration.

 glib/garraylist.c      |  115 ++++++++++++++++++++++++++++++++++++++++++++++++
 glib/garraylist.h      |   14 ++++++
 glib/tests/arraylist.c |    3 +
 3 files changed, 132 insertions(+), 0 deletions(-)
---
diff --git a/glib/garraylist.c b/glib/garraylist.c
index e177c9a..3a5b3cc 100644
--- a/glib/garraylist.c
+++ b/glib/garraylist.c
@@ -427,6 +427,29 @@ g_array_list_remove_index (GArrayList *self,
     any->destroy (data);
 }
 
+gssize
+g_array_list_find (GArrayList *self,
+                   gpointer    data)
+{
+  GArrayListAny *any = (GArrayListAny *)self;
+  GArrayListEmbed *embed = (GArrayListEmbed *)self;
+  GArrayListAlloc *alloc = (GArrayListAlloc *)self;
+  GList *items;
+  gsize i;
+
+  g_return_if_fail (self != NULL);
+
+  items = (any->mode == MODE_EMBED) ? embed->items : alloc->items;
+
+  for (i = 0; i < any->len; i++)
+    {
+      if (items [i].data == data)
+        return i;
+    }
+
+  return -1;
+}
+
 void
 g_array_list_remove (GArrayList *self,
                      gpointer    data)
@@ -527,3 +550,95 @@ g_array_list_clear (GArrayList *self)
   any->len = 0;
   any->mode = MODE_EMBED;
 }
+
+/**
+ * g_array_list_copy:
+ * @self: A #GArrayList.
+ * @copy_func: (scope call): A #GCopyFunc
+ * @copy_data: (allow-none): data for @copy_func or %NULL.
+ *
+ * Creates a new array containing the data found within the #GListArray.
+ * The result should be freed with g_free() when no longer used. If you
+ * incremented a reference count or allocated a new structure in your
+ * copy func, you are responsible for freeing it as well.
+ *
+ * Returns: (transfer full): A newly allocated array that should be freed
+ *   with g_free().
+ */
+gpointer *
+g_array_list_copy (GArrayList *self,
+                   GCopyFunc   copy_func, 
+                   gpointer    copy_data)
+{
+  GArrayListAny *any = (GArrayListAny *)self;
+  GArrayListEmbed *embed = (GArrayListEmbed *)self;
+  GArrayListAlloc *alloc = (GArrayListAlloc *)self;
+  const GList *items;
+  gpointer *ret;
+  gsize i;
+
+  g_return_if_fail (self != NULL);
+
+  ret = g_malloc_n (self->len, sizeof (gpointer));
+  items = (any->mode == MODE_EMBED) ? embed->items : alloc->items;
+
+  if (!copy_func)
+    {
+      for (i = 0; i < self->len; i++)
+        ret [i] = items [i].data;
+    }
+  else
+    {
+      for (i = 0; i < self->len; i++)
+        ret [i] = copy_func (items [i].data, copy_data);
+    }
+
+  return ret;
+}
+
+/**
+ * g_array_list_copy_reversed:
+ * @self: A #GArrayList.
+ * @copy_func: (scope call): A #GCopyFunc
+ * @copy_data: (allow-none): data for @copy_func or %NULL.
+ *
+ * Creates a new array containing the data found within the #GListArray.
+ * The result should be freed with g_free() when no longer used. If you
+ * incremented a reference count or allocated a new structure in your
+ * copy func, you are responsible for freeing it as well.
+ *
+ * This function creates the array in reverse order.
+ *
+ * Returns: (transfer full): A newly allocated array that should be freed
+ *   with g_free().
+ */
+gpointer *
+g_array_list_copy_reversed (GArrayList *self,
+                            GCopyFunc   copy_func, 
+                            gpointer    copy_data)
+{
+  GArrayListAny *any = (GArrayListAny *)self;
+  GArrayListEmbed *embed = (GArrayListEmbed *)self;
+  GArrayListAlloc *alloc = (GArrayListAlloc *)self;
+  const GList *items;
+  gpointer *ret;
+  gsize i;
+
+  g_return_if_fail (self != NULL);
+
+  ret = g_malloc_n (self->len, sizeof (gpointer));
+  items = (any->mode == MODE_EMBED) ? embed->items : alloc->items;
+
+  if (!copy_func)
+    {
+      for (i = self->len; i > 0; i--)
+        ret [i-1] = items [i-1].data;
+    }
+  else
+    {
+      for (i = self->len; i > 0; i--)
+        ret [i-1] = copy_func (items [i-1].data, copy_data);
+    }
+
+  return ret;
+}
diff --git a/glib/garraylist.h b/glib/garraylist.h
index af0b234..d41aac6 100644
--- a/glib/garraylist.h
+++ b/glib/garraylist.h
@@ -81,6 +81,20 @@ void         g_array_list_prepend      (GArrayList     *list,
 GLIB_AVAILABLE_IN_2_46
 void         g_array_list_clear        (GArrayList     *list);
 
+GLIB_AVAILABLE_IN_2_46
+gssize       g_array_list_find         (GArrayList     *list,
+                                        gpointer        data);
+
+GLIB_AVAILABLE_IN_2_46
+gpointer    *g_array_list_copy         (GArrayList     *list,
+                                        GCopyFunc       copy_func,
+                                        gpointer        copy_data);
+
+GLIB_AVAILABLE_IN_2_46
+gpointer    *g_array_list_copy_reversed(GArrayList     *list,
+                                        GCopyFunc       copy_func,
+                                        gpointer        copy_data);
+
 #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 d8ef39a..43fe8ff 100644
--- a/glib/tests/arraylist.c
+++ b/glib/tests/arraylist.c
@@ -47,6 +47,9 @@ test_basic (GArrayList *al)
       g_assert_cmpint (al->len, ==, i);
     }
 
+  g_assert_cmpint (g_array_list_find (al, GSIZE_TO_POINTER (12345)), ==, -1);
+  g_assert_cmpint (g_array_list_find (al, GSIZE_TO_POINTER (500)), ==, 499);
+
   g_assert_cmpint (GPOINTER_TO_SIZE (g_array_list_first(al)), ==, 1);
   g_assert_cmpint (GPOINTER_TO_SIZE (g_array_list_last(al)), ==, 1000);
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]