Add internal finalize method for finalizing an object without deallocating
This commit is contained in:
parent
8156d0fe3a
commit
7aa9ac9f4a
@ -11,6 +11,7 @@
|
|||||||
module tanya.memory;
|
module tanya.memory;
|
||||||
|
|
||||||
import core.exception;
|
import core.exception;
|
||||||
|
import std.algorithm.iteration;
|
||||||
public import std.experimental.allocator : make;
|
public import std.experimental.allocator : make;
|
||||||
import std.traits;
|
import std.traits;
|
||||||
public import tanya.memory.allocator;
|
public import tanya.memory.allocator;
|
||||||
@ -87,8 +88,8 @@ shared Allocator allocator;
|
|||||||
|
|
||||||
shared static this() nothrow @trusted @nogc
|
shared static this() nothrow @trusted @nogc
|
||||||
{
|
{
|
||||||
import tanya.memory.mallocator;
|
import tanya.memory.mmappool;
|
||||||
allocator = Mallocator.instance;
|
allocator = MmapPool.instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
@property ref shared(Allocator) defaultAllocator() nothrow @safe @nogc
|
@property ref shared(Allocator) defaultAllocator() nothrow @safe @nogc
|
||||||
@ -202,41 +203,33 @@ private unittest
|
|||||||
assert(p is null);
|
assert(p is null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* Destroys and deallocates $(D_PARAM p) of type $(D_PARAM T).
|
* Destroys the object.
|
||||||
* It is assumed the respective entities had been allocated with the same
|
* Returns the memory should be freed.
|
||||||
* 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, auto ref T* p)
|
package(tanya) void[] finalize(T)(ref T* p)
|
||||||
{
|
{
|
||||||
static if (hasElaborateDestructor!T)
|
static if (hasElaborateDestructor!T)
|
||||||
{
|
{
|
||||||
destroy(*p);
|
destroy(*p);
|
||||||
}
|
}
|
||||||
() @trusted { allocator.deallocate((cast(void*) p)[0 .. T.sizeof]); }();
|
return (cast(void*) p)[0 .. T.sizeof];
|
||||||
p = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Ditto.
|
package(tanya) void[] finalize(T)(ref T p)
|
||||||
void dispose(T)(shared Allocator allocator, auto ref T p)
|
|
||||||
if (is(T == class) || is(T == interface))
|
if (is(T == class) || is(T == interface))
|
||||||
{
|
{
|
||||||
if (p is null)
|
if (p is null)
|
||||||
{
|
{
|
||||||
return;
|
return null;
|
||||||
}
|
}
|
||||||
static if (is(T == interface))
|
static if (is(T == interface))
|
||||||
{
|
{
|
||||||
version(Windows)
|
version(Windows)
|
||||||
{
|
{
|
||||||
import core.sys.windows.unknwn : IUnknown;
|
import core.sys.windows.unknwn : IUnknown;
|
||||||
static assert(!is(T: IUnknown), "COM interfaces can't be destroyed in "
|
static assert(!is(T : IUnknown), "COM interfaces can't be destroyed in "
|
||||||
~ __PRETTY_FUNCTION__);
|
~ __PRETTY_FUNCTION__);
|
||||||
}
|
}
|
||||||
auto ob = cast(Object) p;
|
auto ob = cast(Object) p;
|
||||||
}
|
}
|
||||||
@ -244,19 +237,13 @@ void dispose(T)(shared Allocator allocator, auto ref T p)
|
|||||||
{
|
{
|
||||||
alias ob = p;
|
alias ob = p;
|
||||||
}
|
}
|
||||||
auto ptr = cast(void *) ob;
|
auto ptr = cast(void*) ob;
|
||||||
|
|
||||||
auto support = ptr[0 .. typeid(ob).initializer.length];
|
auto support = ptr[0 .. typeid(ob).initializer.length];
|
||||||
scope (success)
|
|
||||||
{
|
|
||||||
() @trusted { allocator.deallocate(support); }();
|
|
||||||
p = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto ppv = cast(void**) ptr;
|
auto ppv = cast(void**) ptr;
|
||||||
if (!*ppv)
|
if (!*ppv)
|
||||||
{
|
{
|
||||||
return;
|
return null;
|
||||||
}
|
}
|
||||||
auto pc = cast(ClassInfo*) *ppv;
|
auto pc = cast(ClassInfo*) *ppv;
|
||||||
scope (exit)
|
scope (exit)
|
||||||
@ -280,21 +267,35 @@ void dispose(T)(shared Allocator allocator, auto ref T p)
|
|||||||
{
|
{
|
||||||
_d_monitordelete(cast(Object) ptr, true);
|
_d_monitordelete(cast(Object) ptr, true);
|
||||||
}
|
}
|
||||||
|
return support;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Ditto.
|
package(tanya) void[] finalize(T)(ref T[] p)
|
||||||
void dispose(T)(shared Allocator allocator, auto ref T[] p)
|
|
||||||
{
|
{
|
||||||
static if (hasElaborateDestructor!(typeof(p[0])))
|
static if (hasElaborateDestructor!(typeof(p[0])))
|
||||||
{
|
{
|
||||||
import std.algorithm.iteration;
|
p.each!((ref e) => destroy(e));
|
||||||
p.each!(e => destroy(e));
|
|
||||||
}
|
}
|
||||||
() @trusted { allocator.deallocate(p); }();
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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, auto ref T p)
|
||||||
|
{
|
||||||
|
() @trusted { allocator.deallocate(finalize(p)); }();
|
||||||
p = null;
|
p = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
unittest
|
private unittest
|
||||||
{
|
{
|
||||||
struct S
|
struct S
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user