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