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