From: Ondřej Kuzník Date: Wed, 10 May 2017 14:57:27 +0000 (+0100) Subject: ITS#8732 Extend CIRCLEQ macros X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=6aa6daf2f0306e14705eada03b08acef099e205b;p=openldap ITS#8732 Extend CIRCLEQ macros --- diff --git a/include/ldap_queue.h b/include/ldap_queue.h index 8e13582ed1..6d8ca9a1b4 100644 --- a/include/ldap_queue.h +++ b/include/ldap_queue.h @@ -102,7 +102,9 @@ * 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_ */