On 01/13/15 21:52, Dominikus Dittes Scherkl via Digitalmars-d-learn 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 neat, but the real problems with it are:
1) obfuscation - it hides those trivial bit ops behind layers of
functions and operator overloads, which everyone reading the
code must then figure out;
2) safety - `a.bit` could potentially outlive `a`; D does not
handle object lifetimes, so there's no 100% safe way to prevent
such bugs.

Hence you probably don't actually want to use this.


   struct Bits(E, size_t UB=1) {
      E* e;

      bool opIndexAssign(bool v, size_t idx) {
         auto o = idx/(E.sizeof*8);
         idx %= E.sizeof*8;
         if (o>=UB)
            assert (0);
         if (v)
            e[o] |=   1L<<idx;
         else
            e[o] &= ~(1L<<idx);
         return v;
      }
      bool opIndex(size_t idx) {
         auto o = idx/(E.sizeof*8);
         idx %= E.sizeof*8;
         if (o>=UB)
            assert (0);
         return !!(e[o] & 1L<<idx);
      }
   }

   auto bit(E)(ref E e) @property {
      static if (is(E:A[L], A, size_t L))
         return Bits!(typeof(e[0]), L)(e.ptr);
      else
         return Bits!E(&e);
   }


artur


Reply via email to