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."); "r and index must be same length for makeIndex.");
static if (IndexType.sizeof < size_t.sizeof) 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 " ~ "element type " ~ IndexType.stringof ~ " with length " ~
to!string(r.length) ~ "."); to!string(r.length) ~ ".");
} }
for (IndexType i = 0; i < r.length; ++i) // Use size_t as loop index to avoid overflow on ++i,
{ // e.g. when squeezing 256 elements into a ubyte index.
index[cast(size_t) i] = i; foreach (i; size_t(0) .. size_t(r.length))
} index[i] = cast(IndexType) i;
// sort the index // sort the index
sort!((a, b) => binaryFun!less(r[cast(size_t) a], r[cast(size_t) b]), ss) 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)); (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...) struct Merge(alias less = "a < b", Rs...)
if (Rs.length >= 2 && if (Rs.length >= 2 &&
allSatisfy!(isInputRange, Rs) && allSatisfy!(isInputRange, Rs) &&