]> git.sur5r.net Git - openldap/blobdiff - include/ldap_queue.h
Do not require ac/string.h for lber_pvt.h
[openldap] / include / ldap_queue.h
index f8cd0506460aaaf51fb829377cbf3c42f547de48..34588478372d87840a773a5f1eb323f5bee10a15 100644 (file)
@@ -2,7 +2,7 @@
 /* $OpenLDAP$ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
- * Copyright 2001-2014 The OpenLDAP Foundation.
+ * Copyright 2001-2018 The OpenLDAP Foundation.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * traverse the list. New elements can be added to the list before or after
  * an existing element, at the head of the list, or at the end of the list.
  * A circle queue may be traversed in either direction, but has a more
- * complex end of list detection.
+ * complex end of list detection. Also, it is possible to rotate the queue,
+ * rejoining the ends and splitting it so that a given element becomes the
+ * new head or tail.
  *
  * For details on the use of these macros, see the queue(3) manual page.
  * All macros are prefixed with LDAP_.
@@ -225,7 +227,7 @@ struct {                                                            \
 } while (0)
 
 #define LDAP_STAILQ_ENTRY_INIT(var, field) {                           \
-       (entry)->field.stqe_next = NULL;                                \
+       (var)->field.stqe_next = NULL;                                  \
 }
 
 #define LDAP_STAILQ_FIRST(head)        ((head)->stqh_first)
@@ -384,26 +386,20 @@ struct {                                                          \
 #define LDAP_TAILQ_FOREACH(var, head, field)                           \
        for (var = LDAP_TAILQ_FIRST(head); var; var = LDAP_TAILQ_NEXT(var, field))
 
-#define LDAP_TAILQ_FOREACH_REVERSE(var, head, type, field)             \
-       for ((var) = LDAP_TAILQ_LAST((head), type, field);              \
+#define LDAP_TAILQ_FOREACH_REVERSE(var, head, headname, field)         \
+       for ((var) = LDAP_TAILQ_LAST((head), headname);                 \
             (var);                                                     \
-            (var) = LDAP_TAILQ_PREV((var), head, type, field))
+            (var) = LDAP_TAILQ_PREV((var), headname, field))
 
 #define        LDAP_TAILQ_FIRST(head) ((head)->tqh_first)
 
-#define LDAP_TAILQ_LAST(head, type, field)                             \
-       (LDAP_TAILQ_EMPTY(head) ?                                       \
-               NULL :                                                  \
-               ((struct type *)                                        \
-               ((char *)((head)->tqh_last) - offsetof(struct type, field))))
+#define        LDAP_TAILQ_LAST(head, headname) \
+       (*(((struct headname *)((head)->tqh_last))->tqh_last))
 
 #define        LDAP_TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
 
-#define LDAP_TAILQ_PREV(elm, head, type, field)                        \
-       ((struct type *)((elm)->field.tqe_prev) == LDAP_TAILQ_FIRST(head) ? \
-       NULL :                                                          \
-       ((struct type *)                                                \
-       ((char *)((elm)->field.tqe_prev) - offsetof(struct type, field))))
+#define LDAP_TAILQ_PREV(elm, headname, field) \
+       (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
 
 #define        LDAP_TAILQ_INIT(head) do {                                      \
        (head)->tqh_first = NULL;                                       \
@@ -467,6 +463,9 @@ struct name {                                                               \
        struct type *cqh_last;          /* last element */              \
 }
 
+#define LDAP_CIRCLEQ_HEAD_INITIALIZER(head)                            \
+       { (void *)&(head), (void *)&(head) }
+
 #define LDAP_CIRCLEQ_ENTRY(type)                                       \
 struct {                                                               \
        struct type *cqe_next;          /* next element */              \
@@ -559,4 +558,36 @@ struct {                                                           \
                    (elm)->field.cqe_next;                              \
 } while (0)
 
+#define LDAP_CIRCLEQ_LOOP_NEXT(head, elm, field)                       \
+       (((elm)->field.cqe_next == (void *)(head))                      \
+               ? ((head)->cqh_first)                                   \
+               : ((elm)->field.cqe_next))
+
+#define LDAP_CIRCLEQ_LOOP_PREV(head, elm, field)                       \
+       (((elm)->field.cqe_prev == (void *)(head))                      \
+               ? ((head)->cqh_last)                                    \
+               : ((elm)->field.cqe_prev))
+
+#define LDAP_CIRCLEQ_MAKE_HEAD(head, elm, field) do {                  \
+       if ((elm)->field.cqe_prev != (void *)(head)) {                  \
+               (head)->cqh_first->field.cqe_prev = (head)->cqh_last;   \
+               (head)->cqh_last->field.cqe_next = (head)->cqh_first;   \
+               (head)->cqh_first = elm;                                \
+               (head)->cqh_last = (elm)->field.cqe_prev;               \
+               (elm)->field.cqe_prev->field.cqe_next = (void *)(head); \
+               (elm)->field.cqe_prev = (void *)(head);                 \
+       }                                                               \
+} while (0)
+
+#define LDAP_CIRCLEQ_MAKE_TAIL(head, elm, field) do {                  \
+       if ((elm)->field.cqe_next != (void *)(head)) {                  \
+               (head)->cqh_first->field.cqe_prev = (head)->cqh_last;   \
+               (head)->cqh_last->field.cqe_next = (head)->cqh_first;   \
+               (head)->cqh_first = (elm)->field.cqe_next;              \
+               (head)->cqh_last = elm;                                 \
+               (elm)->field.cqe_next->field.cqe_prev = (void *)(head); \
+               (elm)->field.cqe_next = (void *)(head);                 \
+       }                                                               \
+} while (0)
+
 #endif /* !_LDAP_QUEUE_H_ */