mirror of
https://github.com/dlang/phobos.git
synced 2025-05-01 15:40:36 +03:00
make std.algorithm.sorting @safe-er
This commit is contained in:
parent
6db08d3dad
commit
016d5145b2
1 changed files with 29 additions and 29 deletions
|
@ -120,7 +120,7 @@ if (hasLength!(Range2) && hasSlicing!(Range2))
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
unittest
|
@safe unittest
|
||||||
{
|
{
|
||||||
import std.range : assumeSorted;
|
import std.range : assumeSorted;
|
||||||
int[] a = [ 1, 2, 3 ];
|
int[] a = [ 1, 2, 3 ];
|
||||||
|
@ -337,7 +337,7 @@ if (is(typeof(ordered!less(values))))
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
unittest
|
@safe unittest
|
||||||
{
|
{
|
||||||
assert(ordered(42, 42, 43));
|
assert(ordered(42, 42, 43));
|
||||||
assert(!strictlyOrdered(43, 42, 45));
|
assert(!strictlyOrdered(43, 42, 45));
|
||||||
|
@ -1186,7 +1186,7 @@ sort(alias less = "a < b", SwapStrategy ss = SwapStrategy.unstable,
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
unittest
|
@safe unittest
|
||||||
{
|
{
|
||||||
// Showcase stable sorting
|
// Showcase stable sorting
|
||||||
import std.algorithm.mutation : SwapStrategy;
|
import std.algorithm.mutation : SwapStrategy;
|
||||||
|
@ -1196,7 +1196,7 @@ unittest
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
unittest
|
@safe unittest
|
||||||
{
|
{
|
||||||
// Sorting floating-point numbers in presence of NaN
|
// Sorting floating-point numbers in presence of NaN
|
||||||
double[] numbers = [-0.0, 3.0, -2.0, double.nan, 0.0, -double.nan];
|
double[] numbers = [-0.0, 3.0, -2.0, double.nan, 0.0, -double.nan];
|
||||||
|
@ -1210,7 +1210,7 @@ unittest
|
||||||
assert(numbers.equal!isIdentical(sorted));
|
assert(numbers.equal!isIdentical(sorted));
|
||||||
}
|
}
|
||||||
|
|
||||||
unittest
|
@safe unittest
|
||||||
{
|
{
|
||||||
import std.algorithm.internal : rndstuff;
|
import std.algorithm.internal : rndstuff;
|
||||||
import std.algorithm.mutation : swapRanges;
|
import std.algorithm.mutation : swapRanges;
|
||||||
|
@ -1229,8 +1229,8 @@ unittest
|
||||||
}
|
}
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
bool greater2(int a, int b) { return a + i > b + i; }
|
bool greater2(int a, int b) @safe { return a + i > b + i; }
|
||||||
bool delegate(int, int) greater = &greater2;
|
auto greater = &greater2;
|
||||||
sort!(greater)(a);
|
sort!(greater)(a);
|
||||||
assert(isSorted!(greater)(a));
|
assert(isSorted!(greater)(a));
|
||||||
|
|
||||||
|
@ -1503,9 +1503,9 @@ private template TimSortImpl(alias pred, R)
|
||||||
alias T = ElementType!R;
|
alias T = ElementType!R;
|
||||||
|
|
||||||
alias less = binaryFun!pred;
|
alias less = binaryFun!pred;
|
||||||
bool greater(T a, T b){ return less(b, a); }
|
bool greater()(T a, T b){ return less(b, a); }
|
||||||
bool greaterEqual(T a, T b){ return !less(a, b); }
|
bool greaterEqual()(T a, T b){ return !less(a, b); }
|
||||||
bool lessEqual(T a, T b){ return !less(b, a); }
|
bool lessEqual()(T a, T b){ return !less(b, a); }
|
||||||
|
|
||||||
enum minimalMerge = 128;
|
enum minimalMerge = 128;
|
||||||
enum minimalGallop = 7;
|
enum minimalGallop = 7;
|
||||||
|
@ -1515,7 +1515,7 @@ private template TimSortImpl(alias pred, R)
|
||||||
struct Slice{ size_t base, length; }
|
struct Slice{ size_t base, length; }
|
||||||
|
|
||||||
// Entry point for tim sort
|
// Entry point for tim sort
|
||||||
void sort(R range, T[] temp)
|
void sort()(R range, T[] temp)
|
||||||
{
|
{
|
||||||
import std.algorithm.comparison : min;
|
import std.algorithm.comparison : min;
|
||||||
|
|
||||||
|
@ -1533,7 +1533,7 @@ private template TimSortImpl(alias pred, R)
|
||||||
size_t stackLen = 0;
|
size_t stackLen = 0;
|
||||||
|
|
||||||
// Allocate temporary memory if not provided by user
|
// Allocate temporary memory if not provided by user
|
||||||
if (temp.length < minTemp) temp = uninitializedArray!(T[])(minTemp);
|
if (temp.length < minTemp) temp = () @trusted { return uninitializedArray!(T[])(minTemp); }();
|
||||||
|
|
||||||
for (size_t i = 0; i < range.length; )
|
for (size_t i = 0; i < range.length; )
|
||||||
{
|
{
|
||||||
|
@ -1604,7 +1604,7 @@ private template TimSortImpl(alias pred, R)
|
||||||
|
|
||||||
// Calculates optimal value for minRun:
|
// Calculates optimal value for minRun:
|
||||||
// take first 6 bits of n and add 1 if any lower bits are set
|
// take first 6 bits of n and add 1 if any lower bits are set
|
||||||
pure size_t minRunLength(size_t n)
|
size_t minRunLength()(size_t n)
|
||||||
{
|
{
|
||||||
immutable shift = bsr(n)-5;
|
immutable shift = bsr(n)-5;
|
||||||
auto result = (n>>shift) + !!(n & ~((1<<shift)-1));
|
auto result = (n>>shift) + !!(n & ~((1<<shift)-1));
|
||||||
|
@ -1612,7 +1612,7 @@ private template TimSortImpl(alias pred, R)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns length of first run in range
|
// Returns length of first run in range
|
||||||
size_t firstRun(R range)
|
size_t firstRun()(R range)
|
||||||
out(ret)
|
out(ret)
|
||||||
{
|
{
|
||||||
assert(ret <= range.length);
|
assert(ret <= range.length);
|
||||||
|
@ -1637,7 +1637,7 @@ private template TimSortImpl(alias pred, R)
|
||||||
}
|
}
|
||||||
|
|
||||||
// A binary insertion sort for building runs up to minRun length
|
// A binary insertion sort for building runs up to minRun length
|
||||||
void binaryInsertionSort(R range, size_t sortedLen = 1)
|
void binaryInsertionSort()(R range, size_t sortedLen = 1)
|
||||||
out
|
out
|
||||||
{
|
{
|
||||||
if (!__ctfe) assert(isSorted!pred(range));
|
if (!__ctfe) assert(isSorted!pred(range));
|
||||||
|
@ -1669,7 +1669,7 @@ private template TimSortImpl(alias pred, R)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Merge two runs in stack (at, at + 1)
|
// Merge two runs in stack (at, at + 1)
|
||||||
void mergeAt(R range, Slice[] stack, immutable size_t at, ref size_t minGallop, ref T[] temp)
|
void mergeAt()(R range, Slice[] stack, immutable size_t at, ref size_t minGallop, ref T[] temp)
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
assert(stack.length >= 2);
|
assert(stack.length >= 2);
|
||||||
|
@ -1691,7 +1691,7 @@ private template TimSortImpl(alias pred, R)
|
||||||
|
|
||||||
// Merge two runs in a range. Mid is the starting index of the second run.
|
// Merge two runs in a range. Mid is the starting index of the second run.
|
||||||
// minGallop and temp are references; The calling function must receive the updated values.
|
// minGallop and temp are references; The calling function must receive the updated values.
|
||||||
void merge(R range, size_t mid, ref size_t minGallop, ref T[] temp)
|
void merge()(R range, size_t mid, ref size_t minGallop, ref T[] temp)
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
if (!__ctfe)
|
if (!__ctfe)
|
||||||
|
@ -1726,7 +1726,7 @@ private template TimSortImpl(alias pred, R)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enlarge size of temporary memory if needed
|
// Enlarge size of temporary memory if needed
|
||||||
T[] ensureCapacity(size_t minCapacity, T[] temp)
|
T[] ensureCapacity()(size_t minCapacity, T[] temp)
|
||||||
out(ret)
|
out(ret)
|
||||||
{
|
{
|
||||||
assert(ret.length >= minCapacity);
|
assert(ret.length >= minCapacity);
|
||||||
|
@ -1740,14 +1740,14 @@ private template TimSortImpl(alias pred, R)
|
||||||
if (newSize < minCapacity) newSize = minCapacity;
|
if (newSize < minCapacity) newSize = minCapacity;
|
||||||
|
|
||||||
if (__ctfe) temp.length = newSize;
|
if (__ctfe) temp.length = newSize;
|
||||||
else temp = uninitializedArray!(T[])(newSize);
|
else temp = () @trusted { return uninitializedArray!(T[])(newSize); }();
|
||||||
}
|
}
|
||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Merge front to back. Returns new value of minGallop.
|
// Merge front to back. Returns new value of minGallop.
|
||||||
// temp must be large enough to store range[0 .. mid]
|
// temp must be large enough to store range[0 .. mid]
|
||||||
size_t mergeLo(R range, immutable size_t mid, size_t minGallop, T[] temp)
|
size_t mergeLo()(R range, immutable size_t mid, size_t minGallop, T[] temp)
|
||||||
out
|
out
|
||||||
{
|
{
|
||||||
if (!__ctfe) assert(isSorted!pred(range));
|
if (!__ctfe) assert(isSorted!pred(range));
|
||||||
|
@ -1830,7 +1830,7 @@ private template TimSortImpl(alias pred, R)
|
||||||
|
|
||||||
// Merge back to front. Returns new value of minGallop.
|
// Merge back to front. Returns new value of minGallop.
|
||||||
// temp must be large enough to store range[mid .. range.length]
|
// temp must be large enough to store range[mid .. range.length]
|
||||||
size_t mergeHi(R range, immutable size_t mid, size_t minGallop, T[] temp)
|
size_t mergeHi()(R range, immutable size_t mid, size_t minGallop, T[] temp)
|
||||||
out
|
out
|
||||||
{
|
{
|
||||||
if (!__ctfe) assert(isSorted!pred(range));
|
if (!__ctfe) assert(isSorted!pred(range));
|
||||||
|
@ -2013,7 +2013,7 @@ private template TimSortImpl(alias pred, R)
|
||||||
alias gallopReverseUpper = gallopSearch!( true, true);
|
alias gallopReverseUpper = gallopSearch!( true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
unittest
|
@safe unittest
|
||||||
{
|
{
|
||||||
import std.random : Random, uniform, randomShuffle;
|
import std.random : Random, uniform, randomShuffle;
|
||||||
|
|
||||||
|
@ -2024,7 +2024,7 @@ unittest
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generates data especially for testing sorting with Timsort
|
// Generates data especially for testing sorting with Timsort
|
||||||
static E[] genSampleData(uint seed)
|
static E[] genSampleData(uint seed) @safe
|
||||||
{
|
{
|
||||||
import std.algorithm.mutation : swap, swapRanges;
|
import std.algorithm.mutation : swap, swapRanges;
|
||||||
|
|
||||||
|
@ -2089,7 +2089,7 @@ unittest
|
||||||
// enum result = testSort(seed);
|
// enum result = testSort(seed);
|
||||||
}
|
}
|
||||||
|
|
||||||
unittest
|
@safe unittest
|
||||||
{//bugzilla 4584
|
{//bugzilla 4584
|
||||||
assert(isSorted!"a < b"(sort!("a < b", SwapStrategy.stable)(
|
assert(isSorted!"a < b"(sort!("a < b", SwapStrategy.stable)(
|
||||||
[83, 42, 85, 86, 87, 22, 89, 30, 91, 46, 93, 94, 95, 6,
|
[83, 42, 85, 86, 87, 22, 89, 30, 91, 46, 93, 94, 95, 6,
|
||||||
|
@ -2098,7 +2098,7 @@ unittest
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unittest
|
@safe unittest
|
||||||
{
|
{
|
||||||
//test stable sort + zip
|
//test stable sort + zip
|
||||||
import std.range;
|
import std.range;
|
||||||
|
@ -2110,7 +2110,7 @@ unittest
|
||||||
assert(y == "aebcd"d);
|
assert(y == "aebcd"d);
|
||||||
}
|
}
|
||||||
|
|
||||||
unittest
|
@safe unittest
|
||||||
{
|
{
|
||||||
// Issue 14223
|
// Issue 14223
|
||||||
import std.range, std.array;
|
import std.range, std.array;
|
||||||
|
@ -2224,7 +2224,7 @@ schwartzSort(alias transform, alias less = "a < b",
|
||||||
schwartzSort!"a[0]"(chars);
|
schwartzSort!"a[0]"(chars);
|
||||||
}
|
}
|
||||||
|
|
||||||
unittest
|
@safe unittest
|
||||||
{
|
{
|
||||||
// issue 5924
|
// issue 5924
|
||||||
import std.typecons : Tuple;
|
import std.typecons : Tuple;
|
||||||
|
@ -2232,7 +2232,7 @@ unittest
|
||||||
schwartzSort!((Tuple!(char) c){ return c[0]; })(chars);
|
schwartzSort!((Tuple!(char) c){ return c[0]; })(chars);
|
||||||
}
|
}
|
||||||
|
|
||||||
unittest
|
@safe unittest
|
||||||
{
|
{
|
||||||
import std.algorithm.iteration : map;
|
import std.algorithm.iteration : map;
|
||||||
import std.math : log2;
|
import std.math : log2;
|
||||||
|
@ -2266,7 +2266,7 @@ unittest
|
||||||
assert(isSorted!("a > b")(map!(entropy)(arr)));
|
assert(isSorted!("a > b")(map!(entropy)(arr)));
|
||||||
}
|
}
|
||||||
|
|
||||||
unittest
|
@safe unittest
|
||||||
{
|
{
|
||||||
import std.algorithm.iteration : map;
|
import std.algorithm.iteration : map;
|
||||||
import std.math : log2;
|
import std.math : log2;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue