summaryrefslogtreecommitdiff
path: root/glib/gslist.c
diff options
context:
space:
mode:
authorJonh Wendell <jwendell@gnome.org>2012-06-21 12:23:23 -0300
committerJonh Wendell <jwendell@gnome.org>2012-06-21 17:21:30 -0300
commit2fd6eb7e1cfc878d011ec0b7e58c5e696186516e (patch)
treea71c520b83d5e92d6b5a6f71dcbd0e9bfa7106ee /glib/gslist.c
parente0f4b2b03b877e0360f56836ebfe454aa3a9dca5 (diff)
downloadglib-2fd6eb7e1cfc878d011ec0b7e58c5e696186516e.tar.gz
Adds g_list_copy_deep and g_slist_copy_deep
They make a full (deep) copy of a list. In contrast with g_[s]list_copy(), these functions take a function as a argument to make a copy of each list element, in addition to copying the list container itself. The functions g_[s]list_copy() were reimplemented to just call the new functions with NULL as the function argument, which will behave like current implementation. https://bugzilla.gnome.org/show_bug.cgi?id=675024
Diffstat (limited to 'glib/gslist.c')
-rw-r--r--glib/gslist.c48
1 files changed, 45 insertions, 3 deletions
diff --git a/glib/gslist.c b/glib/gslist.c
index 89e0f2d60..8d32d05e2 100644
--- a/glib/gslist.c
+++ b/glib/gslist.c
@@ -554,7 +554,8 @@ g_slist_delete_link (GSList *list,
* <note><para>
* Note that this is a "shallow" copy. If the list elements
* consist of pointers to data, the pointers are copied but
- * the actual data isn't.
+ * the actual data isn't. See g_slist_copy_deep() if you need
+ * to copy the data as well.
* </para></note>
*
* Returns: a copy of @list
@@ -562,6 +563,41 @@ g_slist_delete_link (GSList *list,
GSList*
g_slist_copy (GSList *list)
{
+ return g_slist_copy_deep (list, NULL, NULL);
+}
+
+/**
+ * g_slist_copy_deep:
+ * @list: a #GSList
+ * @func: a copy function used to copy every element in the list
+ * @user_data: user data passed to the copy function @func, or #NULL
+ *
+ * Makes a full (deep) copy of a #GSList.
+ *
+ * In contrast with g_slist_copy(), this function uses @func to make a copy of
+ * each list element, in addition to copying the list container itself.
+ *
+ * @func, as a #GCopyFunc, takes two arguments, the data to be copied and a user
+ * pointer. It's safe to pass #NULL as user_data, if the copy function takes only
+ * one argument.
+ *
+ * For instance, if @list holds a list of GObjects, you can do:
+ * |[
+ * another_list = g_slist_copy_deep (list, (GCopyFunc) g_object_ref, NULL);
+ * ]|
+ *
+ * And, to entirely free the new list, you could do:
+ * |[
+ * g_slist_free_full (another_list, g_object_unref);
+ * ]|
+ *
+ * Returns: a full copy of @list, use #g_slist_free_full to free it
+ *
+ * Since: 2.34
+ */
+GSList*
+g_slist_copy_deep (GSList *list, GCopyFunc func, gpointer user_data)
+{
GSList *new_list = NULL;
if (list)
@@ -569,14 +605,20 @@ g_slist_copy (GSList *list)
GSList *last;
new_list = _g_slist_alloc ();
- new_list->data = list->data;
+ if (func)
+ new_list->data = func (list->data, user_data);
+ else
+ new_list->data = list->data;
last = new_list;
list = list->next;
while (list)
{
last->next = _g_slist_alloc ();
last = last->next;
- last->data = list->data;
+ if (func)
+ last->data = func (list->data, user_data);
+ else
+ last->data = list->data;
list = list->next;
}
last->next = NULL;