digitalmars.D.learn - Is there a more elegant way to do this?
- bauss (44/44) Mar 11 2017 I was wondering if there's a more elegant way to do something
- bauss (7/10) Mar 11 2017 I saw one improvement to it which would be BitSize!ChildType
- Nicholas Wilson (28/72) Mar 11 2017 template HalfSize(T)
I was wondering if there's a more elegant way to do something like this? template BitSize(T) { enum BitSize = T.sizeof * 8; } struct Data(ParentType,ChildType) { property { ChildType low() { return cast(ChildType)value; } void low(ChildType lowValue) { value = ((high << (BitSize!ParentType / 2)) | lowValue); } ChildType high() { return cast(ChildType)(value >> (BitSize!ParentType / 2)); } void high(ChildType highValue) { value = ((highValue << 16 | low)); } } ParentType value; alias value this; } Example usage: void main() { Data!(uint,ushort) data; data = 14065735; writefln("low: %s high: %s", data.low, data.high); data.low = 41031 ; data.high = 214; writefln("value: %s", data.value); } Basically to explain what it is: You give it a parent-type and a corresponding child-type. Ex. if the parent-type is uint, the child-type would be ushort. if the parent-type is long, the child-type would be int. etc. What it allows you to is to either manipulate the data as the parent-type or as two values of the child type. I was just wondering if there's a more elegant or performant way to do this, perhaps something in Phobos exist already?
Mar 11 2017
On Sunday, 12 March 2017 at 05:13:41 UTC, bauss wrote:I was wondering if there's a more elegant way to do something like this? [...]I saw one improvement to it which would be BitSize!ChildType instead of taking parent type's bit size divided by two. Also value = ((highValue << 16 | low)); Is supposed to be value = ((highValue << BitSize!ChildType | low));
Mar 11 2017
On Sunday, 12 March 2017 at 05:13:41 UTC, bauss wrote:I was wondering if there's a more elegant way to do something like this? template BitSize(T) { enum BitSize = T.sizeof * 8; } struct Data(ParentType,ChildType) { property { ChildType low() { return cast(ChildType)value; } void low(ChildType lowValue) { value = ((high << (BitSize!ParentType / 2)) | lowValue); } ChildType high() { return cast(ChildType)(value >> (BitSize!ParentType / 2)); } void high(ChildType highValue) { value = ((highValue << 16 | low)); } } ParentType value; alias value this; } Example usage: void main() { Data!(uint,ushort) data; data = 14065735; writefln("low: %s high: %s", data.low, data.high); data.low = 41031 ; data.high = 214; writefln("value: %s", data.value); } Basically to explain what it is: You give it a parent-type and a corresponding child-type. Ex. if the parent-type is uint, the child-type would be ushort. if the parent-type is long, the child-type would be int. etc. What it allows you to is to either manipulate the data as the parent-type or as two values of the child type. I was just wondering if there's a more elegant or performant way to do this, perhaps something in Phobos exist already?template HalfSize(T) { static if (T==long) alias HalfSize == int; // repeat for all combos } struct Data(T) { union { T value; struct { version(LittleEndian) { HalfSize!T low; HalfSize!T high; } version(BigEndian) { HalfSize!T low; HalfSize!T high; } } } alias value this; }
Mar 11 2017