Lumiera 0.pre.04
»edit your freedom«
Loading...
Searching...
No Matches
llist.h
Go to the documentation of this file.
1/*
2 llist.h - simple intrusive cyclic double linked list
3
4 Copyright (C)
5 2003, 2005 Christian Thaeter <chth@gmx.net>
6 2008, Christian Thaeter <ct@pipapo.org>
7
8  **Lumiera** is free software; you can redistribute it and/or modify it
9  under the terms of the GNU General Public License as published by the
10  Free Software Foundation; either version 2 of the License, or (at your
11  option) any later version. See the file COPYING for further details.
12*/
13
14#ifndef LLIST_H
15#define LLIST_H
16
17#include <stddef.h>
18
42/* TODO __STDC_VERSION__ 199901L
43150) This macro was not specified in ISO/IEC 9899:1990 and was specified as 199409L in
44ISO/IEC 9899/AMD1:1995. The intention is that this will remain an integer constant of type long
45int that is increased with each revision of this International Standard.
46*/
47#ifdef HAVE_INLINE
48# define LLIST_MACRO static inline
49#else
50# ifdef __GNUC__
51# define LLIST_MACRO static __inline__
52# else
53# define LLIST_MACRO static
54# endif
55#endif
56
57#if defined(LLIST_INTERFACE)
58/* only the interface is generated */
59#define LLIST_FUNC(proto, ...) proto
60#elif defined(LLIST_IMPLEMENTATION)
61/* generate a non inlined implementation */
62#define LLIST_FUNC(proto, ...) proto { __VA_ARGS__ }
63#else
64/* all functions are macro-like inlined */
65#define LLIST_FUNC(proto, ...) LLIST_MACRO proto { __VA_ARGS__ }
66#endif
67
68
69/*
70 * Type of a llist node.
71 */
72#ifndef LLIST_DEFINED
73#define LLIST_DEFINED
75{
78};
79#endif
80typedef struct llist_struct llist;
81typedef llist * LList;
82typedef const llist * const_LList;
83typedef llist ** LList_ref;
84
89#define LLIST_AUTO(name) llist name = {&name,&name}
90
91
92/*
93 some macros for convenience
94*/
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
99
103/* example:
104 struct foo
105 {
106 int bar;
107 llist l;
108 } x;
109 LLIST_TO_STRUCTP (&x.l, foo, l)->bar
110*/
111#define LLIST_TO_STRUCTP(llist, type, member) \
112 ((type*)(((char*)(llist)) - offsetof(type, member)))
113
119#define LLIST_FOREACH(list, node) \
120 for (LList node = llist_head (list); \
121 ! llist_is_end (node, list); \
122 llist_forward (&node))
123
129#define LLIST_FOREACH_REV(list, node) \
130 for (LList node = llist_tail (list); \
131 ! llist_is_end (node, list); \
132 llist_backward (&node))
133
134
141#define LLIST_FORRANGE(start, end, node) \
142 for (LList node = start; \
143 node != end; \
144 llist_forward (&node))
145
152#define LLIST_FORRANGE_REV(rstart, rend, node) \
153 for (LList node = rstart; \
154 node != rend; \
155 llist_backward (&node))
156
157
164#define LLIST_WHILE_HEAD(list, head) \
165 for (LList head = llist_head (list); \
166 !llist_is_empty (list); \
167 head = llist_head (list))
168
175#define LLIST_WHILE_TAIL(list, tail) \
176 for (LList tail = llist_tail (list); \
177 !llist_is_empty (list); \
178 tail = llist_tail (list))
179
186LLIST_FUNC (LList llist_init (LList self),
187 return self->next = self->prev = self;
188);
189
193LLIST_FUNC (int llist_is_empty (const_LList self),
194 return self->next == self;
195);
196
201LLIST_FUNC (int llist_is_single (const_LList self),
202 return self->next->next == self;
203);
204
210LLIST_FUNC (int llist_is_head (const_LList self, const_LList head),
211 return self->next == head;
212);
213
219LLIST_FUNC (int llist_is_tail (const_LList self, const_LList tail),
220 return self->prev == tail;
221);
222
229LLIST_FUNC (int llist_is_end (const_LList self, const_LList end),
230 return self == end;
231);
232
238LLIST_FUNC (int llist_is_member (const_LList self, const_LList member),
239 for (const_LList i = member->next; i != member; i = i->next)
240 {
241 if (i == self)
242 return 1;
243 }
244 return 0;
245);
246
253LLIST_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)
255 {
256 if (i == after)
257 return 1;
258 }
259 return 0;
260);
261
267LLIST_FUNC (unsigned llist_count (const_LList self),
268 unsigned cnt = 0;
269 const_LList i = self;
270 for (; i->next != self; ++cnt, i = i->next);
271 return cnt;
272);
273
274/* private, unlink self some any list but leaves self in a uninitialised state */
275LLIST_FUNC (void llist_unlink_fast_ (LList self),
276 LList nxt = self->next, pre = self->prev;
277 nxt->prev = pre;
278 pre->next = nxt;
279);
280
286LLIST_FUNC (LList llist_unlink (LList self),
287 llist_unlink_fast_ (self);
288 return self->next = self->prev = self;
289);
290
300LLIST_FUNC (LList llist_relocate (LList self),
301 return self->next->prev = self->prev->next = self;
302);
303
304
311LLIST_FUNC (LList llist_insert_next (LList self, LList next),
312 llist_unlink_fast_ (next);
313 self->next->prev = next;
314 next->prev = self;
315 next->next = self->next;
316 self->next = next;
317 return self;
318);
319
326LLIST_FUNC (LList llist_insert_prev (LList self, LList prev),
327 llist_unlink_fast_ (prev);
328 self->prev->next = prev;
329 prev->next = self;
330 prev->prev = self->prev;
331 self->prev = prev;
332 return self;
333);
334
335
343LLIST_FUNC (LList llist_insertlist_next (LList self, LList next),
344 if (!llist_is_empty (next))
345 {
346 self->next->prev = next->prev;
347 next->prev->next = self->next;
348 self->next = next->next;
349 next->next->prev = self;
350
351 next->prev = next->next = next;
352 }
353 return self;
354);
355
363LLIST_FUNC (LList llist_insertlist_prev (LList self, LList prev),
364 if (!llist_is_empty (prev))
365 {
366 self->prev->next = prev->next;
367 prev->next->prev = self->prev;
368 self->prev = prev->prev;
369 prev->prev->next = self;
370
371 prev->prev = prev->next = prev;
372 }
373 return self;
374);
375
376#if 0 //BUG("needs temporary")
383LLIST_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;
388 self->next = start;
389 start->prev = self;
390 return self;
391);
392#endif
393
394#if 0 //BUG("needs temporary")
401LLIST_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;
408 return self;
409);
410#endif
411
418LLIST_FUNC (LList llist_advance (LList self),
419 LList tmp = self->next->next;
420 tmp->prev = self;
421 self->next->prev = self->prev;
422 self->prev->next = self->next;
423 self->prev = self->next;
424 self->next->next = self;
425 self->next = tmp;
426 return self;
427);
428
435LLIST_FUNC (LList llist_retreat (LList self),
436 LList tmp = self->prev->prev;
437 tmp->next = self;
438 self->prev->next = self->next;
439 self->next->prev = self->prev;
440 self->next = self->prev;
441 self->prev->prev = self;
442 self->prev = tmp;
443 return self;
444);
445
446
453LLIST_FUNC (LList llist_next (const_LList self),
454 return self->next;
455);
456
463LLIST_FUNC (LList llist_prev (const_LList self),
464 return self->prev;
465);
466
472LLIST_FUNC (void llist_forward (LList_ref self),
473 *self = (*self)->next;
474);
475
481LLIST_FUNC (void llist_backward (LList_ref self),
482 *self = (*self)->prev;
483);
484
491LLIST_FUNC (LList llist_nth (LList self, int n),
492 if (n>0)
493 while (n--)
494 self = llist_next (self);
495 else
496 while (n++)
497 self = llist_prev (self);
498 return self;
499);
500
507LLIST_FUNC (LList llist_get_nth_stop (LList self, int n, const_LList stop),
508 if (n>0)
509 while (n--)
510 {
511 self = llist_next (self);
512 if (self == stop)
513 return NULL;
514 }
515 else
516 while (n++)
517 {
518 self = llist_prev (self);
519 if (self == stop)
520 return NULL;
521 }
522 return self;
523);
524
525
535typedef int (*llist_cmpfn)(const_LList a, const_LList b, void* extra);
536
537
545LLIST_FUNC (LList llist_sort (LList self, llist_cmpfn cmp, void* extra),
546 llist left;
547 llist right;
548 llist_init (&left);
549 llist_init (&right);
550 unsigned n = 0;
551 if (!llist_is_single (self))
552 {
553 LLIST_WHILE_HEAD (self, head)
554 llist_insert_prev (++n & 1 ? &left : &right, head);
555
556 llist_sort (&left, cmp, extra);
557 llist_sort (&right, cmp, extra);
558
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);
561
562 if (!llist_is_empty (&left))
563 llist_insertlist_prev (self, &left);
564 if (!llist_is_empty (&right))
565 llist_insertlist_prev (self, &right);
566 }
567 return self;
568)
569
570
581 LLIST_FOREACH(self, node)
582 {
583 if (!cmp (node, templ, extra))
584 return node;
585 }
586 return NULL;
587)
588
589
600 LLIST_FOREACH(self, node)
601 {
602 if (!cmp (node, templ, extra))
603 {
604 if (llist_next(self) != node)
605 llist_insert_next (self, node);
606 return node;
607 }
608 }
609 return NULL;
610)
611
612
622LLIST_FUNC (LList llist_sfind (const_LList self, const_LList templ, llist_cmpfn cmp, void* extra),
623 LLIST_FOREACH(self, node)
624 {
625 int c = cmp (node, templ, extra);
626 if (!c)
627 return node;
628 else if (c>0)
629 break;
630 }
631 return NULL;
632)
633
634
635
636#endif /* LLIST_H */
637/*
638// Local Variables:
639// mode: C
640// c-file-style: "gnu"
641// indent-tabs-mode: nil
642// End:
643*/
struct llist_struct * prev
Definition llist.h:77
return NULL
Definition llist.h:586
#define LLIST_FUNC(proto,...)
Definition llist.h:65
const llist * const_LList
Definition llist.h:82
int(* llist_cmpfn)(const_LList a, const_LList b, void *extra)
The comparison function function type.
Definition llist.h:535
llist ** LList_ref
Definition llist.h:83
#define LLIST_WHILE_HEAD(list, head)
Consume a list from head.
Definition llist.h:164
const_LList templ
Definition llist.h:580
const_LList llist_cmpfn cmp
Definition llist.h:580
const_LList llist_cmpfn void * extra
Definition llist.h:580
llist * LList
Definition llist.h:81
#define LLIST_FOREACH(list, node)
Iterate forward over a list.
Definition llist.h:119
struct llist_struct * next
Definition llist.h:76
Node node(size_t id)
Definition dot-gen.hpp:165