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 }