digitalmars.D.learn - How can I map bytes to a matrix of structures?
- teo (17/17) Sep 09 2011 Here is an example of what I am after:
- Timon Gehr (19/36) Sep 09 2011 If you actually want a dynamic DATA[2][] array of length 2, this works:
- Steven Schveighoffer (13/52) Sep 09 2011 You can also use ref, but you have to use a function, as it's impossible...
- bearophile (5/7) Sep 09 2011 I think this is enough:
- teo (2/12) Sep 09 2011 That works. Thanks.
- teo (5/51) Sep 09 2011 Thank you Timon for the good explanation.
- Timon Gehr (16/67) Sep 09 2011 You are welcome. As bearophile suggests, those are nicer though:
Here is an example of what I am after: struct DATA { ubyte D1; ubyte D2; ubyte D3; ubyte D4; } void main() { ubyte[16] a = [ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 ]; auto b = (cast(DATA*)a.ptr)[0 .. 4]; auto c = (cast(DATA[]*)b.ptr)[0 .. 2][0 .. 2]; } I need to have a DATA[2][2]. That code compiles but gives me a segmentation fault.
Sep 09 2011
On 09/09/2011 05:19 PM, teo wrote:Here is an example of what I am after: struct DATA { ubyte D1; ubyte D2; ubyte D3; ubyte D4; } void main() { ubyte[16] a = [ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 ]; auto b = (cast(DATA*)a.ptr)[0 .. 4]; auto c = (cast(DATA[]*)b.ptr)[0 .. 2][0 .. 2]; } I need to have a DATA[2][2]. That code compiles but gives me a segmentation fault.If you actually want a dynamic DATA[2][] array of length 2, this works: auto b=(*(cast(DATA[2][2]*)a.ptr))[]; Otherwise: A simple reinterpret cast should do: auto b=*(cast(DATA[2][2]*)a.ptr); but note that this copies the data, because static arrays have value semantics. If you want to have refer the new array to the same location, you can use a union. void main(){ union Myunion{ ubyte[16] a = [ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 ]; DATA[2][2] b; } Myunion myunion; assert(*(cast(DATA[2][2]*)myunion.a.ptr)==myunion.b); }
Sep 09 2011
On Fri, 09 Sep 2011 11:43:04 -0400, Timon Gehr <timon.gehr gmx.ch> wrote:On 09/09/2011 05:19 PM, teo wrote:You can also use ref, but you have to use a function, as it's impossible to declare a ref local variable except as a function parameter. void main() { ubyte[16] a = ...; void foo(ref DATA[2][2] b) { ... } foo(*(cast(DATA[2][2]*)a.ptr)); } -SteveHere is an example of what I am after: struct DATA { ubyte D1; ubyte D2; ubyte D3; ubyte D4; } void main() { ubyte[16] a = [ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 ]; auto b = (cast(DATA*)a.ptr)[0 .. 4]; auto c = (cast(DATA[]*)b.ptr)[0 .. 2][0 .. 2]; } I need to have a DATA[2][2]. That code compiles but gives me a segmentation fault.If you actually want a dynamic DATA[2][] array of length 2, this works: auto b=(*(cast(DATA[2][2]*)a.ptr))[]; Otherwise: A simple reinterpret cast should do: auto b=*(cast(DATA[2][2]*)a.ptr); but note that this copies the data, because static arrays have value semantics. If you want to have refer the new array to the same location, you can use a union. void main(){ union Myunion{ ubyte[16] a = [ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 ]; DATA[2][2] b; } Myunion myunion; assert(*(cast(DATA[2][2]*)myunion.a.ptr)==myunion.b); }
Sep 09 2011
Timon Gehr:A simple reinterpret cast should do: auto b=*(cast(DATA[2][2]*)a.ptr);I think this is enough: auto b = cast(Data[2][2])a; Bye, bearophile
Sep 09 2011
On Fri, 09 Sep 2011 13:10:41 -0400, bearophile wrote:Timon Gehr:That works. Thanks.A simple reinterpret cast should do: auto b=*(cast(DATA[2][2]*)a.ptr);I think this is enough: auto b = cast(Data[2][2])a; Bye, bearophile
Sep 09 2011
On Fri, 09 Sep 2011 17:43:04 +0200, Timon Gehr wrote:On 09/09/2011 05:19 PM, teo wrote:0x01,Here is an example of what I am after: struct DATA { ubyte D1; ubyte D2; ubyte D3; ubyte D4; } void main() { ubyte[16] a = [ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 ]; auto b = (cast(DATA*)a.ptr)[0 .. 4]; auto c = (cast(DATA[]*)b.ptr)[0 .. 2][0 .. 2]; } I need to have a DATA[2][2]. That code compiles but gives me a segmentation fault.If you actually want a dynamic DATA[2][] array of length 2, this works: auto b=(*(cast(DATA[2][2]*)a.ptr))[]; Otherwise: A simple reinterpret cast should do: auto b=*(cast(DATA[2][2]*)a.ptr); but note that this copies the data, because static arrays have value semantics. If you want to have refer the new array to the same location, you can use a union. void main(){ union Myunion{ ubyte[16] a = [ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 ]; DATA[2][2] b; } Myunion myunion; assert(*(cast(DATA[2][2]*)myunion.a.ptr)==myunion.b); }Thank you Timon for the good explanation. Just one more question (I suspect the answer will be no, but let me ask): is it possible to directly cast to ubyte[][]?
Sep 09 2011
On 09/09/2011 10:25 PM, teo wrote:On Fri, 09 Sep 2011 17:43:04 +0200, Timon Gehr wrote:You are welcome. As bearophile suggests, those are nicer though: auto b=(cast(DATA[2][2]a); // static array auto b=(cast(DATA[2][2]a)[];// dynamic arrayOn 09/09/2011 05:19 PM, teo wrote:0x01,Here is an example of what I am after: struct DATA { ubyte D1; ubyte D2; ubyte D3; ubyte D4; } void main() { ubyte[16] a = [ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 ]; auto b = (cast(DATA*)a.ptr)[0 .. 4]; auto c = (cast(DATA[]*)b.ptr)[0 .. 2][0 .. 2]; } I need to have a DATA[2][2]. That code compiles but gives me a segmentation fault.If you actually want a dynamic DATA[2][] array of length 2, this works: auto b=(*(cast(DATA[2][2]*)a.ptr))[]; Otherwise: A simple reinterpret cast should do: auto b=*(cast(DATA[2][2]*)a.ptr); but note that this copies the data, because static arrays have value semantics. If you want to have refer the new array to the same location, you can use a union. void main(){ union Myunion{ ubyte[16] a = [ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 ]; DATA[2][2] b; } Myunion myunion; assert(*(cast(DATA[2][2]*)myunion.a.ptr)==myunion.b); }Thank you Timon for the good explanation.Just one more question (I suspect the answer will be no, but let me ask): is it possible to directly cast to ubyte[][]?Not directly, because you have to build some structure in memory. an ubyte[][] is an array of dynamic arrays. Each of those dynamic arrays is a 2 field struct consisting of a ptr and a length field. That data you have to construct manually. in case you wanted to turn the ubyte[16] a array to a ubyte[][] b array, with b.length and b[i].length equal to 4, this would probably do the job: ubyte[16] a=[ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 ]; auto b=new ubyte[][](4);// create a ubyte[][] array that can hold 4 ubyte[] values foreach(i,ref x;b) x=a[i*4 .. (i+1)*4]; // compute the values by slicing the original array
Sep 09 2011