/* * vim:ts=4:sw=4:expandtab */ #include #include #include #include #include #include #include "queue.h" struct obj { int abc; TAILQ_ENTRY(obj) entry; }; TAILQ_HEAD(objhead, obj) head; void dump() { struct obj *e; printf("dump:\n"); e = TAILQ_FIRST(&head); printf("first: %d\n", e->abc); e = TAILQ_LAST(&head, objhead); printf("last: %d\n", e->abc); TAILQ_FOREACH(e, &head, entry) { printf(" %d\n", e->abc); } printf("again, but reverse:\n"); TAILQ_FOREACH_REVERSE(e, &head, objhead, entry) { printf(" %d\n", e->abc); } printf("done\n\n"); } #define TAILQ_SWAP(first, second, head, field) do { \ *((first)->field.tqe_prev) = (second); \ (second)->field.tqe_prev = (first)->field.tqe_prev; \ (first)->field.tqe_prev = &((second)->field.tqe_next); \ (first)->field.tqe_next = (second)->field.tqe_next; \ if ((second)->field.tqe_next) \ (second)->field.tqe_next->field.tqe_prev = &((first)->field.tqe_next); \ (second)->field.tqe_next = first; \ if ((head)->tqh_last == &((second)->field.tqe_next)) \ (head)->tqh_last = &((first)->field.tqe_next); \ } while (0) void _TAILQ_SWAP(struct obj *first, struct obj *second, struct objhead *head) { struct obj **tqe_prev = first->entry.tqe_prev; *tqe_prev = second; second->entry.tqe_prev = first->entry.tqe_prev; first->entry.tqe_prev = &(second->entry.tqe_next); first->entry.tqe_next = second->entry.tqe_next; if (second->entry.tqe_next) { struct obj *tqe_next = second->entry.tqe_next; tqe_next->entry.tqe_prev = &(first->entry.tqe_next); } second->entry.tqe_next = first; if (head->tqh_last == &(second->entry.tqe_next)) head->tqh_last = &(first->entry.tqe_next); } int main() { printf("hello\n"); TAILQ_INIT(&head); struct obj first; first.abc = 123; struct obj second; second.abc = 456; struct obj third; third.abc = 789; struct obj fourth; fourth.abc = 999; struct obj fifth; fifth.abc = 5555; /* * ************************************************ */ printf("swapping first two elements:\n"); TAILQ_INSERT_TAIL(&head, &first, entry); TAILQ_INSERT_TAIL(&head, &second, entry); TAILQ_INSERT_TAIL(&head, &third, entry); dump(); TAILQ_SWAP(&first, &second, &head, entry); dump(); /* * ************************************************ */ printf("swapping last two elements:\n"); TAILQ_INIT(&head); TAILQ_INSERT_TAIL(&head, &first, entry); TAILQ_INSERT_TAIL(&head, &second, entry); TAILQ_INSERT_TAIL(&head, &third, entry); dump(); TAILQ_SWAP(&second, &third, &head, entry); dump(); /* * ************************************************ */ printf("longer list:\n"); TAILQ_INIT(&head); TAILQ_INSERT_TAIL(&head, &first, entry); TAILQ_INSERT_TAIL(&head, &second, entry); TAILQ_INSERT_TAIL(&head, &third, entry); TAILQ_INSERT_TAIL(&head, &fourth, entry); dump(); TAILQ_SWAP(&first, &second, &head, entry); dump(); /* * ************************************************ */ printf("longer list 2:\n"); TAILQ_INIT(&head); TAILQ_INSERT_TAIL(&head, &first, entry); TAILQ_INSERT_TAIL(&head, &second, entry); TAILQ_INSERT_TAIL(&head, &third, entry); TAILQ_INSERT_TAIL(&head, &fourth, entry); dump(); TAILQ_SWAP(&second, &third, &head, entry); dump(); /* * ************************************************ */ printf("longer list, swap, then insert:\n"); TAILQ_INIT(&head); TAILQ_INSERT_TAIL(&head, &first, entry); TAILQ_INSERT_TAIL(&head, &second, entry); TAILQ_INSERT_TAIL(&head, &third, entry); TAILQ_INSERT_TAIL(&head, &fourth, entry); dump(); TAILQ_SWAP(&second, &third, &head, entry); dump(); TAILQ_INSERT_AFTER(&head, &third, &fifth, entry); dump(); /* * ************************************************ */ printf("longer list, swap, then append:\n"); TAILQ_INIT(&head); TAILQ_INSERT_TAIL(&head, &first, entry); TAILQ_INSERT_TAIL(&head, &second, entry); TAILQ_INSERT_TAIL(&head, &third, entry); TAILQ_INSERT_TAIL(&head, &fourth, entry); dump(); TAILQ_SWAP(&second, &third, &head, entry); dump(); TAILQ_INSERT_TAIL(&head, &fifth, entry); dump(); /* * ************************************************ */ printf("longer list, swap, then remove:\n"); TAILQ_INIT(&head); TAILQ_INSERT_TAIL(&head, &first, entry); TAILQ_INSERT_TAIL(&head, &second, entry); TAILQ_INSERT_TAIL(&head, &third, entry); TAILQ_INSERT_TAIL(&head, &fourth, entry); dump(); TAILQ_SWAP(&second, &third, &head, entry); dump(); TAILQ_REMOVE(&head, &second, entry); dump(); }