www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - data mapping, more elegant solution?

reply mandel <oh no.es> writes:
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
next sibling parent reply Regan Heath <regan netmail.co.nz> writes:
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
parent reply mandel <oh no.es> writes:
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;
 }
 

I also would have to cast thing to ubyte[8] when I pass it to functions. It's also hackish. :P
Dec 13 2007
next sibling parent reply Regan Heath <regan netmail.co.nz> writes:
mandel wrote:
 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;
 }

I also would have to cast thing to ubyte[8] when I pass it to functions. It's also hackish. :P

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. Regan
Dec 13 2007
parent Regan Heath <regan netmail.co.nz> writes:
Regan Heath wrote:
 mandel wrote:
 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;
 }

I also would have to cast thing to ubyte[8] when I pass it to functions. It's also hackish. :P

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.

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. Regan
Dec 13 2007
prev sibling parent Mike <vertex gmx.at> writes:
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:
 Use a union?

 union thing
 {
    ubyte[8] ub;
    uint     ui;
 }

 void main()
 {
    thing a;
    a.ui =3D 42;
 }

I also would have to cast thing to ubyte[8] when I pass it to function=

 It's also hackish. :P

Then 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
prev sibling parent 0ffh <frank frankhirsch.youknow.what.todo.net> writes:
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