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