Make makeIndex work with all integer widths. Also, since finite random access ranges are required to have a length now anyhow, use a more efficient method of filling the index range that doesn't require iterating over the range to be sorted.

This commit is contained in:
dsimcha 2011-10-14 21:10:49 -04:00
parent 5ffd5b34e8
commit 36a5a7373c

View file

@ -7275,19 +7275,30 @@ void makeIndex(
Range, Range,
RangeIndex) RangeIndex)
(Range r, RangeIndex index) (Range r, RangeIndex index)
if (isRandomAccessRange!(Range) && isRandomAccessRange!(RangeIndex) if (isRandomAccessRange!(Range) && !isInfinite!(Range) &&
&& isIntegral!(ElementType!(RangeIndex))) isRandomAccessRange!(RangeIndex) && !isInfinite!(RangeIndex) &&
isIntegral!(ElementType!(RangeIndex)))
{ {
// assume collection already ordered alias Unqual!(ElementType!RangeIndex) I;
size_t i; enforce(r.length == index.length,
auto r1 = r; "r and index must be same length for makeIndex.");
for (; !r1.empty; r1.popFront, ++i) static if(I.sizeof < size_t.sizeof)
index[i] = i; {
enforce(index.length == i); enforce(r.length <= I.max, "Cannot create an index with " ~
"element type " ~ I.stringof ~ " with length " ~
to!string(r.length) ~ "."
);
}
for(I i = 0; i < r.length; ++i)
{
index[cast(size_t) i] = i;
}
// sort the index // sort the index
bool indirectLess(ElementType!(RangeIndex) a, ElementType!(RangeIndex) b) bool indirectLess(ElementType!(RangeIndex) a, ElementType!(RangeIndex) b)
{ {
return binaryFun!(less)(r[a], r[b]); return binaryFun!(less)(r[cast(size_t) a], r[cast(size_t) b]);
} }
sort!(indirectLess, ss)(index); sort!(indirectLess, ss)(index);
} }
@ -7309,18 +7320,19 @@ unittest
assert(isSorted!("*a < *b")(index1)); assert(isSorted!("*a < *b")(index1));
// index using offsets // index using offsets
auto index2 = new size_t[arr.length]; auto index2 = new long[arr.length];
makeIndex(arr, index2); makeIndex(arr, index2);
assert(isSorted! assert(isSorted!
((size_t a, size_t b){ return arr[a] < arr[b];}) ((long a, long b){
(index2)); return arr[cast(size_t) a] < arr[cast(size_t) b];
})(index2));
// index strings using offsets // index strings using offsets
string[] arr1 = ["I", "have", "no", "chocolate"]; string[] arr1 = ["I", "have", "no", "chocolate"];
auto index3 = new size_t[arr1.length]; auto index3 = new byte[arr1.length];
makeIndex(arr1, index3); makeIndex(arr1, index3);
assert(isSorted! assert(isSorted!
((size_t a, size_t b){ return arr1[a] < arr1[b];}) ((byte a, byte b){ return arr1[a] < arr1[b];})
(index3)); (index3));
} }