Time to kill T() as (sometimes) working T.init alias ?
monarch_dodra
monarchdodra at gmail.com
Tue Dec 11 05:22:41 PST 2012
On Tuesday, 11 December 2012 at 12:52:03 UTC, Dan wrote:
>
> For me it did not compile (No constructor for payload), maybe
> you had a ctor for Payload? I think opAssign is not necessary -
> if I remove it it still seems to work since default opAssign
> calls postblit. I added the ctor, removed opAssign and put it
> here: http://dpaste.dzfl.pl/6ecfe675
>
> Other than that - is there still a subtle bug?
>
> Thanks,
> Dan
Strange, it had compiled for me this morning. Wonder what
happened...
Anyways, this just highlights one of D's inconsistencies:
Payload a = Payload(1, 1); //Legal
Payload* p1 = new Payload(1, 1); //Illegal???
Payload* p2 = [Payload(1, 1)].ptr; //Dirty workaround.
Yeah... You can use the "dirty workaround":
http://dpaste.dzfl.pl/c0258f66
Anyways, opAssign is *definitely* necessary. Without it,
assignment would be equivalent to aliasing, and you wouldn't have
actual COW (both instances would end up modified). What's more,
if the current object had a handle on another payload, you
wouldn't release it, causing it to duplicate for no reason (but
that's moot considering COW is already broken). In my example, it
works because no-one actually *calls* opAssign.
The bug is this (on topic)
//----
S s2 = S(2);
S s0 = S();
s0 = s2; //Crap.
//----
Here, you aren't actually calling "this(int = 0)". Nope. What you
are actually calling is... nothing! This means s0 does not have
an actual payload. This means that in theory, on every write, you
need to check the count... and check there is actually a payload
there first :D ! Yay extra useless checks and increased lazy
initialization on every call!
> There is a fair amount of boilerplate bookeeping. What if the
> struct had two, three, or more maps
Depends on the required granularity. I'd say ideally, you'd put
all three maps in the same "Payload" struct, so things would not
actually be more complicated.
If you try to make each map individually COW, it would only be
slightly more complex. You *would* take a further performance hit
having to call "ensureUnique" on *each* map every modifying call.
Furthermore, you may also take a performance hit in terms of
locality of reference. But that'd be WAY premature to really
worry about.
What you have to keep in mind is that a "triple COW" design would
only make sense if you have functions that modify one of your 3
maps. If they are always modified together, it'd make no sense to
use "triple COW".
//----
When everything is said and done, most of that code can be
templated, or mixed-in.
More information about the Digitalmars-d
mailing list