bitfields
downs
default_357-line at yahoo.de
Sat Jun 27 05:56:57 PDT 2009
novice2 wrote:
> does anyone know: is D2 std.bitmanip compatible with C bitfields?
> can i use it, if i need translate .h file with something like this:
>
> typedef struct {
> unsigned int can_compress : 1;
> unsigned int can_uncompress : 1;
> unsigned int can_get_info : 1;
> unsigned int : 7;
> unsigned int : 16;
> unsigned int : 16;
> unsigned int : 16;
> unsigned int : 16;
> unsigned int : 16;
> } capabilities;
>
> Thanks.
Here's a way to do it.
Enjoy! :)
Usage example:
struct Test {
ushort bits;
mixin GroupPackedAccess!(bits,
ubyte, "stuff", 3,
bool, "otherstuff"
);
}
module packed;
template PackedAccessTools(string NAME, int from, int to) {
const max = 1 << (to-from);
static if (to >= 32) static assert(false, "Too large");
else static if (to >= 16) alias uint type;
else static if (to >= 8) alias ushort type;
else alias ubyte type;
// 0 .. 4 -> ((1 << 4):16 - 1):15 & ~0 -> 7 == 1111
// 4 .. 8 -> ((1 << 8):256 - 1):255 & ~((1 << 4): 16 - 1):15 -> 11110000
const type mask = ((1 << to) - 1) - ((1 << from) - 1);
const ID = NAME~"_"~from.stringof~"_"~to.stringof;
}
template PackedAccess(alias VAR, T, string NAME, int from, int to) {
mixin(ctReplace(`
T NAME() {
static if (is(T == bool))
return (VAR & (°.mask)) != 0;
else
return cast(T) ((VAR & (°.mask)) >> from);
}
T NAME(T nv) {
Assert(nv < °.max, "Value too big");
VAR &= (~°.mask);
VAR |= (nv << from);
return nv;
}
`, "NAME", NAME, "°", "PackedAccessTools!(NAME, from, to)", "·", PackedAccessTools!(NAME, from, to).ID
));
}
template NaturalTypeSize(T) {
static if (is(T==bool)) const NaturalTypeSize = 1;
else static assert(false, "No known default size for "~T.stringof~"!");
}
template GroupPackedAccess(alias VAR, T...) {
static if (T.length > 2) {
static if (is(typeof(T[0])==void)) {
static if (is(typeof(T[4]): int) && !is(T[4]: int)) {
mixin PackedAccess!(VAR, T[2], T[3], T[1], T[1]+T[4]);
mixin GroupPackedAccess!(VAR, void, T[1]+T[4], T[5 ..$]);
} else {
mixin PackedAccess!(VAR, T[2], T[3], T[1], T[1]+NaturalTypeSize!(T[2]));
mixin GroupPackedAccess!(VAR, void, T[1]+NaturalTypeSize!(T[2]), T[4 ..$]);
}
} else {
mixin GroupPackedAccess!(VAR, void, 0, T);
}
}
}
More information about the Digitalmars-d-learn
mailing list