Date: Fri, 17 Jan 2014 06:40:56 +0100 From: Hans Petter Selasky <hans.petter.selasky@bitfrost.no> To: Ian Lepore <ian@FreeBSD.org>, Poul-Henning Kamp <phk@phk.freebsd.dk> Cc: "freebsd-hackers@freebsd.org" <freebsd-hackers@FreeBSD.org> Subject: Re: Make "sys/queue.h" usable with C++ Message-ID: <52D8C268.1080009@bitfrost.no> In-Reply-To: <1389890913.1230.64.camel@revolution.hippie.lan> References: <52D7D302.3090403@bitfrost.no> <1679.1389879981@critter.freebsd.dk> <52D7E674.4010501@bitfrost.no> <16417.1389881910@critter.freebsd.dk> <1389890913.1230.64.camel@revolution.hippie.lan>
next in thread | previous in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format. --------------010008020906000207020705 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit On 01/16/14 17:48, Ian Lepore wrote: > On Thu, 2014-01-16 at 14:18 +0000, Poul-Henning Kamp wrote: >> In message <52D7E674.4010501@bitfrost.no>, Hans Petter Selasky writes: >> Please find attached a proposal for implementation. Remember that queue macros can be used inside extern "C" code and then a global struct define won't work. --HPS --------------010008020906000207020705 Content-Type: text/x-patch; name="queue.h.diff" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="queue.h.diff" === ./queue.h ================================================================== --- ./queue.h (revision 260626) +++ ./queue.h (local) @@ -79,8 +79,10 @@ * * SLIST LIST STAILQ TAILQ * _HEAD + + + + + * _HEAD_TD + + + + * _HEAD_INITIALIZER + + + + * _ENTRY + + + + + * _ENTRY_TD + + + + * _INIT + + + + * _EMPTY + + + + * _FIRST + + + + @@ -146,17 +148,23 @@ /* * Singly-linked List declarations. */ -#define SLIST_HEAD(name, type) \ +#define SLIST_HEAD(name, type) \ + SLIST_HEAD_TD(name, struct type) + +#define SLIST_HEAD_TD(name, type) \ struct name { \ - struct type *slh_first; /* first element */ \ + type *slh_first; /* first element */ \ } #define SLIST_HEAD_INITIALIZER(head) \ { NULL } -#define SLIST_ENTRY(type) \ +#define SLIST_ENTRY(type) \ + SLIST_ENTRY_TD(struct type) + +#define SLIST_ENTRY_TD(type) \ struct { \ - struct type *sle_next; /* next element */ \ + type *sle_next; /* next element */ \ } /* @@ -213,7 +221,8 @@ SLIST_REMOVE_HEAD((head), field); \ } \ else { \ - struct type *curelm = SLIST_FIRST((head)); \ + __typeof(SLIST_FIRST(head)) curelm = \ + SLIST_FIRST(head); \ while (SLIST_NEXT(curelm, field) != (elm)) \ curelm = SLIST_NEXT(curelm, field); \ SLIST_REMOVE_AFTER(curelm, field); \ @@ -231,7 +240,7 @@ } while (0) #define SLIST_SWAP(head1, head2, type) do { \ - struct type *swap_first = SLIST_FIRST(head1); \ + __typeof(SLIST_FIRST(head1)) *swap_first = SLIST_FIRST(head1); \ SLIST_FIRST(head1) = SLIST_FIRST(head2); \ SLIST_FIRST(head2) = swap_first; \ } while (0) @@ -239,18 +248,24 @@ /* * Singly-linked Tail queue declarations. */ -#define STAILQ_HEAD(name, type) \ +#define STAILQ_HEAD(name, type) \ + STAILQ_HEAD_TD(name, struct type) + +#define STAILQ_HEAD_TD(name, type) \ struct name { \ - struct type *stqh_first;/* first element */ \ - struct type **stqh_last;/* addr of last next element */ \ + type *stqh_first;/* first element */ \ + type **stqh_last;/* addr of last next element */ \ } #define STAILQ_HEAD_INITIALIZER(head) \ { NULL, &(head).stqh_first } -#define STAILQ_ENTRY(type) \ +#define STAILQ_ENTRY(type) \ + STAILQ_ENTRY_TD(struct type) + +#define STAILQ_ENTRY_TD(type) \ struct { \ - struct type *stqe_next; /* next element */ \ + type *stqe_next; /* next element */ \ } /* @@ -313,7 +328,8 @@ #define STAILQ_LAST(head, type, field) \ (STAILQ_EMPTY((head)) ? NULL : \ - __containerof((head)->stqh_last, struct type, field.stqe_next)) + __containerof((head)->stqh_last, \ + __typeof(field.stqe_next[0]), field.stqe_next)) #define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next) @@ -323,7 +339,8 @@ STAILQ_REMOVE_HEAD((head), field); \ } \ else { \ - struct type *curelm = STAILQ_FIRST((head)); \ + __typeof(STAILQ_FIRST(head)) curelm = \ + STAILQ_FIRST(head); \ while (STAILQ_NEXT(curelm, field) != (elm)) \ curelm = STAILQ_NEXT(curelm, field); \ STAILQ_REMOVE_AFTER(head, curelm, field); \ @@ -344,8 +361,8 @@ } while (0) #define STAILQ_SWAP(head1, head2, type) do { \ - struct type *swap_first = STAILQ_FIRST(head1); \ - struct type **swap_last = (head1)->stqh_last; \ + __typeof(STAILQ_FIRST(head1)) swap_first = STAILQ_FIRST(head1); \ + __typeof((head1)->stqh_last) swap_last = (head1)->stqh_last; \ STAILQ_FIRST(head1) = STAILQ_FIRST(head2); \ (head1)->stqh_last = (head2)->stqh_last; \ STAILQ_FIRST(head2) = swap_first; \ @@ -360,18 +377,24 @@ /* * List declarations. */ -#define LIST_HEAD(name, type) \ +#define LIST_HEAD(name, type) \ + LIST_HEAD_TD(name, struct type) + +#define LIST_HEAD_TD(name, type) \ struct name { \ - struct type *lh_first; /* first element */ \ + type *lh_first; /* first element */ \ } #define LIST_HEAD_INITIALIZER(head) \ { NULL } -#define LIST_ENTRY(type) \ +#define LIST_ENTRY(type) \ + LIST_ENTRY_TD(struct type) + +#define LIST_ENTRY_TD(type) \ struct { \ - struct type *le_next; /* next element */ \ - struct type **le_prev; /* address of previous next element */ \ + type *le_next; /* next element */ \ + type **le_prev; /* address of previous next element */ \ } /* @@ -460,7 +483,8 @@ #define LIST_PREV(elm, head, type, field) \ ((elm)->field.le_prev == &LIST_FIRST((head)) ? NULL : \ - __containerof((elm)->field.le_prev, struct type, field.le_next)) + __containerof((elm)->field.le_prev, \ + __typeof(field.le_next[0]), field.le_next)) #define LIST_REMOVE(elm, field) do { \ QMD_SAVELINK(oldnext, (elm)->field.le_next); \ @@ -476,7 +500,7 @@ } while (0) #define LIST_SWAP(head1, head2, type, field) do { \ - struct type *swap_tmp = LIST_FIRST((head1)); \ + __typeof(LIST_FIRST(head1)) swap_tmp = LIST_FIRST(head1); \ LIST_FIRST((head1)) = LIST_FIRST((head2)); \ LIST_FIRST((head2)) = swap_tmp; \ if ((swap_tmp = LIST_FIRST((head1))) != NULL) \ @@ -488,10 +512,13 @@ /* * Tail queue declarations. */ -#define TAILQ_HEAD(name, type) \ +#define TAILQ_HEAD(name, type) \ + TAILQ_HEAD_TD(name, struct type) + +#define TAILQ_HEAD_TD(name, type) \ struct name { \ - struct type *tqh_first; /* first element */ \ - struct type **tqh_last; /* addr of last next element */ \ + type *tqh_first; /* first element */ \ + type **tqh_last; /* addr of last next element */ \ TRACEBUF \ } @@ -498,10 +525,13 @@ #define TAILQ_HEAD_INITIALIZER(head) \ { NULL, &(head).tqh_first, TRACEBUF_INITIALIZER } -#define TAILQ_ENTRY(type) \ +#define TAILQ_ENTRY(type) \ + TAILQ_ENTRY_TD(struct type) + +#define TAILQ_ENTRY_TD(type) \ struct { \ - struct type *tqe_next; /* next element */ \ - struct type **tqe_prev; /* address of previous next element */ \ + type *tqe_next; /* next element */ \ + type **tqe_prev; /* address of previous next element */ \ TRACEBUF \ } @@ -649,13 +679,16 @@ } while (0) #define TAILQ_LAST(head, headname) \ - (*(((struct headname *)((head)->tqh_last))->tqh_last)) + (*(((__typeof(head))((head)->tqh_last))->tqh_last)) #define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next) #define TAILQ_PREV(elm, headname, field) \ - (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last)) + TAILQ_PREV_TD(elm, struct headname, field) +#define TAILQ_PREV_TD(elm, headname, field) \ + (*(((headname *)((elm)->field.tqe_prev))->tqh_last)) + #define TAILQ_REMOVE(head, elm, field) do { \ QMD_SAVELINK(oldnext, (elm)->field.tqe_next); \ QMD_SAVELINK(oldprev, (elm)->field.tqe_prev); \ @@ -675,8 +708,8 @@ } while (0) #define TAILQ_SWAP(head1, head2, type, field) do { \ - struct type *swap_first = (head1)->tqh_first; \ - struct type **swap_last = (head1)->tqh_last; \ + __typeof((head1)->tqh_first) swap_first = (head1)->tqh_first; \ + __typeof((head1)->tqh_last) swap_last = (head1)->tqh_last; \ (head1)->tqh_first = (head2)->tqh_first; \ (head1)->tqh_last = (head2)->tqh_last; \ (head2)->tqh_first = swap_first; \ --------------010008020906000207020705--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?52D8C268.1080009>