I was trying to use isSorted to check for monotonicity. For example, [1,2,2,3] is monotonically increasing, but not strictly increasing. I was therefore trying to use isSorted!"a <= b"( [1,2,2,3] ), which failed. Looking at the implementation of isSorted:
bool isSorted(alias less = "a < b", Range)(Range r) if (isForwardRange!(Range))
{
// @@@BUG@@@ Should work with inlined predicate
bool pred(ElementType!Range a, ElementType!Range b)
{
return binaryFun!less(b, a);
}
return findAdjacent!pred(r).empty;
}
which would attempts to validate that all pairs in r conform to "a <= b" by not finding any "b <= a" pairs, which isn't logically correct. I've written a one-line patch below to fix this error. It changes the test from not finding "b <= a" pairs to not finding !"a <= b" pairs (i.e. any pairs ! conforming to the predicate).
bool isSorted(alias less = "a < b", Range)(Range r) if (isForwardRange!(Range))
{
// @@@BUG@@@ Should work with inlined predicate
bool pred(ElementType!Range a, ElementType!Range b)
{
+ return !binaryFun!less(a, b);
- return binaryFun!less(b, a);
}
return findAdjacent!pred(r).empty;
}
Comment #1 by andrei — 2011-04-26T15:06:14Z
isSorted!pred assesses whether the range has been sorted by using pred. So what you want is isSorted!"a < b", which will pass [1, 2, 2, 3].
The bug would stand if adjancentFind!"a <= b" would fail.
Comment #2 by sandford — 2011-04-26T18:59:03Z
Thank you for the clarification. I was definitely confused by the docs on this. What I read was, isSorted tested to see if all element pairs obeyed the predicate, whereas what it actually tests in whether the range conforms to what a range sorted by the predicate would be like.