## 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
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
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
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;
}

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 <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;
}
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
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
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;
}
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
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
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;
}
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=
s.
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
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