basic/list: add LIST_JOIN helper
Joins together two lists, tail to head. a -> b c -> d a -> b -> c -> d
This commit is contained in:
parent
6b222c4b02
commit
5511d8c1b9
|
@ -169,3 +169,18 @@
|
|||
|
||||
#define LIST_IS_EMPTY(head) \
|
||||
(!(head))
|
||||
|
||||
/* Join two lists tail to head: a->b, c->d to a->b->c->d and de-initialise second list */
|
||||
#define LIST_JOIN(name,a,b) \
|
||||
do { \
|
||||
assert(b); \
|
||||
if (!(a)) \
|
||||
(a) = (b); \
|
||||
else { \
|
||||
typeof(*(a)) *_head = (b), *_tail; \
|
||||
LIST_FIND_TAIL(name, (a), _tail); \
|
||||
_tail->name##_next = _head; \
|
||||
_head->name##_prev = _tail; \
|
||||
} \
|
||||
(b) = NULL; \
|
||||
} while (false)
|
||||
|
|
|
@ -12,11 +12,14 @@ int main(int argc, const char *argv[]) {
|
|||
LIST_FIELDS(struct list_item, item);
|
||||
} list_item;
|
||||
LIST_HEAD(list_item, head);
|
||||
LIST_HEAD(list_item, head2);
|
||||
list_item items[4];
|
||||
list_item *cursor;
|
||||
|
||||
LIST_HEAD_INIT(head);
|
||||
LIST_HEAD_INIT(head2);
|
||||
assert_se(head == NULL);
|
||||
assert_se(head2 == NULL);
|
||||
|
||||
for (i = 0; i < ELEMENTSOF(items); i++) {
|
||||
LIST_INIT(item, &items[i]);
|
||||
|
@ -203,5 +206,49 @@ int main(int argc, const char *argv[]) {
|
|||
|
||||
assert_se(head == NULL);
|
||||
|
||||
for (i = 0; i < ELEMENTSOF(items) / 2; i++) {
|
||||
LIST_INIT(item, &items[i]);
|
||||
assert_se(LIST_JUST_US(item, &items[i]));
|
||||
LIST_PREPEND(item, head, &items[i]);
|
||||
}
|
||||
|
||||
for (i = ELEMENTSOF(items) / 2; i < ELEMENTSOF(items); i++) {
|
||||
LIST_INIT(item, &items[i]);
|
||||
assert_se(LIST_JUST_US(item, &items[i]));
|
||||
LIST_PREPEND(item, head2, &items[i]);
|
||||
}
|
||||
|
||||
assert_se(items[0].item_next == NULL);
|
||||
assert_se(items[1].item_next == &items[0]);
|
||||
assert_se(items[2].item_next == NULL);
|
||||
assert_se(items[3].item_next == &items[2]);
|
||||
|
||||
assert_se(items[0].item_prev == &items[1]);
|
||||
assert_se(items[1].item_prev == NULL);
|
||||
assert_se(items[2].item_prev == &items[3]);
|
||||
assert_se(items[3].item_prev == NULL);
|
||||
|
||||
LIST_JOIN(item, head2, head);
|
||||
assert_se(head == NULL);
|
||||
|
||||
assert_se(items[0].item_next == NULL);
|
||||
assert_se(items[1].item_next == &items[0]);
|
||||
assert_se(items[2].item_next == &items[1]);
|
||||
assert_se(items[3].item_next == &items[2]);
|
||||
|
||||
assert_se(items[0].item_prev == &items[1]);
|
||||
assert_se(items[1].item_prev == &items[2]);
|
||||
assert_se(items[2].item_prev == &items[3]);
|
||||
assert_se(items[3].item_prev == NULL);
|
||||
|
||||
LIST_JOIN(item, head, head2);
|
||||
assert_se(head2 == NULL);
|
||||
assert_se(!LIST_IS_EMPTY(head));
|
||||
|
||||
for (i = 0; i < ELEMENTSOF(items); i++)
|
||||
LIST_REMOVE(item, head, &items[i]);
|
||||
|
||||
assert_se(head == NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue