std.algorithm.copy target not passed by reference (bug?)

Ali Çehreli acehreli at yahoo.com
Thu Aug 9 08:54:25 PDT 2012


On 08/09/2012 06:32 AM, Johannes Pfau wrote:
 > I just saw that the target range passed to std.algorithm.copy is not
 > passed by reference. So for a range which is implemented as a simple
 > struct value type and which modifies some internal state a call to copy
 > does not have any effect.

I think this is related to the separation of the concepts of container 
and range.

 > It can be worked around by passing a pointer to that range instead of
 > the range itself, but is there any reason why we can't just add a 'ref'
 > to the target range parameter?

That would have the problem of losing elements from a slice when used as 
an output range:

import std.stdio;
import std.range;

void main()
{
     int[] slice = [ 1, 2, 3 ];
     put(slice, 100);
     writeln(slice);
}

The output:

[2, 3]

The workaround is to make a copy of the output range:

import std.stdio;
import std.range;

void main()
{
     int[] slice = [ 1, 2, 3 ];
     int[] slice2 = slice;

     put(slice2, 100);

     writeln(slice2);
     writeln(slice);
}

The output:

[2, 3]
[100, 2, 3]    <-- original slice is preserved

This is happening as a result of decisions made to make output ranges 
very flexible. I try to explain this flexibility under the OutputRange 
section here:

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

That page lists the ways an object is considered to be used as an output 
range. Slices don't have a put() member function, so they end up being 
used as in the following:

   range.front = e;
   range.popFront();

Anyway, I think that's why copy() takes by copy. :)

Ali



More information about the Digitalmars-d-learn mailing list