Jump to page: 1 2
Thread overview
reinterpret array
Jan 13, 2015
Adam D. Ruppe
Jan 13, 2015
ketmar
Jan 13, 2015
anonymous
Jan 13, 2015
ketmar
Jan 13, 2015
anonymous
Jan 13, 2015
Artur Skawina
Jan 13, 2015
bearophile
Jan 13, 2015
ketmar
January 13, 2015
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
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
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
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
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
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
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
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
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;
January 13, 2015
anonymous:

> a |= 1 << 16;

In D there's also the 2 ^^ x syntax available.

Bye,
bearophile
« First   ‹ Prev
1 2