@@ -96,6 +96,9 @@ typedef struct ns_list {
96
96
* always assign returned entry pointers to a properly typed pointer variable.
97
97
* This assignment will be then type-checked where the compiler supports it, and
98
98
* will dereference correctly on compilers that don't support this extension.
99
+ *
100
+ * If you need to support C++03 compilers that cannot return properly-typed
101
+ * pointers, such as IAR 7, you need to use NS_LIST_TYPECOERCE to force the type.
99
102
* ~~~
100
103
* NS_LIST_HEAD(example_entry_t, link) my_list;
101
104
*
@@ -199,6 +202,27 @@ union \
199
202
#define NS_LIST_TYPECAST_ (list, val ) (0 ? (list)->type : (val))
200
203
#endif
201
204
205
+ /* * \brief Macro to force correct type if necessary.
206
+ *
207
+ * In C, doesn't matter if NS_LIST_TYPECAST_ works or not, as it's legal
208
+ * to assign void * to a pointer. In C++, we can't do that, so need
209
+ * a back-up plan for C++03. This forces the type, so breaks type-safety -
210
+ * only activate when needed, meaning we still get typechecks on other
211
+ * toolchains.
212
+ *
213
+ * If a straight assignment of a ns_list function to a pointer fails
214
+ * on a C++03 compiler, use the following construct. This will not be
215
+ * required with C++11 compilers.
216
+ * ~~~
217
+ * type *elem = NS_LIST_TYPECOERCE(type *, ns_list_get_first(list));
218
+ * ~~~
219
+ */
220
+ #if defined(NS_LIST_PTR_TYPE_) || !defined(__cplusplus)
221
+ #define NS_LIST_TYPECOERCE (type, val ) (val)
222
+ #else
223
+ #define NS_LIST_TYPECOERCE (type, val ) (type) (val)
224
+ #endif
225
+
202
226
/* * \brief Internal macro to check types of input entry pointer. */
203
227
#define NS_LIST_TYPECHECK_ (list, entry ) \
204
228
(NS_PTR_MATCH_((list)->type, (entry), " incorrect entry type for list" ), (entry))
@@ -480,7 +504,8 @@ typedef struct ns_list_link {
480
504
* \param list `(const list_t *)` Pointer to list - evaluated multiple times.
481
505
*/
482
506
#define ns_list_foreach (type, e, list ) \
483
- for (type *e = ns_list_get_first(list); e; e = ns_list_get_next(list, e))
507
+ for (type *e = NS_LIST_TYPECOERCE(type *, ns_list_get_first(list)); \
508
+ e; e = NS_LIST_TYPECOERCE(type *, ns_list_get_next(list, e)))
484
509
485
510
/* * \brief Iterate forwards over a list, where user may delete.
486
511
*
@@ -500,25 +525,26 @@ typedef struct ns_list_link {
500
525
* \param list `(list_t *)` Pointer to list - evaluated multiple times.
501
526
*/
502
527
#define ns_list_foreach_safe (type, e, list ) \
503
- for (type *e = ns_list_get_first(list), *_next##e; \
504
- e && (_next##e = ns_list_get_next(list, e), true ); e = _next##e)
528
+ for (type *e = NS_LIST_TYPECOERCE(type *, ns_list_get_first(list) ), *_next##e; \
529
+ e && (_next##e = NS_LIST_TYPECOERCE(type *, ns_list_get_next(list, e) ), true ); e = _next##e)
505
530
506
531
/* * \brief Iterate backwards over a list.
507
532
*
508
533
* As ns_list_foreach(), but going backwards - see its documentation.
509
534
* Iterating forwards is *slightly* more efficient.
510
535
*/
511
536
#define ns_list_foreach_reverse (type, e, list ) \
512
- for (type *e = ns_list_get_last(list); e; e = ns_list_get_previous(list, e))
537
+ for (type *e = NS_LIST_TYPECOERCE(type *, ns_list_get_last(list)); \
538
+ e; e = NS_LIST_TYPECOERCE(type *, ns_list_get_previous(list, e)))
513
539
514
540
/* * \brief Iterate backwards over a list, where user may delete.
515
541
*
516
542
* As ns_list_foreach_safe(), but going backwards - see its documentation.
517
543
* Iterating forwards is *slightly* more efficient.
518
544
*/
519
545
#define ns_list_foreach_reverse_safe (type, e, list ) \
520
- for (type *e = ns_list_get_last(list), *_next##e; \
521
- e && (_next##e = ns_list_get_previous(list, e), true ); e = _next##e)
546
+ for (type *e = NS_LIST_TYPECOERCE(type *, ns_list_get_last(list) ), *_next##e; \
547
+ e && (_next##e = NS_LIST_TYPECOERCE(type *, ns_list_get_previous(list, e) ), true ); e = _next##e)
522
548
523
549
/* * \hideinitializer \brief Count entries on a list
524
550
*
0 commit comments