Thread overview
alternate idea for bit management in D
Aug 22, 2004
Regan Heath
Aug 22, 2004
antiAlias
Aug 22, 2004
Regan Heath
Aug 23, 2004
Gold Dragon
Aug 23, 2004
Regan Heath
August 22, 2004
After the recent discussion on the problem with bool in struct WRT C implementing bool differently to how D does (D's is an alias to bit) and Matthews suggestion that we remove bit completely, I came up with the idea that we could in fact remove the 'bit' type alltogether, in it's place we simply allow slices of the other integral basic types for example:

struct A {
  ubyte  a;
  ushort b;
  uint   c;
  ulong  d;
}

void main()
{
  A a;

  foreach(bit b; a.a)
    ..

  a.c[8..16] = a.a[];

  ..etc..
}

This would require some compiler magic, it appears to me that there are 3 possibilities for
implementing it:

1. all basic types are actually stored as arrays of bits.
2. the arrays are created/destroyed when required.
3. a keyword is introduced to cause #1 above when desirec, bitmask' perhaps. eg.
  struct A {
    bitmask uint mask;
    uint not_a_bitmask;
  }

3 is clearly the best choice IMHO.

Regan

-- 
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
August 22, 2004
That's an interesting idea. But then, folk would end up wanting more than a maximum of 64 bits (ulong) to operate upon in one go, and so you might as well implement a Bitset class instead. No additional compiler magic would be necessary since the foreach and [] operators are already exposed.

I'm tempted to suggest providing a class implementation instead, especially if one can map a Bitset class onto a specific scalar instance:

class Bitset
{
        // make a bitset on top of an int
        this (inout uint x)
        {
                this (&x, x.sizeof);
        }

        // make a bitset on top of a long
        this (inout ulong x)
        {
                this (&x, x.sizeof);
        }

        // make an bitset of an arbitrary size
        this (int x)
        {
                this (new ubyte[(x+7)/8], x);
        }

        // (where the real work happens)
        private this (void* bits, int length)
        {
        }
}

void main()
{
        uint      set32;
        ulong    set64;

        Bitset bi = new Bitset (set32);
        Bitset bl = new Bitset (set64);
        Bitset bs = new Bitset (23);
}

Of course, there are some concerns about pointer aliasing. Also, it might be better to have a series of "set" methods rather than constructors (for efficiencies sake); But the general notion would work quite nicely, wouldn't it?



"Regan Heath" <regan@netwin.co.nz> wrote in message news:opsc5nd8dq5a2sq9@digitalmars.com...
> After the recent discussion on the problem with bool in struct WRT C implementing bool differently to how D does (D's is an alias to bit) and Matthews suggestion that we remove bit completely, I came up with the idea that we could in fact remove the 'bit' type alltogether, in it's place we simply allow slices of the other integral basic types for example:
>
> struct A {
>    ubyte  a;
>    ushort b;
>    uint   c;
>    ulong  d;
> }
>
> void main()
> {
>    A a;
>
>    foreach(bit b; a.a)
>      ..
>
>    a.c[8..16] = a.a[];
>
>    ..etc..
> }
>
> This would require some compiler magic, it appears to me that there are 3
> possibilities for
> implementing it:
>
> 1. all basic types are actually stored as arrays of bits.
> 2. the arrays are created/destroyed when required.
> 3. a keyword is introduced to cause #1 above when desirec, bitmask'
> perhaps. eg.
>    struct A {
>      bitmask uint mask;
>      uint not_a_bitmask;
>    }
>
> 3 is clearly the best choice IMHO.
>
> Regan
>
> --
> Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/


August 22, 2004
On Sun, 22 Aug 2004 16:04:14 -0700, antiAlias <fu@bar.com> wrote:
> That's an interesting idea. But then, folk would end up wanting more than a
> maximum of 64 bits (ulong) to operate upon in one go

True, I haven't personally, but I guess it's entirely possible.

> , and so you might as
> well implement a Bitset class instead. No additional compiler magic would be
> necessary since the foreach and [] operators are already exposed.

We may as well keep bit[] in that case.

I guess the real problem is with bool in D being different to bool in C.

> I'm tempted to suggest providing a class implementation instead, especially
> if one can map a Bitset class onto a specific scalar instance:
>
> class Bitset
> {
>         // make a bitset on top of an int
>         this (inout uint x)
>         {
>                 this (&x, x.sizeof);
>         }
>
>         // make a bitset on top of a long
>         this (inout ulong x)
>         {
>                 this (&x, x.sizeof);
>         }
>
>         // make an bitset of an arbitrary size
>         this (int x)
>         {
>                 this (new ubyte[(x+7)/8], x);
>         }
>
>         // (where the real work happens)
>         private this (void* bits, int length)
>         {
>         }
> }
>
> void main()
> {
>         uint      set32;
>         ulong    set64;
>
>         Bitset bi = new Bitset (set32);
>         Bitset bl = new Bitset (set64);
>         Bitset bs = new Bitset (23);
> }
>
> Of course, there are some concerns about pointer aliasing. Also, it might be
> better to have a series of "set" methods rather than constructors (for
> efficiencies sake); But the general notion would work quite nicely, wouldn't
> it?

Yes, I think so.

Regan

>
> "Regan Heath" <regan@netwin.co.nz> wrote in message
> news:opsc5nd8dq5a2sq9@digitalmars.com...
>> After the recent discussion on the problem with bool in struct WRT C
>> implementing bool differently to how D does (D's is an alias to bit) and
>> Matthews suggestion that we remove bit completely, I came up with the idea
>> that we could in fact remove the 'bit' type alltogether, in it's place we
>> simply allow slices of the other integral basic types for example:
>>
>> struct A {
>>    ubyte  a;
>>    ushort b;
>>    uint   c;
>>    ulong  d;
>> }
>>
>> void main()
>> {
>>    A a;
>>
>>    foreach(bit b; a.a)
>>      ..
>>
>>    a.c[8..16] = a.a[];
>>
>>    ..etc..
>> }
>>
>> This would require some compiler magic, it appears to me that there are 3
>> possibilities for
>> implementing it:
>>
>> 1. all basic types are actually stored as arrays of bits.
>> 2. the arrays are created/destroyed when required.
>> 3. a keyword is introduced to cause #1 above when desirec, bitmask'
>> perhaps. eg.
>>    struct A {
>>      bitmask uint mask;
>>      uint not_a_bitmask;
>>    }
>>
>> 3 is clearly the best choice IMHO.
>>
>> Regan
>>
>> --
>> Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
>
>



-- 
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
August 23, 2004
Regan Heath wrote:

> I guess the real problem is with bool in D being different to bool in C.

How so? In that it is true 'true' and 'false'. C is false is 0 and less than 0 and true is 1.

# D Way {
#    true = 1
#    false = 0
# }
August 23, 2004
On Sun, 22 Aug 2004 21:57:53 -0500, Gold Dragon <dragonwing@dragonu.net> wrote:
> Regan Heath wrote:
>
>> I guess the real problem is with bool in D being different to bool in C.
>
> How so? In that it is true 'true' and 'false'. C is false is 0 and less than 0 and true is 1.
>
> # D Way {
> #    true = 1
> #    false = 0
> # }

See the thread entitled "bit fields in structs" in the digitalmars.D.bugs NG. Basically in C this..

struct A {
  bool a[2];
  int  b;
};

does not have the same binary layout as this in D

struct A {
  bool a[2];
  int  b;
}

as D packs the bits into one byte and C does not.

Regan

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