Thread overview | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
January 13, 2015 reinterpret array | ||||
---|---|---|---|---|
| ||||
Does the following construct hold water? version(LittleEndian) { /// interpret an array of one type as an array of a different type. /// if the array has odd length, the highest elements are /// not accessible, at worst an empty slice is returned inout ref T[] arrayOf(T, V: U[])(inout ref V a) pure @safe nothrow if(isUnsigned!T && isUnsigned!U) { return (cast(T*)a.ptr)[0 .. a.length * U.sizeof / T.sizeof]; } unittest { ubyte a[5] = { 1, 2, 3, 4, 5 }; auto b = a.arrayOf!uint; assert(typeof(b) == uint[]); assert(b.length == 1); assert(b[0] == 0x04030201); assert(&b[0] == &a[0]); // b is a slice of a b[0] = 0x0a0b0c0d; // this will change a assert(a == { 13, 12, 11, 10, 5 }); ushort c[2] = { 257, 512 }; auto d = c.arrayOf!ubyte; assert(d.length == 4); assert(d[0] == 1); assert(d[1] == 1); assert(d[2] == 0); assert(d[3] == 2); } } I assume taking a slice of a pointer uses the GC, so this cannot be @nogc, am I right? And I assume it is @save, because if I would increase the length of the returned value, the GC will automatically re-allocate, but then of course the adress is no more the same, yes? |
January 13, 2015 Re: reinterpret array | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dominikus Dittes Scherkl | On Tuesday, 13 January 2015 at 17:09:32 UTC, Dominikus Dittes Scherkl wrote:
> I assume taking a slice of a pointer uses the GC, so this cannot be @nogc, am I right?
Nope, slicing never allocates, it just takes an address and length.
If you append to a slice or increase the length though, the GC might reallocate it.
|
January 13, 2015 Re: reinterpret array | ||||
---|---|---|---|---|
| ||||
Posted in reply to Adam D. Ruppe | On Tuesday, 13 January 2015 at 17:12:42 UTC, Adam D. Ruppe wrote:
> On Tuesday, 13 January 2015 at 17:09:32 UTC, Dominikus Dittes Scherkl wrote:
>> I assume taking a slice of a pointer uses the GC, so this cannot be @nogc, am I right?
>
> Nope, slicing never allocates, it just takes an address and length.
>
> If you append to a slice or increase the length though, the GC might reallocate it.
Cool. So I can make the above even @nogc ?
Great.
|
January 13, 2015 Re: reinterpret array | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dominikus Dittes Scherkl Attachments: | On Tue, 13 Jan 2015 17:09:31 +0000 Dominikus Dittes Scherkl via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com> wrote: > /// interpret an array of one type as an array of a different > type. may i point you to this? import std.stdio; void main () { ubyte[] a = [42,0,0,0, 155,2,0,0]; auto b = cast(uint[])a; writeln(b); // "[42, 667]" } |
January 13, 2015 Re: reinterpret array | ||||
---|---|---|---|---|
| ||||
Posted in reply to ketmar | On Tuesday, 13 January 2015 at 18:25:38 UTC, ketmar via Digitalmars-d-learn wrote:
> On Tue, 13 Jan 2015 17:09:31 +0000
> Dominikus Dittes Scherkl via Digitalmars-d-learn
> <digitalmars-d-learn@puremagic.com> wrote:
>
>> /// interpret an array of one type as an array of a different type.
> may i point you to this?
>
> import std.stdio;
>
> void main () {
> ubyte[] a = [42,0,0,0, 155,2,0,0];
> auto b = cast(uint[])a;
> writeln(b); // "[42, 667]"
> }
I see. So this function is completely superfluous :-/
Good to know.
So if I have a function that allowes to do this:
uint a;
a.bit[16] = true;
writeln(a); // 65536
Is it also already available?
Because I somewhat hate it that with D I can create great stuff, but it is not necessary because D already has something much cooler...
|
January 13, 2015 Re: reinterpret array | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dominikus Dittes Scherkl | On Tuesday, 13 January 2015 at 20:00:57 UTC, Dominikus Dittes Scherkl wrote:
> So if I have a function that allowes to do this:
>
> uint a;
> a.bit[16] = true;
> writeln(a); // 65536
>
> Is it also already available?
a |= 1 << 16;
|
January 13, 2015 Re: reinterpret array | ||||
---|---|---|---|---|
| ||||
Posted in reply to anonymous | On Tuesday, 13 January 2015 at 20:11:45 UTC, anonymous wrote:
> On Tuesday, 13 January 2015 at 20:00:57 UTC, Dominikus Dittes Scherkl wrote:
>> So if I have a function that allowes to do this:
>>
>> uint a;
>> a.bit[16] = true;
>> writeln(a); // 65536
>>
>> Is it also already available?
>
> a |= 1 << 16;
Of course you can calculate it, but the
syntax looks quite different if you want to do
a.bit[22] = false:
a &= ~(1<<16);
Or if you want to test a bit:
if(a.bit[16])
instead of
if(a & (1<<16))
much more convenient for arrays:
ulong[100] a;
a.bit[3000] = true;
doing this directly with shifts is lousy (and error prone)
But ok. I see, it's not really awesome :-/
|
January 13, 2015 Re: reinterpret array | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dominikus Dittes Scherkl Attachments: | On Tue, 13 Jan 2015 20:52:13 +0000 Dominikus Dittes Scherkl via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com> wrote: > On Tuesday, 13 January 2015 at 20:11:45 UTC, anonymous wrote: > > On Tuesday, 13 January 2015 at 20:00:57 UTC, Dominikus Dittes Scherkl wrote: > >> So if I have a function that allowes to do this: > >> > >> uint a; > >> a.bit[16] = true; > >> writeln(a); // 65536 > >> > >> Is it also already available? > > > > a |= 1 << 16; > > Of course you can calculate it, but the > syntax looks quite different if you want to do > a.bit[22] = false: > > a &= ~(1<<16); > > Or if you want to test a bit: > > if(a.bit[16]) > > instead of > > if(a & (1<<16)) > > much more convenient for arrays: > > ulong[100] a; > > a.bit[3000] = true; > > doing this directly with shifts is lousy (and error prone) > > But ok. I see, it's not really awesome :-/ it's not better than using something like this: a.bitSet(22); a.bitReset(30); if (a.bit(16)) { ... } you can easily do this with UFCS. you can even write some templates to convert it to bit operations in compile time. |
January 13, 2015 Re: reinterpret array | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dominikus Dittes Scherkl | On Tuesday, 13 January 2015 at 20:52:15 UTC, Dominikus Dittes Scherkl wrote:
> Of course you can calculate it, but the
> syntax looks quite different if you want to do
> a.bit[22] = false:
>
> a &= ~(1<<16);
>
> Or if you want to test a bit:
>
> if(a.bit[16])
>
> instead of
>
> if(a & (1<<16))
>
> much more convenient for arrays:
>
> ulong[100] a;
>
> a.bit[3000] = true;
>
> doing this directly with shifts is lousy (and error prone)
>
> But ok. I see, it's not really awesome :-/
I didn't mean to put a stop to your idea just because we have bitwise operators. You're totally right: They're somewhat cumbersome and easy to get wrong.
We also have std.bitmanip.BitArray which is what you're after, I think:
import std.bitmanip: BitArray;
BitArray ba;
ba.length = 3001;
ba[3000] = true;
|
Copyright © 1999-2021 by the D Language Foundation