mirror of
https://github.com/dlang/phobos.git
synced 2025-04-30 07:00:37 +03:00
Better Sort static assert error messages
This commit is contained in:
parent
73ba45329e
commit
ef2eb4fdb7
2 changed files with 45 additions and 18 deletions
8
changelog/sort_assert_messaged.dd
Normal file
8
changelog/sort_assert_messaged.dd
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
Better static assert messages for `std.algorithm.sorting.sort`
|
||||||
|
|
||||||
|
Up until now `sort` used a template constraint to check if the passed Range
|
||||||
|
could be used. If it were not, it was very tedious to figure out why.
|
||||||
|
|
||||||
|
As the template constraint is not used to overload the symbol template
|
||||||
|
function, the constrains are move into static asserts with expressive error
|
||||||
|
messages.
|
|
@ -1922,14 +1922,8 @@ See_Also:
|
||||||
$(REF binaryFun, std,functional)
|
$(REF binaryFun, std,functional)
|
||||||
*/
|
*/
|
||||||
SortedRange!(Range, less)
|
SortedRange!(Range, less)
|
||||||
sort(alias less = "a < b", SwapStrategy ss = SwapStrategy.unstable,
|
sort(alias less = "a < b", SwapStrategy ss = SwapStrategy.unstable, Range)
|
||||||
Range)(Range r)
|
(Range r)
|
||||||
if (((ss == SwapStrategy.unstable && (hasSwappableElements!Range ||
|
|
||||||
hasAssignableElements!Range)) ||
|
|
||||||
(ss != SwapStrategy.unstable && hasAssignableElements!Range)) &&
|
|
||||||
isRandomAccessRange!Range &&
|
|
||||||
hasSlicing!Range &&
|
|
||||||
hasLength!Range)
|
|
||||||
/+ Unstable sorting uses the quicksort algorithm, which uses swapAt,
|
/+ Unstable sorting uses the quicksort algorithm, which uses swapAt,
|
||||||
which either uses swap(...), requiring swappable elements, or just
|
which either uses swap(...), requiring swappable elements, or just
|
||||||
swaps using assignment.
|
swaps using assignment.
|
||||||
|
@ -1937,21 +1931,46 @@ if (((ss == SwapStrategy.unstable && (hasSwappableElements!Range ||
|
||||||
requiring assignable elements. +/
|
requiring assignable elements. +/
|
||||||
{
|
{
|
||||||
import std.range : assumeSorted;
|
import std.range : assumeSorted;
|
||||||
alias lessFun = binaryFun!(less);
|
static if (ss == SwapStrategy.unstable)
|
||||||
alias LessRet = typeof(lessFun(r.front, r.front)); // instantiate lessFun
|
|
||||||
static if (is(LessRet == bool))
|
|
||||||
{
|
{
|
||||||
static if (ss == SwapStrategy.unstable)
|
static assert(hasSwappableElements!Range || hasAssignableElements!Range,
|
||||||
quickSortImpl!(lessFun)(r, r.length);
|
"When using SwapStragety.unstable, the passed Range '"
|
||||||
else //use Tim Sort for semistable & stable
|
~ Range.stringof ~ "' must"
|
||||||
TimSortImpl!(lessFun, Range).sort(r, null);
|
~ " either fulfill hasSwappableElements, or"
|
||||||
|
~ " hasAssignableElements, both were not the case");
|
||||||
assert(isSorted!lessFun(r), "Failed to sort range of type " ~ Range.stringof);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
static assert(false, "Invalid predicate passed to sort: " ~ less.stringof);
|
static assert(hasAssignableElements!Range, "When using a SwapStragety"
|
||||||
|
~ " != unstable, the"
|
||||||
|
~ " passed Range '" ~ Range.stringof ~ "' must fulfill"
|
||||||
|
~ " hasAssignableElements, which it did not");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static assert(isRandomAccessRange!Range, "The passed Range '"
|
||||||
|
~ Range.stringof ~ "' must be a Random AccessRange "
|
||||||
|
~ "(isRandomAccessRange)");
|
||||||
|
|
||||||
|
static assert(hasSlicing!Range, "The passed Range '"
|
||||||
|
~ Range.stringof ~ "' must allow Slicing (hasSlicing)");
|
||||||
|
|
||||||
|
static assert(hasLength!Range, "The passed Range '"
|
||||||
|
~ Range.stringof ~ "' must have a length (hasLength)");
|
||||||
|
|
||||||
|
alias lessFun = binaryFun!(less);
|
||||||
|
alias LessRet = typeof(lessFun(r.front, r.front)); // instantiate lessFun
|
||||||
|
|
||||||
|
static assert(is(LessRet == bool), "The return type of the template"
|
||||||
|
~ " argument 'less' when used with the binaryFun!less template"
|
||||||
|
~ " must be a bool. This is not the case, the returned type is '"
|
||||||
|
~ LessRet.stringof ~ "'");
|
||||||
|
|
||||||
|
static if (ss == SwapStrategy.unstable)
|
||||||
|
quickSortImpl!(lessFun)(r, r.length);
|
||||||
|
else //use Tim Sort for semistable & stable
|
||||||
|
TimSortImpl!(lessFun, Range).sort(r, null);
|
||||||
|
|
||||||
|
assert(isSorted!lessFun(r), "Failed to sort range of type " ~ Range.stringof);
|
||||||
return assumeSorted!less(r);
|
return assumeSorted!less(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue