1 module ut.lifetime;
2 import numem.lifetime;
3 
4 class TestClass {
5 @nogc:
6     int value;
7 
8     this(int value) {
9         this.value = value;
10     }
11 
12     int func1() { return value; }
13 }
14 
15 class SubClass : TestClass {
16 @nogc:
17     int value2;
18 
19     this(int value, int value2) {
20         super(value);
21         this.value2 = value2;
22     }
23 
24     override
25     int func1() { return value2; }
26 }
27 
28 struct TestStruct {
29     int value;
30 }
31 
32 @("Construct class")
33 @nogc
34 unittest {
35     TestClass a = nogc_new!TestClass(12);
36     assert(a.func1() == 12);
37 
38     // also free.
39     nogc_delete(a);
40 }
41 
42 @("Construct subclass")
43 @nogc
44 unittest {
45     TestClass klass1 = nogc_new!SubClass(1, 2);
46     assert(klass1.func1() == 2);
47     assert(cast(SubClass)klass1);
48 }
49 
50 @("Construct class (nothrow)")
51 nothrow @nogc
52 unittest {
53     import numem.core.exception : assumeNoThrow;
54 
55     TestClass a = assumeNoThrow(() => nogc_new!TestClass(12));
56     assert(a.value == 12);
57 
58     // also free.
59     nogc_delete(a);
60 }
61 
62 @("Construct struct")
63 @nogc
64 unittest {
65     TestStruct* a = nogc_new!TestStruct(12);
66     assert(a.value == 12);
67 
68     // also free.
69     nogc_delete(a);
70 }
71 
72 @("Free struct")
73 @nogc
74 unittest {
75     TestStruct a = TestStruct(12);
76     assert(a.value == 12);
77 
78     // also free.
79     nogc_delete(a);
80 }
81 
82 @("Construct class (Slice list)")
83 @nogc
84 unittest {
85     TestClass[] classList;
86     classList.nu_resize(5).nogc_initialize();
87 
88     foreach(i; 0..classList.length) {
89         classList[i] = nogc_new!TestClass(cast(int)i);
90     }
91 
92     foreach(i; 0..classList.length) {
93         assert(classList[i].value == i);
94     }
95 }
96 
97 @("nogc_zeroinit")
98 unittest {
99     uint var1 = 42;
100     uint[8] var2 = [1, 2, 3, 4, 5, 6, 7, 8];
101 
102     // Single var ref.
103     nogc_zeroinit(var1);
104     assert(var1 == 0);
105 
106     // Var range
107     nogc_zeroinit(var2);
108     foreach(i, value; var2) {
109         assert(value == 0);
110     }
111 }
112 
113 @("nogc_initialize")
114 unittest {
115     import numem.casting : reinterpret_cast;
116 
117     // Pointers should be initialized to null.
118     void* ptr = cast(void*)0xDEADBEEF;
119     assert(nogc_initialize(ptr) is null);
120 
121     // NOTE: non-finite floats, even if the same bit pattern will never be equal.
122     // as such we reinterpret it to a uint to convert it to a bit pattern.
123     float f = 42.0;    
124     uint f_bitpattern = reinterpret_cast!uint(float.init);
125     assert(reinterpret_cast!uint(nogc_initialize(f)) == f_bitpattern);
126 
127     // Basic scalars.
128     ubyte u8 = ubyte.max;
129     byte i8 = byte.max;
130     ushort u16 = ushort.max;
131     short i16 = short.max;
132     uint u32 = uint.max;
133     int i32 = int.max;
134     ulong u64 = ulong.max;
135     long i64 = long.max;
136     assert(nogc_initialize(u8) == 0);
137     assert(nogc_initialize(i8) == 0);
138     assert(nogc_initialize(u16) == 0);
139     assert(nogc_initialize(i16) == 0);
140     assert(nogc_initialize(u32) == 0);
141     assert(nogc_initialize(i32) == 0);
142     assert(nogc_initialize(u64) == 0);
143     assert(nogc_initialize(i64) == 0);
144 
145     // Class references
146     TestClass tclass = reinterpret_cast!TestClass(cast(void*)0xDEADBEEF);
147     assert(cast(void*)nogc_initialize(tclass) is null);
148 
149     // Create new un-constructed class, allocated on the stack.
150     import numem.core.traits : AllocSize;
151     ubyte[AllocSize!TestClass] allocSpace;
152     auto klass = nogc_initialize!TestClass(cast(void[])allocSpace);
153     
154     // Attempt to use the class.
155     // NOTE: In this case due to the simplicitly of the class, the constructor
156     // is not neccesary to run; but eg. NuRefCounted *would* need it.
157     klass.value = 42;
158     assert(&klass.func1 !is null);
159     assert(klass.func1() == 42);
160 
161     // Initializing struct should blit its initial state back in.
162     TestStruct strukt = TestStruct(1000);
163     assert(strukt.value == 1000);
164     assert(nogc_initialize(strukt).value == 0);
165 }
166 
167 // Test creating destroy-with
168 @nu_destroywith!((ref value) { value.i = 42; })
169 struct ValueT {
170     int i = 0;
171 }
172 
173 @("nu_destroywith")
174 unittest {
175     ValueT myvalue;
176     
177     nogc_delete(myvalue);
178     assert(myvalue.i == 42);
179 }
180 
181 extern(C++)
182 class TestCPPClass {
183 @nogc:
184     int value;
185 
186     this(int value) { this.value = value; }
187     ~this() { }
188 }
189 
190 extern(C++)
191 struct TestCPPStruct {
192 @nogc:
193     int value;
194 }
195 
196 @("C++ ctor-dtor")
197 unittest {
198     
199     // throwing
200     TestCPPClass myClass = cpp_new!TestCPPClass(42);
201     assert(myClass !is null);
202     assert(myClass.value == 42);
203     cpp_delete(myClass);
204     assert(myClass is null);
205 
206     TestCPPStruct* myStruct = cpp_new!TestCPPStruct(42);
207     assert(myStruct !is null);
208     assert(myStruct.value == 42);
209     cpp_delete(myStruct);
210     assert(myStruct is null);
211 
212     // nothrow
213     myClass = cpp_trynew!TestCPPClass(42);
214     assert(myClass !is null);
215     assert(myClass.value == 42);
216     cpp_trydelete(myClass);
217     assert(myClass is null);
218 
219     myStruct = cpp_trynew!TestCPPStruct(42);
220     assert(myStruct !is null);
221     assert(myStruct.value == 42);
222     cpp_trydelete(myStruct);
223     assert(myStruct is null);
224 
225 }
226 
227 @("basic types")
228 unittest {
229     import numem.core.memory : nu_dup;
230 
231     string myString = "Hello, world!".nu_dup();
232     nogc_delete(myString);
233 }
234 
235 @("emplace disabled-postblit struct")
236 unittest {
237     __gshared N = 0;
238     static struct DisabledPostblit {
239     @nogc:
240         this(int a) { N += 1; }
241         ~this() { N += 2; }
242         @disable this(this);
243     }
244 
245     {
246         DisabledPostblit s;
247         nogc_construct(s, 1);
248     }
249     assert(N == 3);
250 }