[ccan] [PATCH] list: add list_for_each_rev_safe
David Gibson
david at gibson.dropbear.id.au
Tue Oct 7 10:59:24 EST 2014
On Sun, Oct 05, 2014 at 12:20:45PM +0000, Eric Wong wrote:
> Deleting while iterating backwards will be needed in the
> Ruby st_foreach_reverse_check implementation if we decide
> to port Ruby's st.c to use ccan/list.
>
> ref: http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/65408
>
> Signed-off-by: Eric Wong <normalperson at yhbt.net>
> ---
> ccan/list/list.h | 27 ++++++++++++++++++++++++++-
> ccan/list/test/run.c | 31 ++++++++++++++++++++++++++++++-
> 2 files changed, 56 insertions(+), 2 deletions(-)
>
> diff --git a/ccan/list/list.h b/ccan/list/list.h
> index 983675b..b4a6cdf 100644
> --- a/ccan/list/list.h
> +++ b/ccan/list/list.h
> @@ -527,6 +527,32 @@ static inline const void *list_tail_(const struct list_head *h, size_t off)
> i = container_of_var(i->member.prev, i, member))
>
> /**
> + * list_for_each_rev_safe - iterate through a list backwards,
> + * maybe during deletion
> + * @h: the list_head
> + * @i: the structure containing the list_node
> + * @nxt: the structure containing the list_node
> + * @member: the list_node member of the structure
> + *
> + * This is a convenient wrapper to iterate @i over the entire list backwards.
> + * It's a for loop, so you can break and continue as normal. The extra
> + * variable * @nxt is used to hold the next element, so you can delete @i
> + * from the list.
> + *
> + * Example:
> + * struct child *next;
> + * list_for_each_rev_safe(&parent->children, child, next, list) {
> + * printf("Name: %s\n", child->name);
> + * }
> + */
> +#define list_for_each_rev_safe(h, i, nxt, member) \
> + for (i = container_of_var(list_debug(h, LIST_LOC)->n.prev, i, member), \
> + nxt = container_of_var(i->member.prev, i, member); \
> + &i->member != &(h)->n; \
> + i = nxt, \
> + nxt = container_of_var(i->member.prev, i, member))
For proper orthogonality, I think rather than implementing it this
way, you should implement list_for_each_rev_safe_off() and implement
list_for_each_rev_safe() in terms of it, like the forwards
list_for_each_safe().
Also, I think the way that's implemented is to avoid double-evaluation
of macro arguments, so it's possible there's such a double evaluation
in your version.
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.ozlabs.org/pipermail/ccan/attachments/20141007/b1b3151d/attachment.sig>
More information about the ccan
mailing list