Skip site navigation (1)Skip section navigation (2)
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>