> On Apr 5, 2015, at 10:13 AM, Ben Pfaff <b...@nicira.com> wrote: > > On Fri, Apr 03, 2015 at 03:55:43PM -0700, Jarno Rajahalme wrote: >> Makes popping each member of the list a bit easier. >> >> Signed-off-by: Jarno Rajahalme <jrajaha...@nicira.com> > >> diff --git a/lib/list.h b/lib/list.h >> index b40bbef..bca5d5c 100644 >> --- a/lib/list.h >> +++ b/lib/list.h >> @@ -73,6 +73,12 @@ static inline bool list_is_short(const struct ovs_list *); >> ? INIT_CONTAINER(NEXT, (ITER)->MEMBER.next, MEMBER), 1 \ >> : 0); \ >> (ITER) = (NEXT)) >> +#define LIST_FOR_EACH_POP(ITER, MEMBER, LIST) \ >> + for (struct ovs_list *next__ = (LIST)->next; \ >> + (next__ != (LIST) \ >> + ? (INIT_CONTAINER(ITER, next__, MEMBER), \ >> + (next__ = list_remove(next__)), 1) \ >> + : 0);) >> > > An implementation like this is also possible, I think (I didn't test > it): > > while (!list_is_empty(LIST) > && (INIT_CONTAINER(ITER, (LIST)->next, MEMBER), > list_remove(&(ITER)->MEMBER), > 1)) > > The tradeoffs are a little different. With your implementation, the > code in the loop can insert new elements in the list before the current > iteration point, and those elements won't get visited or deleted. With > mine, any elements inserted anywhere will get visited and deleted (and > there's a little more safety in that there's no next__ that the loop > could destroy by mistake). I don't think that either behavior is > inherently superior, so I'm just presenting this for your thoughts.
I like this! This would be even simpler form: #define LIST_FOR_EACH_POP(ITER, MEMBER, LIST) \ while (!list_is_empty(LIST) \ && (INIT_CONTAINER(ITER, list_pop_front(LIST), MEMBER), 1)) I’ll post a v2 with this and an updated test-list.c. Jarno _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev