1 /** 2 Custom versions of std.experimental.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 }