00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef LLIST_H
00025 #define LLIST_H
00026
00027 #include <stddef.h>
00028
00052
00053
00054
00055
00056
00057 #ifdef HAVE_INLINE
00058 # define LLIST_MACRO static inline
00059 #else
00060 # ifdef __GNUC__
00061 # define LLIST_MACRO static __inline__
00062 # else
00063 # define LLIST_MACRO static
00064 # endif
00065 #endif
00066
00067 #if defined(LLIST_INTERFACE)
00068
00069 #define LLIST_FUNC(proto, ...) proto
00070 #elif defined(LLIST_IMPLEMENTATION)
00071
00072 #define LLIST_FUNC(proto, ...) proto { __VA_ARGS__ }
00073 #else
00074
00075 #define LLIST_FUNC(proto, ...) LLIST_MACRO proto { __VA_ARGS__ }
00076 #endif
00077
00078
00079
00080
00081
00082 struct llist_struct
00083 {
00084 struct llist_struct *next;
00085 struct llist_struct *prev;
00086 };
00087 typedef struct llist_struct llist;
00088 typedef llist * LList;
00089 typedef const llist * const_LList;
00090 typedef llist ** LList_ref;
00091
00092
00097 #define LLIST_AUTO(name) llist name = {&name,&name}
00098
00099
00100
00101
00102
00103 #define llist_insert_head(list, element) llist_insert_next (list, element)
00104 #define llist_insert_tail(list, element) llist_insert_prev (list, element)
00105 #define llist_head llist_next
00106 #define llist_tail llist_prev
00107
00111
00112
00113
00114
00115
00116
00117
00118
00119 #define LLIST_TO_STRUCTP(llist, type, member) \
00120 ((type*)(((char*)(llist)) - offsetof(type, member)))
00121
00127 #define LLIST_FOREACH(list, node) \
00128 for (LList node = llist_head (list); \
00129 ! llist_is_end (node, list); \
00130 llist_forward (&node))
00131
00137 #define LLIST_FOREACH_REV(list, node) \
00138 for (LList node = llist_tail (list); \
00139 ! llist_is_end (node, list); \
00140 llist_backward (&node))
00141
00142
00149 #define LLIST_FORRANGE(start, end, node) \
00150 for (LList node = start; \
00151 node != end; \
00152 llist_forward (&node))
00153
00160 #define LLIST_FORRANGE_REV(rstart, rend, node) \
00161 for (LList node = rstart; \
00162 node != rend; \
00163 llist_backward (&node))
00164
00165
00172 #define LLIST_WHILE_HEAD(list, head) \
00173 for (LList head = llist_head (list); \
00174 !llist_is_empty (list); \
00175 head = llist_head (list))
00176
00183 #define LLIST_WHILE_TAIL(list, tail) \
00184 for (LList tail = llist_tail (list); \
00185 !llist_is_empty (list); \
00186 tail = llist_tail (list))
00187
00194 LLIST_FUNC (void llist_init (LList self),
00195 self->next = self->prev = self;
00196 );
00197
00201 LLIST_FUNC (int llist_is_empty (const_LList self),
00202 return self->next == self;
00203 );
00204
00209 LLIST_FUNC (int llist_is_single (const_LList self),
00210 return self->next->next == self;
00211 );
00212
00218 LLIST_FUNC (int llist_is_head (const_LList self, const_LList head),
00219 return self->next == head;
00220 );
00221
00227 LLIST_FUNC (int llist_is_tail (const_LList self, const_LList tail),
00228 return self->prev == tail;
00229 );
00230
00237 LLIST_FUNC (int llist_is_end (const_LList self, const_LList end),
00238 return self == end;
00239 );
00240
00246 LLIST_FUNC (int llist_is_member (const_LList self, const_LList member),
00247 for (const_LList i = member->next; i != member; i = i->next)
00248 {
00249 if (i == self)
00250 return 1;
00251 }
00252 return 0;
00253 );
00254
00261 LLIST_FUNC (int llist_is_before_after (const_LList self, const_LList before, const_LList after),
00262 for (const_LList i = before->next; i != self; i = i->next)
00263 {
00264 if (i == after)
00265 return 1;
00266 }
00267 return 0;
00268 );
00269
00275 LLIST_FUNC (unsigned llist_count (const_LList self),
00276 unsigned cnt = 0;
00277 const_LList i = self;
00278 for (; i->next != self; ++cnt, i = i->next);
00279 return cnt;
00280 );
00281
00282
00283 LLIST_FUNC (void llist_unlink_fast_ (LList self),
00284 LList nxt = self->next, pre = self->prev;
00285 nxt->prev = pre;
00286 pre->next = nxt;
00287 );
00288
00294 LLIST_FUNC (LList llist_unlink (LList self),
00295 llist_unlink_fast_ (self);
00296 return self->next = self->prev = self;
00297 );
00298
00308 LLIST_FUNC (LList llist_relocate (LList self),
00309 return self->next->prev = self->prev->next = self;
00310 );
00311
00312
00319 LLIST_FUNC (LList llist_insert_next (LList self, LList next),
00320 llist_unlink_fast_ (next);
00321 self->next->prev = next;
00322 next->prev = self;
00323 next->next = self->next;
00324 self->next = next;
00325 return self;
00326 );
00327
00334 LLIST_FUNC (LList llist_insert_prev (LList self, LList prev),
00335 llist_unlink_fast_ (prev);
00336 self->prev->next = prev;
00337 prev->next = self;
00338 prev->prev = self->prev;
00339 self->prev = prev;
00340 return self;
00341 );
00342
00343
00351 LLIST_FUNC (LList llist_insertlist_next (LList self, LList next),
00352 if (!llist_is_empty (next))
00353 {
00354 self->next->prev = next->prev;
00355 next->prev->next = self->next;
00356 self->next = next->next;
00357 next->next->prev = self;
00358
00359 next->prev = next->next = next;
00360 }
00361 return self;
00362 );
00363
00371 LLIST_FUNC (LList llist_insertlist_prev (LList self, LList prev),
00372 if (!llist_is_empty (prev))
00373 {
00374 self->prev->next = prev->next;
00375 prev->next->prev = self->prev;
00376 self->prev = prev->prev;
00377 prev->prev->next = self;
00378
00379 prev->prev = prev->next = prev;
00380 }
00381 return self;
00382 );
00383
00384 #if 0 //BUG("needs temporary")
00385
00391 LLIST_FUNC (LList llist_insertafter_range (LList self, LList start, LList end),
00392 self->next->prev = end->prev;
00393 end->prev->next = self->next;
00394 end->prev = start->prev;
00395 start->prev->next = end;
00396 self->next = start;
00397 start->prev = self;
00398 return self;
00399 );
00400 #endif
00401
00402 #if 0 //BUG("needs temporary")
00403
00409 LLIST_FUNC (LList llist_inserbefore_range (LList self, LList start, LList end),
00410 self->prev->next = start;
00411 start->prev->next = end;
00412 end->prev = start->prev;
00413 start->prev = self->prev;
00414 self->prev = end->prev;
00415 end->prev->next = self;
00416 return self;
00417 );
00418 #endif
00419
00426 LLIST_FUNC (LList llist_advance (LList self),
00427 LList tmp = self->next->next;
00428 tmp->prev = self;
00429 self->next->prev = self->prev;
00430 self->prev->next = self->next;
00431 self->prev = self->next;
00432 self->next->next = self;
00433 self->next = tmp;
00434 return self;
00435 );
00436
00443 LLIST_FUNC (LList llist_retreat (LList self),
00444 LList tmp = self->prev->prev;
00445 tmp->next = self;
00446 self->prev->next = self->next;
00447 self->next->prev = self->prev;
00448 self->next = self->prev;
00449 self->prev->prev = self;
00450 self->prev = tmp;
00451 return self;
00452 );
00453
00454
00461 LLIST_FUNC (LList llist_next (const_LList self),
00462 return self->next;
00463 );
00464
00471 LLIST_FUNC (LList llist_prev (const_LList self),
00472 return self->prev;
00473 );
00474
00480 LLIST_FUNC (void llist_forward (LList_ref self),
00481 *self = (*self)->next;
00482 );
00483
00489 LLIST_FUNC (void llist_backward (LList_ref self),
00490 *self = (*self)->prev;
00491 );
00492
00499 LLIST_FUNC (LList llist_nth (LList self, int n),
00500 if (n>0)
00501 while (n--)
00502 self = llist_next (self);
00503 else
00504 while (n++)
00505 self = llist_prev (self);
00506 return self;
00507 );
00508
00515 LLIST_FUNC (LList llist_get_nth_stop (LList self, int n, const_LList stop),
00516 if (n>0)
00517 while (n--)
00518 {
00519 self = llist_next (self);
00520 if (self == stop)
00521 return NULL;
00522 }
00523 else
00524 while (n++)
00525 {
00526 self = llist_prev (self);
00527 if (self == stop)
00528 return NULL;
00529 }
00530 return self;
00531 );
00532
00533
00540 typedef int (*llist_cmpfn)(LList a, LList b);
00541
00542 LLIST_FUNC (LList llist_sort (LList self, llist_cmpfn cmp),
00543 llist left;
00544 llist right;
00545 llist_init (&left);
00546 llist_init (&right);
00547 unsigned n = 0;
00548 if (!llist_is_single (self))
00549 {
00550 LLIST_WHILE_HEAD (self, head)
00551 llist_insert_prev (++n & 1 ? &left : &right, head);
00552
00553 llist_sort (&left, cmp);
00554 llist_sort (&right, cmp);
00555
00556 while (!llist_is_empty (&left) && !llist_is_empty (&right))
00557 llist_insert_prev (self, cmp (left.next, right.next) < 0 ? left.next : right.next);
00558
00559 if (!llist_is_empty (&left))
00560 llist_insertlist_prev (self, &left);
00561 if (!llist_is_empty (&right))
00562 llist_insertlist_prev (self, &right);
00563 }
00564 return self;
00565 )
00566
00567 #endif
00568
00569
00570
00571
00572
00573
00574