mirror of
https://github.com/dlang/phobos.git
synced 2025-04-29 14:40:30 +03:00
Added std.algorithm.safeLess for safe signed/unsigned comparison; rewrote min/max
This commit is contained in:
parent
1e9c457f14
commit
2815d548d3
2 changed files with 98 additions and 28 deletions
|
@ -7117,17 +7117,9 @@ MinType!T min(T...)(T args)
|
||||||
algoFormat("Invalid arguments: Cannot compare types %s and %s.", T0.stringof, T1.stringof));
|
algoFormat("Invalid arguments: Cannot compare types %s and %s.", T0.stringof, T1.stringof));
|
||||||
|
|
||||||
//Do the "min" proper with a and b
|
//Do the "min" proper with a and b
|
||||||
static if (isIntegral!T0 && isIntegral!T1 &&
|
import std.functional : lessThan;
|
||||||
(mostNegative!T0 < 0) != (mostNegative!T1 < 0))
|
immutable chooseA = lessThan!(T0, T1)(a, b);
|
||||||
{
|
return cast(typeof(return)) (chooseA ? a : b);
|
||||||
static if (mostNegative!T0 < 0)
|
|
||||||
immutable chooseB = b < a && a > 0;
|
|
||||||
else
|
|
||||||
immutable chooseB = b < a || b < 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
immutable chooseB = b < a;
|
|
||||||
return cast(typeof(return)) (chooseB ? b : a);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unittest
|
unittest
|
||||||
|
@ -7209,16 +7201,8 @@ MaxType!T max(T...)(T args)
|
||||||
algoFormat("Invalid arguments: Cannot compare types %s and %s.", T0.stringof, T1.stringof));
|
algoFormat("Invalid arguments: Cannot compare types %s and %s.", T0.stringof, T1.stringof));
|
||||||
|
|
||||||
//Do the "max" proper with a and b
|
//Do the "max" proper with a and b
|
||||||
static if (isIntegral!T0 && isIntegral!T1 &&
|
import std.functional : lessThan;
|
||||||
(mostNegative!T0 < 0) != (mostNegative!T1 < 0))
|
immutable chooseB = lessThan!(T0, T1)(a, b);
|
||||||
{
|
|
||||||
static if (mostNegative!T0 < 0)
|
|
||||||
immutable chooseB = b > a || a < 0;
|
|
||||||
else
|
|
||||||
immutable chooseB = b > a && b > 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
immutable chooseB = b > a;
|
|
||||||
return cast(typeof(return)) (chooseB ? b : a);
|
return cast(typeof(return)) (chooseB ? b : a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
100
std/functional.d
100
std/functional.d
|
@ -133,22 +133,108 @@ unittest
|
||||||
//assert(binaryFun!("return a + b;")(41, 1) == 42);
|
//assert(binaryFun!("return a + b;")(41, 1) == 42);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
private template safeOp(string S)
|
||||||
|
if (is(typeof(mixin("0 "~S~" 0")) == bool))
|
||||||
|
{
|
||||||
|
private bool unsafeOp(ElementType1, ElementType2)(ElementType1 a, ElementType2 b) pure
|
||||||
|
if (isIntegral!ElementType1 && isIntegral!ElementType2)
|
||||||
|
{
|
||||||
|
alias T = CommonType!(ElementType1, ElementType2);
|
||||||
|
return mixin("cast(T)a "~S~" cast(T)b");
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool safeOp(T0, T1)(T0 a, T1 b) pure
|
||||||
|
{
|
||||||
|
static if (isIntegral!T0 && isIntegral!T1 &&
|
||||||
|
(mostNegative!T0 < 0) != (mostNegative!T1 < 0))
|
||||||
|
{
|
||||||
|
static if (S == "<=" || S == "<")
|
||||||
|
{
|
||||||
|
static if (mostNegative!T0 < 0)
|
||||||
|
immutable result = a < 0 || unsafeOp(a, b);
|
||||||
|
else
|
||||||
|
immutable result = b >= 0 && unsafeOp(a, b);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
static if (mostNegative!T0 < 0)
|
||||||
|
immutable result = a >= 0 && unsafeOp(a, b);
|
||||||
|
else
|
||||||
|
immutable result = b < 0 || unsafeOp(a, b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
static assert (is(typeof(mixin("a "~S~" b"))),
|
||||||
|
"Invalid arguments: Cannot compare types " ~ T0.stringof ~ " and " ~ T1.stringof ~ ".");
|
||||||
|
|
||||||
|
immutable result = mixin("a "~S~" b");
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
Predicate that returns $(D_PARAM a < b).
|
Predicate that returns $(D_PARAM a < b).
|
||||||
|
Correctly compares signed and unsigned integers, ie. -1 < 2U.
|
||||||
*/
|
*/
|
||||||
//bool less(T)(T a, T b) { return a < b; }
|
bool lessThan(T0, T1)(T0 a, T1 b)
|
||||||
//alias less = binaryFun!(q{a < b});
|
{
|
||||||
|
return safeOp!"<"(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
unittest
|
||||||
|
{
|
||||||
|
assert(lessThan(2, 3));
|
||||||
|
assert(lessThan(2U, 3U));
|
||||||
|
assert(lessThan(2, 3.0));
|
||||||
|
assert(lessThan(-2, 3U));
|
||||||
|
assert(lessThan(2, 3U));
|
||||||
|
assert(!lessThan(3U, -2));
|
||||||
|
assert(!lessThan(3U, 2));
|
||||||
|
assert(!lessThan(0, 0));
|
||||||
|
assert(!lessThan(0U, 0));
|
||||||
|
assert(!lessThan(0, 0U));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
Predicate that returns $(D_PARAM a > b).
|
Predicate that returns $(D_PARAM a > b).
|
||||||
|
Correctly compares signed and unsigned integers, ie. 2U > -1.
|
||||||
*/
|
*/
|
||||||
//alias greater = binaryFun!(q{a > b});
|
bool greaterThan(T0, T1)(T0 a, T1 b)
|
||||||
|
{
|
||||||
|
return safeOp!">"(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
unittest
|
||||||
|
{
|
||||||
|
assert(!greaterThan(2, 3));
|
||||||
|
assert(!greaterThan(2U, 3U));
|
||||||
|
assert(!greaterThan(2, 3.0));
|
||||||
|
assert(!greaterThan(-2, 3U));
|
||||||
|
assert(!greaterThan(2, 3U));
|
||||||
|
assert(greaterThan(3U, -2));
|
||||||
|
assert(greaterThan(3U, 2));
|
||||||
|
assert(!greaterThan(0, 0));
|
||||||
|
assert(!greaterThan(0U, 0));
|
||||||
|
assert(!greaterThan(0, 0U));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
Predicate that returns $(D_PARAM a == b).
|
Predicate that returns $(D_PARAM a == b).
|
||||||
|
Correctly compares signed and unsigned integers, ie. !(-1 == ~0U).
|
||||||
*/
|
*/
|
||||||
//alias equalTo = binaryFun!(q{a == b});
|
bool equalTo(T0, T1)(T0 a, T1 b)
|
||||||
|
{
|
||||||
|
return safeOp!"=="(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
unittest
|
||||||
|
{
|
||||||
|
assert(equalTo(0U, 0));
|
||||||
|
assert(equalTo(0, 0U));
|
||||||
|
assert(!equalTo(-1, ~0U));
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
N-ary predicate that reverses the order of arguments, e.g., given
|
N-ary predicate that reverses the order of arguments, e.g., given
|
||||||
$(D pred(a, b, c)), returns $(D pred(c, b, a)).
|
$(D pred(a, b, c)), returns $(D pred(c, b, a)).
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue