48 # define LLIST_MACRO static inline 51 # define LLIST_MACRO static __inline__ 53 # define LLIST_MACRO static 57 #if defined(LLIST_INTERFACE) 59 #define LLIST_FUNC(proto, ...) proto 60 #elif defined(LLIST_IMPLEMENTATION) 62 #define LLIST_FUNC(proto, ...) proto { __VA_ARGS__ } 65 #define LLIST_FUNC(proto, ...) LLIST_MACRO proto { __VA_ARGS__ } 81 typedef llist * LList;
82 typedef const llist * const_LList;
83 typedef llist ** LList_ref;
89 #define LLIST_AUTO(name) llist name = {&name,&name} 95 #define llist_insert_head(list, element) llist_insert_next (list, element) 96 #define llist_insert_tail(list, element) llist_insert_prev (list, element) 97 #define llist_head llist_next 98 #define llist_tail llist_prev 111 #define LLIST_TO_STRUCTP(llist, type, member) \ 112 ((type*)(((char*)(llist)) - offsetof(type, member))) 119 #define LLIST_FOREACH(list, node) \ 120 for (LList node = llist_head (list); \ 121 ! llist_is_end (node, list); \ 122 llist_forward (&node)) 129 #define LLIST_FOREACH_REV(list, node) \ 130 for (LList node = llist_tail (list); \ 131 ! llist_is_end (node, list); \ 132 llist_backward (&node)) 141 #define LLIST_FORRANGE(start, end, node) \ 142 for (LList node = start; \ 144 llist_forward (&node)) 152 #define LLIST_FORRANGE_REV(rstart, rend, node) \ 153 for (LList node = rstart; \ 155 llist_backward (&node)) 164 #define LLIST_WHILE_HEAD(list, head) \ 165 for (LList head = llist_head (list); \ 166 !llist_is_empty (list); \ 167 head = llist_head (list)) 175 #define LLIST_WHILE_TAIL(list, tail) \ 176 for (LList tail = llist_tail (list); \ 177 !llist_is_empty (list); \ 178 tail = llist_tail (list)) 187 return self->next = self->prev =
self;
193 LLIST_FUNC (
int llist_is_empty (const_LList
self),
194 return self->next ==
self;
201 LLIST_FUNC (
int llist_is_single (const_LList
self),
202 return self->next->next ==
self;
210 LLIST_FUNC (
int llist_is_head (const_LList
self, const_LList head),
211 return self->next == head;
219 LLIST_FUNC (
int llist_is_tail (const_LList
self, const_LList tail),
220 return self->prev == tail;
229 LLIST_FUNC (
int llist_is_end (const_LList
self, const_LList end),
238 LLIST_FUNC (
int llist_is_member (const_LList
self, const_LList member),
239 for (const_LList i = member->next; i != member; i = i->next)
253 LLIST_FUNC (
int llist_is_before_after (const_LList
self, const_LList before, const_LList after),
254 for (const_LList i = before->next; i !=
self; i = i->next)
267 LLIST_FUNC (
unsigned llist_count (const_LList
self),
269 const_LList i =
self;
270 for (; i->next !=
self; ++cnt, i = i->next);
275 LLIST_FUNC (
void llist_unlink_fast_ (LList
self),
276 LList nxt = self->next, pre = self->prev;
287 llist_unlink_fast_ (
self);
288 return self->next =
self->prev =
self;
300 LLIST_FUNC (LList llist_relocate (LList
self),
301 return self->next->prev = self->prev->next =
self;
311 LLIST_FUNC (LList llist_insert_next (LList
self, LList next),
312 llist_unlink_fast_ (next);
313 self->next->prev = next;
315 next->next =
self->next;
326 LLIST_FUNC (LList llist_insert_prev (LList
self, LList prev),
327 llist_unlink_fast_ (prev);
328 self->prev->next = prev;
330 prev->prev =
self->prev;
343 LLIST_FUNC (LList llist_insertlist_next (LList
self, LList next),
344 if (!llist_is_empty (next))
346 self->next->prev = next->prev;
347 next->prev->next =
self->next;
348 self->next = next->next;
349 next->next->prev =
self;
351 next->prev = next->next = next;
363 LLIST_FUNC (LList llist_insertlist_prev (LList
self, LList prev),
364 if (!llist_is_empty (prev))
366 self->prev->next = prev->next;
367 prev->next->prev =
self->prev;
368 self->prev = prev->prev;
369 prev->prev->next =
self;
371 prev->prev = prev->next = prev;
376 #if 0 //BUG("needs temporary") 383 LLIST_FUNC (LList llist_insertafter_range (LList
self, LList start, LList end),
384 self->next->prev = end->prev;
385 end->prev->next = self->next;
386 end->prev = start->prev;
387 start->prev->next = end;
394 #if 0 //BUG("needs temporary") 401 LLIST_FUNC (LList llist_inserbefore_range (LList
self, LList start, LList end),
402 self->prev->next = start;
403 start->prev->next = end;
404 end->prev = start->prev;
405 start->prev = self->prev;
406 self->prev = end->prev;
407 end->prev->next =
self;
419 LList tmp = self->next->next;
421 self->next->prev = self->prev;
422 self->prev->next = self->next;
423 self->prev = self->next;
424 self->next->next =
self;
436 LList tmp = self->prev->prev;
438 self->prev->next = self->next;
439 self->next->prev = self->prev;
440 self->next = self->prev;
441 self->prev->prev =
self;
453 LLIST_FUNC (LList llist_next (const_LList
self),
463 LLIST_FUNC (LList llist_prev (const_LList
self),
472 LLIST_FUNC (
void llist_forward (LList_ref
self),
473 *
self = (*self)->next;
481 LLIST_FUNC (
void llist_backward (LList_ref
self),
482 *
self = (*self)->prev;
491 LLIST_FUNC (LList llist_nth (LList
self,
int n),
494 self = llist_next (
self);
497 self = llist_prev (
self);
507 LLIST_FUNC (LList llist_get_nth_stop (LList
self,
int n, const_LList stop),
511 self = llist_next (
self);
518 self = llist_prev (
self);
535 typedef int (*
llist_cmpfn)(const_LList a, const_LList b,
void* extra);
551 if (!llist_is_single (
self))
554 llist_insert_prev (++n & 1 ? &left : &right, head);
556 llist_sort (&left, cmp, extra);
557 llist_sort (&right, cmp, extra);
559 while (!llist_is_empty (&left) && !llist_is_empty (&right))
560 llist_insert_prev (
self, cmp (left.next, right.next, extra) < 0 ? left.next : right.next);
562 if (!llist_is_empty (&left))
563 llist_insertlist_prev (
self, &left);
564 if (!llist_is_empty (&right))
565 llist_insertlist_prev (
self, &right);
583 if (!cmp (node, templ, extra))
602 if (!cmp (node, templ, extra))
604 if (llist_next(
self) != node)
605 llist_insert_next (
self, node);
625 int c = cmp (node, templ, extra);
int(* llist_cmpfn)(const_LList a, const_LList b, void *extra)
The comparison function function type.
#define LLIST_FOREACH(list, node)
Iterate forward over a list.
LLIST_FUNC(LList llist_init(LList self), return self->next=self->prev=self;)
Initialise a new llist.
#define LLIST_WHILE_HEAD(list, head)
Consume a list from head.