summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2019-03-16 10:35:28 +0100
committerEugen Wissner <belka@caraus.de>2019-03-16 10:35:28 +0100
commit85d7a2b9ca122301bc1ba9e6167f7533cbd1b2e4 (patch)
treeb2552e8fa4d81ada8aa85ad2fe9b94c7e58a2629
parentb458c6a38097d6165edf52f84176a5178d053ac9 (diff)
downloadtanya-85d7a2b9ca122301bc1ba9e6167f7533cbd1b2e4.tar.gz
Move memory exception into memory.lifecycle
-rw-r--r--README.md1
-rw-r--r--source/tanya/container/array.d3
-rw-r--r--source/tanya/container/buffer.d2
-rw-r--r--source/tanya/container/entry.d2
-rw-r--r--source/tanya/container/hashtable.d2
-rw-r--r--source/tanya/container/list.d2
-rw-r--r--source/tanya/container/package.d2
-rw-r--r--source/tanya/container/set.d2
-rw-r--r--source/tanya/container/string.d2
-rw-r--r--source/tanya/exception.d58
-rw-r--r--source/tanya/memory/allocator.d2
-rw-r--r--source/tanya/memory/lifecycle.d360
-rw-r--r--source/tanya/memory/mallocator.d5
-rw-r--r--source/tanya/memory/mmappool.d3
-rw-r--r--source/tanya/memory/op.d2
-rw-r--r--source/tanya/memory/package.d309
-rw-r--r--source/tanya/memory/smartref.d4
17 files changed, 381 insertions, 380 deletions
diff --git a/README.md b/README.md
index 93fadf1..e22215c 100644
--- a/README.md
+++ b/README.md
@@ -31,7 +31,6 @@ string, Set, Hash table.
* `conv`: This module provides functions for converting between different
types.
* `encoding`: This package provides tools to work with text encodings.
-* `exception`: Common exceptions and errors.
* `format`: Formatting and conversion functions.
* `functional`: Functions that manipulate other functions and their argument
lists.
diff --git a/source/tanya/container/array.d b/source/tanya/container/array.d
index 2b7a2b8..2b3adfa 100644
--- a/source/tanya/container/array.d
+++ b/source/tanya/container/array.d
@@ -5,7 +5,7 @@
/**
* Single-dimensioned array.
*
- * Copyright: Eugene Wissner 2016-2018.
+ * Copyright: Eugene Wissner 2016-2019.
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
* Mozilla Public License, v. 2.0).
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
@@ -17,7 +17,6 @@ module tanya.container.array;
import core.checkedint;
import tanya.algorithm.comparison;
import tanya.algorithm.mutation;
-import tanya.exception;
import tanya.functional;
import tanya.memory;
import tanya.meta.trait;
diff --git a/source/tanya/container/buffer.d b/source/tanya/container/buffer.d
index 4866ca7..b2eeb74 100644
--- a/source/tanya/container/buffer.d
+++ b/source/tanya/container/buffer.d
@@ -5,7 +5,7 @@
/**
* This module contains buffers designed for C-style input/output APIs.
*
- * Copyright: Eugene Wissner 2016-2018.
+ * Copyright: Eugene Wissner 2016-2019.
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
* Mozilla Public License, v. 2.0).
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
diff --git a/source/tanya/container/entry.d b/source/tanya/container/entry.d
index e976cc3..1e7e28f 100644
--- a/source/tanya/container/entry.d
+++ b/source/tanya/container/entry.d
@@ -5,7 +5,7 @@
/*
* Internal package used by containers that rely on entries/nodes.
*
- * Copyright: Eugene Wissner 2016-2018.
+ * Copyright: Eugene Wissner 2016-2019.
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
* Mozilla Public License, v. 2.0).
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
diff --git a/source/tanya/container/hashtable.d b/source/tanya/container/hashtable.d
index b80d220..3571f63 100644
--- a/source/tanya/container/hashtable.d
+++ b/source/tanya/container/hashtable.d
@@ -5,7 +5,7 @@
/**
* Hash table.
*
- * Copyright: Eugene Wissner 2018.
+ * Copyright: Eugene Wissner 2018-2019.
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
* Mozilla Public License, v. 2.0).
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
diff --git a/source/tanya/container/list.d b/source/tanya/container/list.d
index 39edf06..09a5c9f 100644
--- a/source/tanya/container/list.d
+++ b/source/tanya/container/list.d
@@ -6,7 +6,7 @@
* This module contains singly-linked ($(D_PSYMBOL SList)) and doubly-linked
* ($(D_PSYMBOL DList)) lists.
*
- * Copyright: Eugene Wissner 2016-2018.
+ * Copyright: Eugene Wissner 2016-2019.
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
* Mozilla Public License, v. 2.0).
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
diff --git a/source/tanya/container/package.d b/source/tanya/container/package.d
index 783c5d0..1919b39 100644
--- a/source/tanya/container/package.d
+++ b/source/tanya/container/package.d
@@ -5,7 +5,7 @@
/**
* Abstract data types whose instances are collections of other objects.
*
- * Copyright: Eugene Wissner 2016-2018.
+ * Copyright: Eugene Wissner 2016-2019.
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
* Mozilla Public License, v. 2.0).
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
diff --git a/source/tanya/container/set.d b/source/tanya/container/set.d
index b95950b..b06ef91 100644
--- a/source/tanya/container/set.d
+++ b/source/tanya/container/set.d
@@ -6,7 +6,7 @@
* This module implements a $(D_PSYMBOL Set) container that stores unique
* values without any particular order.
*
- * Copyright: Eugene Wissner 2017-2018.
+ * Copyright: Eugene Wissner 2017-2019.
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
* Mozilla Public License, v. 2.0).
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
diff --git a/source/tanya/container/string.d b/source/tanya/container/string.d
index abe60e1..2a50dc6 100644
--- a/source/tanya/container/string.d
+++ b/source/tanya/container/string.d
@@ -17,7 +17,7 @@
* Internally $(D_PSYMBOL String) is represented by a sequence of
* $(D_KEYWORD char)s.
*
- * Copyright: Eugene Wissner 2017-2018.
+ * Copyright: Eugene Wissner 2017-2019.
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
* Mozilla Public License, v. 2.0).
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
diff --git a/source/tanya/exception.d b/source/tanya/exception.d
index 936e4a7..49a2d40 100644
--- a/source/tanya/exception.d
+++ b/source/tanya/exception.d
@@ -2,65 +2,15 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/**
- * Common exceptions and errors.
- *
- * Copyright: Eugene Wissner 2017-2018.
+/*
+ * Copyright: Eugene Wissner 2017-2019.
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
* Mozilla Public License, v. 2.0).
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
* Source: $(LINK2 https://github.com/caraus-ecms/tanya/blob/master/source/tanya/exception.d,
* tanya/exception.d)
*/
+deprecated("Use tanya.memory.lifecycle instead")
module tanya.exception;
-import tanya.conv;
-import tanya.memory;
-
-/**
- * Error thrown if memory allocation fails.
- */
-final class OutOfMemoryError : Error
-{
- /**
- * Constructs new error.
- *
- * Params:
- * msg = The message for the exception.
- * file = The file where the exception occurred.
- * line = The line number where the exception occurred.
- * next = The previous exception in the chain of exceptions, if any.
- */
- this(string msg = "Out of memory",
- string file = __FILE__,
- size_t line = __LINE__,
- Throwable next = null) @nogc nothrow pure @safe
- {
- super(msg, file, line, next);
- }
-
- /// ditto
- this(string msg,
- Throwable next,
- string file = __FILE__,
- size_t line = __LINE__) @nogc nothrow pure @safe
- {
- super(msg, file, line, next);
- }
-}
-
-/**
- * Allocates $(D_PSYMBOL OutOfMemoryError) in a static storage and throws it.
- *
- * Params:
- * msg = Custom error message.
- *
- * Throws: $(D_PSYMBOL OutOfMemoryError).
- */
-void onOutOfMemoryError(string msg = "Out of memory")
-@nogc nothrow pure @trusted
-{
- static ubyte[stateSize!OutOfMemoryError] memory;
- alias PureType = OutOfMemoryError function(string) @nogc nothrow pure;
- throw (cast(PureType) () => emplace!OutOfMemoryError(memory))(msg);
-}
+public import tanya.memory.lifecycle : onOutOfMemoryError, OutOfMemoryError;
diff --git a/source/tanya/memory/allocator.d b/source/tanya/memory/allocator.d
index 1d8139d..3d05a37 100644
--- a/source/tanya/memory/allocator.d
+++ b/source/tanya/memory/allocator.d
@@ -8,7 +8,7 @@
* Allocators are classes encapsulating memory allocation strategy. This allows
* to decouple memory management from the algorithms and the data.
*
- * Copyright: Eugene Wissner 2016-2018.
+ * Copyright: Eugene Wissner 2016-2019.
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
* Mozilla Public License, v. 2.0).
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
diff --git a/source/tanya/memory/lifecycle.d b/source/tanya/memory/lifecycle.d
new file mode 100644
index 0000000..2221af3
--- /dev/null
+++ b/source/tanya/memory/lifecycle.d
@@ -0,0 +1,360 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/**
+ * Lifecycle management functions, types and related exceptions.
+ *
+ * Copyright: Eugene Wissner 2019.
+ * License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
+ * Mozilla Public License, v. 2.0).
+ * Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
+ * Source: $(LINK2 https://github.com/caraus-ecms/tanya/blob/master/source/tanya/memory/init.d,
+ * tanya/memory/init.d)
+ */
+module tanya.memory.lifecycle;
+
+import tanya.algorithm.mutation;
+import tanya.conv;
+import tanya.memory;
+import tanya.meta.trait;
+import tanya.range.primitive;
+
+/**
+ * Error thrown if memory allocation fails.
+ */
+final class OutOfMemoryError : Error
+{
+ /**
+ * Constructs new error.
+ *
+ * Params:
+ * msg = The message for the exception.
+ * file = The file where the exception occurred.
+ * line = The line number where the exception occurred.
+ * next = The previous exception in the chain of exceptions, if any.
+ */
+ this(string msg = "Out of memory",
+ string file = __FILE__,
+ size_t line = __LINE__,
+ Throwable next = null) @nogc nothrow pure @safe
+ {
+ super(msg, file, line, next);
+ }
+
+ /// ditto
+ this(string msg,
+ Throwable next,
+ string file = __FILE__,
+ size_t line = __LINE__) @nogc nothrow pure @safe
+ {
+ super(msg, file, line, next);
+ }
+}
+
+/**
+ * Allocates $(D_PSYMBOL OutOfMemoryError) in a static storage and throws it.
+ *
+ * Params:
+ * msg = Custom error message.
+ *
+ * Throws: $(D_PSYMBOL OutOfMemoryError).
+ */
+void onOutOfMemoryError(string msg = "Out of memory")
+@nogc nothrow pure @trusted
+{
+ static ubyte[stateSize!OutOfMemoryError] memory;
+ alias PureType = OutOfMemoryError function(string) @nogc nothrow pure;
+ throw (cast(PureType) () => emplace!OutOfMemoryError(memory))(msg);
+}
+
+// From druntime
+extern (C)
+private void _d_monitordelete(Object h, bool det) @nogc nothrow pure;
+
+/*
+ * Internal function used to create, resize or destroy a dynamic array. It
+ * may throw $(D_PSYMBOL OutOfMemoryError). The new
+ * allocated part of the array isn't initialized. 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.
+ * allocator = The allocator used for getting memory.
+ * array = A reference to the array being changed.
+ * length = New array length.
+ *
+ * Returns: $(D_PARAM array).
+ */
+package(tanya) T[] resize(T)(shared Allocator allocator,
+ auto ref T[] array,
+ const size_t length) @trusted
+{
+ if (length == 0)
+ {
+ if (allocator.deallocate(array))
+ {
+ return null;
+ }
+ else
+ {
+ onOutOfMemoryError();
+ }
+ }
+
+ void[] buf = array;
+ 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;
+
+ return array;
+}
+
+@nogc nothrow pure @safe unittest
+{
+ int[] p;
+
+ p = defaultAllocator.resize(p, 20);
+ assert(p.length == 20);
+
+ p = defaultAllocator.resize(p, 30);
+ assert(p.length == 30);
+
+ p = defaultAllocator.resize(p, 10);
+ assert(p.length == 10);
+
+ p = defaultAllocator.resize(p, 0);
+ assert(p is null);
+}
+
+/*
+ * Destroys the object.
+ * Returns the memory should be freed.
+ */
+package(tanya) void[] finalize(T)(ref T* p)
+{
+ if (p is null)
+ {
+ return null;
+ }
+ static if (hasElaborateDestructor!T)
+ {
+ destroy(*p);
+ }
+ return (cast(void*) p)[0 .. T.sizeof];
+}
+
+package(tanya) void[] finalize(T)(ref T p)
+if (isPolymorphicType!T)
+{
+ if (p is null)
+ {
+ return null;
+ }
+ 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 null;
+ }
+ 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)
+ {
+ alias DtorType = void function(Object) pure nothrow @safe @nogc;
+ (cast(DtorType) c.destructor)(ob);
+ }
+ }
+ while ((c = c.base) !is null);
+
+ if (ppv[1]) // if monitor is not null
+ {
+ _d_monitordelete(cast(Object) ptr, true);
+ }
+ return support;
+}
+
+package(tanya) void[] finalize(T)(ref T[] p)
+{
+ destroyAll(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;
+}
+
+@nogc nothrow pure @system unittest
+{
+ static struct S
+ {
+ ~this() @nogc nothrow pure @safe
+ {
+ }
+ }
+ auto p = cast(S[]) defaultAllocator.allocate(S.sizeof);
+
+ defaultAllocator.dispose(p);
+}
+
+// Works with interfaces.
+@nogc nothrow pure @safe unittest
+{
+ interface I
+ {
+ }
+ class C : I
+ {
+ }
+ auto c = defaultAllocator.make!C();
+ I i = c;
+
+ 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 (allocator !is null)
+{
+ auto mem = (() @trusted => allocator.allocate(stateSize!T))();
+ if (mem is null)
+ {
+ onOutOfMemoryError();
+ }
+ scope (failure)
+ {
+ () @trusted { allocator.deallocate(mem); }();
+ }
+
+ return emplace!T(mem[0 .. stateSize!T], args);
+}
+
+/**
+ * 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 (allocator !is null)
+{
+ auto mem = (() @trusted => allocator.allocate(stateSize!T))();
+ if (mem is null)
+ {
+ onOutOfMemoryError();
+ }
+ scope (failure)
+ {
+ () @trusted { allocator.deallocate(mem); }();
+ }
+ return emplace!T(mem[0 .. stateSize!T], args);
+}
+
+///
+@nogc nothrow pure @safe unittest
+{
+ int* i = defaultAllocator.make!int(5);
+ assert(*i == 5);
+ defaultAllocator.dispose(i);
+}
+
+/**
+ * Constructs a new array with $(D_PARAM n) elements.
+ *
+ * Params:
+ * T = Array type.
+ * allocator = Allocator.
+ * n = 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 (allocator !is null)
+in (n <= size_t.max / ElementType!T.sizeof)
+{
+ auto ret = allocator.resize!(ElementType!T)(null, n);
+ ret.uninitializedFill(ElementType!T.init);
+ return ret;
+}
+
+///
+@nogc nothrow pure @safe 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/mallocator.d b/source/tanya/memory/mallocator.d
index f7379e8..fdf7ede 100644
--- a/source/tanya/memory/mallocator.d
+++ b/source/tanya/memory/mallocator.d
@@ -3,9 +3,10 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
- * Allocator based on $(D_PSYMBOL malloc), $(D_PSYMBOL realloc) and $(D_PSYMBOL free).
+ * Allocator based on $(D_PSYMBOL malloc), $(D_PSYMBOL realloc) and
+ * $(D_PSYMBOL free).
*
- * Copyright: Eugene Wissner 2017-2018.
+ * Copyright: Eugene Wissner 2017-2019.
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
* Mozilla Public License, v. 2.0).
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
diff --git a/source/tanya/memory/mmappool.d b/source/tanya/memory/mmappool.d
index fb3ef06..5c42241 100644
--- a/source/tanya/memory/mmappool.d
+++ b/source/tanya/memory/mmappool.d
@@ -5,7 +5,7 @@
/*
* Native allocator.
*
- * Copyright: Eugene Wissner 2016-2018.
+ * Copyright: Eugene Wissner 2016-2019.
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
* Mozilla Public License, v. 2.0).
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
@@ -17,7 +17,6 @@ module tanya.memory.mmappool;
version (TanyaNative):
import mir.linux._asm.unistd;
-import tanya.algorithm.comparison;
import tanya.memory.allocator;
import tanya.memory.op;
import tanya.os.error;
diff --git a/source/tanya/memory/op.d b/source/tanya/memory/op.d
index 6df7dd3..6005329 100644
--- a/source/tanya/memory/op.d
+++ b/source/tanya/memory/op.d
@@ -5,7 +5,7 @@
/**
* Set of operations on memory blocks.
*
- * Copyright: Eugene Wissner 2017-2018.
+ * Copyright: Eugene Wissner 2017-2019.
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
* Mozilla Public License, v. 2.0).
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
diff --git a/source/tanya/memory/package.d b/source/tanya/memory/package.d
index 77dc388..8526b5a 100644
--- a/source/tanya/memory/package.d
+++ b/source/tanya/memory/package.d
@@ -5,7 +5,7 @@
/**
* Dynamic memory management.
*
- * Copyright: Eugene Wissner 2016-2018.
+ * Copyright: Eugene Wissner 2016-2019.
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
* Mozilla Public License, v. 2.0).
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
@@ -14,12 +14,10 @@
*/
module tanya.memory;
-import tanya.algorithm.mutation;
import tanya.conv;
-import tanya.exception;
public import tanya.memory.allocator;
+public import tanya.memory.lifecycle;
import tanya.meta.trait;
-import tanya.range.primitive;
/**
* The mixin generates common methods for classes and structs using
@@ -86,10 +84,6 @@ mixin template DefaultAllocator()
}
}
-// From druntime
-extern (C)
-private void _d_monitordelete(Object h, bool det) @nogc nothrow pure;
-
shared Allocator allocator;
private shared(Allocator) getAllocatorInstance() @nogc nothrow
@@ -207,302 +201,3 @@ pure nothrow @safe @nogc
{
return (size - 1) / alignment * alignment + alignment;
}
-
-/*
- * Internal function used to create, resize or destroy a dynamic array. It
- * may throw $(D_PSYMBOL OutOfMemoryError). The new
- * allocated part of the array isn't initialized. 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.
- * allocator = The allocator used for getting memory.
- * array = A reference to the array being changed.
- * length = New array length.
- *
- * Returns: $(D_PARAM array).
- */
-package(tanya) T[] resize(T)(shared Allocator allocator,
- auto ref T[] array,
- const size_t length) @trusted
-{
- if (length == 0)
- {
- if (allocator.deallocate(array))
- {
- return null;
- }
- else
- {
- onOutOfMemoryError();
- }
- }
-
- void[] buf = array;
- 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;
-
- return array;
-}
-
-@nogc nothrow pure @safe unittest
-{
- int[] p;
-
- p = defaultAllocator.resize(p, 20);
- assert(p.length == 20);
-
- p = defaultAllocator.resize(p, 30);
- assert(p.length == 30);
-
- p = defaultAllocator.resize(p, 10);
- assert(p.length == 10);
-
- p = defaultAllocator.resize(p, 0);
- assert(p is null);
-}
-
-/*
- * Destroys the object.
- * Returns the memory should be freed.
- */
-package(tanya) void[] finalize(T)(ref T* p)
-{
- if (p is null)
- {
- return null;
- }
- static if (hasElaborateDestructor!T)
- {
- destroy(*p);
- }
- return (cast(void*) p)[0 .. T.sizeof];
-}
-
-package(tanya) void[] finalize(T)(ref T p)
-if (isPolymorphicType!T)
-{
- if (p is null)
- {
- return null;
- }
- 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 null;
- }
- 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)
- {
- alias DtorType = void function(Object) pure nothrow @safe @nogc;
- (cast(DtorType) c.destructor)(ob);
- }
- }
- while ((c = c.base) !is null);
-
- if (ppv[1]) // if monitor is not null
- {
- _d_monitordelete(cast(Object) ptr, true);
- }
- return support;
-}
-
-package(tanya) void[] finalize(T)(ref T[] p)
-{
- destroyAll(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;
-}
-
-@nogc nothrow pure @system unittest
-{
- static struct S
- {
- ~this() @nogc nothrow pure @safe
- {
- }
- }
- auto p = cast(S[]) defaultAllocator.allocate(S.sizeof);
-
- defaultAllocator.dispose(p);
-}
-
-// Works with interfaces.
-@nogc nothrow pure @safe unittest
-{
- interface I
- {
- }
- class C : I
- {
- }
- auto c = defaultAllocator.make!C();
- I i = c;
-
- 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);
-}
-do
-{
- auto mem = (() @trusted => allocator.allocate(stateSize!T))();
- if (mem is null)
- {
- onOutOfMemoryError();
- }
- scope (failure)
- {
- () @trusted { allocator.deallocate(mem); }();
- }
-
- return emplace!T(mem[0 .. stateSize!T], args);
-}
-
-/**
- * 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);
-}
-do
-{
- auto mem = (() @trusted => allocator.allocate(stateSize!T))();
- if (mem is null)
- {
- onOutOfMemoryError();
- }
- scope (failure)
- {
- () @trusted { allocator.deallocate(mem); }();
- }
- return emplace!T(mem[0 .. stateSize!T], args);
-}
-
-///
-@nogc nothrow pure @safe unittest
-{
- int* i = defaultAllocator.make!int(5);
- assert(*i == 5);
- defaultAllocator.dispose(i);
-}
-
-/**
- * Constructs a new array with $(D_PARAM n) elements.
- *
- * Params:
- * T = Array type.
- * allocator = Allocator.
- * n = 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);
-}
-do
-{
- auto ret = allocator.resize!(ElementType!T)(null, n);
- ret.uninitializedFill(ElementType!T.init);
- return ret;
-}
-
-///
-@nogc nothrow pure @safe 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 020627d..90271e7 100644
--- a/source/tanya/memory/smartref.d
+++ b/source/tanya/memory/smartref.d
@@ -14,7 +14,7 @@
* $(LI Unique ownership)
* )
*
- * Copyright: Eugene Wissner 2016-2018.
+ * Copyright: Eugene Wissner 2016-2019.
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
* Mozilla Public License, v. 2.0).
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
@@ -23,10 +23,8 @@
*/
module tanya.memory.smartref;
-import tanya.algorithm.comparison;
import tanya.algorithm.mutation;
import tanya.conv;
-import tanya.exception;
import tanya.memory;
import tanya.meta.trait;
import tanya.range.primitive;