mirror of
https://github.com/dlang/phobos.git
synced 2025-04-29 14:40:30 +03:00
Introducing ordered()
This commit is contained in:
parent
283374b78c
commit
5ca24b8392
2 changed files with 56 additions and 9 deletions
|
@ -221,6 +221,7 @@ Params:
|
|||
handlers that accept one argument. There can also be a choice that
|
||||
accepts zero arguments. That choice will be invoked if the $(D
|
||||
switchObject) is null.
|
||||
switchObject = the object against which the tests are being made.
|
||||
|
||||
Returns:
|
||||
The value of the selected choice.
|
||||
|
@ -500,7 +501,7 @@ Params:
|
|||
|
||||
Returns:
|
||||
Returns $(D val), if it is between $(D lower) and $(D upper).
|
||||
Otherwise returns the nearest of the two.
|
||||
Otherwise returns the nearest of the two.
|
||||
|
||||
*/
|
||||
auto clamp(T1, T2, T3)(T1 val, T2 lower, T3 upper)
|
||||
|
@ -708,14 +709,14 @@ template equal(alias pred = "a == b")
|
|||
/++
|
||||
This function compares to ranges for equality. The ranges may have
|
||||
different element types, as long as $(D pred(a, b)) evaluates to $(D bool)
|
||||
for $(D a) in $(D r1) and $(D b) in $(D r2).
|
||||
for $(D a) in $(D r1) and $(D b) in $(D r2).
|
||||
Performs $(BIGOH min(r1.length, r2.length)) evaluations of $(D pred).
|
||||
|
||||
Params:
|
||||
r1 = The first range to be compared.
|
||||
r1 = The first range to be compared.
|
||||
r2 = The second range to be compared.
|
||||
|
||||
Returns:
|
||||
Returns:
|
||||
$(D true) if and only if the two ranges compare equal element
|
||||
for element, according to binary predicate $(D pred).
|
||||
|
||||
|
@ -799,7 +800,7 @@ range of range (of range...) comparisons.
|
|||
{
|
||||
import std.algorithm.iteration : map;
|
||||
import std.math : approxEqual;
|
||||
import std.internal.test.dummyrange : ReferenceForwardRange,
|
||||
import std.internal.test.dummyrange : ReferenceForwardRange,
|
||||
ReferenceInputRange, ReferenceInfiniteForwardRange;
|
||||
|
||||
debug(std_algorithm) scope(success)
|
||||
|
|
|
@ -193,6 +193,52 @@ bool isSorted(alias less = "a < b", Range)(Range r) if (isForwardRange!(Range))
|
|||
assert(isSorted(s)); // bidirectional
|
||||
}
|
||||
|
||||
/**
|
||||
Like $(D isSorted), returns $(D true) if the given $(D values) are ordered
|
||||
according to the comparison operation $(D less). Unlike $(D isSorted), takes values
|
||||
directly instead of structured in a range.
|
||||
|
||||
The predicate must be a strict ordering just like with $(D isSorted). For
|
||||
example, $(D "a <= b") is incorrect and will cause failed assertions.
|
||||
|
||||
Params:
|
||||
values = The tested value
|
||||
less = The comparison predicate
|
||||
|
||||
Returns:
|
||||
$(D true) if the values are ordered.
|
||||
*/
|
||||
|
||||
bool ordered(alias less = "a < b", T...)(T values)
|
||||
if ((T.length == 2 && is(typeof(binaryFun!less(values[1], values[0])) : bool))
|
||||
||
|
||||
(T.length > 2 && is(typeof(ordered!less(values[0 .. 1 + $ / 2])))
|
||||
&& is(typeof(ordered!less(values[$ / 2 .. $]))))
|
||||
)
|
||||
{
|
||||
foreach (i, _; T[0 .. $ - 1])
|
||||
{
|
||||
if (binaryFun!less(values[i + 1], values[i]))
|
||||
{
|
||||
assert(!binaryFun!less(values[i], values[i + 1]),
|
||||
__FUNCTION__ ~ ": incorrect non-strict predicate.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
///
|
||||
unittest
|
||||
{
|
||||
assert(ordered(42, 42, 43));
|
||||
assert(!ordered(43, 42, 45));
|
||||
// Ordered lexicographically
|
||||
assert(ordered("Jane", "Jim", "Joe"));
|
||||
// Incidentally also ordered by length decreasing
|
||||
assert(ordered!((a, b) => a.length > b.length)("Jane", "Jim", "Joe"));
|
||||
}
|
||||
|
||||
// partition
|
||||
/**
|
||||
Partitions a range in two using $(D pred) as a
|
||||
|
@ -1229,8 +1275,8 @@ private template TimSortImpl(alias pred, R)
|
|||
immutable run3 = stackLen - 2;
|
||||
immutable run2 = stackLen - 3;
|
||||
immutable run1 = stackLen - 4;
|
||||
|
||||
if ( (stackLen > 2 && stack[run2].length <= stack[run3].length + stack[run4].length) ||
|
||||
|
||||
if ( (stackLen > 2 && stack[run2].length <= stack[run3].length + stack[run4].length) ||
|
||||
(stackLen > 3 && stack[run1].length <= stack[run3].length + stack[run2].length) )
|
||||
{
|
||||
immutable at = stack[run2].length < stack[run4].length ? run2 : run3;
|
||||
|
@ -1238,10 +1284,10 @@ private template TimSortImpl(alias pred, R)
|
|||
}
|
||||
else if (stack[run3].length > stack[run4].length) break;
|
||||
else mergeAt(range, stack[0 .. stackLen], run3, minGallop, temp);
|
||||
|
||||
|
||||
stackLen -= 1;
|
||||
}
|
||||
|
||||
|
||||
// Assert that the code above established the invariant correctly
|
||||
version (assert)
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue