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.smartref; 5 6 import tanya.memory.allocator; 7 import tanya.memory.smartref; 8 import tanya.meta.trait; 9 import tanya.test.stub; 10 11 @nogc @system unittest 12 { 13 auto rc = defaultAllocator.refCounted!int(5); 14 rc = defaultAllocator.make!int(7); 15 assert(*rc == 7); 16 } 17 18 @nogc @system unittest 19 { 20 RefCounted!int rc; 21 assert(!rc.isInitialized); 22 rc = null; 23 assert(!rc.isInitialized); 24 } 25 26 @nogc @system unittest 27 { 28 auto rc = defaultAllocator.refCounted!int(5); 29 30 void func(RefCounted!int param) @nogc 31 { 32 assert(param.count == 2); 33 param = defaultAllocator.make!int(7); 34 assert(param.count == 1); 35 assert(*param == 7); 36 } 37 func(rc); 38 assert(rc.count == 1); 39 assert(*rc == 5); 40 } 41 42 @nogc @system unittest 43 { 44 RefCounted!int rc; 45 46 void func(RefCounted!int param) @nogc 47 { 48 assert(param.count == 0); 49 param = defaultAllocator.make!int(7); 50 assert(param.count == 1); 51 assert(*param == 7); 52 } 53 func(rc); 54 assert(rc.count == 0); 55 } 56 57 @nogc @system unittest 58 { 59 RefCounted!int rc1, rc2; 60 static assert(is(typeof(rc1 = rc2))); 61 } 62 63 @nogc @system unittest 64 { 65 auto rc = RefCounted!int(defaultAllocator); 66 assert(!rc.isInitialized); 67 assert(rc.allocator is defaultAllocator); 68 } 69 70 @nogc @system unittest 71 { 72 auto rc = defaultAllocator.refCounted!int(5); 73 assert(rc.count == 1); 74 75 void func(RefCounted!int rc) @nogc 76 { 77 assert(rc.count == 2); 78 rc = null; 79 assert(!rc.isInitialized); 80 assert(rc.count == 0); 81 } 82 83 assert(rc.count == 1); 84 func(rc); 85 assert(rc.count == 1); 86 87 rc = null; 88 assert(!rc.isInitialized); 89 assert(rc.count == 0); 90 } 91 92 @nogc @system unittest 93 { 94 auto rc = defaultAllocator.refCounted!int(5); 95 assert(*rc == 5); 96 97 void func(RefCounted!int rc) @nogc 98 { 99 assert(rc.count == 2); 100 rc = defaultAllocator.refCounted!int(4); 101 assert(*rc == 4); 102 assert(rc.count == 1); 103 } 104 func(rc); 105 assert(*rc == 5); 106 } 107 108 @nogc @system unittest 109 { 110 auto rc = defaultAllocator.refCounted!(int[])(5); 111 assert(rc.length == 5); 112 } 113 114 @nogc @system unittest 115 { 116 auto p1 = defaultAllocator.make!int(5); 117 auto p2 = p1; 118 auto rc = RefCounted!int(p1, defaultAllocator); 119 assert(rc.get() is p2); 120 } 121 122 @nogc @system unittest 123 { 124 size_t destroyed; 125 { 126 auto rc = defaultAllocator.refCounted!WithDtor(destroyed); 127 } 128 assert(destroyed == 1); 129 } 130 131 @nogc nothrow pure @system unittest 132 { 133 auto s = defaultAllocator.unique!int(5); 134 assert(*s == 5); 135 136 s = null; 137 assert(s is null); 138 } 139 140 @nogc nothrow pure @system unittest 141 { 142 auto s = defaultAllocator.unique!int(5); 143 assert(*s == 5); 144 145 s = defaultAllocator.unique!int(4); 146 assert(*s == 4); 147 } 148 149 @nogc nothrow pure @system unittest 150 { 151 auto p1 = defaultAllocator.make!int(5); 152 auto p2 = p1; 153 154 auto rc = Unique!int(p1, defaultAllocator); 155 assert(rc.get() is p2); 156 } 157 158 @nogc nothrow pure @system unittest 159 { 160 auto rc = Unique!int(defaultAllocator); 161 assert(rc.allocator is defaultAllocator); 162 } 163 164 @nogc @system unittest 165 { 166 uint destroyed; 167 auto a = defaultAllocator.make!A(destroyed); 168 169 assert(destroyed == 0); 170 { 171 auto rc = RefCounted!A(a, defaultAllocator); 172 assert(rc.count == 1); 173 174 void func(RefCounted!A rc) @nogc @system 175 { 176 assert(rc.count == 2); 177 } 178 func(rc); 179 180 assert(rc.count == 1); 181 } 182 assert(destroyed == 1); 183 184 RefCounted!int rc; 185 assert(rc.count == 0); 186 rc = defaultAllocator.make!int(8); 187 assert(rc.count == 1); 188 } 189 190 @nogc nothrow pure @safe unittest 191 { 192 static assert(is(ReturnType!(RefCounted!int.get) == inout int*)); 193 static assert(is(ReturnType!(RefCounted!A.get) == inout A)); 194 static assert(is(ReturnType!(RefCounted!B.get) == inout B*)); 195 } 196 197 @nogc nothrow pure @safe unittest 198 { 199 static assert(is(RefCounted!B)); 200 static assert(is(RefCounted!A)); 201 } 202 203 @nogc @system unittest 204 { 205 struct E 206 { 207 } 208 auto b = defaultAllocator.refCounted!B(15); 209 static assert(is(typeof(b.prop) == int)); 210 static assert(!is(typeof(defaultAllocator.refCounted!B()))); 211 212 static assert(is(typeof(defaultAllocator.refCounted!E()))); 213 static assert(!is(typeof(defaultAllocator.refCounted!E(5)))); 214 { 215 auto rc = defaultAllocator.refCounted!B(3); 216 assert(rc.get().prop == 3); 217 } 218 { 219 auto rc = defaultAllocator.refCounted!E(); 220 assert(rc.count); 221 } 222 } 223 224 @nogc nothrow pure @safe unittest 225 { 226 static assert(is(typeof(defaultAllocator.unique!B(5)))); 227 static assert(is(typeof(defaultAllocator.unique!(int[])(5)))); 228 } 229 230 private class A 231 { 232 uint *destroyed; 233 234 this(ref uint destroyed) @nogc 235 { 236 this.destroyed = &destroyed; 237 } 238 239 ~this() @nogc 240 { 241 ++(*destroyed); 242 } 243 } 244 245 private struct B 246 { 247 int prop; 248 @disable this(); 249 this(int param1) @nogc 250 { 251 prop = param1; 252 } 253 }