14
void (*set_next_fn)(void *, void *),
15
int (*compare_fn)(const void *, const void *));
16
17
+/* Combine two sorted lists. Take from `list` on equality. */
18
+#define DEFINE_LIST_MERGE_INTERNAL(name, type) \
19
+static type *name##__merge(type *list, type *other, \
20
+ int (*compare_fn)(const type *, const type *))\
21
+{ \
22
+ type *result = list, *tail; \
23
+ int prefer_list = compare_fn(list, other) <= 0; \
24
+ \
25
+ if (!prefer_list) { \
26
+ result = other; \
27
+ SWAP(list, other); \
28
+ } \
29
+ for (;;) { \
30
+ do { \
31
+ tail = list; \
32
+ list = name##__get_next(list); \
33
+ if (!list) { \
34
+ name##__set_next(tail, other); \
35
+ return result; \
36
+ } \
37
+ } while (compare_fn(list, other) < prefer_list); \
38
+ name##__set_next(tail, other); \
39
+ prefer_list ^= 1; \
40
+ SWAP(list, other); \
41
+ } \
42
+}
43
+
44
+/*
45
+ * Perform an iterative mergesort using an array of sublists.
46
+ *
47
+ * n is the number of items.
48
+ * ranks[i] is undefined if n & 2^i == 0, and assumed empty.
49
+ * ranks[i] contains a sublist of length 2^i otherwise.
50
+ *
51
+ * The number of bits in a void pointer limits the number of objects
52
+ * that can be created, and thus the number of array elements necessary
53
+ * to be able to sort any valid list.
54
+ *
55
+ * Adding an item to this array is like incrementing a binary number;
56
+ * positional values for set bits correspond to sublist lengths.
57
+ */
58
+#define DEFINE_LIST_SORT_INTERNAL(scope, name, type) \
59
+scope void name(type **listp, \
60
+ int (*compare_fn)(const type *, const type *)) \
61
+{ \
62
+ type *list = *listp; \
63
+ type *ranks[bitsizeof(type *)]; \
64
+ size_t n = 0; \
65
+ \
66
+ if (!list) \
67
+ return; \
68
+ \
69
+ for (;;) { \
70
+ int i; \
71
+ size_t m; \
72
+ type *next = name##__get_next(list); \
73
+ if (next) \
74
+ name##__set_next(list, NULL); \
75
+ for (i = 0, m = n;; i++, m >>= 1) { \
76
+ if (m & 1) { \
77
+ list = name##__merge(ranks[i], list, \
78
+ compare_fn); \
79
+ } else if (next) { \
80
+ break; \
81
+ } else if (!m) { \
82
+ *listp = list; \
83
+ return; \
84
+ } \
85
+ } \
86
+ n++; \
87
+ ranks[i] = list; \
88
+ list = next; \
89
+ } \
90
+}
91
+
92
+#define DECLARE_LIST_SORT(scope, name, type) \
93
+scope void name(type **listp, \
94
+ int (*compare_fn)(const type *, const type *))
95
+
96
+#define DEFINE_LIST_SORT_DEBUG(scope, name, type, next_member, \
97
+ on_get_next, on_set_next) \
98
+ \
99
+static inline type *name##__get_next(const type *elem) \
100
+{ \
101
+ on_get_next; \
102
+ return elem->next_member; \
103
+} \
104
+ \
105
+static inline void name##__set_next(type *elem, type *next) \
106
+{ \
107
+ on_set_next; \
108
+ elem->next_member = next; \
109
+} \
110
+ \
111
+DEFINE_LIST_MERGE_INTERNAL(name, type) \
112
+DEFINE_LIST_SORT_INTERNAL(scope, name, type) \
113
+DECLARE_LIST_SORT(scope, name, type)
114
+
115
+#define DEFINE_LIST_SORT(scope, name, type, next_member) \
116
+DEFINE_LIST_SORT_DEBUG(scope, name, type, next_member, (void)0, (void)0)
117
+
118
#endif