230 lines
4.9 KiB
C
230 lines
4.9 KiB
C
|
/*
|
||
|
* vim:ts=4:sw=4:expandtab
|
||
|
*/
|
||
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <string.h>
|
||
|
#include <unistd.h>
|
||
|
#include <stdbool.h>
|
||
|
#include <stdint.h>
|
||
|
|
||
|
#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();
|
||
|
|
||
|
}
|