fix Issue 17616 - makeIndex cannot fully use range of index type

This commit is contained in:
Martin Nowak 2017-07-07 12:29:02 +02:00 committed by Sebastian Wilzbach
parent 9f0d764854
commit 54bda1e5bc

View file

@ -994,15 +994,15 @@ if (isRandomAccessRange!Range && !isInfinite!Range &&
"r and index must be same length for makeIndex.");
static if (IndexType.sizeof < size_t.sizeof)
{
enforce(r.length <= IndexType.max, "Cannot create an index with " ~
enforce(r.length <= size_t(IndexType.max + 1), "Cannot create an index with " ~
"element type " ~ IndexType.stringof ~ " with length " ~
to!string(r.length) ~ ".");
}
for (IndexType i = 0; i < r.length; ++i)
{
index[cast(size_t) i] = i;
}
// Use size_t as loop index to avoid overflow on ++i,
// e.g. when squeezing 256 elements into a ubyte index.
foreach (i; size_t(0) .. size_t(r.length))
index[i] = cast(IndexType) i;
// sort the index
sort!((a, b) => binaryFun!less(r[cast(size_t) a], r[cast(size_t) b]), ss)
@ -1056,6 +1056,18 @@ if (isRandomAccessRange!Range && !isInfinite!Range &&
(index3));
}
@safe unittest
{
import std.algorithm.comparison : equal;
ubyte[256] index = void;
iota(256).makeIndex(index[]);
assert(index[].equal(iota(256)));
byte[128] sindex = void;
iota(128).makeIndex(sindex[]);
assert(sindex[].equal(iota(128)));
}
struct Merge(alias less = "a < b", Rs...)
if (Rs.length >= 2 &&
allSatisfy!(isInputRange, Rs) &&