mirror of
https://github.com/dlang/phobos.git
synced 2025-05-07 19:49:36 +03:00
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:
parent
5ffd5b34e8
commit
36a5a7373c
1 changed files with 26 additions and 14 deletions
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue