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;
|
||||
|
||||
import core.exception;
|
||||
import std.algorithm.iteration;
|
||||
public import std.experimental.allocator : make;
|
||||
import std.traits;
|
||||
public import tanya.memory.allocator;
|
||||
@ -87,8 +88,8 @@ shared Allocator allocator;
|
||||
|
||||
shared static this() nothrow @trusted @nogc
|
||||
{
|
||||
import tanya.memory.mallocator;
|
||||
allocator = Mallocator.instance;
|
||||
import tanya.memory.mmappool;
|
||||
allocator = MmapPool.instance;
|
||||
}
|
||||
|
||||
@property ref shared(Allocator) defaultAllocator() nothrow @safe @nogc
|
||||
@ -202,33 +203,25 @@ private unittest
|
||||
assert(p is null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
/*
|
||||
* Destroys the object.
|
||||
* Returns the memory should be freed.
|
||||
*/
|
||||
void dispose(T)(shared Allocator allocator, auto ref T* p)
|
||||
package(tanya) void[] finalize(T)(ref T* p)
|
||||
{
|
||||
static if (hasElaborateDestructor!T)
|
||||
{
|
||||
destroy(*p);
|
||||
}
|
||||
() @trusted { allocator.deallocate((cast(void*) p)[0 .. T.sizeof]); }();
|
||||
p = null;
|
||||
return (cast(void*) p)[0 .. T.sizeof];
|
||||
}
|
||||
|
||||
/// Ditto.
|
||||
void dispose(T)(shared Allocator allocator, auto ref T p)
|
||||
package(tanya) void[] finalize(T)(ref T p)
|
||||
if (is(T == class) || is(T == interface))
|
||||
{
|
||||
if (p is null)
|
||||
{
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
static if (is(T == interface))
|
||||
{
|
||||
@ -245,18 +238,12 @@ void dispose(T)(shared Allocator allocator, auto ref T p)
|
||||
alias ob = p;
|
||||
}
|
||||
auto ptr = cast(void*) ob;
|
||||
|
||||
auto support = ptr[0 .. typeid(ob).initializer.length];
|
||||
scope (success)
|
||||
{
|
||||
() @trusted { allocator.deallocate(support); }();
|
||||
p = null;
|
||||
}
|
||||
|
||||
auto ppv = cast(void**) ptr;
|
||||
if (!*ppv)
|
||||
{
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
auto pc = cast(ClassInfo*) *ppv;
|
||||
scope (exit)
|
||||
@ -280,21 +267,35 @@ void dispose(T)(shared Allocator allocator, auto ref T p)
|
||||
{
|
||||
_d_monitordelete(cast(Object) ptr, true);
|
||||
}
|
||||
return support;
|
||||
}
|
||||
|
||||
/// Ditto.
|
||||
void dispose(T)(shared Allocator allocator, auto ref T[] p)
|
||||
package(tanya) void[] finalize(T)(ref T[] p)
|
||||
{
|
||||
static if (hasElaborateDestructor!(typeof(p[0])))
|
||||
{
|
||||
import std.algorithm.iteration;
|
||||
p.each!(e => destroy(e));
|
||||
p.each!((ref 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;
|
||||
}
|
||||
|
||||
unittest
|
||||
private unittest
|
||||
{
|
||||
struct S
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user