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>
