Unstandard

Weak reference implementation.

License
Boost License 1.0.
Authors
Denis Shelomovskij

template  isWeakReferenceable(T)

Detect whether a weak reference to type T can be created.

A weak reference can be created for a class, interface, or delegate.

Warning:
delegate context must be a class instance. I.e. creating a weak reference for a delegate created from a struct member function will result in undefined behavior.

Weak reference will not work for closures unless enhancement D Bugzilla 9601 is implemented as now regular D objects aren't created on closures.

class  WeakReference(T) if (isWeakReferenceable!T);

Implements weak reference.

Note:
The class contains a pointer to a target object thus it behaves as a normal reference if placed in GC block without NO_SCAN attribute.
Tip:
This behaves like C#'s short weak reference or Java's weak reference.

const pure nothrow bool  alive();

Determines whether referenced object is finalized.


inout nothrow inout(T)  target();

Returns referenced object if it isn't finalized thus creating a strong reference to it. Returns null otherwise.


WeakReference!T  weakReference(T)(T target) if (isWeakReferenceable!T);

Convenience function that returns a WeakReference!T object for target.

Examples
auto weak = weakReference(new Object());
// ...
if(auto obj = weak.target)
{
	// Still alive! Let's kill it by hands.
	destroy(obj);
	assert(!weak.alive && !weak.target);
}
Examples
auto weak = weakReference(&(new Object()).toString);
// ...
if(auto del = weak.target)
{
	// It's alive! Let's check and kill it by hands.
	assert(del() == "object.Object");
	destroy(cast(Object) del.ptr);
	assert(!weak.alive && !weak.target);
}

class  WeakReferenceArray(T) if (isWeakReferenceable!T);

Implements weak reference array.

It gives better performance when working with multiple weak references at once.


this(in size_t initialCapacity);

Create weak reference array with initial capacity initialCapacity.

Preconditions:
initialCapacity != 0

const pure nothrow @safe size_t  count();

Total count of (possibly dead) weak references.


const pure nothrow size_t  aliveCount();

Total count of alive weak references.


const pure nothrow @safe size_t  capacity();

Returns the capacity of the array.


const pure nothrow @safe bool  hard();

Determines whether array behaves as a hard reference. false by default.


inout pure nothrow inout(T)[]  buff();

Return array internal buffer which can be safely used while the array behaves as a hard reference.

The array contains aliveCount non-null references. Use removeDead before retrieveing the array to get array of only alive objects.

Note:
Retrieved buffer may become invalid after addition of an object into the array if capacity == count or after reserve or removeDead call.
Preconditions:
hard

void  opOpAssign(string op : "~")(T target);

Appends new weak reference to target to the array.


inout nothrow inout(T)  opIndex(in size_t i);

Returns i-th referenced object if it isn't finalized thus creating a strong reference to it. Returns null otherwise.


void  opIndexAssign(T target, in size_t i);

Changes i-th referenced object.


void  reserve(in size_t newCapacity);

Reserve at least newCapacity elements for appending.


nothrow void  removeDead();

Remove dead weak references from the array. This may decrease count.


nothrow void  makeWeak();

Force the array to behave as a weak reference.


nothrow void  makeHard();

Force the array to behave as a hard reference.


WeakReferenceArray!T  weakReferenceArray(T)(in size_t initialCapacity = 64) if (isWeakReferenceable!T);

Convenience function that returns a WeakReferenceArray!T with initial capacity initialCapacity.