Jump to page: 1 2 3
Thread overview
struct to byte[]
Dec 12, 2006
Luís Marques
Dec 12, 2006
Kirk McDonald
Dec 12, 2006
Frits van Bommel
Dec 12, 2006
Luís Marques
Dec 12, 2006
Gregor Richards
Dec 13, 2006
John Demme
Dec 13, 2006
Luís Marques
Dec 13, 2006
Alexander Panek
Dec 13, 2006
novice2
Dec 13, 2006
Alexander Panek
Dec 13, 2006
Endea
Dec 13, 2006
Alexander Panek
Dec 13, 2006
Derek Parnell
Dec 14, 2006
BCS
Dec 14, 2006
Derek Parnell
Dec 14, 2006
Hasan Aljudy
Dec 14, 2006
Bill Baxter
Dec 14, 2006
BCS
Dec 15, 2006
Derek Parnell
Dec 14, 2006
Luís Marques
Dec 13, 2006
Hasan Aljudy
December 12, 2006
Hello,

Converting a structure to ubyte[] or similar is something that I have been doing frequently while converting C to D code.

Can we have a "cast(type[])" working for structures, please?

I suppose that type should include at least ubyte, byte and char, if not all the basic data types.

Is there a reason for this explicit cast not to work automatically? (I know that templates can alleviate this)

E.g.

struct Foo
{
    int a;
    float b;
}

converts to ubyte[8] via "cast(ubyte[])".


--
Luís
December 12, 2006
Luís Marques wrote:
> Hello,
> 
> Converting a structure to ubyte[] or similar is something that I have been doing frequently while converting C to D code.
> 
> Can we have a "cast(type[])" working for structures, please?
> 
> I suppose that type should include at least ubyte, byte and char, if not all the basic data types.
> 
> Is there a reason for this explicit cast not to work automatically? (I know that templates can alleviate this)
> 
> E.g.
> 
> struct Foo
> {
>     int a;
>     float b;
> }
> 
> converts to ubyte[8] via "cast(ubyte[])".
> 
> 
> -- 
> Luís

Foo f;
ubyte[] u = (cast(ubyte*)&f)[0 .. Foo.sizeof];

-- 
Kirk McDonald
Pyd: Wrapping Python with D
http://pyd.dsource.org
December 12, 2006
Kirk McDonald wrote:
> Luís Marques wrote:
>> Can we have a "cast(type[])" working for structures, please?
<snip>
>> E.g.
>>
>> struct Foo
>> {
>>     int a;
>>     float b;
>> }
>>
>> converts to ubyte[8] via "cast(ubyte[])".
> 
> Foo f;
> ubyte[] u = (cast(ubyte*)&f)[0 .. Foo.sizeof];

Or:

Foo f;
ubyte[] u = cast(ubyte[])(&f[0..1]);

This works more cleanly with types of size > 1 as well, but IIRC basically asserts[1] (Foo.sizeof % T.sizeof == 0). So don't use this code if you're not sure it will fit exactly into a T[].


[1]: Statically? Don't recall at the moment...
December 12, 2006
Frits van Bommel wrote:
> Kirk McDonald wrote:
>> Foo f;
>> ubyte[] u = (cast(ubyte*)&f)[0 .. Foo.sizeof];
> 
> Or:
> 
> Foo f;
> ubyte[] u = cast(ubyte[])(&f[0..1]);
> 
> This works more cleanly with types of size > 1 as well, but IIRC basically asserts[1] (Foo.sizeof % T.sizeof == 0). So don't use this code if you're not sure it will fit exactly into a T[].
> 
> 
> [1]: Statically? Don't recall at the moment...

I have been using Kirk's version. Frits' variant is interesting (thanks!). Still, is there a reason not to allow a direct cast to ubyte[]? I don't see much of a problem and I suppose it wouldn't be much work (no?). It seems so much cleaner and readable to just cast it directly.
December 12, 2006
Luís Marques wrote:
> Frits van Bommel wrote:
> 
>> Kirk McDonald wrote:
>>
>>> Foo f;
>>> ubyte[] u = (cast(ubyte*)&f)[0 .. Foo.sizeof];
>>
>>
>> Or:
>>
>> Foo f;
>> ubyte[] u = cast(ubyte[])(&f[0..1]);
>>
>> This works more cleanly with types of size > 1 as well, but IIRC basically asserts[1] (Foo.sizeof % T.sizeof == 0). So don't use this code if you're not sure it will fit exactly into a T[].
>>
>>
>> [1]: Statically? Don't recall at the moment...
> 
> 
> I have been using Kirk's version. Frits' variant is interesting (thanks!). Still, is there a reason not to allow a direct cast to ubyte[]? I don't see much of a problem and I suppose it wouldn't be much work (no?). It seems so much cleaner and readable to just cast it directly.

I agree. There are plenty of ways to cast it, but they're fairly arcane. This is useful enough, and so long as it's explicit I don't think it's at all confusing.

Perhaps as an alternative (idea stolen from #d), some_struct.bytearray as an implicit property.

 - Gregor Richards
December 13, 2006
Luís Marques wrote:

> Frits van Bommel wrote:
>> Kirk McDonald wrote:
>>> Foo f;
>>> ubyte[] u = (cast(ubyte*)&f)[0 .. Foo.sizeof];
>> 
>> Or:
>> 
>> Foo f;
>> ubyte[] u = cast(ubyte[])(&f[0..1]);
>> 
>> This works more cleanly with types of size > 1 as well, but IIRC basically asserts[1] (Foo.sizeof % T.sizeof == 0). So don't use this code if you're not sure it will fit exactly into a T[].
>> 
>> 
>> [1]: Statically? Don't recall at the moment...
> 
> I have been using Kirk's version. Frits' variant is interesting (thanks!). Still, is there a reason not to allow a direct cast to ubyte[]? I don't see much of a problem and I suppose it wouldn't be much work (no?). It seems so much cleaner and readable to just cast it directly.

The reason Foo cannot be casted to ubyte is because they are different sizes.  ubyte[] is a pointer and a length, whereas Foo is anything.  It makes more sense to be able to be able to cast from a Foo* to ubyte, thus the & in Kirk's code.  This, however, will only fill the pointer part of ubyte[]- it still can't know the length.  The [0 .. Foo.sizeof] bit gives the dynamic array the length.

If you're looking for an operator to convert a arbitrary piece of data to an array of bytes, a cast is not what you're looking for.  I agree this would be useful, though... A template in phobos would be nice.

-- 
~John Demme
me@teqdruid.com
http://www.teqdruid.com/
December 13, 2006
John Demme wrote:
> The reason Foo cannot be casted to ubyte is because they are different
> sizes.  ubyte[] is a pointer and a length, whereas Foo is anything.  It
> makes more sense to be able to be able to cast from a Foo* to ubyte, thus
> the & in Kirk's code.  This, however, will only fill the pointer part of
> ubyte[]- it still can't know the length.  The [0 .. Foo.sizeof] bit gives
> the dynamic array the length.
> 
> If you're looking for an operator to convert a arbitrary piece of data to an
> array of bytes, a cast is not what you're looking for.  I agree this would
> be useful, though... A template in phobos would be nice.

Foo, being a struct, has an address and a .sizeof, giving us a pointer and a length. Why then type it explicitly, when the compiler has all the information and the cast is explicit, unambiguous and readable?
December 13, 2006
ubyte [] toByteArray (T) (T t) {
	return (cast(ubyte *)&t)[0..T.sizeof].dup
}
> Is there a reason for this explicit cast not to work automatically? (I know that templates can alleviate this)
> 
> E.g.
> 
> struct Foo
> {
>     int a;
>     float b;
> }

Foo f;
auto b = toByteArray!(Foo)(f); // Yay!


Hope that helps. :P

> 
> -- 
> Luís
December 13, 2006
== Quote from Alexander Panek (a.panek@brainsware.org)'s article
> ubyte [] toByteArray (T) (T t) {
> 	return (cast(ubyte *)&t)[0..T.sizeof].dup
> }

> auto b = toByteArray!(Foo)(f); // Yay!

why we need two parameters?
compiler don't know type of f?
December 13, 2006
novice2 wrote:
> [...]
>> auto b = toByteArray!(Foo)(f); // Yay!
> 
> why we need two parameters?
> compiler don't know type of f?

That's how templates work. Another option would be to alias for frequently used types.

alias toByteArray!(Foo) FooToByteArray; // or similar
« First   ‹ Prev
1 2 3