spir <[email protected]> wrote:

(1) In my case, I do not want to modify the range (actually the private collection), because the type is not only about beeing a range (~ provide iteration). So that I defined the range methods, using a private 'rangeIndex slot', as (the type also maintains a 'length' slot):

    private uint rangeIndex;
    @property void popFront () {
        // (re)start...
        if (this.rangeIndex >= this.length)
            this.rangeIndex = 0;
        // ...or move on
        else
            ++ this.rangeIndex;
    }
    @property bool empty () {
        return (this.rangeIndex >= this.length);
    }
    @property T front () {
        return this.stacks[this.rangeIndex];
    }

Note that this also enables a restarting feature :-)

In this case, you probably want to use the idiom I described in the other
thread, that opSlice() return a range struct. Consider:

foreach ( i, e; myRange ) {
    if ( i == 3 ) break;
}

foreach ( i, e; myRange ) {
    // What is i?
}

For the restarting feature, forward ranges expose a function save(),
which returns a copy of the range as it was at the time of save() being
called. In many cases, save's body is simply 'return this;'.


(2) How then can I introduce indexed iteration (or more generally iteration with more than one parameter to the block), using ranges? The blocking (!) point is there is no way for front() to return a several multiple results. I can cheat using a tuple or struct, but D won't understand and unpack it for the user :-) Sure, the user may know I return a pack, but...

I know. There is currently no solution to this except opApply.

--
Simen

Reply via email to