[ovs-dev] [PATCH] lib/list: Add LIST_FOR_EACH_POP.
Jarno Rajahalme
jrajahalme at nicira.com
Mon Apr 6 20:48:00 UTC 2015
> On Apr 5, 2015, at 10:13 AM, Ben Pfaff <blp at 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 <jrajahalme at 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
More information about the dev
mailing list