Implement own dispose
This commit is contained in:
parent
f75433e0e6
commit
c8e6d44f7b
@ -898,7 +898,10 @@ struct Integer
|
||||
}
|
||||
|
||||
/**
|
||||
* Casting to boolean.
|
||||
* Casting.
|
||||
*
|
||||
* Params:
|
||||
* T = Target type.
|
||||
*
|
||||
* Returns: $(D_KEYWORD false) if the $(D_PSYMBOL Integer) is 0,
|
||||
* $(D_KEYWORD true) otherwise.
|
||||
@ -911,7 +914,10 @@ struct Integer
|
||||
/**
|
||||
* Casting to integer types.
|
||||
*
|
||||
* Returns: Integer type.
|
||||
* Params:
|
||||
* T = Target type.
|
||||
*
|
||||
* Returns: Signed integer.
|
||||
*/
|
||||
T opCast(T : long)() const// pure nothrow @safe @nogc
|
||||
{
|
||||
|
@ -10,11 +10,16 @@
|
||||
*/
|
||||
module tanya.memory;
|
||||
|
||||
import core.exception;
|
||||
import std.algorithm.mutation;
|
||||
public import std.experimental.allocator;
|
||||
public import std.experimental.allocator : make, makeArray, expandArray,
|
||||
stateSize, shrinkArray;
|
||||
import std.traits;
|
||||
public import tanya.memory.allocator;
|
||||
public import tanya.memory.types;
|
||||
|
||||
private extern (C) void _d_monitordelete(Object h, bool det) @nogc;
|
||||
|
||||
shared Allocator allocator;
|
||||
|
||||
shared static this() nothrow @safe @nogc
|
||||
@ -82,3 +87,117 @@ unittest
|
||||
defaultAllocator.resizeArray(p, 0);
|
||||
assert(p is null);
|
||||
}
|
||||
|
||||
private void deStruct(T)(ref T s)
|
||||
if (is(S == struct))
|
||||
{
|
||||
static if (__traits(hasMember, T, "__xdtor")
|
||||
&& __traits(isSame, T, __traits(parent, s.__xdtor)))
|
||||
{
|
||||
s.__xdtor();
|
||||
}
|
||||
auto buf = (cast(ubyte*) &s)[0 .. T.sizeof];
|
||||
auto init = cast(ubyte[])typeid(T).initializer();
|
||||
if (init.ptr is null) // null ptr means initialize to 0s
|
||||
{
|
||||
buf[] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
buf[] = init[];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys and deallocates $(D_PARAM p) of type $(D_PARAM T).
|
||||
* It is assumed the respective entities had been allocated with the same
|
||||
* allocator.
|
||||
*
|
||||
* Params:
|
||||
* T = Type of $(D_PARAM p).
|
||||
* allocator = Allocator the $(D_PARAM p) was allocated with.
|
||||
* p = Object or array to be destroyed.
|
||||
*/
|
||||
void dispose(T)(shared Allocator allocator, T* p)
|
||||
{
|
||||
static if (hasElaborateDestructor!T)
|
||||
{
|
||||
deStruct(*p);
|
||||
}
|
||||
allocator.deallocate((cast(void*) p)[0 .. T.sizeof]);
|
||||
}
|
||||
|
||||
/// Ditto.
|
||||
void dispose(T)(shared Allocator allocator, T p)
|
||||
if (is(T == class) || is(T == interface))
|
||||
{
|
||||
if (p is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
static if (is(T == interface))
|
||||
{
|
||||
version(Windows)
|
||||
{
|
||||
import core.sys.windows.unknwn : IUnknown;
|
||||
static assert(!is(T: IUnknown), "COM interfaces can't be destroyed in "
|
||||
~ __PRETTY_FUNCTION__);
|
||||
}
|
||||
auto ob = cast(Object) p;
|
||||
}
|
||||
else
|
||||
{
|
||||
alias ob = p;
|
||||
}
|
||||
auto ptr = cast(void *) ob;
|
||||
auto support = ptr[0 .. typeid(ob).initializer.length];
|
||||
|
||||
auto ppv = cast(void**) ptr;
|
||||
if (!*ppv)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto pc = cast(ClassInfo*) *ppv;
|
||||
try
|
||||
{
|
||||
auto c = *pc;
|
||||
do
|
||||
{
|
||||
if (c.destructor) // call destructor
|
||||
{
|
||||
(cast(void function (Object)) c.destructor)(cast(Object) ptr);
|
||||
}
|
||||
}
|
||||
while ((c = c.base) !is null);
|
||||
|
||||
if (ppv[1]) // if monitor is not null
|
||||
{
|
||||
_d_monitordelete(cast(Object) ptr, true);
|
||||
}
|
||||
auto w = (*pc).initializer;
|
||||
ptr[0 .. w.length] = w[];
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
onFinalizeError(*pc, e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
*ppv = null;
|
||||
}
|
||||
allocator.deallocate(support);
|
||||
}
|
||||
|
||||
/// Ditto.
|
||||
void dispose(T)(shared Allocator allocator, T[] array)
|
||||
{
|
||||
static if (hasElaborateDestructor!(typeof(array[0])))
|
||||
{
|
||||
foreach (ref e; array)
|
||||
{
|
||||
deStruct(e);
|
||||
}
|
||||
}
|
||||
allocator.deallocate(array);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user