Jump to page: 1 2
Thread overview
How to convert struct to void[]?
Sep 10, 2004
mcl
Sep 10, 2004
Regan Heath
Sep 10, 2004
Derek Parnell
Sep 10, 2004
Regan Heath
Sep 10, 2004
mcl
Sep 10, 2004
Russ Lewis
Sep 11, 2004
Nick
Sep 12, 2004
Regan Heath
Sep 13, 2004
Sean Kelly
Sep 13, 2004
Regan Heath
Sep 13, 2004
Nick
Sep 12, 2004
Sha Chancellor
Sep 12, 2004
Regan Heath
Sep 25, 2004
Sha Chancellor
Sep 26, 2004
Ivan Senji
Sep 26, 2004
Sha Chancellor
Sep 10, 2004
Vathix
Sep 10, 2004
Regan Heath
Sep 10, 2004
Helmut Leitner
Sep 12, 2004
Garett Bass
September 10, 2004
I'm stuck.  What is the best way to convert a struct to a void[]?  I'm using the socket library in phobos and I want to send an aligned struct over the network. Here's the best solution I've come up with so far...

#template Yuck(T)
#{
#    void[] toVoid(inout T src)
#	{
#		ubyte* data = cast(ubyte*)&src;
#		ubyte[] copy = new ubyte[src.sizeof];
#
#		foreach(ubyte b; copy)
#			b = *(data++);
#
#		return cast(void[])copy;
#	}
#}

To convert a struct to void[], I use the following...

#struct Foo { ... }
#
#Foo f;
#void[] fv = Yuck!(Foo).toVoid(f);

Please tell me there is a better way to do this...


September 10, 2004
On Fri, 10 Sep 2004 01:44:51 +0000 (UTC), mcl <mcl_member@pathlink.com> wrote:

> I'm stuck.  What is the best way to convert a struct to a void[]?  I'm using the
> socket library in phobos and I want to send an aligned struct over the network.
> Here's the best solution I've come up with so far...
>
> #template Yuck(T)
> #{
> #    void[] toVoid(inout T src)
> #	{
> #		ubyte* data = cast(ubyte*)&src;
> #		ubyte[] copy = new ubyte[src.sizeof];
> #		
> #		foreach(ubyte b; copy)
> #			b = *(data++);
> #		
> #		return cast(void[])copy;
> #	}
> #}
>
> To convert a struct to void[], I use the following...
>
> #struct Foo { ... }
> #
> #Foo f;
> #void[] fv = Yuck!(Foo).toVoid(f);
>
> Please tell me there is a better way to do this...

It's a little known fact that you can slice a pointer giving you an array. Slicing a void* will give you a void[]. You can also cast any memory address to a void*, So...

template toVoid(Struct)
{
  void[] toVoid(inout Struct s)
  {
    return (cast(void*)&s)[0..s.sizeof];
  }
}

should do it.

Regan

-- 
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
September 10, 2004
On Fri, 10 Sep 2004 14:22:56 +1200, Regan Heath wrote:

> On Fri, 10 Sep 2004 01:44:51 +0000 (UTC), mcl <mcl_member@pathlink.com> wrote:
> 
>> I'm stuck.  What is the best way to convert a struct to a void[]?  I'm
>> using the
>> socket library in phobos and I want to send an aligned struct over the
>> network.
>> Here's the best solution I've come up with so far...
>>
>> #template Yuck(T)
>> #{
>> #    void[] toVoid(inout T src)
>> #	{
>> #		ubyte* data = cast(ubyte*)&src;
>> #		ubyte[] copy = new ubyte[src.sizeof];
>> #
>> #		foreach(ubyte b; copy)
>> #			b = *(data++);
>> #
>> #		return cast(void[])copy;
>> #	}
>> #}
>>
>> To convert a struct to void[], I use the following...
>>
>> #struct Foo { ... }
>> #
>> #Foo f;
>> #void[] fv = Yuck!(Foo).toVoid(f);
>>
>> Please tell me there is a better way to do this...
> 
> It's a little known fact that you can slice a pointer giving you an array. Slicing a void* will give you a void[]. You can also cast any memory address to a void*, So...
> 
> template toVoid(Struct)
> {
>    void[] toVoid(inout Struct s)
>    {
>      return (cast(void*)&s)[0..s.sizeof];
>    }
> }
> 
> should do it.
> 
> Regan

It does! And you don't need a template either.

Foo f;
void[] fv = (cast(void*)&f)[0..f.sizeof];

writefln("%d", fv.length);
writefln("%X", cast(uint)&fv[0]);
writefln("%X", cast(uint)&f);

-- 
Derek
Melbourne, Australia
10/Sep/04 12:45:22 PM
September 10, 2004
On Fri, 10 Sep 2004 12:49:47 +1000, Derek Parnell <derek@psych.ward> wrote:
> On Fri, 10 Sep 2004 14:22:56 +1200, Regan Heath wrote:
>
>> On Fri, 10 Sep 2004 01:44:51 +0000 (UTC), mcl <mcl_member@pathlink.com>
>> wrote:
>>
>>> I'm stuck.  What is the best way to convert a struct to a void[]?  I'm
>>> using the
>>> socket library in phobos and I want to send an aligned struct over the
>>> network.
>>> Here's the best solution I've come up with so far...
>>>
>>> #template Yuck(T)
>>> #{
>>> #    void[] toVoid(inout T src)
>>> #	{
>>> #		ubyte* data = cast(ubyte*)&src;
>>> #		ubyte[] copy = new ubyte[src.sizeof];
>>> #		
>>> #		foreach(ubyte b; copy)
>>> #			b = *(data++);
>>> #		
>>> #		return cast(void[])copy;
>>> #	}
>>> #}
>>>
>>> To convert a struct to void[], I use the following..
>>>
>>> #struct Foo { ... }
>>> #
>>> #Foo f;
>>> #void[] fv = Yuck!(Foo).toVoid(f);
>>>
>>> Please tell me there is a better way to do this...
>>
>> It's a little known fact that you can slice a pointer giving you an array.
>> Slicing a void* will give you a void[]. You can also cast any memory
>> address to a void*, So...
>>
>> template toVoid(Struct)
>> {
>>    void[] toVoid(inout Struct s)
>>    {
>>      return (cast(void*)&s)[0..s.sizeof];
>>    }
>> }
>>
>> should do it.
>>
>> Regan
>
> It does! And you don't need a template either.
>
> Foo f;
> void[] fv = (cast(void*)&f)[0..f.sizeof];
>
> writefln("%d", fv.length);
> writefln("%X", cast(uint)&fv[0]);
> writefln("%X", cast(uint)&f);

Yeah. I assumed there was a reason for using a template.

Regan

-- 
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
September 10, 2004
"mcl" <mcl_member@pathlink.com> wrote in message news:chr0uj$rvk$1@digitaldaemon.com...
> I'm stuck.  What is the best way to convert a struct to a void[]?  I'm
using the
> socket library in phobos and I want to send an aligned struct over the
network.
> Here's the best solution I've come up with so far...
>

(&f)[0 .. 1]  works just fine. Any array implicitly converts to void[].


September 10, 2004
On Fri, 10 Sep 2004 01:15:15 -0400, Vathix <vathixSpamFix@dprogramming.com> wrote:
> "mcl" <mcl_member@pathlink.com> wrote in message
> news:chr0uj$rvk$1@digitaldaemon.com...
>> I'm stuck.  What is the best way to convert a struct to a void[]?  I'm
> using the
>> socket library in phobos and I want to send an aligned struct over the
> network.
>> Here's the best solution I've come up with so far...
>>
>
> (&f)[0 .. 1]  works just fine. Any array implicitly converts to void[].

Duh.. (/me smacks my head) of course.

Regan

-- 
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
September 10, 2004

Vathix wrote:
> 
> "mcl" <mcl_member@pathlink.com> wrote in message news:chr0uj$rvk$1@digitaldaemon.com...
> > I'm stuck.  What is the best way to convert a struct to a void[]?  I'm
> using the
> > socket library in phobos and I want to send an aligned struct over the
> network.
> > Here's the best solution I've come up with so far...
> >
> 
> (&f)[0 .. 1]  works just fine. Any array implicitly converts to void[].

Makes a nice FAQ entry:
   <http://www.wikiservice.at/wiki4d/wiki.cgi?FaqRoadmap#Howtoconverttovoid>

-- 
Helmut Leitner    leitner@hls.via.at
Graz, Austria   www.hls-software.com
September 10, 2004
In article <opsd3hv4o15a2sq9@digitalmars.com>, Regan Heath says...
>
>On Fri, 10 Sep 2004 12:49:47 +1000, Derek Parnell <derek@psych.ward> wrote:
>> On Fri, 10 Sep 2004 14:22:56 +1200, Regan Heath wrote:
>>
>>> On Fri, 10 Sep 2004 01:44:51 +0000 (UTC), mcl <mcl_member@pathlink.com>
>>> wrote:
>>>
>>>> I'm stuck.  What is the best way to convert a struct to a void[]?  I'm
>>>> using the
>>>> socket library in phobos and I want to send an aligned struct over the
>>>> network.
>>>> Here's the best solution I've come up with so far...
>>>>
>>>> #template Yuck(T)
>>>> #{
>>>> #    void[] toVoid(inout T src)
>>>> #	{
>>>> #		ubyte* data = cast(ubyte*)&src;
>>>> #		ubyte[] copy = new ubyte[src.sizeof];
>>>> #
>>>> #		foreach(ubyte b; copy)
>>>> #			b = *(data++);
>>>> #
>>>> #		return cast(void[])copy;
>>>> #	}
>>>> #}
>>>>
>>>> To convert a struct to void[], I use the following..
>>>>
>>>> #struct Foo { ... }
>>>> #
>>>> #Foo f;
>>>> #void[] fv = Yuck!(Foo).toVoid(f);
>>>>
>>>> Please tell me there is a better way to do this...
>>>
>>> It's a little known fact that you can slice a pointer giving you an
>>> array.
>>> Slicing a void* will give you a void[]. You can also cast any memory
>>> address to a void*, So...
>>>
>>> template toVoid(Struct)
>>> {
>>>    void[] toVoid(inout Struct s)
>>>    {
>>>      return (cast(void*)&s)[0..s.sizeof];
>>>    }
>>> }
>>>
>>> should do it.
>>>
>>> Regan
>>
>> It does! And you don't need a template either.
>>
>> Foo f;
>> void[] fv = (cast(void*)&f)[0..f.sizeof];
>>
>> writefln("%d", fv.length);
>> writefln("%X", cast(uint)&fv[0]);
>> writefln("%X", cast(uint)&f);
>
>Yeah. I assumed there was a reason for using a template.


The reason for the template was to abstract the code for use with different structs since it's a bit complicated. The slice trick is far more elegant, since it's a one-liner.  My only concern: Is the pointer slice in place?   I could see this being a problem with stack allocated structs/classes...


September 10, 2004
mcl wrote:
>>>Foo f;
>>>void[] fv = (cast(void*)&f)[0..f.sizeof];
>>>
>>>writefln("%d", fv.length);
>>>writefln("%X", cast(uint)&fv[0]);
>>>writefln("%X", cast(uint)&f);
> 
> The reason for the template was to abstract the code for use with different
> structs since it's a bit complicated. The slice trick is far more elegant, since
> it's a one-liner.  My only concern: Is the pointer slice in place?   I could see
> this being a problem with stack allocated structs/classes...   

Yes.  If you want to copy it, then just append .dup:

void[] fv = (&f)[0..f.sizeof].dup;

September 11, 2004
In article <cht6ve$1vma$1@digitaldaemon.com>, Russ Lewis says...
>
>void[] fv = (&f)[0..f.sizeof].dup;
>

By the way, it's (&f)[0..1], not (&f)[0..f.sizeof]. If f is a Foo then (&f) is
of type (Foo*), so a slice of one element will include one entire struct. I have
corrected this in the wiki as well.

Nick


« First   ‹ Prev
1 2