1 static class Foo{
2 int i;
3
4 this(int i)pure nothrow @safe @nogc{
5 this.i = i;
6 }
7 }
8
9 static class Bar : Foo{
10 double d;
11
12 this(int i, double d)pure nothrow @safe @nogc{
13 super(i);
14 this.d = d;
15 }
16 }
17
18 static class Zee : Bar{
19 bool b;
20
21 this(int i, double d, bool b)pure nothrow @safe @nogc{
22 super(i, d);
23 this.b = b;
24 }
25
26 ~this()nothrow @system{
27 }
28 }
29
30 ///simple:
31 {
32 SharedPtr!long a = SharedPtr!long.make(42);
33 assert(a.useCount == 1);
34
35 SharedPtr!(const long) b = a;
36 assert(a.useCount == 2);
37
38 SharedPtr!long.WeakType w = a.weak; //or WeakPtr!long
39 assert(a.useCount == 2);
40 assert(a.weakCount == 1);
41
42 SharedPtr!long c = w.lock;
43 assert(a.useCount == 3);
44 assert(a.weakCount == 1);
45
46 assert(*c == 42);
47 assert(c.get == 42);
48 }
49
50 ///polymorphism and aliasing:
51 {
52 ///create SharedPtr
53 SharedPtr!Foo foo = SharedPtr!Bar.make(42, 3.14);
54 SharedPtr!Zee zee = SharedPtr!Zee.make(42, 3.14, false);
55
56 ///dynamic cast:
57 SharedPtr!Bar bar = dynCast!Bar(foo);
58 assert(bar != null);
59 assert(foo.useCount == 2);
60
61 ///this doesnt work because Foo destructor attributes are more restrictive then Zee's:
62 //SharedPtr!Foo x = zee;
63
64 ///this does work:
65 SharedPtr!(Foo, DestructorType!(Foo, Zee)) x = zee;
66 assert(zee.useCount == 2);
67
68 ///aliasing (shared ptr `d` share ref counting with `bar`):
69 SharedPtr!double d = SharedPtr!double(bar, &bar.get.d);
70 assert(d != null);
71 assert(*d == 3.14);
72 assert(foo.useCount == 3);
73 }
74
75
76 ///multi threading:
77 {
78 ///create SharedPtr with atomic ref counting
79 SharedPtr!(shared Foo) foo = SharedPtr!(shared Bar).make(42, 3.14);
80
81 ///this doesnt work:
82 //foo.get.i += 1;
83
84 import core.atomic : atomicFetchAdd;
85 atomicFetchAdd(foo.get.i, 1);
86 assert(foo.get.i == 43);
87
88
89 ///creating `shared(SharedPtr)`:
90 shared SharedPtr!(shared Bar) bar = share(dynCast!Bar(foo));
91
92 ///`shared(SharedPtr)` is not lock free but `RcPtr` is lock free.
93 static assert(typeof(bar).isLockFree == false);
94
95 ///multi thread operations (`load`, `store`, `exchange` and `compareExchange`):
96 SharedPtr!(shared Bar) bar2 = bar.load();
97 assert(bar2 != null);
98 assert(bar2.useCount == 3);
99
100 SharedPtr!(shared Bar) bar3 = bar.exchange(null);
101 assert(bar3 != null);
102 assert(bar3.useCount == 3);
103 }
104
105 ///dynamic array:
106 {
107 import std.algorithm : all, equal;
108
109 SharedPtr!(long[]) a = SharedPtr!(long[]).make(10, -1);
110 assert(a.length == 10);
111 assert(a.get.length == 10);
112 assert(a.get.all!(x => x == -1));
113
114 for(int i = 0; i < a.length; ++i){
115 a.get[i] = i;
116 }
117 assert(a.get[] == [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
118
119 ///aliasing:
120 SharedPtr!long a6 = SharedPtr!long(a, &a.get[6]);
121 assert(*a6 == a.get[6]);
122 }//make SharedPtr object
static struct Foo{
int i;
this(int i)pure nothrow @safe @nogc{
this.i = i;
}
}
{
auto foo = SharedPtr!Foo.make(42);
auto foo2 = SharedPtr!Foo.make!Mallocator(42); //explicit stateless allocator
}
{
import std.experimental.allocator : make, dispose;
static void deleter(long* x)pure nothrow @trusted @nogc{
Mallocator.instance.dispose(x);
}
long* element = Mallocator.instance.make!long;
auto x = SharedPtr!long.make(element, &deleter);
}
{
auto arr = SharedPtr!(long[]).make(10); //dynamic array with length 10
assert(arr.length == 10);
}//alloc SharedPtr object
import std.experimental.allocator : make, dispose, allocatorObject;
auto allocator = allocatorObject(Mallocator.instance);
{
auto x = SharedPtr!long.alloc(allocator, 42);
}
{
static void deleter(long* x)pure nothrow @trusted @nogc{
Mallocator.instance.dispose(x);
}
long* element = Mallocator.instance.make!long;
auto x = SharedPtr!long.alloc(allocator, element, &deleter);
}
{
auto arr = SharedPtr!(long[]).alloc(allocator, 10); //dynamic array with length 10
assert(arr.length == 10);
}
Alias to SharedPtr with different order of template parameters