Upgrading a codebase from 2.065 to 2.066
Dominikus Dittes Scherkl via Digitalmars-d
digitalmars-d at puremagic.com
Tue Jul 8 03:46:41 PDT 2014
On Tuesday, 8 July 2014 at 06:08:58 UTC, Brian Schott wrote:
> On Tuesday, 8 July 2014 at 06:02:51 UTC, Iain Buclaw via
> Digitalmars-d wrote:
>> I would ask why are you passing integers to isNaN.
>
> We passed T to isNaN, and sometimes T was uint.
I would like to have a NaN in any type and be able to call isNaN
for any (numeric) type. In fact I work with the following:
/// add a property to numeric types that can be used as return
value if a result is out of bounds
template @property T invalid(T) @primitive if(isNumeric!T)
{
static if(isFloat!T)
return T.init;
else static if(isSigned!T)
return T.min;
else // unsigned
return T.max;
}
/// returns the save (not invalid) minimum value for the given
type
template @property T smin(T) @primitive if(isNumeric!T)
{
static if(isIntegral!T && isSigned!T)
return T.min+1;
else
return T.min;
}
/// returns the save (not invalid) maximum value for the given
type
template @property T smax(T) @primitive if(isNumeric!T)
{
static if(isUnsigned!T)
return T.max-1u;
else
return T.max;
}
/// take any NaN as invalid floatingpoint value,
/// T.max as invalid value of unsigned types and
/// T.min as invalid value of signed types
bool isInvalid(T)(const(T) x) @primitive if(isNumeric!T)
{
static if(isFloat!T)
return isNaN(x);
else static if(isSigned!T)
return x == T.min;
else // unsigned
return x == T.max;
}
(btw: @primitive is my internal shorthand for "pure @safe @nogc
@nothrow")
because it allows to define save functions like e.g. a save
downcast:
/// returns T.invalid if x is outside the target type range
T limit(T, U)(const(U) x) @primitive if(isNumeric!T &&
isNumeric!U)
{
static if(Unqual!T == Unqual!U) // nop
return x;
else static if(isFloat!T)
return cast(T)x; // let D handle this internally
else static if(isFloat!U)
return (isNaN(x) || x <= cast(U)T.min-1.0f || x >=
cast(U)T.max+1.0f) ? T.invalid : cast(T)x;
else static if(isSigned!T)
{
static if(T.sizeof > U.sizeof) // nothing to limit
return cast(T)x;
else static if(isUnsigned!U) // limit one direction
return (x > T.max) ? T.invalid : cast(T)x;
else // limit both directions
return (x < T.min || x > T.max) ? T.invalid : cast(T)x;
}
else // unsigned result
{
static if(isSigned!U) // prohibit negative values
if(x < 0) return T.invalid;
static if(T.sizeof >= U.sizeof) // no further limit
return cast(T)x;
else // prohibit also big positive values
return (x > T.max) ? T.invalid : cast(T)x;
}
}
More information about the Digitalmars-d
mailing list