Back to index

openldap  2.4.31
ldap_queue.h
Go to the documentation of this file.
00001 /* ldap_queue.h -- queue macros */
00002 /* $OpenLDAP$ */
00003 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
00004  *
00005  * Copyright 2001-2012 The OpenLDAP Foundation.
00006  * All rights reserved.
00007  *
00008  * Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted only as authorized by the OpenLDAP
00010  * Public License.
00011  *
00012  * A copy of this license is available in file LICENSE in the
00013  * top-level directory of the distribution or, alternatively, at
00014  * <http://www.OpenLDAP.org/license.html>.
00015  */
00016 /* Copyright (c) 1991, 1993
00017  *     The Regents of the University of California.  All rights reserved.
00018  *
00019  * Redistribution and use in source and binary forms, with or without
00020  * modification, are permitted provided that the following conditions
00021  * are met:
00022  * 1. Redistributions of source code must retain the above copyright
00023  *    notice, this list of conditions and the following disclaimer.
00024  * 2. Redistributions in binary form must reproduce the above copyright
00025  *    notice, this list of conditions and the following disclaimer in the
00026  *    documentation and/or other materials provided with the distribution.
00027  * 3. All advertising materials mentioning features or use of this software
00028  *    must display the following acknowledgement:
00029  *     This product includes software developed by the University of
00030  *     California, Berkeley and its contributors.
00031  * 4. Neither the name of the University nor the names of its contributors
00032  *    may be used to endorse or promote products derived from this software
00033  *    without specific prior written permission.
00034  *
00035  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00036  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00037  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00038  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00039  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00040  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00041  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00042  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00043  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00044  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00045  * SUCH DAMAGE.
00046  *
00047  *     @(#)queue.h   8.5 (Berkeley) 8/20/94
00048  * $FreeBSD: src/sys/sys/queue.h,v 1.32.2.5 2001/09/30 21:12:54 luigi Exp $
00049  *
00050  * See also: ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
00051  */
00052 /* ACKNOWLEDGEMENTS:
00053  * This work is derived from FreeBSD queue.h work.  Adapted for use in
00054  * OpenLDAP Software by Kurt D. Zeilenga.
00055  */
00056 
00057 #ifndef _LDAP_QUEUE_H_
00058 #define       _LDAP_QUEUE_H_
00059 
00060 /*
00061  * This file defines five types of data structures: singly-linked lists,
00062  * singly-linked tail queues, lists, tail queues, and circular queues.
00063  *
00064  * A singly-linked list is headed by a single forward pointer. The elements
00065  * are singly linked for minimum space and pointer manipulation overhead at
00066  * the expense of O(n) removal for arbitrary elements. New elements can be
00067  * added to the list after an existing element or at the head of the list.
00068  * Elements being removed from the head of the list should use the explicit
00069  * macro for this purpose for optimum efficiency. A singly-linked list may
00070  * only be traversed in the forward direction.  Singly-linked lists are ideal
00071  * for applications with large datasets and few or no removals or for
00072  * implementing a LIFO queue.
00073  *
00074  * A singly-linked tail queue is headed by a pair of pointers, one to the
00075  * head of the list and the other to the tail of the list. The elements are
00076  * singly linked for minimum space and pointer manipulation overhead at the
00077  * expense of O(n) removal for arbitrary elements. New elements can be added
00078  * to the list after an existing element, at the head of the list, or at the
00079  * end of the list. Elements being removed from the head of the tail queue
00080  * should use the explicit macro for this purpose for optimum efficiency.
00081  * A singly-linked tail queue may only be traversed in the forward direction.
00082  * Singly-linked tail queues are ideal for applications with large datasets
00083  * and few or no removals or for implementing a FIFO queue.
00084  *
00085  * A list is headed by a single forward pointer (or an array of forward
00086  * pointers for a hash table header). The elements are doubly linked
00087  * so that an arbitrary element can be removed without a need to
00088  * traverse the list. New elements can be added to the list before
00089  * or after an existing element or at the head of the list. A list
00090  * may only be traversed in the forward direction.
00091  *
00092  * A tail queue is headed by a pair of pointers, one to the head of the
00093  * list and the other to the tail of the list. The elements are doubly
00094  * linked so that an arbitrary element can be removed without a need to
00095  * traverse the list. New elements can be added to the list before or
00096  * after an existing element, at the head of the list, or at the end of
00097  * the list. A tail queue may be traversed in either direction.
00098  *
00099  * A circle queue is headed by a pair of pointers, one to the head of the
00100  * list and the other to the tail of the list. The elements are doubly
00101  * linked so that an arbitrary element can be removed without a need to
00102  * traverse the list. New elements can be added to the list before or after
00103  * an existing element, at the head of the list, or at the end of the list.
00104  * A circle queue may be traversed in either direction, but has a more
00105  * complex end of list detection.
00106  *
00107  * For details on the use of these macros, see the queue(3) manual page.
00108  * All macros are prefixed with LDAP_.
00109  *
00110  *                   SLIST_ LIST_  STAILQ_       TAILQ_ CIRCLEQ_
00111  * _HEAD             +      +      +      +      +
00112  * _ENTRY            +      +      +      +      +
00113  * _INIT             +      +      +      +      +
00114  * _ENTRY_INIT              +      +      +      +      +
00115  * _EMPTY            +      +      +      +      +
00116  * _FIRST            +      +      +      +      +
00117  * _NEXT             +      +      +      +      +
00118  * _PREV             -      -      -      +      +
00119  * _LAST             -      -      +      +      +
00120  * _FOREACH          +      +      +      +      +
00121  * _FOREACH_REVERSE  -      -      -      +      +
00122  * _INSERT_HEAD             +      +      +      +      +
00123  * _INSERT_BEFORE    -      +      -      +      +
00124  * _INSERT_AFTER     +      +      +      +      +
00125  * _INSERT_TAIL             -      -      +      +      +
00126  * _REMOVE_HEAD             +      -      +      -      -
00127  * _REMOVE           +      +      +      +      +
00128  *
00129  */
00130 
00131 /*
00132  * Singly-linked List definitions.
00133  */
00134 #define LDAP_SLIST_HEAD(name, type)                                   \
00135 struct name {                                                  \
00136        struct type *slh_first;     /* first element */                \
00137 }
00138 
00139 #define LDAP_SLIST_HEAD_INITIALIZER(head)                      \
00140        { NULL }
00141 
00142 #define LDAP_SLIST_ENTRY(type)                                        \
00143 struct {                                                       \
00144        struct type *sle_next;      /* next element */                 \
00145 }
00146 
00147 #define LDAP_SLIST_ENTRY_INITIALIZER(entry)                           \
00148        { NULL }
00149 
00150 /*
00151  * Singly-linked List functions.
00152  */
00153 #define       LDAP_SLIST_EMPTY(head)      ((head)->slh_first == NULL)
00154 
00155 #define       LDAP_SLIST_FIRST(head)      ((head)->slh_first)
00156 
00157 #define LDAP_SLIST_FOREACH(var, head, field)                          \
00158        for((var) = (head)->slh_first; (var); (var) = (var)->field.sle_next)
00159 
00160 #define LDAP_SLIST_INIT(head) {                                       \
00161        (head)->slh_first = NULL;                               \
00162 }
00163 
00164 #define LDAP_SLIST_ENTRY_INIT(var, field) {                           \
00165        (var)->field.sle_next = NULL;                                  \
00166 }
00167 
00168 #define LDAP_SLIST_INSERT_AFTER(slistelm, elm, field) do {            \
00169        (elm)->field.sle_next = (slistelm)->field.sle_next;            \
00170        (slistelm)->field.sle_next = (elm);                            \
00171 } while (0)
00172 
00173 #define LDAP_SLIST_INSERT_HEAD(head, elm, field) do {                 \
00174        (elm)->field.sle_next = (head)->slh_first;                     \
00175        (head)->slh_first = (elm);                              \
00176 } while (0)
00177 
00178 #define LDAP_SLIST_NEXT(elm, field)       ((elm)->field.sle_next)
00179 
00180 #define LDAP_SLIST_REMOVE_HEAD(head, field) do {               \
00181        (head)->slh_first = (head)->slh_first->field.sle_next;         \
00182 } while (0)
00183 
00184 #define LDAP_SLIST_REMOVE(head, elm, type, field) do {                \
00185        if ((head)->slh_first == (elm)) {                       \
00186               LDAP_SLIST_REMOVE_HEAD((head), field);                  \
00187        }                                                       \
00188        else {                                                  \
00189               struct type *curelm = (head)->slh_first;         \
00190               while( curelm->field.sle_next != (elm) )         \
00191                      curelm = curelm->field.sle_next;          \
00192               curelm->field.sle_next =                         \
00193                   curelm->field.sle_next->field.sle_next;             \
00194        }                                                       \
00195 } while (0)
00196 
00197 /*
00198  * Singly-linked Tail queue definitions.
00199  */
00200 #define LDAP_STAILQ_HEAD(name, type)                                  \
00201 struct name {                                                  \
00202        struct type *stqh_first;/* first element */                    \
00203        struct type **stqh_last;/* addr of last next element */        \
00204 }
00205 
00206 #define LDAP_STAILQ_HEAD_INITIALIZER(head)                            \
00207        { NULL, &(head).stqh_first }
00208 
00209 #define LDAP_STAILQ_ENTRY(type)                                       \
00210 struct {                                                       \
00211        struct type *stqe_next;     /* next element */                 \
00212 }
00213 
00214 #define LDAP_STAILQ_ENTRY_INITIALIZER(entry)                          \
00215        { NULL }
00216 
00217 /*
00218  * Singly-linked Tail queue functions.
00219  */
00220 #define LDAP_STAILQ_EMPTY(head) ((head)->stqh_first == NULL)
00221 
00222 #define       LDAP_STAILQ_INIT(head) do {                             \
00223        (head)->stqh_first = NULL;                              \
00224        (head)->stqh_last = &(head)->stqh_first;                \
00225 } while (0)
00226 
00227 #define LDAP_STAILQ_ENTRY_INIT(var, field) {                          \
00228        (entry)->field.stqe_next = NULL;                        \
00229 }
00230 
00231 #define LDAP_STAILQ_FIRST(head)    ((head)->stqh_first)
00232 
00233 #define       LDAP_STAILQ_LAST(head, type, field)                            \
00234        (LDAP_STAILQ_EMPTY(head) ?                              \
00235               NULL :                                           \
00236                ((struct type *)                                \
00237               ((char *)((head)->stqh_last) - offsetof(struct type, field))))
00238 
00239 #define LDAP_STAILQ_FOREACH(var, head, field)                         \
00240        for((var) = (head)->stqh_first; (var); (var) = (var)->field.stqe_next)
00241 
00242 #define LDAP_STAILQ_INSERT_HEAD(head, elm, field) do {                \
00243        if (((elm)->field.stqe_next = (head)->stqh_first) == NULL)     \
00244               (head)->stqh_last = &(elm)->field.stqe_next;            \
00245        (head)->stqh_first = (elm);                             \
00246 } while (0)
00247 
00248 #define LDAP_STAILQ_INSERT_TAIL(head, elm, field) do {                \
00249        (elm)->field.stqe_next = NULL;                                 \
00250        *(head)->stqh_last = (elm);                             \
00251        (head)->stqh_last = &(elm)->field.stqe_next;                   \
00252 } while (0)
00253 
00254 #define LDAP_STAILQ_INSERT_AFTER(head, tqelm, elm, field) do {        \
00255        if (((elm)->field.stqe_next = (tqelm)->field.stqe_next) == NULL)\
00256               (head)->stqh_last = &(elm)->field.stqe_next;            \
00257        (tqelm)->field.stqe_next = (elm);                       \
00258 } while (0)
00259 
00260 #define LDAP_STAILQ_NEXT(elm, field)      ((elm)->field.stqe_next)
00261 
00262 #define LDAP_STAILQ_REMOVE_HEAD(head, field) do {                     \
00263        if (((head)->stqh_first =                               \
00264             (head)->stqh_first->field.stqe_next) == NULL)             \
00265               (head)->stqh_last = &(head)->stqh_first;         \
00266 } while (0)
00267 
00268 #define LDAP_STAILQ_REMOVE_HEAD_UNTIL(head, elm, field) do {          \
00269        if (((head)->stqh_first = (elm)->field.stqe_next) == NULL)     \
00270               (head)->stqh_last = &(head)->stqh_first;         \
00271 } while (0)
00272 
00273 #define LDAP_STAILQ_REMOVE(head, elm, type, field) do {               \
00274        if ((head)->stqh_first == (elm)) {                      \
00275               LDAP_STAILQ_REMOVE_HEAD(head, field);                   \
00276        }                                                       \
00277        else {                                                  \
00278               struct type *curelm = (head)->stqh_first;        \
00279               while( curelm->field.stqe_next != (elm) )        \
00280                      curelm = curelm->field.stqe_next;         \
00281               if((curelm->field.stqe_next =                           \
00282                   curelm->field.stqe_next->field.stqe_next) == NULL)  \
00283                      (head)->stqh_last = &(curelm)->field.stqe_next;  \
00284        }                                                       \
00285 } while (0)
00286 
00287 /*
00288  * List definitions.
00289  */
00290 #define LDAP_LIST_HEAD(name, type)                             \
00291 struct name {                                                  \
00292        struct type *lh_first;      /* first element */                \
00293 }
00294 
00295 #define LDAP_LIST_HEAD_INITIALIZER(head)                       \
00296        { NULL }
00297 
00298 #define LDAP_LIST_ENTRY(type)                                         \
00299 struct {                                                       \
00300        struct type *le_next;       /* next element */                 \
00301        struct type **le_prev;      /* address of previous next element */    \
00302 }
00303 
00304 #define LDAP_LIST_ENTRY_INITIALIZER(entry)                     \
00305        { NULL, NULL }
00306 
00307 /*
00308  * List functions.
00309  */
00310 
00311 #define       LDAP_LIST_EMPTY(head) ((head)->lh_first == NULL)
00312 
00313 #define LDAP_LIST_FIRST(head)      ((head)->lh_first)
00314 
00315 #define LDAP_LIST_FOREACH(var, head, field)                           \
00316        for((var) = (head)->lh_first; (var); (var) = (var)->field.le_next)
00317 
00318 #define       LDAP_LIST_INIT(head) do {                               \
00319        (head)->lh_first = NULL;                                \
00320 } while (0)
00321 
00322 #define LDAP_LIST_ENTRY_INIT(var, field) do {                         \
00323        (var)->field.le_next = NULL;                                   \
00324        (var)->field.le_prev = NULL;                                   \
00325 } while (0)
00326 
00327 #define LDAP_LIST_INSERT_AFTER(listelm, elm, field) do {              \
00328        if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \
00329               (listelm)->field.le_next->field.le_prev =        \
00330                   &(elm)->field.le_next;                       \
00331        (listelm)->field.le_next = (elm);                       \
00332        (elm)->field.le_prev = &(listelm)->field.le_next;              \
00333 } while (0)
00334 
00335 #define LDAP_LIST_INSERT_BEFORE(listelm, elm, field) do {             \
00336        (elm)->field.le_prev = (listelm)->field.le_prev;        \
00337        (elm)->field.le_next = (listelm);                       \
00338        *(listelm)->field.le_prev = (elm);                      \
00339        (listelm)->field.le_prev = &(elm)->field.le_next;              \
00340 } while (0)
00341 
00342 #define LDAP_LIST_INSERT_HEAD(head, elm, field) do {                  \
00343        if (((elm)->field.le_next = (head)->lh_first) != NULL)         \
00344               (head)->lh_first->field.le_prev = &(elm)->field.le_next;\
00345        (head)->lh_first = (elm);                               \
00346        (elm)->field.le_prev = &(head)->lh_first;               \
00347 } while (0)
00348 
00349 #define LDAP_LIST_NEXT(elm, field) ((elm)->field.le_next)
00350 
00351 #define LDAP_LIST_REMOVE(elm, field) do {                      \
00352        if ((elm)->field.le_next != NULL)                       \
00353               (elm)->field.le_next->field.le_prev =                   \
00354                   (elm)->field.le_prev;                        \
00355        *(elm)->field.le_prev = (elm)->field.le_next;                  \
00356 } while (0)
00357 
00358 /*
00359  * Tail queue definitions.
00360  */
00361 #define LDAP_TAILQ_HEAD(name, type)                                   \
00362 struct name {                                                  \
00363        struct type *tqh_first;     /* first element */                \
00364        struct type **tqh_last;     /* addr of last next element */           \
00365 }
00366 
00367 #define LDAP_TAILQ_HEAD_INITIALIZER(head)                      \
00368        { NULL, &(head).tqh_first }
00369 
00370 #define LDAP_TAILQ_ENTRY(type)                                        \
00371 struct {                                                       \
00372        struct type *tqe_next;      /* next element */                 \
00373        struct type **tqe_prev;     /* address of previous next element */    \
00374 }
00375 
00376 #define LDAP_TAILQ_ENTRY_INITIALIZER(entry)                           \
00377        { NULL, NULL }
00378 
00379 /*
00380  * Tail queue functions.
00381  */
00382 #define       LDAP_TAILQ_EMPTY(head) ((head)->tqh_first == NULL)
00383 
00384 #define LDAP_TAILQ_FOREACH(var, head, field)                          \
00385        for (var = LDAP_TAILQ_FIRST(head); var; var = LDAP_TAILQ_NEXT(var, field))
00386 
00387 #define LDAP_TAILQ_FOREACH_REVERSE(var, head, type, field)            \
00388        for ((var) = LDAP_TAILQ_LAST((head), type, field);             \
00389             (var);                                             \
00390             (var) = LDAP_TAILQ_PREV((var), head, type, field))
00391 
00392 #define       LDAP_TAILQ_FIRST(head) ((head)->tqh_first)
00393 
00394 #define LDAP_TAILQ_LAST(head, type, field)                            \
00395        (LDAP_TAILQ_EMPTY(head) ?                               \
00396               NULL :                                           \
00397               ((struct type *)                                 \
00398               ((char *)((head)->tqh_last) - offsetof(struct type, field))))
00399 
00400 #define       LDAP_TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
00401 
00402 #define LDAP_TAILQ_PREV(elm, head, type, field)                \
00403        ((struct type *)((elm)->field.tqe_prev) == LDAP_TAILQ_FIRST(head) ? \
00404        NULL :                                                  \
00405        ((struct type *)                                        \
00406        ((char *)((elm)->field.tqe_prev) - offsetof(struct type, field))))
00407 
00408 #define       LDAP_TAILQ_INIT(head) do {                              \
00409        (head)->tqh_first = NULL;                               \
00410        (head)->tqh_last = &(head)->tqh_first;                         \
00411 } while (0)
00412 
00413 #define LDAP_TAILQ_ENTRY_INIT(var, field) do {                        \
00414        (var)->field.tqe_next = NULL;                                  \
00415        (var)->field.tqe_prev = NULL;                                  \
00416 } while (0)
00417 
00418 #define LDAP_TAILQ_INSERT_HEAD(head, elm, field) do {                 \
00419        if (((elm)->field.tqe_next = (head)->tqh_first) != NULL)       \
00420               (head)->tqh_first->field.tqe_prev =                     \
00421                   &(elm)->field.tqe_next;                      \
00422        else                                                    \
00423               (head)->tqh_last = &(elm)->field.tqe_next;              \
00424        (head)->tqh_first = (elm);                              \
00425        (elm)->field.tqe_prev = &(head)->tqh_first;                    \
00426 } while (0)
00427 
00428 #define LDAP_TAILQ_INSERT_TAIL(head, elm, field) do {                 \
00429        (elm)->field.tqe_next = NULL;                                  \
00430        (elm)->field.tqe_prev = (head)->tqh_last;               \
00431        *(head)->tqh_last = (elm);                              \
00432        (head)->tqh_last = &(elm)->field.tqe_next;                     \
00433 } while (0)
00434 
00435 #define LDAP_TAILQ_INSERT_AFTER(head, listelm, elm, field) do {              \
00436        if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
00437               (elm)->field.tqe_next->field.tqe_prev =          \
00438                   &(elm)->field.tqe_next;                      \
00439        else                                                    \
00440               (head)->tqh_last = &(elm)->field.tqe_next;              \
00441        (listelm)->field.tqe_next = (elm);                      \
00442        (elm)->field.tqe_prev = &(listelm)->field.tqe_next;            \
00443 } while (0)
00444 
00445 #define LDAP_TAILQ_INSERT_BEFORE(listelm, elm, field) do {            \
00446        (elm)->field.tqe_prev = (listelm)->field.tqe_prev;             \
00447        (elm)->field.tqe_next = (listelm);                      \
00448        *(listelm)->field.tqe_prev = (elm);                            \
00449        (listelm)->field.tqe_prev = &(elm)->field.tqe_next;            \
00450 } while (0)
00451 
00452 #define LDAP_TAILQ_REMOVE(head, elm, field) do {               \
00453        if (((elm)->field.tqe_next) != NULL)                           \
00454               (elm)->field.tqe_next->field.tqe_prev =          \
00455                   (elm)->field.tqe_prev;                       \
00456        else                                                    \
00457               (head)->tqh_last = (elm)->field.tqe_prev;        \
00458        *(elm)->field.tqe_prev = (elm)->field.tqe_next;                \
00459 } while (0)
00460 
00461 /*
00462  * Circular queue definitions.
00463  */
00464 #define LDAP_CIRCLEQ_HEAD(name, type)                                 \
00465 struct name {                                                  \
00466        struct type *cqh_first;            /* first element */         \
00467        struct type *cqh_last;             /* last element */          \
00468 }
00469 
00470 #define LDAP_CIRCLEQ_ENTRY(type)                               \
00471 struct {                                                       \
00472        struct type *cqe_next;             /* next element */          \
00473        struct type *cqe_prev;             /* previous element */             \
00474 }
00475 
00476 /*
00477  * Circular queue functions.
00478  */
00479 #define LDAP_CIRCLEQ_EMPTY(head) ((head)->cqh_first == (void *)(head))
00480 
00481 #define LDAP_CIRCLEQ_FIRST(head) ((head)->cqh_first)
00482 
00483 #define LDAP_CIRCLEQ_FOREACH(var, head, field)                        \
00484        for((var) = (head)->cqh_first;                                 \
00485            (var) != (void *)(head);                                   \
00486            (var) = (var)->field.cqe_next)
00487 
00488 #define LDAP_CIRCLEQ_FOREACH_REVERSE(var, head, field)                \
00489        for((var) = (head)->cqh_last;                                  \
00490            (var) != (void *)(head);                                   \
00491            (var) = (var)->field.cqe_prev)
00492 
00493 #define       LDAP_CIRCLEQ_INIT(head) do {                                   \
00494        (head)->cqh_first = (void *)(head);                            \
00495        (head)->cqh_last = (void *)(head);                      \
00496 } while (0)
00497 
00498 #define LDAP_CIRCLEQ_ENTRY_INIT(var, field) do {               \
00499        (var)->field.cqe_next = NULL;                                  \
00500        (var)->field.cqe_prev = NULL;                                  \
00501 } while (0)
00502 
00503 #define LDAP_CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do {     \
00504        (elm)->field.cqe_next = (listelm)->field.cqe_next;             \
00505        (elm)->field.cqe_prev = (listelm);                      \
00506        if ((listelm)->field.cqe_next == (void *)(head))        \
00507               (head)->cqh_last = (elm);                        \
00508        else                                                    \
00509               (listelm)->field.cqe_next->field.cqe_prev = (elm);      \
00510        (listelm)->field.cqe_next = (elm);                      \
00511 } while (0)
00512 
00513 #define LDAP_CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do {    \
00514        (elm)->field.cqe_next = (listelm);                      \
00515        (elm)->field.cqe_prev = (listelm)->field.cqe_prev;             \
00516        if ((listelm)->field.cqe_prev == (void *)(head))        \
00517               (head)->cqh_first = (elm);                       \
00518        else                                                    \
00519               (listelm)->field.cqe_prev->field.cqe_next = (elm);      \
00520        (listelm)->field.cqe_prev = (elm);                      \
00521 } while (0)
00522 
00523 #define LDAP_CIRCLEQ_INSERT_HEAD(head, elm, field) do {               \
00524        (elm)->field.cqe_next = (head)->cqh_first;                     \
00525        (elm)->field.cqe_prev = (void *)(head);                        \
00526        if ((head)->cqh_last == (void *)(head))                        \
00527               (head)->cqh_last = (elm);                        \
00528        else                                                    \
00529               (head)->cqh_first->field.cqe_prev = (elm);              \
00530        (head)->cqh_first = (elm);                              \
00531 } while (0)
00532 
00533 #define LDAP_CIRCLEQ_INSERT_TAIL(head, elm, field) do {               \
00534        (elm)->field.cqe_next = (void *)(head);                        \
00535        (elm)->field.cqe_prev = (head)->cqh_last;               \
00536        if ((head)->cqh_first == (void *)(head))                \
00537               (head)->cqh_first = (elm);                       \
00538        else                                                    \
00539               (head)->cqh_last->field.cqe_next = (elm);        \
00540        (head)->cqh_last = (elm);                               \
00541 } while (0)
00542 
00543 #define LDAP_CIRCLEQ_LAST(head) ((head)->cqh_last)
00544 
00545 #define LDAP_CIRCLEQ_NEXT(elm,field) ((elm)->field.cqe_next)
00546 
00547 #define LDAP_CIRCLEQ_PREV(elm,field) ((elm)->field.cqe_prev)
00548 
00549 #define       LDAP_CIRCLEQ_REMOVE(head, elm, field) do {                     \
00550        if ((elm)->field.cqe_next == (void *)(head))                   \
00551               (head)->cqh_last = (elm)->field.cqe_prev;        \
00552        else                                                    \
00553               (elm)->field.cqe_next->field.cqe_prev =                 \
00554                   (elm)->field.cqe_prev;                       \
00555        if ((elm)->field.cqe_prev == (void *)(head))                   \
00556               (head)->cqh_first = (elm)->field.cqe_next;              \
00557        else                                                    \
00558               (elm)->field.cqe_prev->field.cqe_next =                 \
00559                   (elm)->field.cqe_next;                       \
00560 } while (0)
00561 
00562 #endif /* !_LDAP_QUEUE_H_ */