Problems with OutputRanges

Ali Çehreli acehreli at yahoo.com
Mon Mar 24 20:42:47 PDT 2014


On 03/24/2014 07:42 PM, Meta wrote:

 > I'm not sure what I'm doing wrong... the following code prints nothing:
 >
 > void main()
 > {
 >      import std.stdio, std.range;
 >
 >      string str = "asdf";
 >      auto sink = new dchar[](str.length);
 >      auto fun = (dchar c) { sink.put(c); };
 >      foreach (dchar c; str)
 >      {
 >          fun(c);
 >      }
 >      writeln(sink);
 > }
 >
 > If I print sink's length inside the foreach loop, its length is reduced
 > by 1 each step, until it's 0. That explains why nothing is being
 > printed, but why is put altering the length of the array?

Very many things can be output ranges depending on what operations they 
support:

   http://dlang.org/phobos/std_range.html#.put

sink above is a slice, matching "if R defines put, r.front = e if r is 
an input range (followed by r.popFront())" in the above document. That's 
popFront() in that excerpt that is causing the loss of element here.

I have a more detailed explanation of this under the "Using slices as 
OutputRange" section in the following chapter:

   http://ddili.org/ders/d.en/ranges.html

So, one of the solutions here is to use a surrogate slice instead:

     auto sinkSurrogate = sink;
     auto fun = (dchar c) { sinkSurrogate.put(c); };

Now, sinkSurrogate will lose elements and sink will still be usable.

Ali



More information about the Digitalmars-d-learn mailing list