_indexed_ iteration using opApply or range

Simen kjaeraas simen.kjaras at gmail.com
Sun Dec 12 13:30:14 PST 2010


spir <denis.spir at gmail.com> 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


More information about the Digitalmars-d-learn mailing list