]> git.sur5r.net Git - openldap/commitdiff
ITS#8732 Extend CIRCLEQ macros
authorOndřej Kuzník <ondra@mistotebe.net>
Wed, 10 May 2017 14:57:27 +0000 (15:57 +0100)
committerOndřej Kuzník <ondra@mistotebe.net>
Thu, 28 Sep 2017 07:53:58 +0000 (08:53 +0100)
include/ldap_queue.h

index 8e13582ed122dce4fffb90a081375a17d7c000c2..6d8ca9a1b4cd021658b537945f0659426dc21c0e 100644 (file)
  * 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_.
@@ -461,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 */              \
@@ -553,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_ */