DIP74: Reference Counted Class Objects
bitwise via Digitalmars-d
digitalmars-d at puremagic.com
Wed Mar 4 12:04:58 PST 2015
On Wednesday, 4 March 2015 at 18:59:54 UTC, Andrei Alexandrescu
wrote:
> On 3/4/15 10:48 AM, bitwise wrote:
>> After looking at DIP74, it seems that there is no way to
>> create a weak
>> reference to a ref counted object, but is not explicitly
>> stated. Has
>> this idea been considered at all?
>
> DIP74 aims at not disallowing weak references whilst leaving it
> to libraries to effect implementations, but we'd need a proof
> of concept implementation to make sure DIP74 is enough as is.
> -- Andrei
I suppose you could add "getWeak()" and "releaseWeak()" to a ref
counted class, and implement a "struct Weak(T)" that calls them
for you, but I doesn't seem like much of a leap to just add
something like this to the DIP.
couldn't "opAddWeak" and "opReleaseWeak" be added and follow
identical rules to "opAddRef" and "opRelease"? The compiler could
simply insert "opAddWeak() instead of opAddRef() when it found
the "weak" keyword.
For example:
class Widget {
private uint _refs = 1;
private uint _weaks = 0;
private int[] _payload; // owned
void opAddRef() {
++_refs;
}
void opRelease() {
if (--_refs == 0) {
GC.free(_payload.ptr);
_payload = null;
// I'm assuming this would leave "_weaks" and "_refs"
untouched
this.destroy();
if(_weaks == 0) {
GC.free(cast(void*)this);
}
}
}
void opAddWeak() {
++_weaks;
}
void opReleaseWeak() {
if(--_weaks == 0 && _refs == 0) {
GC.free(cast(void*)this);
}
}
// optional/recommended
bool expired() {
return _refs == 0;
}
}
Widget a = new Widget; // refs == 1, weaks == 0
Widget b = weak a; // refs == 1, weaks == 1
//a.opAddWeak();
Widget c = b;
// b.opAddRef(); // refs == 2, weaks == 1
a = null; // refs == 1, weaks == 1
//a.opRelease();
assert(b.expired() == false);
c = null; // refs == 0, weaks == 1
// c.opRelease();
assert(b.expired() == true);
b = null; // refs == 0, weaks == 0
// b.opReleaseWeak();
////////// or for function calls:
void func(weak Widget a) {
//...
}
Widget a = new Widget;
func(a);
More information about the Digitalmars-d
mailing list