Packing enums
ketmar via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Wed Jul 1 00:45:08 PDT 2015
On Monday, 29 June 2015 at 22:05:47 UTC, qznc wrote:
> Something like this:
>
> enum X { A, B, C };
> enum Y { foo, bar, baz };
> alias both = TwoEnums!(X,Y);
> static assert(both.sizeof == 1);
> both z;
> z.X = B;
> z.Y = bar;
that's so easy that it's not even funny...
enum X { A, B, C };
enum Y { foo, bar, baz };
align(1) struct TwoEnums(E0, E1) if (is(E0 == enum) && is(E1 ==
enum)) {
private import std.string : format;
static assert(E0.min >= 0 && E1.min >= 0 && E0.max < 256 &&
E1.max < 256 && E0.max+E1.max < 256, "enums can't be packed");
static assert(E0.max > 0 && E1.max > 0, "can't pack dummy
enums");
align(1):
ubyte v_;
template opDispatch(string mt) {
static if (mt == E0.stringof) {
@property E0 implE0 () { return cast(E0)(v_%E0.max); }
@property void implE0 (E0 nv) { v_ =
cast(ubyte)((v_/E0.max)*E0.max+cast(ubyte)nv); }
alias opDispatch = implE0;
} else static if (mt == E1.stringof) {
@property E1 implE1 () { return cast(E1)(v_/E0.max); }
@property void implE1 (E1 nv) { v_ =
cast(ubyte)((v_%E0.max)+cast(ubyte)nv*E0.max); }
alias opDispatch = implE1;
} else {
static assert(0);
}
}
}
alias both = TwoEnums!(X, Y);
static assert(both.sizeof == 1);
void main () {
import std.stdio;
both z;
writeln(z.X, " ; ", z.Y, "; v_=", z.v_); // A ; foo; v_=0
z.X = X.B;
writeln(z.X, " ; ", z.Y, "; v_=", z.v_); // B ; foo; v_=1
z.Y = Y.bar;
writeln(z.X, " ; ", z.Y, "; v_=", z.v_); // B ; bar; v_=3
}
More information about the Digitalmars-d-learn
mailing list