www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - alternate idea for bit management in D

reply Regan Heath <regan netwin.co.nz> writes:
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/
Aug 22 2004
parent reply "antiAlias" <fu bar.com> writes:
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/

Aug 22 2004
parent reply Regan Heath <regan netwin.co.nz> writes:
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/
Aug 22 2004
parent reply Gold Dragon <dragonwing dragonu.net> writes:
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 # }
Aug 22 2004
parent Regan Heath <regan netwin.co.nz> writes:
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/
Aug 22 2004