reinterpret array
Artur Skawina via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Tue Jan 13 15:36:35 PST 2015
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
More information about the Digitalmars-d-learn
mailing list