[1/4] list.h: Add macros for reverse iteration (take 2)

Dan Hipschman dsh at linux.ucla.edu
Tue Jun 5 20:48:21 CDT 2007


This patch is the same as before.  I'm not sure which patch got
rejected last time, this one or the one after it (or both), but I'm
guessing it was the larger one and this one was rejected on the
grounds that it's pointless if nothing uses it.  The only guess I have
at what could be wrong with it is if Alexandre felt it broke the
abstraction of a linked list, but if the list is doubly-linked, why
not take advantage of it?

On the other hand, maybe my second patch was just too large and needed
more than a single day to review, but I've made minor improvements to
it in that time, anyway.

---
 include/wine/list.h |   51 +++++++++++++++++++++++++++++++++++----------------
 1 files changed, 35 insertions(+), 16 deletions(-)

diff --git a/include/wine/list.h b/include/wine/list.h
index dede5b4..4f6fde0 100644
--- a/include/wine/list.h
+++ b/include/wine/list.h
@@ -172,29 +172,48 @@ static inline void list_move_head( struct list *dst, struct list *src )
     list_init(src);
 }
 
-/* iterate through the list */
-#define LIST_FOR_EACH(cursor,list) \
-    for ((cursor) = (list)->next; (cursor) != (list); (cursor) = (cursor)->next)
+#define LIST_FOR_EACH_LINK(cursor, list, link) \
+    for ((cursor) = (list)->link; (cursor) != (list); (cursor) = (cursor)->link)
 
-/* iterate through the list, with safety against removal */
-#define LIST_FOR_EACH_SAFE(cursor, cursor2, list) \
-    for ((cursor) = (list)->next, (cursor2) = (cursor)->next; \
+#define LIST_FOR_EACH_SAFE_LINK(cursor, cursor2, list, link) \
+    for ((cursor) = (list)->link, (cursor2) = (cursor)->link; \
          (cursor) != (list); \
-         (cursor) = (cursor2), (cursor2) = (cursor)->next)
+         (cursor) = (cursor2), (cursor2) = (cursor)->link)
 
-/* iterate through the list using a list entry */
-#define LIST_FOR_EACH_ENTRY(elem, list, type, field) \
-    for ((elem) = LIST_ENTRY((list)->next, type, field); \
+#define LIST_FOR_EACH_ENTRY_LINK(elem, list, type, field, link) \
+    for ((elem) = LIST_ENTRY((list)->link, type, field); \
          &(elem)->field != (list); \
-         (elem) = LIST_ENTRY((elem)->field.next, type, field))
+         (elem) = LIST_ENTRY((elem)->field.link, type, field))
 
-/* iterate through the list using a list entry, with safety against removal */
-#define LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, list, type, field) \
-    for ((cursor) = LIST_ENTRY((list)->next, type, field), \
-         (cursor2) = LIST_ENTRY((cursor)->field.next, type, field); \
+#define LIST_FOR_EACH_ENTRY_SAFE_LINK(cursor, cursor2, list, type, field, link) \
+    for ((cursor) = LIST_ENTRY((list)->link, type, field), \
+         (cursor2) = LIST_ENTRY((cursor)->field.link, type, field); \
          &(cursor)->field != (list); \
          (cursor) = (cursor2), \
-         (cursor2) = LIST_ENTRY((cursor)->field.next, type, field))
+         (cursor2) = LIST_ENTRY((cursor)->field.link, type, field))
+
+/* iterate through the list */
+#define LIST_FOR_EACH(cursor, list) \
+    LIST_FOR_EACH_LINK(cursor, list, next)
+/* iterate through the list, with safety against removal */
+#define LIST_FOR_EACH_SAFE(cursor, cursor2, list) \
+    LIST_FOR_EACH_SAFE_LINK(cursor, cursor2, list, next)
+/* iterate through the list using a list entry */
+#define LIST_FOR_EACH_ENTRY(elem, list, type, field) \
+    LIST_FOR_EACH_ENTRY_LINK(elem, list, type, field, next)
+/* iterate through the list using a list entry, with safety against removal */
+#define LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, list, type, field) \
+    LIST_FOR_EACH_ENTRY_SAFE_LINK(cursor, cursor2, list, type, field, next)
+
+/* same as above, but start from the tail and work towards the head */
+#define LIST_FOR_EACH_REV(cursor, list) \
+    LIST_FOR_EACH_LINK(cursor, list, prev)
+#define LIST_FOR_EACH_SAFE_REV(cursor, cursor2, list) \
+    LIST_FOR_EACH_SAFE_LINK(cursor, cursor2, list, prev)
+#define LIST_FOR_EACH_ENTRY_REV(elem, list, type, field) \
+    LIST_FOR_EACH_ENTRY_LINK(elem, list, type, field, prev)
+#define LIST_FOR_EACH_ENTRY_SAFE_REV(cursor, cursor2, list, type, field) \
+    LIST_FOR_EACH_ENTRY_SAFE_LINK(cursor, cursor2, list, type, field, prev)
 
 /* macros for statically initialized lists */
 #define LIST_INIT(list)  { &(list), &(list) }



More information about the wine-patches mailing list