4 struct mergesort_sublist
{
9 static void *get_nth_next(void *list
, unsigned long n
,
10 void *(*get_next_fn
)(const void *))
13 list
= get_next_fn(list
);
17 static void *pop_item(struct mergesort_sublist
*l
,
18 void *(*get_next_fn
)(const void *))
21 l
->ptr
= get_next_fn(l
->ptr
);
22 l
->len
= l
->ptr
? (l
->len
- 1) : 0;
26 void *mergesort(void *list
,
27 void *(*get_next_fn
)(const void *),
28 void (*set_next_fn
)(void *, void *),
29 int (*compare_fn
)(const void *, const void *))
35 for (l
= 1; ; l
*= 2) {
37 struct mergesort_sublist p
, q
;
40 q
.ptr
= get_nth_next(p
.ptr
, l
, get_next_fn
);
45 if (compare_fn(p
.ptr
, q
.ptr
) > 0)
46 list
= curr
= pop_item(&q
, get_next_fn
);
48 list
= curr
= pop_item(&p
, get_next_fn
);
51 while (p
.len
|| q
.len
) {
55 curr
= pop_item(&q
, get_next_fn
);
57 curr
= pop_item(&p
, get_next_fn
);
58 else if (compare_fn(p
.ptr
, q
.ptr
) > 0)
59 curr
= pop_item(&q
, get_next_fn
);
61 curr
= pop_item(&p
, get_next_fn
);
62 set_next_fn(prev
, curr
);
66 q
.ptr
= get_nth_next(p
.ptr
, l
, get_next_fn
);
67 q
.len
= q
.ptr
? l
: 0;
70 set_next_fn(curr
, NULL
);