Comment #0 by ellery-newcomer — 2012-02-11T11:52:25Z
Way back in 2.054 you could use std.algorithm.copy in an overlapping copy, e.g.,
copy(a[5 .. 10], a[4 .. 9]);
Fast forward a couple releases, and copy seems to be delegating to
a[4 .. 9] = a[5 .. 10];
in the interest of speed, but here overlapping copy is prohibited by spec and implementation.
I maintain that std.algorithm.copy should permit overlapping copy in the case of arrays because
1: it is consistent with STL copy's semantics (see Note 2)
2: copy can still do an overlapping copy on non-array range types*, and failing to do so on arrays is an inconsistency
If this behavior is desired, the docs should at least make mention of it. Also note that if copy's behavior is reverted, it could be the solution for issue 1317.
*proof:
auto a = make!(SList!int) ([1,2,3,4,5,6,7,8,9,10]);
auto r1 = a[];
auto r2 = a[];
r2.popFront();
copy(r2,r1);
writeln(a[]); // prints [2, 3, 4, 5, 6, 7, 8, 9, 10, 10]
Comment #1 by dsimcha — 2012-02-11T14:47:10Z
Agreed. I implemented the special-casing a few releases back because the performance difference was huge, and the overlapping copy thing was an oversight, not a conscious decision. I'll put in an extra test for overlap and fallback to naive copying if the arrays do overlap.
Comment #2 by bearophile_hugs — 2012-02-11T14:54:13Z
(In reply to comment #1)
> I'll put in an extra test for overlap and
> fallback to naive copying if the arrays do overlap.
Is using memmove() good there is overlap?
Comment #3 by dsimcha — 2012-02-11T15:21:17Z
(In reply to comment #2)
> (In reply to comment #1)
> > I'll put in an extra test for overlap and
> > fallback to naive copying if the arrays do overlap.
>
> Is using memmove() good there is overlap?
I don't think it would have the same semantics in all cases. memmove() requires semantics identical to if an intermediate buffer were used. Imagine copying a[4..9] to a[5..10].
Comment #4 by github-bugzilla — 2012-02-11T16:36:39Z
Comment #6 by ellery-newcomer — 2012-02-12T08:10:17Z
Awesome. May I additionally request that overlapping copy be mentioned in the documentation
1: in std.algorithm.copy
something like
copy(a[5 .. 10], a[4 .. 9]); //valid
copy(a[4 .. 9], a[5 .. 10]); //invalid
copy(retro(a[5 .. 10]), retro(a[4 .. 9])); // invalid
copy(retro(a[4 .. 9]), retro(a[5 .. 10])); // valid
2: in Language / Arrays / Array Copying
just point the reader to std.algorithm.copy for overlapping copy