Main Page | Modules | Data Structures | File List | Data Fields

queue.h

00001 /*  $Id: queue.h,v 1.2 2005/12/04 20:41:15 tho Exp $ */
00002 /*  $OpenBSD: queue.h,v 1.22 2001/06/23 04:39:35 angelos Exp $  */
00003 /*  $NetBSD: queue.h,v 1.11 1996/05/16 05:17:14 mycroft Exp $   */
00004 
00005 #ifndef _U_QUEUE_H_
00006 #define _U_QUEUE_H_
00007 
00008 
00009 /* A list is headed by a single forward pointer (or an array of forward
00010  * pointers for a hash table header). The elements are doubly linked so that
00011  * an arbitrary element can be removed without a need to traverse the list. 
00012  * New elements can be added to the list before or after an existing element 
00013  * or at the head of the list. A list may only be traversed in the forward 
00014  * direction. */
00015 
00016 #define LIST_HEAD(name, type)                                           \
00017 struct name {                                                           \
00018         struct type *lh_first;  /* first element */                     \
00019 }
00020 
00021 #define LIST_HEAD_INITIALIZER(head)                                     \
00022         { NULL }
00023 
00024 #define LIST_ENTRY(type)                                                \
00025 struct {                                                                \
00026         struct type *le_next;   /* next element */                      \
00027         struct type **le_prev;  /* address of previous next element */  \
00028 }
00029 
00030 #define LIST_FIRST(head)                ((head)->lh_first)
00031 #define LIST_END(head)                  NULL
00032 #define LIST_EMPTY(head)                (LIST_FIRST(head) == LIST_END(head))
00033 #define LIST_NEXT(elm, field)           ((elm)->field.le_next)
00034 
00035 #define LIST_FOREACH(var, head, field)                                  \
00036         for((var) = LIST_FIRST(head);                                   \
00037             (var)!= LIST_END(head);                                     \
00038             (var) = LIST_NEXT(var, field))
00039 
00040 #define LIST_INIT(head) do {                                            \
00041         LIST_FIRST(head) = LIST_END(head);                              \
00042 } while (0)
00043 
00044 #define LIST_INSERT_AFTER(listelm, elm, field) do {                     \
00045         if (((elm)->field.le_next = (listelm)->field.le_next) != NULL)  \
00046                 (listelm)->field.le_next->field.le_prev =               \
00047                     &(elm)->field.le_next;                              \
00048         (listelm)->field.le_next = (elm);                               \
00049         (elm)->field.le_prev = &(listelm)->field.le_next;               \
00050 } while (0)
00051 
00052 #define LIST_INSERT_BEFORE(listelm, elm, field) do {                    \
00053         (elm)->field.le_prev = (listelm)->field.le_prev;                \
00054         (elm)->field.le_next = (listelm);                               \
00055         *(listelm)->field.le_prev = (elm);                              \
00056         (listelm)->field.le_prev = &(elm)->field.le_next;               \
00057 } while (0)
00058 
00059 #define LIST_INSERT_HEAD(head, elm, field) do {                         \
00060         if (((elm)->field.le_next = (head)->lh_first) != NULL)          \
00061                 (head)->lh_first->field.le_prev = &(elm)->field.le_next;\
00062         (head)->lh_first = (elm);                                       \
00063         (elm)->field.le_prev = &(head)->lh_first;                       \
00064 } while (0)
00065 
00066 #define LIST_REMOVE(elm, field) do {                                    \
00067         if ((elm)->field.le_next != NULL)                               \
00068                 (elm)->field.le_next->field.le_prev =                   \
00069                     (elm)->field.le_prev;                               \
00070         *(elm)->field.le_prev = (elm)->field.le_next;                   \
00071 } while (0)
00072 
00073 #define LIST_REPLACE(elm, elm2, field) do {                             \
00074         if (((elm2)->field.le_next = (elm)->field.le_next) != NULL)     \
00075                 (elm2)->field.le_next->field.le_prev =                  \
00076                     &(elm2)->field.le_next;                             \
00077         (elm2)->field.le_prev = (elm)->field.le_prev;                   \
00078         *(elm2)->field.le_prev = (elm2);                                \
00079 } while (0)
00080 
00081 
00082 /* A tail queue is headed by a pair of pointers, one to the head of the
00083  * list and the other to the tail of the list. The elements are doubly
00084  * linked so that an arbitrary element can be removed without a need to
00085  * traverse the list. New elements can be added to the list after
00086  * an existing element, at the head of the list, or at the end of the
00087  * list. A tail queue may only be traversed in the forward direction. */
00088 
00089 /* Tail queue definitions. */
00090 #define TAILQ_HEAD(name, type)                                              \
00091 struct name {                                                               \
00092         struct type *tqh_first;     /* first element */                     \
00093         struct type **tqh_last;     /* addr of last next element */         \
00094 }
00095 
00096 #define TAILQ_ENTRY(type)                                                   \
00097 struct {                                                                    \
00098         struct type *tqe_next;      /* next element */                      \
00099         struct type **tqe_prev;     /* address of previous next element */  \
00100 }
00101 
00102 /* Tail queue functions. */
00103 #define TAILQ_INIT(head) {                                                  \
00104         (head)->tqh_first = NULL;                                           \
00105         (head)->tqh_last = &(head)->tqh_first;                              \
00106 }
00107 
00108 #define TAILQ_INSERT_HEAD(head, elm, field) {                               \
00109         if (((elm)->field.tqe_next = (head)->tqh_first) != NULL)            \
00110                 (elm)->field.tqe_next->field.tqe_prev =                     \
00111                     &(elm)->field.tqe_next;                                 \
00112         else                                                                \
00113                 (head)->tqh_last = &(elm)->field.tqe_next;                  \
00114         (head)->tqh_first = (elm);                                          \
00115         (elm)->field.tqe_prev = &(head)->tqh_first;                         \
00116 }
00117 
00118 #define TAILQ_INSERT_TAIL(head, elm, field) {                               \
00119         (elm)->field.tqe_next = NULL;                                       \
00120         (elm)->field.tqe_prev = (head)->tqh_last;                           \
00121         *(head)->tqh_last = (elm);                                          \
00122         (head)->tqh_last = &(elm)->field.tqe_next;                          \
00123 }
00124 
00125 #define TAILQ_INSERT_AFTER(head, listelm, elm, field) {                     \
00126         if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)    \
00127                 (elm)->field.tqe_next->field.tqe_prev =                     \
00128                     &(elm)->field.tqe_next;                                 \
00129         else                                                                \
00130                 (head)->tqh_last = &(elm)->field.tqe_next;                  \
00131         (listelm)->field.tqe_next = (elm);                                  \
00132         (elm)->field.tqe_prev = &(listelm)->field.tqe_next;                 \
00133 }
00134 
00135 #define TAILQ_INSERT_BEFORE(listelm, elm, field) do {                       \
00136         (elm)->field.tqe_prev = (listelm)->field.tqe_prev;                  \
00137         (elm)->field.tqe_next = (listelm);                                  \
00138         *(listelm)->field.tqe_prev = (elm);                                 \
00139         (listelm)->field.tqe_prev = &(elm)->field.tqe_next;                 \
00140 } while (0)
00141 
00142 #define TAILQ_REMOVE(head, elm, field) {                                    \
00143         if (((elm)->field.tqe_next) != NULL)                                \
00144                 (elm)->field.tqe_next->field.tqe_prev =                     \
00145                     (elm)->field.tqe_prev;                                  \
00146         else                                                                \
00147                 (head)->tqh_last = (elm)->field.tqe_prev;                   \
00148         *(elm)->field.tqe_prev = (elm)->field.tqe_next;                     \
00149 }
00150 
00151 
00152 /* A circle queue is headed by a pair of pointers, one to the head of the
00153  * list and the other to the tail of the list. The elements are doubly
00154  * linked so that an arbitrary element can be removed without a need to
00155  * traverse the list. New elements can be added to the list before or after
00156  * an existing element, at the head of the list, or at the end of the list.
00157  * A circle queue may be traversed in either direction, but has a more
00158  * complex end of list detection. */
00159 
00160 /* Circular queue definitions. */
00161 #define CIRCLEQ_HEAD(name, type)                                            \
00162 struct name {                                                               \
00163         struct type *cqh_first;               /* first element */           \
00164         struct type *cqh_last;                /* last element */            \
00165 }
00166 
00167 #define CIRCLEQ_ENTRY(type)                                                 \
00168 struct {                                                                    \
00169         struct type *cqe_next;                /* next element */            \
00170         struct type *cqe_prev;                /* previous element */        \
00171 }
00172 
00173 /* Circular queue functions. */
00174 #define CIRCLEQ_INIT(head) {                                                \
00175         (head)->cqh_first = (void *)(head);                                 \
00176         (head)->cqh_last = (void *)(head);                                  \
00177 }
00178 
00179 #define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) {                   \
00180         (elm)->field.cqe_next = (listelm)->field.cqe_next;                  \
00181         (elm)->field.cqe_prev = (listelm);                                  \
00182         if ((listelm)->field.cqe_next == (void *)(head))                    \
00183                 (head)->cqh_last = (elm);                                   \
00184         else                                                                \
00185                 (listelm)->field.cqe_next->field.cqe_prev = (elm);          \
00186         (listelm)->field.cqe_next = (elm);                                  \
00187 }
00188 
00189 #define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) {                  \
00190         (elm)->field.cqe_next = (listelm);                                  \
00191         (elm)->field.cqe_prev = (listelm)->field.cqe_prev;                  \
00192         if ((listelm)->field.cqe_prev == (void *)(head))                    \
00193                 (head)->cqh_first = (elm);                                  \
00194         else                                                                \
00195                 (listelm)->field.cqe_prev->field.cqe_next = (elm);          \
00196         (listelm)->field.cqe_prev = (elm);                                  \
00197 }
00198 
00199 #define CIRCLEQ_INSERT_HEAD(head, elm, field) {                             \
00200         (elm)->field.cqe_next = (head)->cqh_first;                          \
00201         (elm)->field.cqe_prev = (void *)(head);                             \
00202         if ((head)->cqh_last == (void *)(head))                             \
00203                 (head)->cqh_last = (elm);                                   \
00204         else                                                                \
00205                 (head)->cqh_first->field.cqe_prev = (elm);                  \
00206         (head)->cqh_first = (elm);                                          \
00207 }
00208 
00209 #define CIRCLEQ_INSERT_TAIL(head, elm, field) {                             \
00210         (elm)->field.cqe_next = (void *)(head);                             \
00211         (elm)->field.cqe_prev = (head)->cqh_last;                           \
00212         if ((head)->cqh_first == (void *)(head))                            \
00213                 (head)->cqh_first = (elm);                                  \
00214         else                                                                \
00215                 (head)->cqh_last->field.cqe_next = (elm);                   \
00216         (head)->cqh_last = (elm);                                           \
00217 }
00218 
00219 #define CIRCLEQ_REMOVE(head, elm, field) {                                  \
00220         if ((elm)->field.cqe_next == (void *)(head))                        \
00221                 (head)->cqh_last = (elm)->field.cqe_prev;                   \
00222         else                                                                \
00223                 (elm)->field.cqe_next->field.cqe_prev =                     \
00224                     (elm)->field.cqe_prev;                                  \
00225         if ((elm)->field.cqe_prev == (void *)(head))                        \
00226                 (head)->cqh_first = (elm)->field.cqe_next;                  \
00227         else                                                                \
00228                 (elm)->field.cqe_prev->field.cqe_next =                     \
00229                     (elm)->field.cqe_next;                                  \
00230 }
00231 
00232 #ifndef LIST_ENTRY_NULL
00233 #define LIST_ENTRY_NULL { NULL, NULL }
00234 #endif
00235 
00236 #ifndef LIST_FOREACH
00237 #define LIST_FOREACH(var, head, entries)                                    \
00238     for (var = (head)->lh_first; var != NULL; var = var->entries.le_next)
00239 #endif
00240 
00241 #ifndef LIST_FIRST
00242 #define LIST_FIRST(head)    ((head)->lh_first)
00243 #endif 
00244 
00245 #ifndef TAILQ_ENTRY_NULL
00246 #define TAILQ_ENTRY_NULL { NULL, NULL }
00247 #endif
00248 
00249 #ifndef TAILQ_FIRST
00250 #define TAILQ_FIRST(head)   ((head)->tqh_first)
00251 #endif 
00252 
00253 #ifndef TAILQ_END
00254 #define TAILQ_END(head)     NULL
00255 #endif
00256 
00257 #ifndef TAILQ_NEXT
00258 #define TAILQ_NEXT(elm, field)  ((elm)->field.tqe_next)
00259 #endif
00260 
00261 #ifndef TAILQ_LAST
00262 #define TAILQ_LAST(head, headname)                                          \
00263         (*(((struct headname *)((head)->tqh_last))->tqh_last))
00264 #endif
00265 
00266 #ifndef TAILQ_PREV
00267 #define TAILQ_PREV(elm, headname, field)                                    \
00268         (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
00269 #endif
00270 
00271 #ifndef TAILQ_EMPTY
00272 #define TAILQ_EMPTY(head)                                                   \
00273         (TAILQ_FIRST(head) == TAILQ_END(head))
00274 #endif
00275 
00276 #ifndef TAILQ_FOREACH
00277 #define TAILQ_FOREACH(var, head, field)                                     \
00278         for((var) = TAILQ_FIRST(head);                                      \
00279             (var) != TAILQ_END(head);                                       \
00280             (var) = TAILQ_NEXT(var, field))
00281 #endif
00282 
00283 #ifndef TAILQ_FOREACH_REVERSE
00284 #define TAILQ_FOREACH_REVERSE(var, head, field, headname)                   \
00285         for((var) = TAILQ_LAST(head, headname);                             \
00286             (var) != TAILQ_END(head);                                       \
00287             (var) = TAILQ_PREV(var, headname, field))
00288 #endif
00289 
00290 #endif /* !_U_QUEUE_H_ */

←Products
© 2005-2006 - KoanLogic S.r.l. - All rights reserved