[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