Function IntrusivePtr.compareExchangeStrong
Compares the IntrusivePtr
pointers pointed-to by this
and expected
.
bool compareExchangeStrong(MemoryOrder success = MemoryOrder .seq, MemoryOrder failure = success, E, D, This)
(
scope ref E expected,
scope D desired
) scope
if (isIntrusivePtr!E && !is(E == shared) && isIntrusivePtr!D && !is(D == shared) && (isMoveConstructable!(D, This) && isMutable!This) && (isCopyConstructable!(This, E) && isMutable!E) && (This .isWeak == D .isWeak) && (This .isWeak == E .isWeak));
If they are equivalent (store the same pointer value, and either share ownership of the same object or are both empty), assigns desired
into this
using the memory ordering constraints specified by success
and returns true
.
If they are not equivalent, assigns this
into expected
using the memory ordering constraints specified by failure
and returns false
.
More info in c++ std::atomic
Examples
static class Foo{
long i;
ControlBlock!(int, int) c;
this(long i)pure nothrow @safe @nogc{
this .i = i;
}
bool opEquals(this This)(long i)const @trusted{
import std .traits : Unqual;
auto self = cast(Unqual!This)this;
return (self .i == i);
}
}
alias Type = Foo;
static foreach(enum bool weak; [true, false]){
//fail
{
IntrusivePtr!Type a = IntrusivePtr!Type .make(123);
IntrusivePtr!Type b = IntrusivePtr!Type .make(42);
IntrusivePtr!Type c = IntrusivePtr!Type .make(666);
static if(weak)a .compareExchangeWeak(b, c);
else a .compareExchangeStrong(b, c);
assert(*a == 123);
assert(*b == 123);
assert(*c == 666);
}
//success
{
IntrusivePtr!Type a = IntrusivePtr!Type .make(123);
IntrusivePtr!Type b = a;
IntrusivePtr!Type c = IntrusivePtr!Type .make(666);
static if(weak)a .compareExchangeWeak(b, c);
else a .compareExchangeStrong(b, c);
assert(*a == 666);
assert(*b == 123);
assert(*c == 666);
}
//shared fail
{
shared IntrusivePtr!(shared Type) a = IntrusivePtr!(shared Type) .make(123);
IntrusivePtr!(shared Type) b = IntrusivePtr!(shared Type) .make(42);
IntrusivePtr!(shared Type) c = IntrusivePtr!(shared Type) .make(666);
static if(weak)a .compareExchangeWeak(b, c);
else a .compareExchangeStrong(b, c);
auto tmp = a .exchange(null);
assert(*tmp == 123);
assert(*b == 123);
assert(*c == 666);
}
//shared success
{
IntrusivePtr!(shared Type) b = IntrusivePtr!(shared Type) .make(123);
shared IntrusivePtr!(shared Type) a = b;
IntrusivePtr!(shared Type) c = IntrusivePtr!(shared Type) .make(666);
static if(weak)a .compareExchangeWeak(b, c);
else a .compareExchangeStrong(b, c);
auto tmp = a .exchange(null);
assert(*tmp == 666);
assert(*b == 123);
assert(*c == 666);
}
}