mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2025-01-03 19:25:26 +00:00
glib_compat: lift g_list_sort() & g_slist_sort() from glib code
This commit is contained in:
parent
b05087d314
commit
fba6046fd0
|
@ -178,49 +178,99 @@ GList *g_list_remove_link(GList *list, GList *llink)
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
GList *g_list_sort(GList *list, GCompareFunc compare)
|
// code copied from glib/glist.c, version 2.28.0
|
||||||
|
static GList *g_list_sort_merge(GList *l1,
|
||||||
|
GList *l2,
|
||||||
|
GFunc compare_func,
|
||||||
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
GList *i, *it, *j;
|
GList list, *l, *lprev;
|
||||||
/* base case for singletons or empty lists */
|
gint cmp;
|
||||||
if (list == NULL || list->next == NULL) return list;
|
|
||||||
i = list;
|
l = &list;
|
||||||
j = i->next;
|
lprev = NULL;
|
||||||
/* i walks half as fast as j, ends up in middle */
|
|
||||||
while (j) {
|
while (l1 && l2)
|
||||||
j = j->next;
|
{
|
||||||
if (j) {
|
cmp = ((GCompareDataFunc) compare_func) (l1->data, l2->data, user_data);
|
||||||
i = i->next;
|
|
||||||
j = j->next;
|
if (cmp <= 0)
|
||||||
}
|
{
|
||||||
}
|
l->next = l1;
|
||||||
/* split the list midway */
|
l1 = l1->next;
|
||||||
j = i->next;
|
}
|
||||||
j->prev = NULL; /* make j the head of its own list */
|
else
|
||||||
i->next = NULL;
|
{
|
||||||
/* will never have NULL return from either call below */
|
l->next = l2;
|
||||||
i = g_list_sort(list, compare);
|
l2 = l2->next;
|
||||||
j = g_list_sort(j, compare);
|
}
|
||||||
if ((*compare)(i->data, j->data) <= 0) {
|
l = l->next;
|
||||||
list = i;
|
l->prev = lprev;
|
||||||
i = i->next;
|
lprev = l;
|
||||||
} else {
|
}
|
||||||
list = j;
|
l->next = l1 ? l1 : l2;
|
||||||
j = j->next;
|
l->next->prev = l;
|
||||||
}
|
|
||||||
it = list;
|
return list.next;
|
||||||
while (i && j) {
|
}
|
||||||
if ((*compare)(i->data, j->data) <= 0) {
|
|
||||||
it->next = i;
|
static GList *g_list_sort_real(GList *list,
|
||||||
i = i->next;
|
GFunc compare_func,
|
||||||
} else {
|
gpointer user_data)
|
||||||
it->next = j;
|
{
|
||||||
j = j->next;
|
GList *l1, *l2;
|
||||||
}
|
|
||||||
it = it->next;
|
if (!list)
|
||||||
}
|
return NULL;
|
||||||
if (i) it->next = i;
|
if (!list->next)
|
||||||
else it->next = j;
|
return list;
|
||||||
return list;
|
|
||||||
|
l1 = list;
|
||||||
|
l2 = list->next;
|
||||||
|
|
||||||
|
while ((l2 = l2->next) != NULL)
|
||||||
|
{
|
||||||
|
if ((l2 = l2->next) == NULL)
|
||||||
|
break;
|
||||||
|
l1 = l1->next;
|
||||||
|
}
|
||||||
|
l2 = l1->next;
|
||||||
|
l1->next = NULL;
|
||||||
|
|
||||||
|
return g_list_sort_merge (g_list_sort_real (list, compare_func, user_data),
|
||||||
|
g_list_sort_real (l2, compare_func, user_data),
|
||||||
|
compare_func,
|
||||||
|
user_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* g_list_sort:
|
||||||
|
* @list: a #GList
|
||||||
|
* @compare_func: the comparison function used to sort the #GList.
|
||||||
|
* This function is passed the data from 2 elements of the #GList
|
||||||
|
* and should return 0 if they are equal, a negative value if the
|
||||||
|
* first element comes before the second, or a positive value if
|
||||||
|
* the first element comes after the second.
|
||||||
|
*
|
||||||
|
* Sorts a #GList using the given comparison function.
|
||||||
|
*
|
||||||
|
* Returns: the start of the sorted #GList
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* GCompareFunc:
|
||||||
|
* @a: a value.
|
||||||
|
* @b: a value to compare with.
|
||||||
|
* @Returns: negative value if @a < @b; zero if @a = @b; positive
|
||||||
|
* value if @a > @b.
|
||||||
|
*
|
||||||
|
* Specifies the type of a comparison function used to compare two
|
||||||
|
* values. The function should return a negative integer if the first
|
||||||
|
* value comes before the second, 0 if they are equal, or a positive
|
||||||
|
* integer if the first value comes after the second.
|
||||||
|
**/
|
||||||
|
GList *g_list_sort (GList *list, GCompareFunc compare_func)
|
||||||
|
{
|
||||||
|
return g_list_sort_real (list, (GFunc) compare_func, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* END of g_list related functions */
|
/* END of g_list related functions */
|
||||||
|
@ -267,48 +317,82 @@ GSList *g_slist_prepend(GSList *list, gpointer data)
|
||||||
return head;
|
return head;
|
||||||
}
|
}
|
||||||
|
|
||||||
GSList *g_slist_sort(GSList *list, GCompareFunc compare)
|
static GSList *g_slist_sort_merge (GSList *l1,
|
||||||
|
GSList *l2,
|
||||||
|
GFunc compare_func,
|
||||||
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
GSList *i, *it, *j;
|
GSList list, *l;
|
||||||
/* base case for singletons or empty lists */
|
gint cmp;
|
||||||
if (list == NULL || list->next == NULL) return list;
|
|
||||||
i = list;
|
l=&list;
|
||||||
j = i->next;
|
|
||||||
/* i walks half as fast as j, ends up in middle */
|
while (l1 && l2)
|
||||||
while (j) {
|
{
|
||||||
j = j->next;
|
cmp = ((GCompareDataFunc) compare_func) (l1->data, l2->data, user_data);
|
||||||
if (j) {
|
|
||||||
i = i->next;
|
if (cmp <= 0)
|
||||||
j = j->next;
|
{
|
||||||
}
|
l=l->next=l1;
|
||||||
}
|
l1=l1->next;
|
||||||
/* split the list midway */
|
}
|
||||||
j = i->next;
|
else
|
||||||
i->next = NULL;
|
{
|
||||||
/* will never have NULL return from either call below */
|
l=l->next=l2;
|
||||||
i = g_slist_sort(list, compare);
|
l2=l2->next;
|
||||||
j = g_slist_sort(j, compare);
|
}
|
||||||
if ((*compare)(i->data, j->data) <= 0) {
|
}
|
||||||
list = i;
|
l->next= l1 ? l1 : l2;
|
||||||
i = i->next;
|
|
||||||
} else {
|
return list.next;
|
||||||
list = j;
|
}
|
||||||
j = j->next;
|
|
||||||
}
|
static GSList *g_slist_sort_real (GSList *list,
|
||||||
it = list;
|
GFunc compare_func,
|
||||||
while (i && j) {
|
gpointer user_data)
|
||||||
if ((*compare)(i->data, j->data) <= 0) {
|
{
|
||||||
it->next = i;
|
GSList *l1, *l2;
|
||||||
i = i->next;
|
|
||||||
} else {
|
if (!list)
|
||||||
it->next = j;
|
return NULL;
|
||||||
j = j->next;
|
if (!list->next)
|
||||||
}
|
return list;
|
||||||
it = it->next;
|
|
||||||
}
|
l1 = list;
|
||||||
if (i) it->next = i;
|
l2 = list->next;
|
||||||
else it->next = j;
|
|
||||||
return list;
|
while ((l2 = l2->next) != NULL)
|
||||||
|
{
|
||||||
|
if ((l2 = l2->next) == NULL)
|
||||||
|
break;
|
||||||
|
l1=l1->next;
|
||||||
|
}
|
||||||
|
l2 = l1->next;
|
||||||
|
l1->next = NULL;
|
||||||
|
|
||||||
|
return g_slist_sort_merge (g_slist_sort_real (list, compare_func, user_data),
|
||||||
|
g_slist_sort_real (l2, compare_func, user_data),
|
||||||
|
compare_func,
|
||||||
|
user_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* g_slist_sort:
|
||||||
|
* @list: a #GSList
|
||||||
|
* @compare_func: the comparison function used to sort the #GSList.
|
||||||
|
* This function is passed the data from 2 elements of the #GSList
|
||||||
|
* and should return 0 if they are equal, a negative value if the
|
||||||
|
* first element comes before the second, or a positive value if
|
||||||
|
* the first element comes after the second.
|
||||||
|
*
|
||||||
|
* Sorts a #GSList using the given comparison function.
|
||||||
|
*
|
||||||
|
* Returns: the start of the sorted #GSList
|
||||||
|
*/
|
||||||
|
GSList *g_slist_sort (GSList *list,
|
||||||
|
GCompareFunc compare_func)
|
||||||
|
{
|
||||||
|
return g_slist_sort_real (list, (GFunc) compare_func, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* END of g_slist related functions */
|
/* END of g_slist related functions */
|
||||||
|
|
|
@ -44,11 +44,13 @@ typedef unsigned int guint;
|
||||||
typedef char gchar;
|
typedef char gchar;
|
||||||
typedef int gboolean;
|
typedef int gboolean;
|
||||||
|
|
||||||
|
typedef gint (*GCompareDataFunc)(gconstpointer a,
|
||||||
|
gconstpointer b,
|
||||||
|
gpointer user_data);
|
||||||
typedef void (*GFunc)(gpointer data, gpointer user_data);
|
typedef void (*GFunc)(gpointer data, gpointer user_data);
|
||||||
typedef gint (*GCompareFunc)(gconstpointer v1, gconstpointer v2);
|
typedef gint (*GCompareFunc)(gconstpointer v1, gconstpointer v2);
|
||||||
typedef void (*GDestroyNotify)(gpointer data);
|
typedef void (*GDestroyNotify)(gpointer data);
|
||||||
|
|
||||||
guint g_direct_hash(gconstpointer v);
|
|
||||||
guint g_str_hash(gconstpointer v);
|
guint g_str_hash(gconstpointer v);
|
||||||
gboolean g_str_equal(gconstpointer v1, gconstpointer v2);
|
gboolean g_str_equal(gconstpointer v1, gconstpointer v2);
|
||||||
guint g_int_hash(gconstpointer v);
|
guint g_int_hash(gconstpointer v);
|
||||||
|
|
Loading…
Reference in a new issue