Thread overview | ||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
December 12, 2006 struct to byte[] | ||||
---|---|---|---|---|
| ||||
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 Re: struct to byte[] | ||||
---|---|---|---|---|
| ||||
Posted in reply to Luís Marques | 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 Re: struct to byte[] | ||||
---|---|---|---|---|
| ||||
Posted in reply to Kirk McDonald | 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 Re: struct to byte[] | ||||
---|---|---|---|---|
| ||||
Posted in reply to Frits van Bommel | 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 Re: struct to byte[] | ||||
---|---|---|---|---|
| ||||
Posted in reply to Luís Marques | 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 Re: struct to byte[] | ||||
---|---|---|---|---|
| ||||
Posted in reply to Luís Marques | 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 Re: struct to byte[] | ||||
---|---|---|---|---|
| ||||
Posted in reply to John Demme | 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 Re: struct to byte[] | ||||
---|---|---|---|---|
| ||||
Posted in reply to Luís Marques | 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 Re: struct to byte[] | ||||
---|---|---|---|---|
| ||||
Posted in reply to Alexander Panek | == 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 Re: struct to byte[] | ||||
---|---|---|---|---|
| ||||
Posted in reply to novice2 | 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
|
Copyright © 1999-2021 by the D Language Foundation