Function dynCastMove

Dynamic cast for shared pointers if ElementType is class with D linkage.

{null} dynCastMove(T, Ptr)()
if (isIntrusive!T && isIntrusivePtr!Ptr && !is(Ptr == shared) && !Ptr.isWeak && isClassOrInterface!T && (__traits(getLinkage, T) == "D") && isClassOrInterface!(Ptr.ElementType) && (__traits(getLinkage, Ptr.ElementType) == "D"));

Creates a new instance of IntrusivePtr whose stored pointer is obtained from ptr's stored pointer using a dynaic cast expression.

If ptr is null or dynamic cast fail then result IntrusivePtr is null. Otherwise, the new IntrusivePtr will share ownership with the initial value of ptr.

Example

static class Base{
    ControlBlock!(int, int) c;
}
static class Foo : Base{
    int i;

    this(int i)pure nothrow @safe @nogc{
        this.i = i;
    }
}

static class Bar : Foo{
    double d;

    this(int i, double d)pure nothrow @safe @nogc{
        super(i);
        this.d = d;
    }
}

static class Zee : Base{
}

{
    IntrusivePtr!(const Foo) foo = IntrusivePtr!Bar.make(42, 3.14);
    //assert(foo.get.i == 42);

    auto bar = dynCastMove!Bar(foo);
    assert(bar != null);
    //assert(bar.get.d == 3.14);
    static assert(is(typeof(bar) == IntrusivePtr!(const Bar)));

    auto zee = dynCastMove!Zee(bar);
    assert(zee == null);
    static assert(is(typeof(zee) == IntrusivePtr!(const Zee)));
}

{
    IntrusivePtr!(const Foo) foo = IntrusivePtr!Bar.make(42, 3.14);
    //assert(foo.get.i == 42);

    auto bar = dynCastMove!Bar(foo);
    assert(bar != null);
    assert(foo == null);
    //assert(bar.get.d == 3.14);
    static assert(is(typeof(bar) == IntrusivePtr!(const Bar)));

    auto zee = dynCastMove!Zee(bar);
    assert(bar != null);
    assert(zee == null);
    static assert(is(typeof(zee) == IntrusivePtr!(const Zee)));
}