diff --git a/glib/glib.h b/glib/glib.h index 22c12254ba..c77ccc3d7d 100644 --- a/glib/glib.h +++ b/glib/glib.h @@ -397,6 +397,9 @@ GList* g_list_prepend (GList *list, GList* g_list_insert (GList *list, gpointer data, gint position); +GList* g_list_insert_sorted (GList *list, + gpointer data, + GCompareFunc func); GList* g_list_concat (GList *list1, GList *list2); GList* g_list_remove (GList *list, @@ -415,6 +418,8 @@ void g_list_foreach (GList *list, GFunc func, gpointer user_data); +#define g_list_previous(list) (((GList *)list)->prev) +#define g_list_next(list) (((GList *)list)->next) /* Singly linked lists */ @@ -428,6 +433,9 @@ GSList* g_slist_prepend (GSList *list, GSList* g_slist_insert (GSList *list, gpointer data, gint position); +GSList* g_slist_insert_sorted (GSList *list, + gpointer data, + GCompareFunc func); GSList* g_slist_concat (GSList *list1, GSList *list2); GSList* g_slist_remove (GSList *list, @@ -445,6 +453,7 @@ void g_slist_foreach (GSList *list, GFunc func, gpointer user_data); +#define g_slist_next(list) (((GSList *)list)->next) /* List Allocators */ diff --git a/glib/glist.c b/glib/glist.c index 679bfac88b..9af3c79a6c 100644 --- a/glib/glist.c +++ b/glib/glist.c @@ -363,3 +363,55 @@ g_list_foreach (GList *list, list = list->next; } } + + +GList* +g_list_insert_sorted (GList *list, + gpointer data, + GCompareFunc func) +{ + GList *tmp_list = list; + GList *new_list; + gint cmp; + + if (!list) + { + new_list = g_list_alloc(); + new_list->data = data; + return new_list; + } + + cmp = (*func) (tmp_list->data, data); + + while ((tmp_list->next) && (cmp > 0)) + { + tmp_list = tmp_list->next; + cmp = (*func) (tmp_list->data, data); + } + + if (cmp == 0) + return list; + + new_list = g_list_alloc(); + new_list->data = data; + + if ((!tmp_list->next) && (cmp > 0)) + { + tmp_list->next = new_list; + new_list->prev = tmp_list; + return list; + } + + if (tmp_list->prev) + { + tmp_list->prev->next = new_list; + new_list->prev = tmp_list->prev; + } + new_list->next = tmp_list; + tmp_list->prev = new_list; + + if (tmp_list == list) + return new_list; + else + return list; +} diff --git a/glib/gslist.c b/glib/gslist.c index a0782673eb..248bfdb99a 100644 --- a/glib/gslist.c +++ b/glib/gslist.c @@ -336,3 +336,54 @@ g_slist_foreach (GSList *list, list = list->next; } } + +GSList* +g_slist_insert_sorted (GSList *list, + gpointer data, + GCompareFunc func) +{ + GSList *tmp_list = list; + GSList *prev_list = NULL; + GSList *new_list; + gint cmp; + + if (!list) + { + new_list = g_slist_alloc(); + new_list->data = data; + return new_list; + } + + cmp = (*func) (tmp_list->data, data); + + while ((tmp_list->next) && (cmp > 0)) + { + prev_list = tmp_list; + tmp_list = tmp_list->next; + cmp = (*func) (tmp_list->data, data); + } + + if (cmp == 0) + return list; + + new_list = g_slist_alloc(); + new_list->data = data; + + if ((!tmp_list->next) && (cmp > 0)) + { + tmp_list->next = new_list; + return list; + } + + if (prev_list) + { + prev_list->next = new_list; + new_list->next = tmp_list; + return list; + } + else + { + new_list->next = list; + return new_list; + } +} diff --git a/glib/testglib.c b/glib/testglib.c index 4357b2364d..74231b5ece 100644 --- a/glib/testglib.c +++ b/glib/testglib.c @@ -43,6 +43,29 @@ my_hash_compare (gpointer a, return *((gint*) a) == *((gint*) b); } +gint +my_list_compare_one (gpointer a, gpointer b) +{ + gint one = *((gint*)a); + gint two = *((gint*)b); + return one-two; +}; + +gint +my_list_compare_two (gpointer a, gpointer b) +{ + gint one = *((gint*)a); + gint two = *((gint*)b); + return two-one; +}; + +/* void +my_list_print (gpointer a, gpointer b) +{ + gint three = *((gint*)a); + g_print("%d", three); +}; */ + gint my_compare (gpointer a, gpointer b) @@ -74,6 +97,8 @@ main (int argc, GStringChunk *string_chunk; GTimer *timer; gint nums[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + gint morenums[10] = { 8, 9, 7, 0, 3, 2, 5, 1, 4, 6}; + gchar *mem[10000], *tmp_string, *tmp_string_2; gint i, j; GArray *garray; @@ -96,9 +121,45 @@ main (int argc, { t = g_list_nth (list, i); if (*((gint*) t->data) != (9 - i)) - g_error ("failed"); + g_error ("Regular insert failed"); } + g_list_free (list); + list = NULL; + + for (i = 0; i < 10; i++) + list = g_list_insert_sorted (list, &morenums[i], my_list_compare_one); + + /* + g_print("\n"); + g_list_foreach (list, my_list_print, NULL); + */ + + for (i = 0; i < 10; i++) + { + t = g_list_nth (list, i); + if (*((gint*) t->data) != (9 - i)) + g_error ("Sorted insert failed"); + } + + g_list_free (list); + list = NULL; + + for (i = 0; i < 10; i++) + list = g_list_insert_sorted (list, &morenums[i], my_list_compare_two); + + /* + g_print("\n"); + g_list_foreach (list, my_list_print, NULL); + */ + + for (i = 0; i < 10; i++) + { + t = g_list_nth (list, i); + if (*((gint*) t->data) != i) + g_error ("Sorted insert failed"); + } + g_list_free (list); g_print ("ok\n"); @@ -119,6 +180,42 @@ main (int argc, } g_slist_free (slist); + slist = NULL; + + for (i = 0; i < 10; i++) + slist = g_slist_insert_sorted (slist, &morenums[i], my_list_compare_one); + + /* + g_print("\n"); + g_slist_foreach (slist, my_list_print, NULL); + */ + + for (i = 0; i < 10; i++) + { + st = g_slist_nth (slist, i); + if (*((gint*) st->data) != (9 - i)) + g_error ("Sorted insert failed"); + } + + g_slist_free(slist); + slist = NULL; + + for (i = 0; i < 10; i++) + slist = g_slist_insert_sorted (slist, &morenums[i], my_list_compare_two); + + /* + g_print("\n"); + g_slist_foreach (slist, my_list_print, NULL); + */ + + for (i = 0; i < 10; i++) + { + st = g_slist_nth (slist, i); + if (*((gint*) st->data) != i) + g_error("Sorted insert failed"); + } + + g_slist_free(slist); g_print ("ok\n");