1 /** 2 Custom versions of stdx.allocator functions (unfortunately) 3 */ 4 module automem.allocator; 5 6 import automem.utils: destruct; 7 8 /** 9 10 Destroys and then deallocates (using $(D alloc)) the object pointed to by a 11 pointer, the class object referred to by a $(D class) or $(D interface) 12 reference, or an entire array. It is assumed the respective entities had been 13 allocated with the same allocator. 14 15 */ 16 void dispose(A, T)(auto ref A alloc, T* p) 17 { 18 import std.traits: hasElaborateDestructor; 19 20 static if (hasElaborateDestructor!T) 21 { 22 destruct(*p); 23 } 24 alloc.deallocate((cast(void*) p)[0 .. T.sizeof]); 25 } 26 27 /// Ditto 28 void dispose(A, T)(auto ref A alloc, T p) 29 if (is(T == class) || is(T == interface)) 30 { 31 32 if (!p) return; 33 static if (is(T == interface)) 34 { 35 version(Windows) 36 { 37 import core.sys.windows.unknwn : IUnknown; 38 static assert(!is(T: IUnknown), "COM interfaces can't be destroyed in " 39 ~ __PRETTY_FUNCTION__); 40 } 41 auto ob = cast(Object) p; 42 } 43 else 44 alias ob = p; 45 auto support = (cast(void*) ob)[0 .. typeid(ob).initializer.length]; 46 47 destruct(p); 48 49 alloc.deallocate(support); 50 } 51 52 /// Ditto 53 void dispose(A, T)(auto ref A alloc, T[] array) 54 { 55 import std.traits: hasElaborateDestructor; 56 57 static if (hasElaborateDestructor!(typeof(array[0]))) 58 { 59 foreach (ref e; array) 60 { 61 destruct(e); 62 } 63 } 64 alloc.deallocate(array); 65 } 66 67 /// 68 @system unittest 69 { 70 71 import stdx.allocator: theAllocator, make, makeArray; 72 73 static int x; 74 static interface I 75 { 76 void method(); 77 } 78 static class A : I 79 { 80 int y; 81 override void method() { x = 21; } 82 ~this() { x = 42; } 83 } 84 static class B : A 85 { 86 } 87 auto a = theAllocator.make!A; 88 a.method(); 89 assert(x == 21); 90 theAllocator.dispose(a); 91 assert(x == 42); 92 93 B b = theAllocator.make!B; 94 b.method(); 95 assert(x == 21); 96 theAllocator.dispose(b); 97 assert(x == 42); 98 99 I i = theAllocator.make!B; 100 i.method(); 101 assert(x == 21); 102 theAllocator.dispose(i); 103 assert(x == 42); 104 105 int[] arr = theAllocator.makeArray!int(43); 106 theAllocator.dispose(arr); 107 } 108 109 /// 110 @system unittest //bugzilla 15721 111 { 112 import stdx.allocator: make; 113 import stdx.allocator.mallocator : Mallocator; 114 115 interface Foo {} 116 class Bar: Foo {} 117 118 Bar bar; 119 Foo foo; 120 bar = Mallocator.instance.make!Bar; 121 foo = cast(Foo) bar; 122 Mallocator.instance.dispose(foo); 123 }