On Tuesday, 13 January 2015 at 23:36:51 UTC, Artur Skawina via Digitalmars-d-learn wrote:
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;

Ok, but this is the case with any function - and this modulo stuff
is easy but not so trivial that a function is not justified.

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.
This can be addressed with the newer proposed mechanisms and a little
more information-hiding (generator function):


Hence you probably don't actually want to use this.
[...]
I had something pretty close to that in mind:

@property inout bit(T)(inout ref T a)
   pure @safe @nogc nothrow
   if(isUnsigned!T || (isArray!T && isUnsigned!T[0]))
{
   struct BitArray(T)
   {
   private:
      enum s = std.bitop.bsr(T.sizeof)+2;
      enum m = (1<<s)-1;
      inout T* r;
      size_t len;
   public:
      this(inout T* p, size_t d) { r = p; len = d<<s; }

      bool opIndex(size_t idx) const // get bit
      {
         return (idx < len) ? (r[idx>>s]>>(idx & m))&1u : false;
      }

      static if(isMutable!T)
      {
void opIndexAssign(bool b, size_t idx) // set or clear bit
         {
            if(idx < len)
            {
               if(b) r[idx>>s] |= 1u<<(idx & m);
               else r[idx>>s] &= ~(cast(T)1<<(idx & m));
            }
         }
      }
   }
   static if(isUnsigned!T)
      return BitArray(&a, 1);
   else
      return BitArray(&a[0], a.length);
}

Reply via email to