19typedef struct gp_list_head {
20 struct gp_list_head *next;
23typedef struct gp_dlist_head {
24 struct gp_dlist_head *next;
25 struct gp_dlist_head *prev;
28typedef struct gp_list {
34typedef struct gp_dlist {
40#define GP_LIST_ENTRY(ptr, structure, member) \
41 GP_CONTAINER_OF(ptr, structure, member)
43#define GP_LIST_FOREACH(list, entry) \
44 for (entry = (list)->head; entry; entry = entry->next)
46#define GP_DLIST_REV_FOREACH(list, entry) \
47 for (entry = (list)->tail; entry; entry = entry->prev)
60 entry->next = list->head;
78 entry->next->prev = entry;
84static inline void gp_list_push_tail_(gp_list *list, gp_list_head *entry)
91 list->tail->next = entry;
104 gp_list_push_tail_(list, entry);
117 gp_list_push_tail_((gp_list *)list, (gp_list_head*)entry);
119 entry->prev = list->tail;
133 entry->next = after->next;
136 after->next->prev = entry;
154 entry->next = before;
155 entry->prev = before->prev;
158 before->prev->next = entry;
162 before->prev = entry;
177 gp_list_head *ret = list->head;
185 list->head = list->head->next;
205 if (ret && ret->next)
206 ret->next->prev = NULL;
221 gp_dlist_head *ret = list->tail;
226 list->tail = ret->prev;
231 ret->prev->next = NULL;
249 entry->prev->next = entry->next;
251 list->head = entry->next;
254 entry->next->prev = entry->prev;
256 list->tail = entry->prev;
264static inline gp_list_head *gp_list_merge_sort(gp_list_head *head,
265 int (*cmp)(
const void *,
const void *))
267 gp_list_head *middle, *tmp, *ret;
269 if (!head || !head->next)
272 for (middle = tmp = head; tmp; tmp = tmp->next) {
274 middle = middle->next;
280 head = gp_list_merge_sort(head, cmp);
281 middle = gp_list_merge_sort(middle, cmp);
283 if (cmp(head, middle)) {
288 middle = middle->next;
291 while (head || middle) {
292 while (head && (!middle || cmp(middle, head) <= 0)) {
298 while (middle && (!head || cmp(head, middle) <= 0)) {
301 middle = middle->next;
337 int (*cmp)(
const void *,
const void *))
344 list->head = gp_list_merge_sort(list->head, cmp);
346 for (tail = list->head; tail->next; tail = tail->next);
360 int (*cmp)(
const void *,
const void *))
367 list->head = (gp_dlist_head*)gp_list_merge_sort((gp_list_head*)list->head, cmp);
370 list->head->prev = NULL;
372 for (i = list->head; i->next; i = i->next)
static void gp_dlist_push_tail(gp_dlist *list, gp_dlist_head *entry)
Pushes into tail of double linked list.
static void gp_dlist_push_after(gp_dlist *list, gp_dlist_head *after, gp_dlist_head *entry)
Pushes an entry into a double linked list after an entry.
static gp_dlist_head * gp_dlist_pop_head(gp_dlist *list)
Pops from a head of a double linked list.
static void gp_dlist_push_before(gp_dlist *list, gp_dlist_head *before, gp_dlist_head *entry)
Pushes an entry into a double linked list before an entry.
static gp_list_head * gp_list_pop_head(gp_list *list)
Pops from a head of a linked list.
static void gp_list_push_tail(gp_list *list, gp_list_head *entry)
Pushes into tail of linked list.
static void gp_dlist_rem(gp_dlist *list, gp_dlist_head *entry)
Removes a entry from a double linked list.
static void gp_list_push_head(gp_list *list, gp_list_head *entry)
Pushes into head of linked list.
static void gp_dlist_push_head(gp_dlist *list, gp_dlist_head *entry)
Pushes into head of double linked list.
static gp_dlist_head * gp_dlist_pop_tail(gp_dlist *list)
Pops from a tail of a double linked list.
static void gp_dlist_sort(gp_dlist *list, int(*cmp)(const void *, const void *))
Sorts a double linked list given a compare function.
static void gp_list_sort(gp_list *list, int(*cmp)(const void *, const void *))
Sorts a linked list given a element comparsion function.