129 lines
3.4 KiB
D
129 lines
3.4 KiB
D
// NOTE: comes from std.bitmanip
|
|
|
|
// PERMUTE_ARGS:
|
|
|
|
private string myToString(ulong n)
|
|
{
|
|
return n < 10
|
|
? "" ~ cast(char) (n + '0')
|
|
: myToString(n / 10) ~ myToString(n % 10);
|
|
}
|
|
|
|
private string toStringSfx(ulong n)
|
|
{
|
|
return myToString(n) ~ (n > uint.max ? "UL" : "U");
|
|
}
|
|
|
|
private string CreateAccessors(
|
|
string store, T, string name, size_t len, size_t offset)()
|
|
{
|
|
static if (!name.length)
|
|
{
|
|
// No need to create any accessor
|
|
return "";
|
|
}
|
|
else
|
|
{
|
|
static const
|
|
maskAllElse = ((1uL << len) - 1u) << offset,
|
|
maskMyself = ~maskAllElse,
|
|
signBitCheck = 1uL << (len - 1),
|
|
extendSign = ~((1uL << len) - 1);
|
|
|
|
string result;
|
|
static if (is(T == bool))
|
|
{
|
|
static assert(len == 1);
|
|
// getter
|
|
result ~= "bool " ~ name ~ "(){ return "
|
|
~ "("~store~" & "~toStringSfx(maskAllElse)~") != 0;}";
|
|
// setter
|
|
result ~= "void " ~ name ~ "(bool v){"
|
|
~ "if (v) "~store~" |= "~toStringSfx(maskAllElse)~";"
|
|
~ "else "~store~" &= "~toStringSfx(maskMyself)~";}";
|
|
}
|
|
else
|
|
{
|
|
// getter
|
|
result ~= T.stringof ~ " " ~ name ~ "(){ auto result = "
|
|
~ "("~store~" & "
|
|
~ toStringSfx(maskAllElse) ~ ") >>"
|
|
~ toStringSfx(offset) ~ ";";
|
|
static if (T.min < 0)
|
|
{
|
|
result ~= "if (result >= " ~ toStringSfx(signBitCheck)
|
|
~ ") result |= " ~ toStringSfx(extendSign) ~ ";";
|
|
}
|
|
result ~= " return cast(" ~ T.stringof ~ ") result;}";
|
|
// setter
|
|
result ~= "void " ~ name ~ "(" ~ T.stringof
|
|
~ " v){ "~store~" = ("~store~" & "
|
|
~ toStringSfx(maskMyself) ~ ") | "
|
|
~ "((cast(typeof("~store~")) v << " ~ toStringSfx(offset)
|
|
~ ") & " ~ toStringSfx(maskAllElse)
|
|
~ ");}";
|
|
}
|
|
return result;
|
|
}
|
|
}
|
|
|
|
private string createStoreName(Ts...)()
|
|
{
|
|
static if (Ts.length == 0)
|
|
return "";
|
|
else
|
|
return Ts[1] ~ createStoreName!(Ts[3 .. $])();
|
|
}
|
|
|
|
private string CreateFields(string store, size_t offset, Ts...)()
|
|
{
|
|
static if (!Ts.length)
|
|
{
|
|
static if (offset == ubyte.sizeof * 8)
|
|
return "private ubyte " ~ store ~ ";";
|
|
else static if (offset == ushort.sizeof * 8)
|
|
return "private ushort " ~ store ~ ";";
|
|
else static if (offset == uint.sizeof * 8)
|
|
return "private uint " ~ store ~ ";";
|
|
else static if (offset == ulong.sizeof * 8)
|
|
return "private ulong " ~ store ~ ";";
|
|
else
|
|
static assert(false, ToString!(offset));
|
|
}
|
|
else
|
|
{
|
|
return CreateAccessors!(store, Ts[0], Ts[1], Ts[2], offset)()
|
|
~ CreateFields!(store, offset + Ts[2], Ts[3 .. $])();
|
|
}
|
|
}
|
|
|
|
template BitFields(T...)
|
|
{
|
|
//pragma(msg, CreateFields!(createStoreName!(T)(), 0, T)());
|
|
mixin(CreateFields!(createStoreName!(T)(), 0, T)());
|
|
}
|
|
|
|
struct FloatRep
|
|
{
|
|
mixin BitFields!(
|
|
uint, "fraction", 23,
|
|
uint, "exponent", 8,
|
|
bool, "sign", 1);
|
|
}
|
|
|
|
struct DoubleRep
|
|
{
|
|
mixin BitFields!(
|
|
ulong, "fraction", 52,
|
|
uint, "exponent", 11,
|
|
bool, "sign", 1);
|
|
}
|
|
|
|
struct Bug2355(string x) {}
|
|
static assert(is(Bug2355!"a" U : Bug2355!V, string V));
|
|
|
|
int main()
|
|
{
|
|
return 0;
|
|
}
|