blob: 3d6e456cc2958ea16b28d0546531b29c660f6d0c [file] [log] [blame]
module imports.aXXXXX;
auto min(A, B)(A a, B b) { return a < b ? a : b; }
alias TypeTuple(T...) = T;
private template CustomFloatParams(uint bits)
{
static if (bits == 8) alias CustomFloatParams!( 4, 3) CustomFloatParams;
static if (bits == 16) alias CustomFloatParams!(10, 5) CustomFloatParams;
static if (bits == 32) alias CustomFloatParams!(23, 8) CustomFloatParams;
static if (bits == 64) alias CustomFloatParams!(52, 11) CustomFloatParams;
static if (bits == 80) alias CustomFloatParams!(64, 15) CustomFloatParams;
}
private template CustomFloatParams(uint precision, uint exponentWidth)
{
alias TypeTuple!(
precision,
exponentWidth,
) CustomFloatParams;
}
private union ToBinary(F)
if (is(typeof(CustomFloatParams!(F.sizeof*8))) || is(F == real))
{
F set;
// If on Linux or Mac, where 80-bit reals are padded, ignore the
// padding.
CustomFloat!(CustomFloatParams!(min(F.sizeof*8, 80))) get;
// Convert F to the correct binary type.
static typeof(get) opCall(F value)
{
ToBinary r;
r.set = value;
return r.get;
}
alias get this;
}
struct CustomFloat(uint precision, uint exponentWidth)
if ((1 + precision + exponentWidth) % 8 == 0 && precision + exponentWidth > 0)
{
public:
@property bool sign() { return 1; }
@property void sign(bool) {}
this(F)(F input)
if (__traits(compiles, cast(real)input))
{
this = input;
}
void opAssign(F)(F input)
if (__traits(compiles, cast(real)input))
{
static if (is(F == float) || is(F == double) || is(F == real))
auto value = ToBinary!(F)(input);
else auto value = ToBinary!(real)(input);
sign = value.sign;
}
@property F get(F)()
if (is(F == float) || is(F == double) || is(F == real))
{
ToBinary result;
return F.init;
}
T opCast(T)()
if (__traits(compiles, get!T))
{
return get!T;
}
}