foreach without front

Idan Arye via Digitalmars-d digitalmars-d at puremagic.com
Mon Aug 11 09:30:35 PDT 2014


On Monday, 11 August 2014 at 15:40:18 UTC, Jonathan Marler wrote:
> I know this is kinda "nit picky" but it would be nice if 
> foreach supported iterating through input ranges without 
> accessing the front function.
>
> foreach(myInputRange) {
>     // myInputRange has a front function but it is
>     // never called because the foreach has no type list
> }
>
> One case where I think this would be preferable is when input 
> ranges iterate over larger data structures or data that is 
> trashed after every iteration.  Like the following example.
>
> struct MyData {
>   int someInt;
>   string someString;
>   ubyte[128] data;
> }
>
> struct MyDataInputRange {
>   MyData* dataBuffer;
>   this(MyData* dataBuffer) {
>     this.dataBuffer = dataBuffer;
>   }
>   @property bool empty() { /* empty logic */ }
>   @property MyData* front() { return dataBuffer; }
>   @property popFront() { }
> }
> void main()
> {
>   MyData data;
>   foreach(dataPointer; MyDataInputRange(&data)) {
>     // It doesn't make much sense to use dataPointer when you
>     // already have direct access to the data buffer
>   }
>   foreach(MyDataInputRange(&data)) {
>     // This allows you to iterate over the range using the same 
> buffer
>   }
> }
>
> I realize that in this case it results in such an infinitesimal 
> optimization but I'm bringing this up because it seems like a 
> feature that:
>   1. would be relatively easy to implement
>   2. could be useful in some other cases
>
> Has anyone wanted this feature before?

`foreach` should manage it's own iterator's resources - it 
shouldn't rely on some memory declared outside it's scope that'll 
be accessible after the loop is finished. You can always manage 
the iteration manually:

     struct MyData {
         int someInt;
         string someString;
         ubyte[128] data;
     }

     struct MyDataInputRange {
         MyData* dataBuffer;
         this(MyData* dataBuffer) {
             this.dataBuffer = dataBuffer;
         }
         bool moveNext() { /* return true unless reached the end 
of the loop */ }
     }
     void main()
     {
         MyData data;
         for(auto dataInputRange = MyDataInputRange(&data);
                 dataInputRange.moveNext();) {
         }
     }


More information about the Digitalmars-d mailing list