1 module ut; 2 3 public import unit_threaded; 4 public import test_allocator: TestAllocator; 5 6 mixin template TestUtils() { 7 import unit_threaded; 8 import test_allocator; 9 10 /** 11 Returns an object that, while in scope, replaces whatever 12 theAllocator was with TestAllocator. 13 */ 14 auto theTestAllocator() { 15 static struct Context { 16 import stdx.allocator: theAllocator; 17 18 TestAllocator testAllocator; 19 typeof(theAllocator) oldAllocator; 20 21 static auto create() { 22 import stdx.allocator: allocatorObject; 23 24 Context ctx; 25 26 ctx.oldAllocator = theAllocator; 27 theAllocator = allocatorObject(ctx.testAllocator); 28 29 return ctx; 30 } 31 32 ~this() { 33 import stdx.allocator: dispose; 34 35 // 2.079.0 changed the API - we check here 36 static if(__traits(compiles, testAllocator.dispose(theAllocator))) 37 testAllocator.dispose(theAllocator); 38 39 theAllocator = oldAllocator; 40 } 41 } 42 43 return Context.create; 44 } 45 46 @Setup 47 void before() { 48 } 49 50 @Shutdown 51 void after() { 52 reset; 53 } 54 55 void reset() { 56 Struct.numStructs = 0; 57 Class.numClasses = 0; 58 SharedStruct.numStructs = 0; 59 NoGcStruct.numStructs = 0; 60 } 61 62 63 void _writelnUt(T...)(T args) { 64 try { 65 () @trusted { writelnUt(args); }(); 66 } catch(Exception ex) { 67 assert(false); 68 } 69 } 70 71 private struct Struct { 72 int i; 73 static int numStructs = 0; 74 75 this(int i) @safe nothrow { 76 this.i = i; 77 78 ++numStructs; 79 _writelnUt("Struct ", &this, " normal ctor, i=", i, ", N=", numStructs); 80 } 81 82 this(this) @safe nothrow { 83 ++numStructs; 84 _writelnUt("Struct ", &this, " postBlit ctor, i=", i, ", N=", numStructs); 85 } 86 87 ~this() @safe nothrow const { 88 --numStructs; 89 _writelnUt("Struct ", &this, " dtor, i=", i, ", N=", numStructs); 90 } 91 92 int twice() @safe pure const nothrow { 93 return i * 2; 94 } 95 } 96 97 private struct SharedStruct { 98 int i; 99 static int numStructs = 0; 100 101 this(int i) @safe nothrow shared { 102 this.i = i; 103 104 ++numStructs; 105 try () @trusted { 106 _writelnUt("Struct normal ctor ", &this, ", i=", i, ", N=", numStructs); 107 }(); 108 catch(Exception ex) {} 109 } 110 111 this(this) @safe nothrow shared { 112 ++numStructs; 113 try () @trusted { 114 _writelnUt("Struct postBlit ctor ", &this, ", i=", i, ", N=", numStructs); 115 }(); 116 catch(Exception ex) {} 117 } 118 119 ~this() @safe nothrow { 120 --numStructs; 121 try () @trusted { _writelnUt("Struct dtor ", &this, ", i=", i, ", N=", numStructs); }(); 122 catch(Exception ex) {} 123 } 124 125 int twice() @safe pure const nothrow shared { 126 return i * 2; 127 } 128 } 129 130 private class Class { 131 int i; 132 static int numClasses = 0; 133 134 this(int i) @safe nothrow { 135 this.i = i; 136 ++numClasses; 137 } 138 139 ~this() @safe nothrow { 140 --numClasses; 141 } 142 143 int twice() @safe pure const nothrow { 144 return i * 2; 145 } 146 } 147 148 private struct SafeAllocator { 149 150 import stdx.allocator.mallocator: Mallocator; 151 152 void[] allocate(this T)(size_t i) @trusted nothrow @nogc { 153 return Mallocator.instance.allocate(i); 154 } 155 156 void deallocate(this T)(void[] bytes) @trusted nothrow @nogc { 157 Mallocator.instance.deallocate(bytes); 158 } 159 } 160 161 private struct NoGcStruct { 162 int i; 163 164 static int numStructs = 0; 165 166 this(int i) @safe @nogc nothrow { 167 this.i = i; 168 169 ++numStructs; 170 } 171 172 this(this) @safe @nogc nothrow { 173 ++numStructs; 174 } 175 176 ~this() @safe @nogc nothrow { 177 --numStructs; 178 } 179 180 } 181 182 private class NoGcClass { 183 int i; 184 static int numClasses = 0; 185 186 this(int i) @safe @nogc nothrow { 187 this.i = i; 188 ++numClasses; 189 } 190 191 ~this() @safe @nogc nothrow { 192 --numClasses; 193 } 194 } 195 196 private struct SharedStructWithIndirection { 197 string s; 198 this(string s) shared { 199 this.s = s; 200 } 201 } 202 }