1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this
3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 module tanya.memory.tests.lifetime;
5 
6 import tanya.memory.allocator;
7 import tanya.memory.lifetime;
8 import tanya.test.stub;
9 
10 @nogc nothrow pure @safe unittest
11 {
12     int[] p;
13 
14     p = defaultAllocator.resize(p, 20);
15     assert(p.length == 20);
16 
17     p = defaultAllocator.resize(p, 30);
18     assert(p.length == 30);
19 
20     p = defaultAllocator.resize(p, 10);
21     assert(p.length == 10);
22 
23     p = defaultAllocator.resize(p, 0);
24     assert(p is null);
25 }
26 
27 @nogc nothrow pure @system unittest
28 {
29     static struct S
30     {
31         ~this() @nogc nothrow pure @safe
32         {
33         }
34     }
35     auto p = cast(S[]) defaultAllocator.allocate(S.sizeof);
36 
37     defaultAllocator.dispose(p);
38 }
39 
40 // Works with interfaces.
41 @nogc nothrow pure @safe unittest
42 {
43     interface I
44     {
45     }
46     class C : I
47     {
48     }
49     auto c = defaultAllocator.make!C();
50     I i = c;
51 
52     defaultAllocator.dispose(i);
53     defaultAllocator.dispose(i);
54 }
55 
56 // Handles "Cannot access frame pointer" error.
57 @nogc nothrow pure @safe unittest
58 {
59     struct F
60     {
61         ~this() @nogc nothrow pure @safe
62         {
63         }
64     }
65     static assert(is(typeof(emplace!F((void[]).init))));
66 }
67 
68 // Can emplace structs without a constructor
69 @nogc nothrow pure @safe unittest
70 {
71     static assert(is(typeof(emplace!WithDtor(null, WithDtor()))));
72     static assert(is(typeof(emplace!WithDtor(null))));
73 }
74 
75 // Doesn't call a destructor on uninitialized elements
76 @nogc nothrow pure @system unittest
77 {
78     static struct SWithDtor
79     {
80         private bool canBeInvoked = false;
81         ~this() @nogc nothrow pure @safe
82         {
83             assert(this.canBeInvoked);
84         }
85     }
86     void[SWithDtor.sizeof] memory = void;
87     auto actual = emplace!SWithDtor(memory[], SWithDtor(true));
88     assert(actual.canBeInvoked);
89 }
90 
91 // Initializes structs if no arguments are given
92 @nogc nothrow pure @safe unittest
93 {
94     static struct SEntry
95     {
96         byte content;
97     }
98     ubyte[1] mem = [3];
99 
100     assert(emplace!SEntry(cast(void[]) mem[0 .. 1]).content == 0);
101 }
102 
103 // Postblit is called when emplacing a struct
104 @nogc nothrow pure @system unittest
105 {
106     static struct S
107     {
108         bool called = false;
109         this(this) @nogc nothrow pure @safe
110         {
111             this.called = true;
112         }
113     }
114     S target;
115     S* sp = ⌖
116 
117     emplace!S(sp[0 .. 1], S());
118     assert(target.called);
119 }
120 
121 // Is pure.
122 @nogc nothrow pure @system unittest
123 {
124     struct S
125     {
126         this(this)
127         {
128         }
129     }
130     S source, target = void;
131     static assert(is(typeof({ moveEmplace(source, target); })));
132 }
133 
134 // Moves nested.
135 @nogc nothrow pure @system unittest
136 {
137     struct Nested
138     {
139         void method() @nogc nothrow pure @safe
140         {
141         }
142     }
143     Nested source, target = void;
144     moveEmplace(source, target);
145     assert(source == target);
146 }
147 
148 // Emplaces static arrays.
149 @nogc nothrow pure @system unittest
150 {
151     static struct S
152     {
153         size_t member;
154         this(size_t i) @nogc nothrow pure @safe
155         {
156             this.member = i;
157         }
158         ~this() @nogc nothrow pure @safe
159         {
160         }
161     }
162     S[2] source = [ S(5), S(5) ], target = void;
163     moveEmplace(source, target);
164     assert(source[0].member == 0);
165     assert(target[0].member == 5);
166     assert(source[1].member == 0);
167     assert(target[1].member == 5);
168 }
169 
170 // Moves if source is target.
171 @nogc nothrow pure @safe unittest
172 {
173     int x = 5;
174     move(x, x);
175     assert(x == 5);
176 }
177