RefCounted

Defines a reference-counted object containing a T value as payload.

An instance of RefCounted is a reference to a structure, which is referred to as the store, or storage implementation struct in this documentation. The store contains a reference count and the T payload. RefCounted uses malloc to allocate the store. As instances of RefCounted are copied or go out of scope, they will automatically increment or decrement the reference count. When the reference count goes down to zero, RefCounted will call destroy against the payload and call free to deallocate the store. If the T payload contains any references to GC-allocated memory, then RefCounted will add it to the GC memory that is scanned for pointers, and remove it from GC scanning before free is called on the store.

One important consequence of destroy is that it will call the destructor of the T payload. GC-managed references are not guaranteed to be valid during a destructor call, but other members of T, such as file handles or pointers to malloc memory, will still be valid during the destructor call. This allows the T to deallocate or clean up any non-GC resources immediately after the reference count has reached zero.

RefCounted is unsafe and should be used with care. No references to the payload should be escaped outside the RefCounted object.

The autoInit option makes the object ensure the store is automatically initialized. Leaving autoInit == RefCountedAutoInitialize.yes (the default option) is convenient but has the cost of a test whenever the payload is accessed. If autoInit == RefCountedAutoInitialize.no, user code must call either refCountedStore.isInitialized or refCountedStore.ensureInitialized before attempting to access the payload. Not doing so results in null pointer dereference.

Constructors

this
this(A args)
this(T val)

Constructor that initializes the payload.

Destructor

~this
~this()

Destructor that tracks the reference count appropriately. If !refCountedStore.isInitialized, does nothing. When the reference count goes down to zero, calls destroy agaist the payload and calls free to deallocate the corresponding resource.

Postblit

this(this)
this(this)

Constructor that tracks the reference count appropriately. If !refCountedStore.isInitialized, does nothing.

Alias This

refCountedPayload

Returns a reference to the payload. If (autoInit == RefCountedAutoInitialize.yes), calls refCountedStore.ensureInitialized. Otherwise, just issues assert(refCountedStore.isInitialized).

Members

Functions

opAssign
void opAssign(T rhs)

Assignment operators

opAssign
void opAssign(typeof(this) rhs)

Assignment operators

Properties

refCountedPayload
T refCountedPayload [@property getter]
inout(T) refCountedPayload [@property getter]

Returns a reference to the payload. If (autoInit == RefCountedAutoInitialize.yes), calls refCountedStore.ensureInitialized. Otherwise, just issues assert(refCountedStore.isInitialized). Used with alias refCountedPayload this;, so callers can just use the RefCounted object as a T.

refCountedStore
inout(RefCountedStore) refCountedStore [@property getter]

Returns storage implementation struct.

Structs

RefCountedStore
struct RefCountedStore

RefCounted storage implementation.

Examples

// A pair of an `int` and a `size_t` - the latter being the
// reference count - will be dynamically allocated
auto rc1 = RefCounted!int(5);
assert(rc1 == 5);
// No more allocation, add just one extra reference count
auto rc2 = rc1;
// Reference semantics
rc2 = 42;
assert(rc1 == 42);
// the pair will be freed when rc1 and rc2 go out of scope

Meta

Suggestion Box / Bug Report