Remove resizeArray alias

This commit is contained in:
2017-03-19 06:10:27 +01:00
parent d0ada39fa7
commit b90c56395c
2 changed files with 423 additions and 430 deletions

View File

@ -23,59 +23,61 @@ public import tanya.memory.allocator;
*/
mixin template DefaultAllocator()
{
/// Allocator.
protected shared Allocator allocator_;
/// Allocator.
protected shared Allocator allocator_;
/**
* Params:
* allocator = The allocator should be used.
*/
this(shared Allocator allocator)
in
{
assert(allocator !is null);
}
body
{
this.allocator_ = allocator;
}
/**
* Params:
* allocator = The allocator should be used.
*
* Precondition: $(D_INLINECODE allocator_ !is null)
*/
this(shared Allocator allocator)
in
{
assert(allocator !is null);
}
body
{
this.allocator_ = allocator;
}
/**
* This property checks if the allocator was set in the constructor
* and sets it to the default one, if not.
*
* Returns: Used allocator.
*
* Postcondition: $(D_INLINECODE allocator_ !is null)
*/
protected @property shared(Allocator) allocator() nothrow @safe @nogc
out (allocator)
{
assert(allocator !is null);
}
body
{
if (allocator_ is null)
{
allocator_ = defaultAllocator;
}
return allocator_;
}
/**
* This property checks if the allocator was set in the constructor
* and sets it to the default one, if not.
*
* Returns: Used allocator.
*
* Postcondition: $(D_INLINECODE allocator !is null)
*/
protected @property shared(Allocator) allocator() nothrow @safe @nogc
out (allocator)
{
assert(allocator !is null);
}
body
{
if (allocator_ is null)
{
allocator_ = defaultAllocator;
}
return allocator_;
}
/// Ditto.
@property shared(Allocator) allocator() const nothrow @trusted @nogc
out (allocator)
{
assert(allocator !is null);
}
body
{
if (allocator_ is null)
{
return defaultAllocator;
}
return cast(shared Allocator) allocator_;
}
/// Ditto.
@property shared(Allocator) allocator() const nothrow @trusted @nogc
out (allocator)
{
assert(allocator !is null);
}
body
{
if (allocator_ is null)
{
return defaultAllocator;
}
return cast(shared Allocator) allocator_;
}
}
// From druntime
@ -85,28 +87,28 @@ shared Allocator allocator;
shared static this() nothrow @trusted @nogc
{
import tanya.memory.mmappool;
allocator = MmapPool.instance;
import tanya.memory.mmappool;
allocator = MmapPool.instance;
}
@property ref shared(Allocator) defaultAllocator() nothrow @safe @nogc
out (allocator)
{
assert(allocator !is null);
assert(allocator !is null);
}
body
{
return allocator;
return allocator;
}
@property void defaultAllocator(shared(Allocator) allocator) nothrow @safe @nogc
in
{
assert(allocator !is null);
assert(allocator !is null);
}
body
{
.allocator = allocator;
.allocator = allocator;
}
/**
@ -114,101 +116,92 @@ body
* object of type $(D_PARAM T).
*
* Params:
* T = Object type.
* T = Object type.
*/
template stateSize(T)
{
static if (is(T == class) || is(T == interface))
{
enum stateSize = __traits(classInstanceSize, T);
}
else
{
enum stateSize = T.sizeof;
}
static if (is(T == class) || is(T == interface))
{
enum stateSize = __traits(classInstanceSize, T);
}
else
{
enum stateSize = T.sizeof;
}
}
/**
* Params:
* size = Raw size.
* alignment = Alignment.
* size = Raw size.
* alignment = Alignment.
*
* Returns: Aligned size.
*/
size_t alignedSize(in size_t size, in size_t alignment = 8) pure nothrow @safe @nogc
{
return (size - 1) / alignment * alignment + alignment;
return (size - 1) / alignment * alignment + alignment;
}
/**
* Internal function used to create, resize or destroy a dynamic array. It
* throws $(D_PSYMBOL OutOfMemoryError) if $(D_PARAM Throws) is set. The new
* may throw $(D_PSYMBOL OutOfMemoryError). The new
* allocated part of the array is initialized only if $(D_PARAM Init)
* is set. This function can be trusted only in the data structures that
* can ensure that the array is allocated/rellocated/deallocated with the
* same allocator.
*
* Params:
* T = Element type of the array being created.
* Init = If should be initialized.
* Throws = If $(D_PSYMBOL OutOfMemoryError) should be throwsn.
* allocator = The allocator used for getting memory.
* array = A reference to the array being changed.
* length = New array length.
* T = Element type of the array being created.
* Init = If should be initialized.
* allocator = The allocator used for getting memory.
* array = A reference to the array being changed.
* length = New array length.
*
* Returns: $(D_KEYWORD true) upon success, $(D_KEYWORD false) if memory could
* not be reallocated. In the latter
* Returns: $(D_PARAM array).
*/
package(tanya) bool resize(T,
bool Init = true,
bool Throws = true)
(shared Allocator allocator,
ref T[] array,
in size_t length) @trusted
package(tanya) T[] resize(T,
bool Init = true)
(shared Allocator allocator,
auto ref T[] array,
const size_t length) @trusted
{
void[] buf = array;
static if (Init)
{
immutable oldLength = array.length;
}
if (!allocator.reallocate(buf, length * T.sizeof))
{
static if (Throws)
{
onOutOfMemoryError;
}
return false;
}
// Casting from void[] is unsafe, but we know we cast to the original type.
array = cast(T[]) buf;
void[] buf = array;
static if (Init)
{
const oldLength = array.length;
}
if (!allocator.reallocate(buf, length * T.sizeof))
{
onOutOfMemoryError;
}
// Casting from void[] is unsafe, but we know we cast to the original type.
array = cast(T[]) buf;
static if (Init)
{
if (oldLength < length)
{
array[oldLength .. $] = T.init;
}
}
return true;
static if (Init)
{
if (oldLength < length)
{
array[oldLength .. $] = T.init;
}
}
return array;
}
package(tanya) alias resizeArray = resize;
///
unittest
private unittest
{
int[] p;
int[] p;
defaultAllocator.resizeArray(p, 20);
assert(p.length == 20);
p = defaultAllocator.resize(p, 20);
assert(p.length == 20);
defaultAllocator.resizeArray(p, 30);
assert(p.length == 30);
p = defaultAllocator.resize(p, 30);
assert(p.length == 30);
defaultAllocator.resizeArray(p, 10);
assert(p.length == 10);
p = defaultAllocator.resize(p, 10);
assert(p.length == 10);
defaultAllocator.resizeArray(p, 0);
assert(p is null);
p = defaultAllocator.resize(p, 0);
assert(p is null);
}
/**
@ -217,101 +210,101 @@ unittest
* allocator.
*
* Params:
* T = Type of $(D_PARAM p).
* allocator = Allocator the $(D_PARAM p) was allocated with.
* p = Object or array to be destroyed.
* 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)
{
static if (hasElaborateDestructor!T)
{
destroy(*p);
}
() @trusted { allocator.deallocate((cast(void*) p)[0 .. T.sizeof]); }();
p = null;
static if (hasElaborateDestructor!T)
{
destroy(*p);
}
() @trusted { allocator.deallocate((cast(void*) p)[0 .. T.sizeof]); }();
p = null;
}
/// Ditto.
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)
{
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;
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];
scope (success)
{
() @trusted { allocator.deallocate(support); }();
p = null;
}
auto support = ptr[0 .. typeid(ob).initializer.length];
scope (success)
{
() @trusted { allocator.deallocate(support); }();
p = null;
}
auto ppv = cast(void**) ptr;
if (!*ppv)
{
return;
}
auto pc = cast(ClassInfo*) *ppv;
scope (exit)
{
*ppv = null;
}
auto ppv = cast(void**) ptr;
if (!*ppv)
{
return;
}
auto pc = cast(ClassInfo*) *ppv;
scope (exit)
{
*ppv = null;
}
auto c = *pc;
do
{
// Assume the destructor is @nogc. Leave it nothrow since the destructor
// shouldn't throw and if it does, it is an error anyway.
if (c.destructor)
{
(cast(void function (Object) nothrow @safe @nogc) c.destructor)(ob);
}
}
while ((c = c.base) !is null);
auto c = *pc;
do
{
// Assume the destructor is @nogc. Leave it nothrow since the destructor
// shouldn't throw and if it does, it is an error anyway.
if (c.destructor)
{
(cast(void function (Object) nothrow @safe @nogc) c.destructor)(ob);
}
}
while ((c = c.base) !is null);
if (ppv[1]) // if monitor is not null
{
_d_monitordelete(cast(Object) ptr, true);
}
if (ppv[1]) // if monitor is not null
{
_d_monitordelete(cast(Object) ptr, true);
}
}
/// Ditto.
void dispose(T)(shared Allocator allocator, auto ref T[] p)
{
static if (hasElaborateDestructor!(typeof(p[0])))
{
import std.algorithm.iteration;
p.each!(e => destroy(e));
}
() @trusted { allocator.deallocate(p); }();
p = null;
static if (hasElaborateDestructor!(typeof(p[0])))
{
import std.algorithm.iteration;
p.each!(e => destroy(e));
}
() @trusted { allocator.deallocate(p); }();
p = null;
}
unittest
{
struct S
{
~this()
{
}
}
auto p = cast(S[]) defaultAllocator.allocate(S.sizeof);
struct S
{
~this()
{
}
}
auto p = cast(S[]) defaultAllocator.allocate(S.sizeof);
defaultAllocator.dispose(p);
defaultAllocator.dispose(p);
}