www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - std.algorithm.copy target not passed by reference (bug?)

reply Johannes Pfau <nospam example.com> writes:
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.
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?
Aug 09 2012
parent =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
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
Aug 09 2012