Bill Baxter wrote:
On Fri, Jan 23, 2009 at 8:10 AM, Christopher Wright <[email protected]> wrote:
Ary Borenszweig wrote:
If the compiler can transform a "foreach" into an opApply call, passing
the foreach body and converting breaks to "return 1" statements... can't
opApply be specified as:

int opApply(void delegate(ref uint) dg) { // note: delegate returns void
}

and the compiler transforms the opApply signature to the one that's used
now, plus converting each dg call to a call and a check of return value  !=
0 and return 1 in that case?
This only fails if you wish to take a particular action when the calling
code breaks out of iteration. This is not such a large use case that I think
it worth preserving.

Why do you mean by "fails"? The compiler transforms the foreach's body, it can transform the opApply's body.


It's not?

foreach(i;  things) {
      if (i==a) continue;
      if (i==b) break;
      if (i==d) return;
      if (i==c) goto somewhere;
}

Those are all fairly common things to do from inside the 'dg' call.
The int is how the compiler distinguishes which case got you out of
the dg.

--bb

Aaaah... Now I see what's the return value of opApply for. So I tried your code:

(just the relevant piece)
---
int main(char[][] args) {
        int a = 1, b = 2, c = 3, d = 4;
        
    Foo foo = new Foo();
    foreach(i; foo) {
        if (i==a) continue;
        if (i==b) break;
        if (i==d) return;
        if (i==c) goto somewhere;
    }

    somewhere:

    return 0;
}
---

and DMD spits out this:

---
int main(char[][] args) {
        int a = 1, b = 2, c = 3, d = 4;
        
        Foo foo = new Foo;
        switch(foo.opApply(delegate (uint __applyArg0) {
                        {
                                uint i = __applyArg0;
                                if(i == cast(uint) a)
                                        return 0;
                                if(i == cast(uint) b)
                                        return 1;
                                if(i == cast(uint) d)
                                        return 2;
                                if(i == cast(uint) c)
                                        return 3;
                        }
                        return 0;
                } )) {
                default:
                        break;
                case 2:
                        return;
                case 3:
                        goto somewhere;
        }
        
        somewhere:
        
        return 0;
}
---

Intersting. The compiler (Walter?) is being smart here. :-)

Reply via email to