Report a bug
If you spot a problem with this page, click here to create a GitHub issue.
Improve this page
Quickly fork, edit online, and submit a pull request for this page. Requires a signed-in GitHub account. This works well for small changes. If you'd like to make larger changes you may want to consider using a local clone.


Thread-safe reference-counted shared pointers

This implementation supports class and struct (alias this) polymorphism.
struct mir_rcptr(T);
Thread safe reference counting array.
This implementation supports class and struct (alias this) polymorphism.
__xdtor if any is used to destruct objects.
The implementation never adds roots into the GC.
Unqual!T _value;

template opUnary(string op : "*")
inout @property scope inout(T) _get_value();
pure nothrow @nogc @safe void proxySwap(ref typeof(this) rhs);
const pure nothrow @nogc scope @safe bool opEquals(typeof(null));

const pure nothrow @nogc scope @safe bool opEquals(Y)(auto ref scope const ThisTemplate!Y rhs);
const pure nothrow @nogc scope @trusted sizediff_t opCmp(Y)(auto ref scope const ThisTemplate!Y rhs);
const pure nothrow @nogc scope @trusted size_t toHash();
ref @trusted auto opAssign(typeof(null)) return;
ref @trusted auto opAssign(return typeof(this) rhs) return;
ref @trusted auto opAssign(Q)(return ThisTemplate!Q rhs) return
if (isImplicitlyConvertible!(Q*, T*));
alias RCPtr = mir_rcptr(T);
auto shareMember(string member, T, Args...)(return mir_rcptr!T context, auto ref Args args);
shared pointer of the member and the context from the current pointer.
@system .mir_rcptr!R createRCWithContext(R, F)(return R value, return const mir_rcptr!F context)
if (is(R == class) || is(R == interface));

@system .mir_rcptr!R createRCWithContext(R, F)(return ref R value, return const mir_rcptr!F context)
if (!is(R == class) && !is(R == interface));
shared pointer constructed with current context.
@trusted mir_rcptr!R castTo(R, T)(return mir_rcptr!T context)
if (isImplicitlyConvertible!(T, R));

@trusted mir_rcptr!(const(R)) castTo(R, T)(return const mir_rcptr!T context)
if (isImplicitlyConvertible!(const(T), const(R)));

@trusted mir_rcptr!(immutable(R)) castTo(R, T)(return immutable mir_rcptr!T context)
if (isImplicitlyConvertible!(immutable(T), immutable(R)));
Construct a shared pointer of a required type with a current context. Provides polymorphism abilities for classes and structures with alias this syntax.
template createRC(T) if (!is(T == interface) && !__traits(isAbstractClass, T))
auto a = createRC!double(10);
auto b = a;
assert(*b == 10);
*b = 100;
assert(*a == 100);
Classes with empty constructor
static class C
    int index = 34;
assert(createRC!C.index == 34);
static interface I { ref double bar() @safe pure nothrow @nogc; }
static abstract class D { int index; }
static class C : D, I
    double value;
    ref double bar() @safe pure nothrow @nogc { return value; }
    this(double d) { value = d; }
auto a = createRC!C(10);
assert(a._counter == 1);
auto b = a;
assert(a._counter == 2);
assert((*b).value == 10);
b.value = 100; // access via alias this syntax
assert(a.value == 100);
assert(a._counter == 2);

auto d = a.castTo!D; //RCPtr!D
assert(d._counter == 3);
d.index = 234;
assert(a.index == 234);
auto i = a.castTo!I; //RCPtr!I
assert( == 100);
assert(i._counter == 4);

auto v = a.shareMember!"value"; //RCPtr!double
auto w = a.shareMember!"bar"; //RCPtr!double
assert(i._counter == 6);
assert(*v == 100);
()@trusted{assert(&*w is &*v);}();
'Alias This' support
struct S
    double e;
struct C
    int i;
    S s;
    // 'alias' should be accesable by reference
    // or a class/interface
    alias s this;

auto a = createRC!C(10, S(3));
auto s = a.castTo!S; // RCPtr!S
assert(s._counter == 2);
assert(s.e == 3);
mir_rcptr!T createRC(Args...)(auto ref Args args);