IntrusivePtr.compareExchangeStrong

Compares the IntrusivePtr pointers pointed-to by this and expected.

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<std::shared_ptr>.

struct IntrusivePtr
scope
bool
compareExchangeStrong
(
MemoryOrder success = MemoryOrder.seq
MemoryOrder failure = success
E
D
this This
)
(
ref scope E expected
,
scope D desired
)
if (
!is(E == shared)
&&
&&
!is(D == shared)
&&
(
isMoveConstructable!(D, This) &&
isMutable!This
)
&&
(
isCopyConstructable!(This, E) &&
isMutable!E
)
&&
(This.isWeak == D.isWeak)
&&
(This.isWeak == E.isWeak)
)

Examples

1 static class Foo{
2     long i;
3     ControlBlock!(int, int) c;
4 
5     this(long i)pure nothrow @safe @nogc{
6         this.i = i;
7     }
8 
9     bool opEquals(this This)(long i)const @trusted{
10         import std.traits : Unqual;
11         auto self = cast(Unqual!This)this;
12         return (self.i == i);
13     }
14 
15 
16 }
17 alias Type = Foo;
18 static foreach(enum bool weak; [true, false]){
19     //fail
20     {
21         IntrusivePtr!Type a = IntrusivePtr!Type.make(123);
22         IntrusivePtr!Type b = IntrusivePtr!Type.make(42);
23         IntrusivePtr!Type c = IntrusivePtr!Type.make(666);
24 
25         static if(weak)a.compareExchangeWeak(b, c);
26         else a.compareExchangeStrong(b, c);
27 
28         assert(*a == 123);
29         assert(*b == 123);
30         assert(*c == 666);
31 
32     }
33 
34     //success
35     {
36         IntrusivePtr!Type a = IntrusivePtr!Type.make(123);
37         IntrusivePtr!Type b = a;
38         IntrusivePtr!Type c = IntrusivePtr!Type.make(666);
39 
40         static if(weak)a.compareExchangeWeak(b, c);
41         else a.compareExchangeStrong(b, c);
42 
43         assert(*a == 666);
44         assert(*b == 123);
45         assert(*c == 666);
46     }
47 
48     //shared fail
49     {
50         shared IntrusivePtr!(shared Type) a = IntrusivePtr!(shared Type).make(123);
51         IntrusivePtr!(shared Type) b = IntrusivePtr!(shared Type).make(42);
52         IntrusivePtr!(shared Type) c = IntrusivePtr!(shared Type).make(666);
53 
54         static if(weak)a.compareExchangeWeak(b, c);
55         else a.compareExchangeStrong(b, c);
56 
57         auto tmp = a.exchange(null);
58         assert(*tmp == 123);
59         assert(*b == 123);
60         assert(*c == 666);
61     }
62 
63     //shared success
64     {
65         IntrusivePtr!(shared Type) b = IntrusivePtr!(shared Type).make(123);
66         shared IntrusivePtr!(shared Type) a = b;
67         IntrusivePtr!(shared Type) c = IntrusivePtr!(shared Type).make(666);
68 
69         static if(weak)a.compareExchangeWeak(b, c);
70         else a.compareExchangeStrong(b, c);
71 
72         auto tmp = a.exchange(null);
73         assert(*tmp == 666);
74         assert(*b == 123);
75         assert(*c == 666);
76     }
77 }

Meta