opApply not called for foeach(container)

Steven Schveighoffer schveiguy at yahoo.com
Thu Jul 12 14:18:21 PDT 2012


On Wed, 11 Jul 2012 11:10:16 -0400, kenji hara <k.hara.pg at gmail.com> wrote:

> I think the online documentation
> (http://dlang.org/statement.html#ForeachStatement) is not sufficient.
>
> foreach (e; aggr) { ...body...}
>
> Current dmd translates above foreach statement like follows.
>
> 1. If aggr has opApply or opApplyReverse, it's used.
>
> 2. If aggr has empty/front/popFront:
>  2a. If aggr has slice operation, it's translated to:
>
>   for (auto __r = aggr[];  // If aggr is a container (e.g.  
> std.container.Array),
>                            // foreach will get its range object for
> the iteration.
>       !__r.empty;
>       __r.popFront()) { auto e = __r.front; ...body... }
>
>  2b. If aggr doesn't have slice operation, it's translated to:
>
>   for (auto __r = aggr;  // If aggr is copyable, saves the original  
> range.
>       !__r.empty;
>       __r.popFront()) { auto e = __r.front; ...body... }
>
> 3. If aggr is static or dynamic array, it's translated to:
>
>   for (auto __tmp = aggr[], __key = 0;  // If aggr is static array,
> get its slice for iteration.
>       !__key < __tmp.length;
>       ++__key) { auto e = __tmp[__key]; ...body... }
>
> These come from the dmd source code.
> https://github.com/D-Programming-Language/dmd/blob/master/src/opover.c#L1226
> https://github.com/D-Programming-Language/dmd/blob/master/src/statement.c#L1522
>

This is wrong.  Why should we require aggr having empty/front/popFront to  
trigger a call to opSlice, which could have completely different type from  
aggr?  What if the result of opSlice has opApply?

If opSlice is to be used, this is how it should go (in order of  
precedence):

1. if aggr has opApply or opApplyReverse, use it.

2. if aggr has opSlice, and the result of aggr.opSlice() has opApply or  
opApplyReverse, use it.

3. if aggr has opSlice, and the result of aggr.opSlice() has  
empty/front/popfront, use it as in your 2a above.

4. if aggr has empty/front/popFront, use it as in your 2b above.

5. static or dynamic array.

I should also note that the existence of opApply should not preclude later  
possibilities if that opApply can't compile for the given foreach  
parameters.

-Steve


More information about the Digitalmars-d mailing list