import std.string: format; import std.asserterror: AssertError; import meta.nameof: symbolnameof; // useful but not necessary align (1) struct Uint24 { alias typeof(*this) ThisType; // Can this be avoided? // can be replaced by the struct name if symbolnameof isn't available const name = symbolnameof!(ThisType); const uint init = 0; // this init doesn't work well with typedef: // typedef Uint24 Uint24b = 10; const uint min = 0; const uint max = (1 << 24) - 1; // 16_777_215 ushort low = init & 0xffff; ubyte up = init >> 16; static ThisType opCall(long n) { ThisType self; assert(n >= this.min && n <= this.max, format("%s(%d) not representable in 24 bits.", name, n)); self.low = n & 0xffff; self.up = n >> 16; return self; } void opAssign(long n) { assert(n >= this.min && n <= this.max, format("%s(%d) not representable in 24 bits.", name, n)); low = n & 0xffff; up = n >> 16; } uint opCast() { //return (up << 16) | low; // worse? return *(cast(uint*)(cast(void*)this)); } uint val() { return *(cast(uint*)(cast(void*)this)); } bool opEquals(ThisType other) { //return (this.up == other.up) && (this.low == other.low); // worse? uint self_uint = *(cast(uint*)(cast(void*)this)); uint other_uint = *(cast(uint*)(cast(void*)(&other))); return self_uint == other_uint; } bool opEquals(long n) { uint self_uint = *(cast(uint*)(cast(void*)this)); return self_uint == n; } bool opEquals(int n) { uint self_uint = *(cast(uint*)(cast(void*)this)); return self_uint == n; } int opCmp(ThisType other) { uint self_uint = *(cast(uint*)(cast(void*)this)); uint other_uint = *(cast(uint*)(cast(void*)(&other))); if (self_uint > other_uint) return 1; if (self_uint < other_uint) return -1; return 0; } int opCmp(long n) { uint self_uint = *(cast(uint*)(cast(void*)this)); if (self_uint > n) return 1; else return self_uint < n ? -1 : 0; } int opCmp(int n) { uint self_uint = *(cast(uint*)(cast(void*)this)); if (self_uint > n) return 1; else return self_uint < n ? -1 : 0; } string toString() { uint self_uint = *(cast(uint*)(cast(void*)this)); return format("%s(%d)", name, self_uint); } }