Transience of .front in input vs. forward ranges

Tommi tommitissari at hotmail.com
Mon Nov 5 20:18:18 PST 2012


I don't think this whole issue has anything to do with ranges. I 
think this is an issue of assuming that the symbol = means "copy 
what's on the right to what's on the left". When in reality, = 
could mean: (if what's on the right has reference semantics) 
"make what's on the left reference the same thing that the thing 
on the right references".

I think all range types should be allowed to return whatever they 
want from their front property. It's the responsibility of the 
user of the range to *actually* copy what front returns (if 
that's what he intends), instead of assuming that = means copy.

In the code below, X marks the bug:

module main;

import std.stdio;
import std.range;

class MyData
{
     int _value;
}

struct MyFwdRange
{
     MyData _myData;

     this(MyData md)
     {
         _myData = md;
     }

     @property MyData front()
     {
         return _myData;
     }

     @property bool empty() const
     {
         return _myData._value > 10;
     }

     void popFront()
     {
         _myData._value++;
     }

     @property MyFwdRange save() const
     {
         auto copy = MyFwdRange();
         copy._myData = new MyData();
         copy._myData._value = _myData._value;
         return copy;
     }
}

void printFirstAndSecond(R)(R range)
     if (isForwardRange!MyFwdRange)
{
     //         X
     auto first = range.front; // That is *not* copying

     range.popFront();
     writeln(first._value, " ", range.front._value);
}

void main()
{
     auto mfr = MyFwdRange(new MyData());

     printFirstAndSecond(mfr); // prints: 1 1 (instead of 0 1)
}


More information about the Digitalmars-d mailing list