digitalmars.D.learn - data mapping, more elegant solution?
- mandel (8/8) Dec 13 2007 Hi,
- Regan Heath (13/25) Dec 13 2007 Use a union?
- mandel (4/18) Dec 13 2007 This way I can't insert data at arbitrary places, e.g. array[4..8].
- Regan Heath (13/31) Dec 13 2007 If you want to insert a 'short' into it then add an array of shorts too:
- Regan Heath (24/59) Dec 13 2007 I must have been half asleep when I posted that. I got the sizes
- Mike (33/51) Dec 13 2007 Then pack the hackish things away into something:
- 0ffh (7/19) Dec 13 2007 Well, if "array[0..4]=42;" does what you say, I think it does the right
Hi, I want to map a uint to a position of an ubyte array. Atm. I use this: ubyte[8] array; *cast(uint*) &array.ptr[0] = 42; But is there a nicer solution to do achive this? Smth. like "array[0..4] = 42;", but this tries to assign 42 to every byte (resulting in [0x2a, 0x2a, 0x2a, 0x2a, 0x00, 0x00, 0x00, 0x00]).
Dec 13 2007
mandel wrote:Hi, I want to map a uint to a position of an ubyte array. Atm. I use this: ubyte[8] array; *cast(uint*) &array.ptr[0] = 42; But is there a nicer solution to do achive this? Smth. like "array[0..4] = 42;", but this tries to assign 42 to every byte (resulting in [0x2a, 0x2a, 0x2a, 0x2a, 0x00, 0x00, 0x00, 0x00]).Use a union? union thing { ubyte[8] ub; uint ui; } void main() { thing a; a.ui = 42; } Regan
Dec 13 2007
On Thu, 13 Dec 2007 13:35:35 +0000, Regan Heath wrote:Use a union? union thing { ubyte[8] ub; uint ui; } void main() { thing a; a.ui = 42; }This way I can't insert data at arbitrary places, e.g. array[4..8]. I also would have to cast thing to ubyte[8] when I pass it to functions. It's also hackish. :P
Dec 13 2007
mandel wrote:On Thu, 13 Dec 2007 13:35:35 +0000, Regan Heath wrote:If you want to insert a 'short' into it then add an array of shorts too: union thing { ubyte[8] ub; ushort[2] us; uint ui; } thing a; a.us[0] = 1; //ub[0..4] a.us[1] = 2; //ub[4..8] It's less hackish, and cleaner/clearer than using casts. ReganUse a union? union thing { ubyte[8] ub; uint ui; } void main() { thing a; a.ui = 42; }This way I can't insert data at arbitrary places, e.g. array[4..8]. I also would have to cast thing to ubyte[8] when I pass it to functions. It's also hackish. :P
Dec 13 2007
Regan Heath wrote:mandel wrote:I must have been half asleep when I posted that. I got the sizes confused. You have 64 bits of data, so your complete union would look something like: union thing { ubyte[8] ub; ushort[4] us; uint[2] ui; ulong ul; } I got the assignments correct though, a.us[0] assigns to a.ub[0..4] and so on. You may need to deal with big/little endian issues, not sure. If you really hate the union and would rather use a cast I suggest: ubyte[8] array; (cast(uint*)&array)[0] = 1; //array[0..4] (cast(uint*)&array)[1] = 2; //array[4..8] I think that works, I don't have a compiler here to test it, it might need to be: (cast(uint*)&array)[0..2][0] = 1; //array[0..4] (cast(uint*)&array)[0..2][1] = 2; //array[4..8] The above creates a temporary dynamic array of type uint with length == 2, which is less efficient than the union .. and more typing too. ReganOn Thu, 13 Dec 2007 13:35:35 +0000, Regan Heath wrote:If you want to insert a 'short' into it then add an array of shorts too: union thing { ubyte[8] ub; ushort[2] us; uint ui; } thing a; a.us[0] = 1; //ub[0..4] a.us[1] = 2; //ub[4..8] It's less hackish, and cleaner/clearer than using casts.Use a union? union thing { ubyte[8] ub; uint ui; } void main() { thing a; a.ui = 42; }This way I can't insert data at arbitrary places, e.g. array[4..8]. I also would have to cast thing to ubyte[8] when I pass it to functions. It's also hackish. :P
Dec 13 2007
On Thu, 13 Dec 2007 14:43:51 +0100, mandel <oh no.es> wrote:On Thu, 13 Dec 2007 13:35:35 +0000, Regan Heath wrote:s.Use a union? union thing { ubyte[8] ub; uint ui; } void main() { thing a; a.ui =3D 42; }This way I can't insert data at arbitrary places, e.g. array[4..8]. I also would have to cast thing to ubyte[8] when I pass it to function=It's also hackish. :PThen pack the hackish things away into something: struct thing { union { ubyte[8] ub; uint ui; } void opAssign(uint value) { ui =3D value; } uint opCall() { return value; } void opIndexAssign(byte value, uint idx) { ub[idx] =3D value; } byte opIndex(uint idx) { return ub[idx]; } } Better? You can pass that to functions. For arbitrary places you're eith= er = stuck with the casting or you maybe can do something with opSlice. -Mike -- = Using Opera's revolutionary e-mail client: http://www.opera.com/mail/
Dec 13 2007
mandel wrote:Hi, I want to map a uint to a position of an ubyte array. Atm. I use this: ubyte[8] array; *cast(uint*) &array.ptr[0] = 42; But is there a nicer solution to do achive this? Smth. like "array[0..4] = 42;", but this tries to assign 42 to every byte (resulting in [0x2a, 0x2a, 0x2a, 0x2a, 0x00, 0x00, 0x00, 0x00]).Well, if "array[0..4]=42;" does what you say, I think it does the right thing. Your solution is the right one, altough I'd use more braces. It's hard to be more elegant when crossing type boundaries. Some other languages I could mention would not even allow the canonical C solution (which is what you are doing)... regards, frank
Dec 13 2007