Introducing ordered()

This commit is contained in:
Andrei Alexandrescu 2015-03-26 17:39:11 -07:00
parent 283374b78c
commit 5ca24b8392
2 changed files with 56 additions and 9 deletions

View file

@ -221,6 +221,7 @@ Params:
handlers that accept one argument. There can also be a choice that handlers that accept one argument. There can also be a choice that
accepts zero arguments. That choice will be invoked if the $(D accepts zero arguments. That choice will be invoked if the $(D
switchObject) is null. switchObject) is null.
switchObject = the object against which the tests are being made.
Returns: Returns:
The value of the selected choice. The value of the selected choice.

View file

@ -193,6 +193,52 @@ bool isSorted(alias less = "a < b", Range)(Range r) if (isForwardRange!(Range))
assert(isSorted(s)); // bidirectional 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 // partition
/** /**
Partitions a range in two using $(D pred) as a Partitions a range in two using $(D pred) as a