Thread overview | |||||||||
---|---|---|---|---|---|---|---|---|---|
|
December 13, 2007 data mapping, more elegant solution? | ||||
---|---|---|---|---|
| ||||
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]). |
December 13, 2007 Re: data mapping, more elegant solution? | ||||
---|---|---|---|---|
| ||||
Posted in reply to mandel | 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
|
December 13, 2007 Re: data mapping, more elegant solution? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Regan Heath | 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
|
December 13, 2007 Re: data mapping, more elegant solution? | ||||
---|---|---|---|---|
| ||||
Posted in reply to mandel | 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
|
December 13, 2007 Re: data mapping, more elegant solution? | ||||
---|---|---|---|---|
| ||||
Posted in reply to mandel | 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 = 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 Then pack the hackish things away into something: struct thing { union { ubyte[8] ub; uint ui; } void opAssign(uint value) { ui = value; } uint opCall() { return value; } void opIndexAssign(byte value, uint idx) { ub[idx] = value; } byte opIndex(uint idx) { return ub[idx]; } } Better? You can pass that to functions. For arbitrary places you're either 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/ |
December 13, 2007 Re: data mapping, more elegant solution? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Regan Heath | 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
|
December 13, 2007 Re: data mapping, more elegant solution? | ||||
---|---|---|---|---|
| ||||
Posted in reply to mandel | 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
|
Copyright © 1999-2021 by the D Language Foundation