More range woes: std.array.save is invalid

monarch_dodra monarchdodra at gmail.com
Wed Dec 19 23:25:42 PST 2012


On Thursday, 20 December 2012 at 07:05:08 UTC, H. S. Teoh wrote:
> The problem is std.array.save:
>
> @property T[] save(T)(T[] a) @safe pure nothrow
> {
>     return a;
> }
>
> This implementation is only correct for certain values of T. It 
> is wrong
> when T is a forward range, for example, because if you save a 
> T[] and
> iterate over its elements, it will consume the T's in the 
> array, so that
> the original range has elements that are now consumed.
>
> T

I'd say that's the correct behavior: A range is just a way to 
iterate over contents, and "save" makes no promise (and *should* 
make no promise) to make copies of the range's elements.

If you modify one of the elements in your range, then you'd 
better hope that change is seen by all other ranges iterating 
over the same data.

What I'm basically saying is:
//----
auto a = [1, 2, 3]
auto b = a.save;
b[0] = 5;
assert(a[0] == 5); //Correct behavior
//----

The fact that you have ints or forwards ranges as elements is 
irrelevant.

---------------------------
BTW: Just the same way, "dup" will not transitively duplicate the 
contents of an array, or of std.container.array.

---------------------------
To get your described behavior, then you should wrap your array 
into your own range, and make the array's elements part of your 
iteration definition. This way you'll surprise no one.


More information about the Digitalmars-d mailing list