Header And Logo

PostgreSQL
| The world's most advanced open source database.

ilist.h

Go to the documentation of this file.
00001 /*-------------------------------------------------------------------------
00002  *
00003  * ilist.h
00004  *      integrated/inline doubly- and singly-linked lists
00005  *
00006  * These list types are useful when there are only a predetermined set of
00007  * lists that an object could be in.  List links are embedded directly into
00008  * the objects, and thus no extra memory management overhead is required.
00009  * (Of course, if only a small proportion of existing objects are in a list,
00010  * the link fields in the remainder would be wasted space.  But usually,
00011  * it saves space to not have separately-allocated list nodes.)
00012  *
00013  * None of the functions here allocate any memory; they just manipulate
00014  * externally managed memory.  The APIs for singly and doubly linked lists
00015  * are identical as far as capabilities of both allow.
00016  *
00017  * Each list has a list header, which exists even when the list is empty.
00018  * An empty singly-linked list has a NULL pointer in its header.
00019  * There are two kinds of empty doubly linked lists: those that have been
00020  * initialized to NULL, and those that have been initialized to circularity.
00021  * (If a dlist is modified and then all its elements are deleted, it will be
00022  * in the circular state.)  We prefer circular dlists because there are some
00023  * operations that can be done without branches (and thus faster) on lists
00024  * that use circular representation.  However, it is often convenient to
00025  * initialize list headers to zeroes rather than setting them up with an
00026  * explicit initialization function, so we also allow the other case.
00027  *
00028  * EXAMPLES
00029  *
00030  * Here's a simple example demonstrating how this can be used.  Let's assume
00031  * we want to store information about the tables contained in a database.
00032  *
00033  * #include "lib/ilist.h"
00034  *
00035  * // Define struct for the databases including a list header that will be
00036  * // used to access the nodes in the table list later on.
00037  * typedef struct my_database
00038  * {
00039  *      char       *datname;
00040  *      dlist_head  tables;
00041  *      // ...
00042  * } my_database;
00043  *
00044  * // Define struct for the tables.  Note the list_node element which stores
00045  * // prev/next list links.  The list_node element need not be first.
00046  * typedef struct my_table
00047  * {
00048  *      char       *tablename;
00049  *      dlist_node  list_node;
00050  *      perm_t      permissions;
00051  *      // ...
00052  * } my_table;
00053  *
00054  * // create a database
00055  * my_database *db = create_database();
00056  *
00057  * // and add a few tables to its table list
00058  * dlist_push_head(&db->tables, &create_table(db, "a")->list_node);
00059  * ...
00060  * dlist_push_head(&db->tables, &create_table(db, "b")->list_node);
00061  *
00062  *
00063  * To iterate over the table list, we allocate an iterator variable and use
00064  * a specialized looping construct.  Inside a dlist_foreach, the iterator's
00065  * 'cur' field can be used to access the current element.  iter.cur points to
00066  * a 'dlist_node', but most of the time what we want is the actual table
00067  * information; dlist_container() gives us that, like so:
00068  *
00069  * dlist_iter   iter;
00070  * dlist_foreach(iter, &db->tables)
00071  * {
00072  *      my_table   *tbl = dlist_container(my_table, list_node, iter.cur);
00073  *      printf("we have a table: %s in database %s\n",
00074  *             tbl->tablename, db->datname);
00075  * }
00076  *
00077  *
00078  * While a simple iteration is useful, we sometimes also want to manipulate
00079  * the list while iterating.  There is a different iterator element and looping
00080  * construct for that.  Suppose we want to delete tables that meet a certain
00081  * criterion:
00082  *
00083  * dlist_mutable_iter miter;
00084  * dlist_foreach_modify(miter, &db->tables)
00085  * {
00086  *      my_table   *tbl = dlist_container(my_table, list_node, miter.cur);
00087  *
00088  *      if (!tbl->to_be_deleted)
00089  *          continue;       // don't touch this one
00090  *
00091  *      // unlink the current table from the linked list
00092  *      dlist_delete(miter.cur);
00093  *      // as these lists never manage memory, we can still access the table
00094  *      // after it's been unlinked
00095  *      drop_table(db, tbl);
00096  * }
00097  *
00098  *
00099  * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
00100  * Portions Copyright (c) 1994, Regents of the University of California
00101  *
00102  * IDENTIFICATION
00103  *      src/include/lib/ilist.h
00104  *-------------------------------------------------------------------------
00105  */
00106 #ifndef ILIST_H
00107 #define ILIST_H
00108 
00109 /*
00110  * Enable for extra debugging. This is rather expensive, so it's not enabled by
00111  * default even when USE_ASSERT_CHECKING.
00112  */
00113 /* #define ILIST_DEBUG */
00114 
00115 /*
00116  * Node of a doubly linked list.
00117  *
00118  * Embed this in structs that need to be part of a doubly linked list.
00119  */
00120 typedef struct dlist_node dlist_node;
00121 struct dlist_node
00122 {
00123     dlist_node *prev;
00124     dlist_node *next;
00125 };
00126 
00127 /*
00128  * Head of a doubly linked list.
00129  *
00130  * Non-empty lists are internally circularly linked.  Circular lists have the
00131  * advantage of not needing any branches in the most common list manipulations.
00132  * An empty list can also be represented as a pair of NULL pointers, making
00133  * initialization easier.
00134  */
00135 typedef struct dlist_head
00136 {
00137     /*
00138      * head.next either points to the first element of the list; to &head if
00139      * it's a circular empty list; or to NULL if empty and not circular.
00140      *
00141      * head.prev either points to the last element of the list; to &head if
00142      * it's a circular empty list; or to NULL if empty and not circular.
00143      */
00144     dlist_node  head;
00145 } dlist_head;
00146 
00147 
00148 /*
00149  * Doubly linked list iterator.
00150  *
00151  * Used as state in dlist_foreach() and dlist_reverse_foreach(). To get the
00152  * current element of the iteration use the 'cur' member.
00153  *
00154  * Iterations using this are *not* allowed to change the list while iterating!
00155  *
00156  * NB: We use an extra "end" field here to avoid multiple evaluations of
00157  * arguments in the dlist_foreach() macro.
00158  */
00159 typedef struct dlist_iter
00160 {
00161     dlist_node *cur;            /* current element */
00162     dlist_node *end;            /* last node we'll iterate to */
00163 } dlist_iter;
00164 
00165 /*
00166  * Doubly linked list iterator allowing some modifications while iterating.
00167  *
00168  * Used as state in dlist_foreach_modify(). To get the current element of the
00169  * iteration use the 'cur' member.
00170  *
00171  * Iterations using this are only allowed to change the list at the current
00172  * point of iteration. It is fine to delete the current node, but it is *not*
00173  * fine to insert or delete adjacent nodes.
00174  *
00175  * NB: We need a separate type for mutable iterations so that we can store
00176  * the 'next' node of the current node in case it gets deleted or modified.
00177  */
00178 typedef struct dlist_mutable_iter
00179 {
00180     dlist_node *cur;            /* current element */
00181     dlist_node *next;           /* next node we'll iterate to */
00182     dlist_node *end;            /* last node we'll iterate to */
00183 } dlist_mutable_iter;
00184 
00185 /*
00186  * Node of a singly linked list.
00187  *
00188  * Embed this in structs that need to be part of a singly linked list.
00189  */
00190 typedef struct slist_node slist_node;
00191 struct slist_node
00192 {
00193     slist_node *next;
00194 };
00195 
00196 /*
00197  * Head of a singly linked list.
00198  *
00199  * Singly linked lists are not circularly linked, in contrast to doubly linked
00200  * lists; we just set head.next to NULL if empty.  This doesn't incur any
00201  * additional branches in the usual manipulations.
00202  */
00203 typedef struct slist_head
00204 {
00205     slist_node  head;
00206 } slist_head;
00207 
00208 /*
00209  * Singly linked list iterator.
00210  *
00211  * Used as state in slist_foreach(). To get the current element of the
00212  * iteration use the 'cur' member.
00213  *
00214  * Do *not* manipulate the list while iterating!
00215  *
00216  * NB: this wouldn't really need to be an extra struct, we could use a
00217  * slist_node * directly. We prefer a separate type for consistency.
00218  */
00219 typedef struct slist_iter
00220 {
00221     slist_node *cur;
00222 } slist_iter;
00223 
00224 /*
00225  * Singly linked list iterator allowing some modifications while iterating.
00226  *
00227  * Used as state in slist_foreach_modify().
00228  *
00229  * Iterations using this are allowed to remove the current node and to add
00230  * more nodes ahead of the current node.
00231  */
00232 typedef struct slist_mutable_iter
00233 {
00234     slist_node *cur;            /* current element */
00235     slist_node *next;           /* next node we'll iterate to */
00236 } slist_mutable_iter;
00237 
00238 
00239 /* Static initializers */
00240 #define DLIST_STATIC_INIT(name) {{&(name).head, &(name).head}}
00241 #define SLIST_STATIC_INIT(name) {{NULL}}
00242 
00243 
00244 /* Prototypes for functions too big to be inline */
00245 
00246 /* Caution: this is O(n) */
00247 extern void slist_delete(slist_head *head, slist_node *node);
00248 
00249 #ifdef ILIST_DEBUG
00250 extern void dlist_check(dlist_head *head);
00251 extern void slist_check(slist_head *head);
00252 #else
00253 /*
00254  * These seemingly useless casts to void are here to keep the compiler quiet
00255  * about the argument being unused in many functions in a non-debug compile,
00256  * in which functions the only point of passing the list head pointer is to be
00257  * able to run these checks.
00258  */
00259 #define dlist_check(head)   ((void) (head))
00260 #define slist_check(head)   ((void) (head))
00261 #endif   /* ILIST_DEBUG */
00262 
00263 
00264 /*
00265  * We want the functions below to be inline; but if the compiler doesn't
00266  * support that, fall back on providing them as regular functions.  See
00267  * STATIC_IF_INLINE in c.h.
00268  */
00269 #ifndef PG_USE_INLINE
00270 extern void dlist_init(dlist_head *head);
00271 extern bool dlist_is_empty(dlist_head *head);
00272 extern void dlist_push_head(dlist_head *head, dlist_node *node);
00273 extern void dlist_push_tail(dlist_head *head, dlist_node *node);
00274 extern void dlist_insert_after(dlist_node *after, dlist_node *node);
00275 extern void dlist_insert_before(dlist_node *before, dlist_node *node);
00276 extern void dlist_delete(dlist_node *node);
00277 extern dlist_node *dlist_pop_head_node(dlist_head *head);
00278 extern void dlist_move_head(dlist_head *head, dlist_node *node);
00279 extern bool dlist_has_next(dlist_head *head, dlist_node *node);
00280 extern bool dlist_has_prev(dlist_head *head, dlist_node *node);
00281 extern dlist_node *dlist_next_node(dlist_head *head, dlist_node *node);
00282 extern dlist_node *dlist_prev_node(dlist_head *head, dlist_node *node);
00283 extern dlist_node *dlist_head_node(dlist_head *head);
00284 extern dlist_node *dlist_tail_node(dlist_head *head);
00285 
00286 /* dlist macro support functions */
00287 extern void *dlist_tail_element_off(dlist_head *head, size_t off);
00288 extern void *dlist_head_element_off(dlist_head *head, size_t off);
00289 #endif   /* !PG_USE_INLINE */
00290 
00291 #if defined(PG_USE_INLINE) || defined(ILIST_INCLUDE_DEFINITIONS)
00292 /*
00293  * Initialize a doubly linked list.
00294  * Previous state will be thrown away without any cleanup.
00295  */
00296 STATIC_IF_INLINE void
00297 dlist_init(dlist_head *head)
00298 {
00299     head->head.next = head->head.prev = &head->head;
00300 }
00301 
00302 /*
00303  * Is the list empty?
00304  *
00305  * An empty list has either its first 'next' pointer set to NULL, or to itself.
00306  */
00307 STATIC_IF_INLINE bool
00308 dlist_is_empty(dlist_head *head)
00309 {
00310     dlist_check(head);
00311 
00312     return head->head.next == NULL || head->head.next == &(head->head);
00313 }
00314 
00315 /*
00316  * Insert a node at the beginning of the list.
00317  */
00318 STATIC_IF_INLINE void
00319 dlist_push_head(dlist_head *head, dlist_node *node)
00320 {
00321     if (head->head.next == NULL)    /* convert NULL header to circular */
00322         dlist_init(head);
00323 
00324     node->next = head->head.next;
00325     node->prev = &head->head;
00326     node->next->prev = node;
00327     head->head.next = node;
00328 
00329     dlist_check(head);
00330 }
00331 
00332 /*
00333  * Insert a node at the end of the list.
00334  */
00335 STATIC_IF_INLINE void
00336 dlist_push_tail(dlist_head *head, dlist_node *node)
00337 {
00338     if (head->head.next == NULL)    /* convert NULL header to circular */
00339         dlist_init(head);
00340 
00341     node->next = &head->head;
00342     node->prev = head->head.prev;
00343     node->prev->next = node;
00344     head->head.prev = node;
00345 
00346     dlist_check(head);
00347 }
00348 
00349 /*
00350  * Insert a node after another *in the same list*
00351  */
00352 STATIC_IF_INLINE void
00353 dlist_insert_after(dlist_node *after, dlist_node *node)
00354 {
00355     node->prev = after;
00356     node->next = after->next;
00357     after->next = node;
00358     node->next->prev = node;
00359 }
00360 
00361 /*
00362  * Insert a node before another *in the same list*
00363  */
00364 STATIC_IF_INLINE void
00365 dlist_insert_before(dlist_node *before, dlist_node *node)
00366 {
00367     node->prev = before->prev;
00368     node->next = before;
00369     before->prev = node;
00370     node->prev->next = node;
00371 }
00372 
00373 /*
00374  * Delete 'node' from its list (it must be in one).
00375  */
00376 STATIC_IF_INLINE void
00377 dlist_delete(dlist_node *node)
00378 {
00379     node->prev->next = node->next;
00380     node->next->prev = node->prev;
00381 }
00382 
00383 /*
00384  * Remove and return the first node from a list (there must be one).
00385  */
00386 STATIC_IF_INLINE dlist_node *
00387 dlist_pop_head_node(dlist_head *head)
00388 {
00389     dlist_node *node;
00390 
00391     Assert(!dlist_is_empty(head));
00392     node = head->head.next;
00393     dlist_delete(node);
00394     return node;
00395 }
00396 
00397 /*
00398  * Move element from its current position in the list to the head position in
00399  * the same list.
00400  *
00401  * Undefined behaviour if 'node' is not already part of the list.
00402  */
00403 STATIC_IF_INLINE void
00404 dlist_move_head(dlist_head *head, dlist_node *node)
00405 {
00406     /* fast path if it's already at the head */
00407     if (head->head.next == node)
00408         return;
00409 
00410     dlist_delete(node);
00411     dlist_push_head(head, node);
00412 
00413     dlist_check(head);
00414 }
00415 
00416 /*
00417  * Check whether 'node' has a following node.
00418  * Caution: unreliable if 'node' is not in the list.
00419  */
00420 STATIC_IF_INLINE bool
00421 dlist_has_next(dlist_head *head, dlist_node *node)
00422 {
00423     return node->next != &head->head;
00424 }
00425 
00426 /*
00427  * Check whether 'node' has a preceding node.
00428  * Caution: unreliable if 'node' is not in the list.
00429  */
00430 STATIC_IF_INLINE bool
00431 dlist_has_prev(dlist_head *head, dlist_node *node)
00432 {
00433     return node->prev != &head->head;
00434 }
00435 
00436 /*
00437  * Return the next node in the list (there must be one).
00438  */
00439 STATIC_IF_INLINE dlist_node *
00440 dlist_next_node(dlist_head *head, dlist_node *node)
00441 {
00442     Assert(dlist_has_next(head, node));
00443     return node->next;
00444 }
00445 
00446 /*
00447  * Return previous node in the list (there must be one).
00448  */
00449 STATIC_IF_INLINE dlist_node *
00450 dlist_prev_node(dlist_head *head, dlist_node *node)
00451 {
00452     Assert(dlist_has_prev(head, node));
00453     return node->prev;
00454 }
00455 
00456 /* internal support function to get address of head element's struct */
00457 STATIC_IF_INLINE void *
00458 dlist_head_element_off(dlist_head *head, size_t off)
00459 {
00460     Assert(!dlist_is_empty(head));
00461     return (char *) head->head.next - off;
00462 }
00463 
00464 /*
00465  * Return the first node in the list (there must be one).
00466  */
00467 STATIC_IF_INLINE dlist_node *
00468 dlist_head_node(dlist_head *head)
00469 {
00470     return (dlist_node *) dlist_head_element_off(head, 0);
00471 }
00472 
00473 /* internal support function to get address of tail element's struct */
00474 STATIC_IF_INLINE void *
00475 dlist_tail_element_off(dlist_head *head, size_t off)
00476 {
00477     Assert(!dlist_is_empty(head));
00478     return (char *) head->head.prev - off;
00479 }
00480 
00481 /*
00482  * Return the last node in the list (there must be one).
00483  */
00484 STATIC_IF_INLINE dlist_node *
00485 dlist_tail_node(dlist_head *head)
00486 {
00487     return (dlist_node *) dlist_tail_element_off(head, 0);
00488 }
00489 #endif   /* PG_USE_INLINE || ILIST_INCLUDE_DEFINITIONS */
00490 
00491 /*
00492  * Return the containing struct of 'type' where 'membername' is the dlist_node
00493  * pointed at by 'ptr'.
00494  *
00495  * This is used to convert a dlist_node * back to its containing struct.
00496  */
00497 #define dlist_container(type, membername, ptr)                              \
00498     (AssertVariableIsOfTypeMacro(ptr, dlist_node *),                        \
00499      AssertVariableIsOfTypeMacro(((type *) NULL)->membername, dlist_node),  \
00500      ((type *) ((char *) (ptr) - offsetof(type, membername))))
00501 
00502 /*
00503  * Return the address of the first element in the list.
00504  *
00505  * The list must not be empty.
00506  */
00507 #define dlist_head_element(type, membername, lhead)                         \
00508     (AssertVariableIsOfTypeMacro(((type *) NULL)->membername, dlist_node),  \
00509      (type *) dlist_head_element_off(lhead, offsetof(type, membername)))
00510 
00511 /*
00512  * Return the address of the last element in the list.
00513  *
00514  * The list must not be empty.
00515  */
00516 #define dlist_tail_element(type, membername, lhead)                         \
00517     (AssertVariableIsOfTypeMacro(((type *) NULL)->membername, dlist_node),  \
00518      ((type *) dlist_tail_element_off(lhead, offsetof(type, membername))))
00519 
00520 /*
00521  * Iterate through the list pointed at by 'lhead' storing the state in 'iter'.
00522  *
00523  * Access the current element with iter.cur.
00524  *
00525  * It is *not* allowed to manipulate the list during iteration.
00526  */
00527 #define dlist_foreach(iter, lhead)                                          \
00528     for (AssertVariableIsOfTypeMacro(iter, dlist_iter),                     \
00529          AssertVariableIsOfTypeMacro(lhead, dlist_head *),                  \
00530          (iter).end = &(lhead)->head,                                       \
00531          (iter).cur = (iter).end->next ? (iter).end->next : (iter).end;     \
00532          (iter).cur != (iter).end;                                          \
00533          (iter).cur = (iter).cur->next)
00534 
00535 /*
00536  * Iterate through the list pointed at by 'lhead' storing the state in 'iter'.
00537  *
00538  * Access the current element with iter.cur.
00539  *
00540  * Iterations using this are only allowed to change the list at the current
00541  * point of iteration. It is fine to delete the current node, but it is *not*
00542  * fine to insert or delete adjacent nodes.
00543  */
00544 #define dlist_foreach_modify(iter, lhead)                                   \
00545     for (AssertVariableIsOfTypeMacro(iter, dlist_mutable_iter),             \
00546          AssertVariableIsOfTypeMacro(lhead, dlist_head *),                  \
00547          (iter).end = &(lhead)->head,                                       \
00548          (iter).cur = (iter).end->next ? (iter).end->next : (iter).end,     \
00549          (iter).next = (iter).cur->next;                                    \
00550          (iter).cur != (iter).end;                                          \
00551          (iter).cur = (iter).next, (iter).next = (iter).cur->next)
00552 
00553 /*
00554  * Iterate through the list in reverse order.
00555  *
00556  * It is *not* allowed to manipulate the list during iteration.
00557  */
00558 #define dlist_reverse_foreach(iter, lhead)                                  \
00559     for (AssertVariableIsOfTypeMacro(iter, dlist_iter),                     \
00560          AssertVariableIsOfTypeMacro(lhead, dlist_head *),                  \
00561          (iter).end = &(lhead)->head,                                       \
00562          (iter).cur = (iter).end->prev ? (iter).end->prev : (iter).end;     \
00563          (iter).cur != (iter).end;                                          \
00564          (iter).cur = (iter).cur->prev)
00565 
00566 
00567 /*
00568  * We want the functions below to be inline; but if the compiler doesn't
00569  * support that, fall back on providing them as regular functions.  See
00570  * STATIC_IF_INLINE in c.h.
00571  */
00572 #ifndef PG_USE_INLINE
00573 extern void slist_init(slist_head *head);
00574 extern bool slist_is_empty(slist_head *head);
00575 extern void slist_push_head(slist_head *head, slist_node *node);
00576 extern void slist_insert_after(slist_node *after, slist_node *node);
00577 extern slist_node *slist_pop_head_node(slist_head *head);
00578 extern bool slist_has_next(slist_head *head, slist_node *node);
00579 extern slist_node *slist_next_node(slist_head *head, slist_node *node);
00580 extern slist_node *slist_head_node(slist_head *head);
00581 
00582 /* slist macro support function */
00583 extern void *slist_head_element_off(slist_head *head, size_t off);
00584 #endif
00585 
00586 #if defined(PG_USE_INLINE) || defined(ILIST_INCLUDE_DEFINITIONS)
00587 /*
00588  * Initialize a singly linked list.
00589  * Previous state will be thrown away without any cleanup.
00590  */
00591 STATIC_IF_INLINE void
00592 slist_init(slist_head *head)
00593 {
00594     head->head.next = NULL;
00595 }
00596 
00597 /*
00598  * Is the list empty?
00599  */
00600 STATIC_IF_INLINE bool
00601 slist_is_empty(slist_head *head)
00602 {
00603     slist_check(head);
00604 
00605     return head->head.next == NULL;
00606 }
00607 
00608 /*
00609  * Insert a node at the beginning of the list.
00610  */
00611 STATIC_IF_INLINE void
00612 slist_push_head(slist_head *head, slist_node *node)
00613 {
00614     node->next = head->head.next;
00615     head->head.next = node;
00616 
00617     slist_check(head);
00618 }
00619 
00620 /*
00621  * Insert a node after another *in the same list*
00622  */
00623 STATIC_IF_INLINE void
00624 slist_insert_after(slist_node *after, slist_node *node)
00625 {
00626     node->next = after->next;
00627     after->next = node;
00628 }
00629 
00630 /*
00631  * Remove and return the first node from a list (there must be one).
00632  */
00633 STATIC_IF_INLINE slist_node *
00634 slist_pop_head_node(slist_head *head)
00635 {
00636     slist_node *node;
00637 
00638     Assert(!slist_is_empty(head));
00639     node = head->head.next;
00640     head->head.next = node->next;
00641     slist_check(head);
00642     return node;
00643 }
00644 
00645 /*
00646  * Check whether 'node' has a following node.
00647  */
00648 STATIC_IF_INLINE bool
00649 slist_has_next(slist_head *head, slist_node *node)
00650 {
00651     slist_check(head);
00652 
00653     return node->next != NULL;
00654 }
00655 
00656 /*
00657  * Return the next node in the list (there must be one).
00658  */
00659 STATIC_IF_INLINE slist_node *
00660 slist_next_node(slist_head *head, slist_node *node)
00661 {
00662     Assert(slist_has_next(head, node));
00663     return node->next;
00664 }
00665 
00666 /* internal support function to get address of head element's struct */
00667 STATIC_IF_INLINE void *
00668 slist_head_element_off(slist_head *head, size_t off)
00669 {
00670     Assert(!slist_is_empty(head));
00671     return (char *) head->head.next - off;
00672 }
00673 
00674 /*
00675  * Return the first node in the list (there must be one).
00676  */
00677 STATIC_IF_INLINE slist_node *
00678 slist_head_node(slist_head *head)
00679 {
00680     return (slist_node *) slist_head_element_off(head, 0);
00681 }
00682 #endif   /* PG_USE_INLINE || ILIST_INCLUDE_DEFINITIONS */
00683 
00684 /*
00685  * Return the containing struct of 'type' where 'membername' is the slist_node
00686  * pointed at by 'ptr'.
00687  *
00688  * This is used to convert a slist_node * back to its containing struct.
00689  */
00690 #define slist_container(type, membername, ptr)                              \
00691     (AssertVariableIsOfTypeMacro(ptr, slist_node *),                        \
00692      AssertVariableIsOfTypeMacro(((type *) NULL)->membername, slist_node),  \
00693      ((type *) ((char *) (ptr) - offsetof(type, membername))))
00694 
00695 /*
00696  * Return the address of the first element in the list.
00697  *
00698  * The list must not be empty.
00699  */
00700 #define slist_head_element(type, membername, lhead)                         \
00701     (AssertVariableIsOfTypeMacro(((type *) NULL)->membername, slist_node),  \
00702      (type *) slist_head_element_off(lhead, offsetof(type, membername)))
00703 
00704 /*
00705  * Iterate through the list pointed at by 'lhead' storing the state in 'iter'.
00706  *
00707  * Access the current element with iter.cur.
00708  *
00709  * It is *not* allowed to manipulate the list during iteration.
00710  */
00711 #define slist_foreach(iter, lhead)                                          \
00712     for (AssertVariableIsOfTypeMacro(iter, slist_iter),                     \
00713          AssertVariableIsOfTypeMacro(lhead, slist_head *),                  \
00714          (iter).cur = (lhead)->head.next;                                   \
00715          (iter).cur != NULL;                                                \
00716          (iter).cur = (iter).cur->next)
00717 
00718 /*
00719  * Iterate through the list pointed at by 'lhead' storing the state in 'iter'.
00720  *
00721  * Access the current element with iter.cur.
00722  *
00723  * Iterations using this are allowed to remove the current node and to add
00724  * more nodes ahead of the current node.
00725  */
00726 #define slist_foreach_modify(iter, lhead)                                   \
00727     for (AssertVariableIsOfTypeMacro(iter, slist_mutable_iter),             \
00728          AssertVariableIsOfTypeMacro(lhead, slist_head *),                  \
00729          (iter).cur = (lhead)->head.next,                                   \
00730          (iter).next = (iter).cur ? (iter).cur->next : NULL;                \
00731          (iter).cur != NULL;                                                \
00732          (iter).cur = (iter).next,                                          \
00733          (iter).next = (iter).next ? (iter).next->next : NULL)
00734 
00735 #endif   /* ILIST_H */