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