Add macros for iterating the containing entry

This commit is contained in:
Nils O. Selåsdal
2013-11-30 13:40:05 +01:00
parent bcafaace29
commit 6dc59ccbf8
2 changed files with 88 additions and 22 deletions
+66 -8
View File
@@ -155,16 +155,44 @@ static UC_INLINE void uc_tailq_move_tail(struct TailQ *entry, struct TailQ *head
* @param head the struct TailQ* head of the tailq
*/
#define UC_TAILQ_FOREACH(entry, head)\
for ((entry) = (head)->next; (entry) != (head); (entry) = (entry)->next)
for ((entry) = UC_TAILQ_FIRST(head); \
(entry) != (head); \
(entry) = UC_TAILQ_NEXT(entry))
/** Iterate over a tailq in reverse order. The tailq cannot be altered while
* iterating.
/** Iterate over the containing element in a tailq.
* The tailq cannot be altered while iterating.
*
* @param ptr a pointer to the struct which the tailq nodes are member of
* @param member the member of ptr that is the tailq node
* @param head the struct TailQ* head of the tailq
*/
#define UC_TAILQ_FOREACH_CONTAINER(ptr, member, head)\
for ((ptr) = UC_TAILQ_CONTAINER(UC_TAILQ_FIRST(head), typeof(*ptr), member);\
&(ptr)->member != (head);\
(ptr) = UC_TAILQ_CONTAINER(UC_TAILQ_NEXT(&(ptr)->member), typeof(*ptr), member))
/** Iterate over a tailq in reverse order.
* The tailq cannot be altered while iterating.
*
* @param entry a struct TailQ* to which each element is assigned.
* @param head the struct TailQ* head of the tailq
*/
#define UC_TAILQ_FOREACH_REVERSE(entry, head)\
for ((entry) = (head)->prev; (entry) != (head); (entry) = (entry)->prev)
for ((entry) = UC_TAILQ_LAST(entry); \
(entry) != (head); \
(entry) = UC_TAILQ_PREV(entry)
/** Iterate over the containing element in a tailq in reverse.
* The tailq cannot be altered while iterating.
*
* @param ptr a pointer to the struct which the tailq nodes are member of
* @param member the member of ptr that is the tailq node
* @param head the struct TailQ* head of the tailq
*/
#define UC_TAILQ_FOREACH_REVERSE_CONTAINER(ptr, member, head)\
for ((ptr) = UC_TAILQ_CONTAINER(UC_TAILQ_LAST(head), typeof(*ptr), member);\
&(ptr)->member != (head);\
(ptr) = UC_TAILQ_CONTAINER(UC_TAILQ_PREV(&(ptr)->member), typeof(*ptr), member))
/** Iterate over a tailq. safe to remove the entry when iterating.
*
@@ -173,9 +201,24 @@ static UC_INLINE void uc_tailq_move_tail(struct TailQ *entry, struct TailQ *head
* @param head the struct TailQ* head of the tailq
*/
#define UC_TAILQ_FOREACH_SAFE(entry, nxt, head)\
for ((entry) = (head)->next, nxt = (entry)->next; \
for ((entry) = UC_TAILQ_FIRST(head), (nxt) = UC_TAILQ_NEXT(entry); \
(entry) != (head); \
(entry) = (nxt), (nxt) = (entry)->next)
(entry) = (nxt), (nxt) = UC_TAILQ_NEXT(entry))\
/** Iterate over the containing element in a tailq, safe to remove
* the entry when iterating
*
* @param ptr a pointer to the struct which the tailq nodes are member of
* @param nxt same type as ptr needed for temporary storage.
* @param member the member of ptr that is the tailq node
* @param head the struct TailQ* head of the tailq
*/
#define UC_TAILQ_FOREACH_CONTAINER_SAFE(ptr, nxt, member, head)\
for ((ptr) = UC_TAILQ_CONTAINER(UC_TAILQ_FIRST(head), typeof(*ptr), member),\
(nxt) = UC_TAILQ_CONTAINER(UC_TAILQ_NEXT(&(ptr)->member), typeof(*ptr), member);\
&(ptr)->member != (head);\
(ptr) = (nxt),\
(nxt) = UC_TAILQ_CONTAINER(UC_TAILQ_NEXT(&(ptr)->member), typeof(*ptr), member))
/** Iterate over a tailq in reverse order. safe to remove the entry when
* iterating.
@@ -185,9 +228,24 @@ static UC_INLINE void uc_tailq_move_tail(struct TailQ *entry, struct TailQ *head
* @param head the struct TailQ* head of the tailq
*/
#define UC_TAILQ_FOREACH_REVERSE_SAFE(entry, prv, head)\
for ((entry) = (head)->prev, prev = (entry)->prev; \
for ((entry) = UC_TAILQ_LAST(head), (prv) = UC_TAILQ_PREV(entry); \
(entry) != (head); \
(entry) = (prv), (prv) = (entry)->prev)
(entry) = (prv), (prv) = UC_TAILQ_PREV(entry))\
/** Iterate over the containing element in a tailq in reverse order, safe
* to remove the entry when iterating
*
* @param ptr a pointer to the struct which the tailq nodes are member of
* @param prv same type as ptr needed for temporary storage.
* @param member the member of ptr that is the tailq node
* @param head the struct TailQ* head of the tailq
*/
#define UC_TAILQ_FOREACH_REVERSE_CONTAINER_SAFE(ptr, prv, member, head)\
for ((ptr) = UC_TAILQ_CONTAINER(UC_TAILQ_LAST(head), typeof(*ptr), member),\
(prv) = UC_TAILQ_CONTAINER(UC_TAILQ_PREV(&(ptr)->member), typeof(*ptr), member);\
&(ptr)->member != (head);\
(ptr) = (prv),\
(prv) = UC_TAILQ_CONTAINER(UC_TAILQ_NEXT(&(ptr)->member), typeof(*ptr), member))
#undef UC_INLINE