1
- /* Linux-like doubly-linked list implementation */
1
+ /* Linux-like circular doubly-linked list implementation */
2
2
3
3
#pragma once
4
4
@@ -8,11 +8,19 @@ extern "C" {
8
8
9
9
#include <stddef.h>
10
10
11
- /* "typeof" is a GNU extension.
11
+ /**
12
+ * Feature detection for 'typeof':
13
+ * - Supported as a GNU extension in GCC/Clang.
14
+ * - Part of C23 standard (ISO/IEC 9899:2024).
15
+ *
12
16
* Reference: https://gcc.gnu.org/onlinedocs/gcc/Typeof.html
13
17
*/
14
- #if defined(__GNUC__ ) || defined(__clang__ )
18
+ #if defined(__GNUC__ ) || defined(__clang__ ) || \
19
+ (defined(__STDC__ ) && defined(__STDC_VERSION__ ) && \
20
+ (__STDC_VERSION__ >= 202311L )) /* C23 ?*/
15
21
#define __LIST_HAVE_TYPEOF 1
22
+ #else
23
+ #define __LIST_HAVE_TYPEOF 0
16
24
#endif
17
25
18
26
/**
@@ -46,11 +54,11 @@ struct list_head {
46
54
* Return: @type pointer of structure containing ptr
47
55
*/
48
56
#ifndef container_of
49
- #ifdef __LIST_HAVE_TYPEOF
50
- #define container_of (ptr , type , member ) \
51
- __extension__({ \
52
- const __typeof__ (((type *) 0)->member) *__pmember = (ptr); \
53
- (type *) ((char *) __pmember - offsetof(type, member)); \
57
+ #if __LIST_HAVE_TYPEOF
58
+ #define container_of (ptr , type , member ) \
59
+ __extension__({ \
60
+ const typeof (((type *) 0)->member) *__pmember = (ptr); \
61
+ (type *) ((char *) __pmember - offsetof(type, member)); \
54
62
})
55
63
#else
56
64
#define container_of (ptr , type , member ) \
@@ -379,54 +387,61 @@ static inline void list_move_tail(struct list_head *node,
379
387
for (node = (head)->next; node != (head); node = node->next)
380
388
381
389
/**
382
- * list_for_each_entry - Iterate over list entries
383
- * @entry: pointer used as iterator
384
- * @head: pointer to the head of the list
385
- * @member: name of the list_head member variable in struct type of @entry
386
- *
387
- * The nodes and the head of the list must be kept unmodified while
388
- * iterating through it. Any modifications to the the list will cause undefined
389
- * behavior.
390
- *
391
- * FIXME: remove dependency of __typeof__ extension
390
+ * list_for_each_entry - Iterate over a list of entries
391
+ * @entry: Pointer to the structure type, used as the loop iterator.
392
+ * @head: Pointer to the list_head structure representing the list head.
393
+ * @member: Name of the list_head member within the structure type of @entry.
394
+ *
395
+ * Iterates over a circular doubly-linked list, starting from the first node
396
+ * after @head until reaching @head again. The macro assumes the list structure
397
+ * remains unmodified during iteration; any changes (e.g., adding/removing
398
+ * nodes) may result in undefined behavior.
392
399
*/
393
- #ifdef __LIST_HAVE_TYPEOF
394
- #define list_for_each_entry (entry , head , member ) \
395
- for (entry = list_entry((head)->next, __typeof__ (*entry), member); \
396
- &entry->member != (head); \
397
- entry = list_entry(entry->member.next, __typeof__ (*entry), member))
400
+ #if __LIST_HAVE_TYPEOF
401
+ #define list_for_each_entry (entry , head , member ) \
402
+ for (entry = list_entry((head)->next, typeof (*entry), member); \
403
+ &entry->member != (head); \
404
+ entry = list_entry(entry->member.next, typeof (*entry), member))
398
405
#endif
399
406
400
407
/**
401
- * list_for_each_safe - Iterate over list nodes and allow deletions
402
- * @node: list_head pointer used as iterator
403
- * @safe: list_head pointer used to store info for next entry in list
404
- * @head: pointer to the head of the list
405
- *
406
- * The current node (iterator) is allowed to be removed from the list. Any
407
- * other modifications to the the list will cause undefined behavior.
408
+ * list_for_each_safe - Iterate over list nodes, allowing removal
409
+ * @node: Pointer to a list_head structure, used as the loop iterator.
410
+ * @safe: Pointer to a list_head structure, storing the next node for safe
411
+ * iteration.
412
+ * @head: Pointer to the list_head structure representing the list head.
413
+ *
414
+ * Iterates over a circular doubly-linked list, starting from the first node
415
+ * after @head and continuing until reaching @head again. This macro allows
416
+ * safe removal of the current node (@node) during iteration by pre-fetching
417
+ * the next node into @safe. Other modifications to the list structure (e.g.,
418
+ * adding nodes or altering @head) may result in undefined behavior.
408
419
*/
409
420
#define list_for_each_safe (node , safe , head ) \
410
421
for (node = (head)->next, safe = node->next; node != (head); \
411
422
node = safe, safe = node->next)
412
423
413
424
/**
414
- * list_for_each_entry_safe - Iterate over list entries and allow deletes
415
- * @entry: pointer used as iterator
416
- * @safe: @type pointer used to store info for next entry in list
417
- * @head: pointer to the head of the list
418
- * @member: name of the list_head member variable in struct type of @entry
419
- *
420
- * The current node (iterator) is allowed to be removed from the list. Any
421
- * other modifications to the the list will cause undefined behavior.
422
- *
423
- * FIXME: remove dependency of __typeof__ extension
425
+ * list_for_each_entry_safe - Iterate over a list, allowing node removal
426
+ * @entry: Pointer to the structure type, used as the loop iterator.
427
+ * @safe: Pointer to the structure type, storing the next entry for safe
428
+ * iteration.
429
+ * @head: Pointer to the list_head structure representing the list head.
430
+ * @member: Name of the list_head member within the structure type of @entry.
431
+ *
432
+ * Iterates over a circular doubly-linked list, starting from the first node
433
+ * after @head and continuing until reaching @head again. This macro permits
434
+ * safe removal of the current node (@entry) during iteration by pre-fetching
435
+ * the next node into @safe. Other modifications to the list structure (e.g.,
436
+ * adding nodes or altering @head) may result in undefined behavior.
424
437
*/
425
- #define list_for_each_entry_safe (entry , safe , head , member ) \
426
- for (entry = list_entry((head)->next, __typeof__(*entry), member), \
427
- safe = list_entry(entry->member.next, __typeof__(*entry), member); \
428
- &entry->member != (head); entry = safe, \
429
- safe = list_entry(safe->member.next, __typeof__(*entry), member))
438
+ #if __LIST_HAVE_TYPEOF
439
+ #define list_for_each_entry_safe (entry , safe , head , member ) \
440
+ for (entry = list_entry((head)->next, typeof(*entry), member), \
441
+ safe = list_entry(entry->member.next, typeof(*entry), member); \
442
+ &entry->member != (head); entry = safe, \
443
+ safe = list_entry(safe->member.next, typeof(*entry), member))
444
+ #endif
430
445
431
446
#undef __LIST_HAVE_TYPEOF
432
447
0 commit comments