This is the mail archive of the newlib@sourceware.org mailing list for the newlib project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH 4/8] Make the system queue header file fully usable within C++ programs by adding macros to define class lists.


From: hselasky <hselasky@FreeBSD.org>

This change is backwards compatible for all use within C and C++
programs. Only C++ programs will have added support to use the queue
macros within classes. Previously the queue macros could only be used
within structures.

The queue.3 manual page has been updated to describe the new
functionality and some alphabetic sorting has been done while
at it.

Differential Revision:	https://reviews.freebsd.org/D2745
PR:			200827 (exp-run)
MFC after:		2 weeks
---
 newlib/libc/include/sys/queue.h | 87 ++++++++++++++++++++++++++++++++++-------
 1 file changed, 73 insertions(+), 14 deletions(-)

diff --git a/newlib/libc/include/sys/queue.h b/newlib/libc/include/sys/queue.h
index f00e92f..d6c821f 100644
--- a/newlib/libc/include/sys/queue.h
+++ b/newlib/libc/include/sys/queue.h
@@ -79,8 +79,10 @@
  *
  *				SLIST	LIST	STAILQ	TAILQ
  * _HEAD			+	+	+	+
+ * _CLASS_HEAD			+	+	+	+
  * _HEAD_INITIALIZER		+	+	+	+
  * _ENTRY			+	+	+	+
+ * _CLASS_ENTRY			+	+	+	+
  * _INIT			+	+	+	+
  * _EMPTY			+	+	+	+
  * _FIRST			+	+	+	+
@@ -143,6 +145,15 @@ struct qm_trace {
 #define	TRASHIT(x)
 #endif	/* QUEUE_MACRO_DEBUG */
 
+#ifdef __cplusplus
+/*
+ * In C++ there can be structure lists and class lists:
+ */
+#define	QUEUE_TYPEOF(type) type
+#else
+#define	QUEUE_TYPEOF(type) struct type
+#endif
+
 /*
  * Singly-linked List declarations.
  */
@@ -151,6 +162,11 @@ struct name {								\
 	struct type *slh_first;	/* first element */			\
 }
 
+#define	SLIST_CLASS_HEAD(name, type)					\
+struct name {								\
+	class type *slh_first;	/* first element */			\
+}
+
 #define	SLIST_HEAD_INITIALIZER(head)					\
 	{ NULL }
 
@@ -159,6 +175,11 @@ struct {								\
 	struct type *sle_next;	/* next element */			\
 }
 
+#define	SLIST_CLASS_ENTRY(type)						\
+struct {								\
+	class type *sle_next;		/* next element */		\
+}
+
 /*
  * Singly-linked List functions.
  */
@@ -213,7 +234,7 @@ struct {								\
 		SLIST_REMOVE_HEAD((head), field);			\
 	}								\
 	else {								\
-		struct type *curelm = SLIST_FIRST((head));		\
+		QUEUE_TYPEOF(type) *curelm = SLIST_FIRST(head);		\
 		while (SLIST_NEXT(curelm, field) != (elm))		\
 			curelm = SLIST_NEXT(curelm, field);		\
 		SLIST_REMOVE_AFTER(curelm, field);			\
@@ -231,7 +252,7 @@ struct {								\
 } while (0)
 
 #define SLIST_SWAP(head1, head2, type) do {				\
-	struct type *swap_first = SLIST_FIRST(head1);			\
+	QUEUE_TYPEOF(type) *swap_first = SLIST_FIRST(head1);		\
 	SLIST_FIRST(head1) = SLIST_FIRST(head2);			\
 	SLIST_FIRST(head2) = swap_first;				\
 } while (0)
@@ -245,6 +266,12 @@ struct name {								\
 	struct type **stqh_last;/* addr of last next element */		\
 }
 
+#define	STAILQ_CLASS_HEAD(name, type)					\
+struct name {								\
+	class type *stqh_first;	/* first element */			\
+	class type **stqh_last;	/* addr of last next element */		\
+}
+
 #define	STAILQ_HEAD_INITIALIZER(head)					\
 	{ NULL, &(head).stqh_first }
 
@@ -253,6 +280,11 @@ struct {								\
 	struct type *stqe_next;	/* next element */			\
 }
 
+#define	STAILQ_CLASS_ENTRY(type)					\
+struct {								\
+	class type *stqe_next;	/* next element */			\
+}
+
 /*
  * Singly-linked Tail queue functions.
  */
@@ -311,9 +343,10 @@ struct {								\
 	(head)->stqh_last = &STAILQ_NEXT((elm), field);			\
 } while (0)
 
-#define	STAILQ_LAST(head, type, field)					\
-	(STAILQ_EMPTY((head)) ? NULL :					\
-	    __containerof((head)->stqh_last, struct type, field.stqe_next))
+#define	STAILQ_LAST(head, type, field)				\
+	(STAILQ_EMPTY((head)) ? NULL :				\
+	    __containerof((head)->stqh_last,			\
+	    QUEUE_TYPEOF(type), field.stqe_next))
 
 #define	STAILQ_NEXT(elm, field)	((elm)->field.stqe_next)
 
@@ -323,7 +356,7 @@ struct {								\
 		STAILQ_REMOVE_HEAD((head), field);			\
 	}								\
 	else {								\
-		struct type *curelm = STAILQ_FIRST((head));		\
+		QUEUE_TYPEOF(type) *curelm = STAILQ_FIRST(head);	\
 		while (STAILQ_NEXT(curelm, field) != (elm))		\
 			curelm = STAILQ_NEXT(curelm, field);		\
 		STAILQ_REMOVE_AFTER(head, curelm, field);		\
@@ -349,8 +382,8 @@ struct {								\
 } while (0)
 
 #define STAILQ_SWAP(head1, head2, type) do {				\
-	struct type *swap_first = STAILQ_FIRST(head1);			\
-	struct type **swap_last = (head1)->stqh_last;			\
+	QUEUE_TYPEOF(type) *swap_first = STAILQ_FIRST(head1);		\
+	QUEUE_TYPEOF(type) **swap_last = (head1)->stqh_last;		\
 	STAILQ_FIRST(head1) = STAILQ_FIRST(head2);			\
 	(head1)->stqh_last = (head2)->stqh_last;			\
 	STAILQ_FIRST(head2) = swap_first;				\
@@ -370,6 +403,11 @@ struct name {								\
 	struct type *lh_first;	/* first element */			\
 }
 
+#define	LIST_CLASS_HEAD(name, type)					\
+struct name {								\
+	class type *lh_first;	/* first element */			\
+}
+
 #define	LIST_HEAD_INITIALIZER(head)					\
 	{ NULL }
 
@@ -379,6 +417,12 @@ struct {								\
 	struct type **le_prev;	/* address of previous next element */	\
 }
 
+#define	LIST_CLASS_ENTRY(type)						\
+struct {								\
+	class type *le_next;	/* next element */			\
+	class type **le_prev;	/* address of previous next element */	\
+}
+
 /*
  * List functions.
  */
@@ -463,9 +507,10 @@ struct {								\
 
 #define	LIST_NEXT(elm, field)	((elm)->field.le_next)
 
-#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))
+#define	LIST_PREV(elm, head, type, field)			\
+	((elm)->field.le_prev == &LIST_FIRST((head)) ? NULL :	\
+	    __containerof((elm)->field.le_prev,			\
+	    QUEUE_TYPEOF(type), field.le_next))
 
 #define	LIST_REMOVE(elm, field) do {					\
 	QMD_SAVELINK(oldnext, (elm)->field.le_next);			\
@@ -481,7 +526,7 @@ struct {								\
 } while (0)
 
 #define LIST_SWAP(head1, head2, type, field) do {			\
-	struct type *swap_tmp = LIST_FIRST((head1));			\
+	QUEUE_TYPEOF(type) *swap_tmp = LIST_FIRST(head1);		\
 	LIST_FIRST((head1)) = LIST_FIRST((head2));			\
 	LIST_FIRST((head2)) = swap_tmp;					\
 	if ((swap_tmp = LIST_FIRST((head1))) != NULL)			\
@@ -500,6 +545,13 @@ struct name {								\
 	TRACEBUF							\
 }
 
+#define	TAILQ_CLASS_HEAD(name, type)					\
+struct name {								\
+	class type *tqh_first;	/* first element */			\
+	class type **tqh_last;	/* addr of last next element */		\
+	TRACEBUF							\
+}
+
 #define	TAILQ_HEAD_INITIALIZER(head)					\
 	{ NULL, &(head).tqh_first, TRACEBUF_INITIALIZER }
 
@@ -510,6 +562,13 @@ struct {								\
 	TRACEBUF							\
 }
 
+#define	TAILQ_CLASS_ENTRY(type)						\
+struct {								\
+	class type *tqe_next;	/* next element */			\
+	class type **tqe_prev;	/* address of previous next element */	\
+	TRACEBUF							\
+}
+
 /*
  * Tail queue functions.
  */
@@ -680,8 +739,8 @@ struct {								\
 } while (0)
 
 #define TAILQ_SWAP(head1, head2, type, field) do {			\
-	struct type *swap_first = (head1)->tqh_first;			\
-	struct type **swap_last = (head1)->tqh_last;			\
+	QUEUE_TYPEOF(type) *swap_first = (head1)->tqh_first;		\
+	QUEUE_TYPEOF(type) **swap_last = (head1)->tqh_last;		\
 	(head1)->tqh_first = (head2)->tqh_first;			\
 	(head1)->tqh_last = (head2)->tqh_last;				\
 	(head2)->tqh_first = swap_first;				\
-- 
1.8.4.5


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]