Function IntrusivePtr.exchange
Stores the non shared
IntrusivePtr
pointer ptr in the shared(IntrusivePtr)
pointed to by this
and returns the value formerly pointed-to by this, atomically or with mutex.
IntrusivePtr exchange(MemoryOrder order = MemoryOrder .seq, This)
(
typeof(null)
) scope
if (isMutable!This);
IntrusivePtr exchange(MemoryOrder order = MemoryOrder .seq, Rhs, This)
(
scope Rhs ptr
) scope
if (isIntrusivePtr!Rhs && !is(Rhs == shared) && isMoveConstructable!(Rhs, This) && isMutable!This);
Examples
static struct Foo{
ControlBlock!(int, int) c;
int i;
this(int i)pure nothrow @safe @nogc{
this .i = i;
}
}
//lvalue exchange
{
shared x = IntrusivePtr!(shared Foo) .make(123);
auto y = IntrusivePtr!(shared Foo) .make(42);
auto z = x .exchange(y);
assert(x .load .get .i == 42);
assert(y .get .i == 42);
assert(z .get .i == 123);
}
//rvalue exchange
{
shared x = IntrusivePtr!(shared Foo) .make(123);
auto y = IntrusivePtr!(shared Foo) .make(42);
import core .lifetime : move;
auto z = x .exchange(move(y));
assert(x .load .get .i == 42);
assert(y == null);
assert(z .get .i == 123);
}
//null exchange (same as move)
{
shared x = IntrusivePtr!(shared Foo) .make(123);
auto z = x .exchange(null);
assert(x .load == null);
assert(z .get .i == 123);
}
//swap:
{
shared x = IntrusivePtr!(shared Foo) .make(123);
auto y = IntrusivePtr!(shared Foo) .make(42);
//opAssign is same as store
import core .lifetime : move;
y = x .exchange(move(y));
assert(x .load .get .i == 42);
assert(y .get .i == 123);
}