If the WeakRef reference a RefCounted.
Release the reference.
shall only call the destructor one time.
size_t dtorcalled = 0; struct S { int x; @safe ~this() { if (x) dtorcalled++; } @disable this(this); } { auto rc1 = S(1).refCounted; assert(rc1.refCount == 1); assert(rc1.impl.weakCnt == 1); auto rc2 = rc1; assert(rc2.refCount == 2); assert(rc2.impl.weakCnt == 1); auto wrc1 = rc1.weakRef; assert(wrc1.impl.useCnt == 2); assert(wrc1.impl.weakCnt == 2); } assert(dtorcalled == 1);
shall destroy the object even though there are cycles because they are WeakRef.
size_t dtorcalled = 0; struct S { int x; WeakRef!(typeof(this)) other; @safe ~this() { if (x) dtorcalled++; } @disable this(this); } { auto rc1 = S(1).refCounted; auto rc2 = S(2).refCounted; rc1.other = rc2.weakRef; rc2.other = rc1.weakRef; assert(rc1.impl.useCnt == 1); assert(rc1.impl.weakCnt == 2); assert(rc2.impl.useCnt == 1); assert(rc2.impl.weakCnt == 2); } assert(dtorcalled == 2);
WeakRef is a smart pointer that holds a non-owning ("weak") reference to an object that is managed by RefCounted. It must be converted to a RefCounted via asRefCounted() in order to access the referenced object.
WeakRef models temporary ownership: when an object needs to be accessed only if it exists, and it may be deleted at any time by someone else, WeakRef is used to track the object, and it is converted to RefCounted to assume temporary ownership. If the original RefCounted is destroyed at this time, the object's lifetime is extended until the temporary RefCounted is destroyed as well.
Another use for WeakRef is to break reference cycles formed by objects managed by RefCounted. if such cycle is orphaned (i.e. there are no outside shared pointers into the cycle), the RefCounted reference counts cannot reach zero and the memory is leaked. To prevent this, one of the pointers in the cycle can be made weak.