mirror of
https://github.com/dlang/phobos.git
synced 2025-04-30 07:00:37 +03:00
Fix Issue 18215 - std.array.replace throws a range violation if the from range is longer than the array
This commit is contained in:
parent
1f319fe22f
commit
7c0dab8d12
1 changed files with 41 additions and 2 deletions
39
std/array.d
39
std/array.d
|
@ -2124,6 +2124,7 @@ if (isDynamicArray!(E[]) && isForwardRange!R1 && isForwardRange!R2
|
||||||
&& (hasLength!R2 || isSomeString!R2))
|
&& (hasLength!R2 || isSomeString!R2))
|
||||||
{
|
{
|
||||||
import std.algorithm.searching : find;
|
import std.algorithm.searching : find;
|
||||||
|
import std.range : dropOne;
|
||||||
|
|
||||||
if (from.empty) return subject;
|
if (from.empty) return subject;
|
||||||
|
|
||||||
|
@ -2134,6 +2135,10 @@ if (isDynamicArray!(E[]) && isForwardRange!R1 && isForwardRange!R2
|
||||||
auto app = appender!(E[])();
|
auto app = appender!(E[])();
|
||||||
app.put(subject[0 .. subject.length - balance.length]);
|
app.put(subject[0 .. subject.length - balance.length]);
|
||||||
app.put(to.save);
|
app.put(to.save);
|
||||||
|
// replacing an element in an array is different to a range replacement
|
||||||
|
static if (is(Unqual!E : Unqual!R1))
|
||||||
|
replaceInto(app, balance.dropOne, from, to);
|
||||||
|
else
|
||||||
replaceInto(app, balance[from.length .. $], from, to);
|
replaceInto(app, balance[from.length .. $], from, to);
|
||||||
|
|
||||||
return app.data;
|
return app.data;
|
||||||
|
@ -2146,6 +2151,35 @@ if (isDynamicArray!(E[]) && isForwardRange!R1 && isForwardRange!R2
|
||||||
assert("Hello Wörld".replace("l", "h") == "Hehho Wörhd");
|
assert("Hello Wörld".replace("l", "h") == "Hehho Wörhd");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@safe unittest
|
||||||
|
{
|
||||||
|
assert([1, 2, 3, 4, 2].replace([2], [5]) == [1, 5, 3, 4, 5]);
|
||||||
|
assert([3, 3, 3].replace([3], [0]) == [0, 0, 0]);
|
||||||
|
assert([3, 3, 4, 3].replace([3, 3], [1, 1, 1]) == [1, 1, 1, 4, 3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://issues.dlang.org/show_bug.cgi?id=18215
|
||||||
|
@safe unittest
|
||||||
|
{
|
||||||
|
auto arr = ["aaa.dd", "b"];
|
||||||
|
arr = arr.replace("aaa.dd", ".");
|
||||||
|
assert(arr == [".", "b"]);
|
||||||
|
|
||||||
|
arr = ["_", "_", "aaa.dd", "b", "c", "aaa.dd", "e"];
|
||||||
|
arr = arr.replace("aaa.dd", ".");
|
||||||
|
assert(arr == ["_", "_", ".", "b", "c", ".", "e"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://issues.dlang.org/show_bug.cgi?id=18215
|
||||||
|
@safe unittest
|
||||||
|
{
|
||||||
|
assert([[0], [1, 2], [0], [3]].replace([0], [4]) == [[4], [1, 2], [4], [3]]);
|
||||||
|
assert([[0], [1, 2], [0], [3], [1, 2]]
|
||||||
|
.replace([1, 2], [0]) == [[0], [0], [0], [3], [0]]);
|
||||||
|
assert([[0], [1, 2], [0], [3], [1, 2], [0], [1, 2]]
|
||||||
|
.replace([[0], [1, 2]], [[4]]) == [[4], [0], [3], [1, 2], [4]]);
|
||||||
|
}
|
||||||
|
|
||||||
/// ditto
|
/// ditto
|
||||||
void replaceInto(E, Sink, R1, R2)(Sink sink, E[] subject, R1 from, R2 to)
|
void replaceInto(E, Sink, R1, R2)(Sink sink, E[] subject, R1 from, R2 to)
|
||||||
if (isOutputRange!(Sink, E) && isDynamicArray!(E[])
|
if (isOutputRange!(Sink, E) && isDynamicArray!(E[])
|
||||||
|
@ -2153,6 +2187,7 @@ if (isOutputRange!(Sink, E) && isDynamicArray!(E[])
|
||||||
&& (hasLength!R2 || isSomeString!R2))
|
&& (hasLength!R2 || isSomeString!R2))
|
||||||
{
|
{
|
||||||
import std.algorithm.searching : find;
|
import std.algorithm.searching : find;
|
||||||
|
import std.range : dropOne;
|
||||||
|
|
||||||
if (from.empty)
|
if (from.empty)
|
||||||
{
|
{
|
||||||
|
@ -2169,6 +2204,10 @@ if (isOutputRange!(Sink, E) && isDynamicArray!(E[])
|
||||||
}
|
}
|
||||||
sink.put(subject[0 .. subject.length - balance.length]);
|
sink.put(subject[0 .. subject.length - balance.length]);
|
||||||
sink.put(to.save);
|
sink.put(to.save);
|
||||||
|
// replacing an element in an array is different to a range replacement
|
||||||
|
static if (is(Unqual!E : Unqual!R1))
|
||||||
|
subject = balance.dropOne;
|
||||||
|
else
|
||||||
subject = balance[from.length .. $];
|
subject = balance[from.length .. $];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue