On Saturday, 21 January 2017 at 15:55:35 UTC, Xavier Bigand wrote:
I don't see any other use case than for initialized maths struct to an invalid state, and because it is generally in template that working with integers and floats it is easier to have same properties (when it have the same meaning).

I use

/// consider T.max to be NaN of unsigned types
/// and T.min to be NaN of signed types
@property bool isNaN(T)(const(T) x) pure @safe @nogc nothrow if(isIntegral!T)
{
   static if(isSigned!T)
      return x == T.min;
   else // unsigned
      return x == T.max;
}

/// add a property to numeric types that can be used as return value if a result is out of bounds
template invalid(T) if(isNumeric!T)
{
   static if(isFloatingPoint!T)
      @property enum invalid = T.init;
   else static if(isSigned!T)
      @property enum invalid = T.min; // 0x80..00
   else // unsigned
      @property enum invalid = T.max; // 0xFF..FF
}

/// returns the save (not invalid) minimum value for the given type
template smin(T) if(isNumeric!T)
{
   static if(isFloatingPoint!T)
@property enum smin = -T.max; // T.min is the smallest representable positive value!!
   else static if(isSigned!T)
      @property enum smin = T(T.min+1);
   else // unsigned
      @property enum smin = T.min; // 0
}

/// returns the save (not invalid) maximum value for the given type
template smax(T) if(isNumeric!T)
{
   static if(isUnsigned!T)
      @property enum smax = T(T.max-1u);
   else
      @property enum smax = T.max;
}

Reply via email to