From owner-freebsd-hackers@FreeBSD.ORG Fri Jan 17 05:39:57 2014 Return-Path: Delivered-To: freebsd-hackers@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 595FACCA; Fri, 17 Jan 2014 05:39:57 +0000 (UTC) Received: from mta05.bitpro.no (mta05.bitpro.no [92.42.64.202]) by mx1.freebsd.org (Postfix) with ESMTP id C38C61FCE; Fri, 17 Jan 2014 05:39:56 +0000 (UTC) Received: from mail.lockless.no (mail.lockless.no [46.29.221.38]) by mta05.bitpro.no (Postfix) with ESMTPS id 0DB4017FD08; Fri, 17 Jan 2014 06:39:53 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by mail.lockless.no (Postfix) with ESMTP id 98DF98F686A; Fri, 17 Jan 2014 06:40:42 +0100 (CET) X-Virus-Scanned: by amavisd-new-2.6.4 (20090625) (Debian) at lockless.no Received: from mail.lockless.no ([127.0.0.1]) by localhost (mail.lockless.no [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id EYnTBAJmUgej; Fri, 17 Jan 2014 06:40:40 +0100 (CET) Received: from laptop015.home.selasky.org (cm-176.74.213.204.customer.telag.net [176.74.213.204]) by mail.lockless.no (Postfix) with ESMTPSA id 81EE48F602A; Fri, 17 Jan 2014 06:40:40 +0100 (CET) Message-ID: <52D8C268.1080009@bitfrost.no> Date: Fri, 17 Jan 2014 06:40:56 +0100 From: Hans Petter Selasky Organization: Bitfrost A/S User-Agent: Mozilla/5.0 (X11; FreeBSD amd64; rv:24.0) Gecko/20100101 Thunderbird/24.1.0 MIME-Version: 1.0 To: Ian Lepore , Poul-Henning Kamp Subject: Re: Make "sys/queue.h" usable with C++ 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> In-Reply-To: <1389890913.1230.64.camel@revolution.hippie.lan> Content-Type: multipart/mixed; boundary="------------010008020906000207020705" X-Mailman-Approved-At: Fri, 17 Jan 2014 05:48:35 +0000 Cc: "freebsd-hackers@freebsd.org" X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.17 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 17 Jan 2014 05:39:57 -0000 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--