summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/tanya/memory/package.d133
-rw-r--r--source/tanya/memory/smartref.d5
2 files changed, 134 insertions, 4 deletions
diff --git a/source/tanya/memory/package.d b/source/tanya/memory/package.d
index eef28e4..a9491fe 100644
--- a/source/tanya/memory/package.d
+++ b/source/tanya/memory/package.d
@@ -14,7 +14,9 @@ module tanya.memory;
import core.exception;
import std.algorithm.iteration;
-public import std.experimental.allocator : make;
+import std.algorithm.mutation;
+import std.conv;
+import std.range;
import std.traits;
public import tanya.memory.allocator;
import tanya.memory.mmappool;
@@ -356,3 +358,132 @@ private pure unittest
defaultAllocator.dispose(i);
defaultAllocator.dispose(i);
}
+
+/**
+ * Constructs a new class instance of type $(D_PARAM T) using $(D_PARAM args)
+ * as the parameter list for the constructor of $(D_PARAM T).
+ *
+ * Params:
+ * T = Class type.
+ * A = Types of the arguments to the constructor of $(D_PARAM T).
+ * allocator = Allocator.
+ * args = Constructor arguments of $(D_PARAM T).
+ *
+ * Returns: Newly created $(D_PSYMBOL T).
+ *
+ * Precondition: $(D_INLINECODE allocator !is null)
+ */
+T make(T, A...)(shared Allocator allocator, auto ref A args)
+if (is(T == class))
+in
+{
+ assert(allocator !is null);
+}
+body
+{
+ T ret;
+ const size = stateSize!T;
+
+ auto mem = (() @trusted => allocator.allocate(size))();
+ if (mem is null)
+ {
+ onOutOfMemoryError();
+ }
+ scope (failure)
+ {
+ () @trusted { allocator.deallocate(mem); }();
+ }
+
+ ret = emplace!T(mem[0 .. size], args);
+
+ return ret;
+}
+
+/**
+ * Constructs a value object of type $(D_PARAM T) using $(D_PARAM args)
+ * as the parameter list for the constructor of $(D_PARAM T) and returns a
+ * pointer to the new object.
+ *
+ * Params:
+ * T = Object type.
+ * A = Types of the arguments to the constructor of $(D_PARAM T).
+ * allocator = Allocator.
+ * args = Constructor arguments of $(D_PARAM T).
+ *
+ * Returns: Pointer to the created object.
+ *
+ * Precondition: $(D_INLINECODE allocator !is null)
+ */
+T* make(T, A...)(shared Allocator allocator, auto ref A args)
+if (!is(T == interface)
+ && !is(T == class)
+ && !isAssociativeArray!T
+ && !isArray!T)
+in
+{
+ assert(allocator !is null);
+}
+body
+{
+ typeof(return) ret;
+ const size = stateSize!T;
+
+ auto mem = (() @trusted => allocator.allocate(size))();
+ if (mem is null)
+ {
+ onOutOfMemoryError();
+ }
+ scope (failure)
+ {
+ () @trusted { allocator.deallocate(mem); }();
+ }
+
+ auto ptr = (() @trusted => (cast(T*) mem[0 .. size].ptr))();
+ ret = emplace!T(ptr, args);
+
+ return ret;
+}
+
+///
+unittest
+{
+ int* i = defaultAllocator.make!int(5);
+ assert(*i == 5);
+ defaultAllocator.dispose(i);
+}
+
+/**
+ * Constructs a new array with $(D_PARAM size) elements.
+ *
+ * Params:
+ * T = Array type.
+ * allocator = Allocator.
+ * size = Array size.
+ *
+ * Returns: Newly created array.
+ *
+ * Precondition: $(D_INLINECODE allocator !is null
+ * && n <= size_t.max / ElementType!T.sizeof)
+ */
+T make(T)(shared Allocator allocator, const size_t n)
+if (isArray!T)
+in
+{
+ assert(allocator !is null);
+ assert(n <= size_t.max / ElementType!T.sizeof);
+}
+body
+{
+ auto ret = allocator.resize!(ElementType!T)(null, n);
+ ret.uninitializedFill(ElementType!T.init);
+ return ret;
+}
+
+///
+unittest
+{
+ int[] i = defaultAllocator.make!(int[])(2);
+ assert(i.length == 2);
+ assert(i[0] == int.init && i[1] == int.init);
+ defaultAllocator.dispose(i);
+}
diff --git a/source/tanya/memory/smartref.d b/source/tanya/memory/smartref.d
index 87aaa45..4b89e4f 100644
--- a/source/tanya/memory/smartref.d
+++ b/source/tanya/memory/smartref.d
@@ -548,8 +548,7 @@ in
}
body
{
- auto payload = allocator.resize!(ElementType!T)(null, size);
- return RefCounted!T(payload, allocator);
+ return RefCounted!T(allocator.make!T(size), allocator);
}
///
@@ -852,7 +851,7 @@ in
}
body
{
- auto payload = allocator.make!(T, shared Allocator, A)(args);
+ auto payload = allocator.make!(T, A)(args);
return Unique!T(payload, allocator);
}