From b90c56395cb8a3c4cabde4acc7654dd9ceffc87e Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Sun, 19 Mar 2017 06:10:27 +0100 Subject: [PATCH] Remove resizeArray alias --- source/tanya/math/random.d | 474 +++++++++++++++++----------------- source/tanya/memory/package.d | 379 +++++++++++++-------------- 2 files changed, 423 insertions(+), 430 deletions(-) diff --git a/source/tanya/math/random.d b/source/tanya/math/random.d index e58d209..76295f7 100644 --- a/source/tanya/math/random.d +++ b/source/tanya/math/random.d @@ -8,8 +8,8 @@ * Copyright: Eugene Wissner 2016. * License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/, * Mozilla Public License, v. 2.0). - * Authors: $(LINK2 mailto:belka@caraus.de, Eugene Wissner) - */ + * Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner) + */ module tanya.math.random; import std.digest.sha; @@ -27,20 +27,20 @@ enum maxGather = 128; */ class EntropyException : Exception { - /** - * Params: - * msg = Message to output. - * 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, - string file = __FILE__, - size_t line = __LINE__, - Throwable next = null) pure @safe nothrow const @nogc - { - super(msg, file, line, next); - } + /** + * Params: + * msg = Message to output. + * 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, + string file = __FILE__, + size_t line = __LINE__, + Throwable next = null) pure @safe nothrow const @nogc + { + super(msg, file, line, next); + } } /** @@ -48,103 +48,103 @@ class EntropyException : Exception */ abstract class EntropySource { - /// Amount of already generated entropy. - protected ushort size_; + /// Amount of already generated entropy. + protected ushort size_; - /** - * Returns: Minimum bytes required from the entropy source. - */ - @property immutable(ubyte) threshold() const @safe pure nothrow; + /** + * Returns: Minimum bytes required from the entropy source. + */ + @property immutable(ubyte) threshold() const @safe pure nothrow; - /** - * Returns: Whether this entropy source is strong. - */ - @property immutable(bool) strong() const @safe pure nothrow; + /** + * Returns: Whether this entropy source is strong. + */ + @property immutable(bool) strong() const @safe pure nothrow; - /** - * Returns: Amount of already generated entropy. - */ - @property ushort size() const @safe pure nothrow - { - return size_; - } + /** + * Returns: Amount of already generated entropy. + */ + @property ushort size() const @safe pure nothrow + { + return size_; + } - /** - * Params: - * size = Amount of already generated entropy. Cannot be smaller than the - * already set value. - */ - @property void size(ushort size) @safe pure nothrow - { - size_ = size; - } + /** + * Params: + * size = Amount of already generated entropy. Cannot be smaller than the + * already set value. + */ + @property void size(ushort size) @safe pure nothrow + { + size_ = size; + } - /** - * Poll the entropy source. - * - * Params: - * output = Buffer to save the generate random sequence (the method will - * to fill the buffer). - * - * Returns: Number of bytes that were copied to the $(D_PARAM output) - * or $(D_PSYMBOL Nullable!ubyte.init) on error. - */ - Nullable!ubyte poll(out ubyte[maxGather] output); + /** + * Poll the entropy source. + * + * Params: + * output = Buffer to save the generate random sequence (the method will + * to fill the buffer). + * + * Returns: Number of bytes that were copied to the $(D_PARAM output) + * or $(D_PSYMBOL Nullable!ubyte.init) on error. + */ + Nullable!ubyte poll(out ubyte[maxGather] output); } version (linux) { - extern (C) long syscall(long number, ...) nothrow; + extern (C) long syscall(long number, ...) nothrow; - /** - * Uses getrandom system call. - */ - class PlatformEntropySource : EntropySource - { - /** - * Returns: Minimum bytes required from the entropy source. - */ - override @property immutable(ubyte) threshold() const @safe pure nothrow - { - return 32; - } + /** + * Uses getrandom system call. + */ + class PlatformEntropySource : EntropySource + { + /** + * Returns: Minimum bytes required from the entropy source. + */ + override @property immutable(ubyte) threshold() const @safe pure nothrow + { + return 32; + } - /** - * Returns: Whether this entropy source is strong. - */ - override @property immutable(bool) strong() const @safe pure nothrow - { - return true; - } + /** + * Returns: Whether this entropy source is strong. + */ + override @property immutable(bool) strong() const @safe pure nothrow + { + return true; + } - /** - * Poll the entropy source. - * - * Params: - * output = Buffer to save the generate random sequence (the method will - * to fill the buffer). - * - * Returns: Number of bytes that were copied to the $(D_PARAM output) - * or $(D_PSYMBOL Nullable!ubyte.init) on error. - */ - override Nullable!ubyte poll(out ubyte[maxGather] output) nothrow - out (length) - { - assert(length <= maxGather); - } - body - { - // int getrandom(void *buf, size_t buflen, unsigned int flags); - auto length = syscall(318, output.ptr, output.length, 0); - Nullable!ubyte ret; + /** + * Poll the entropy source. + * + * Params: + * output = Buffer to save the generate random sequence (the method will + * to fill the buffer). + * + * Returns: Number of bytes that were copied to the $(D_PARAM output) + * or $(D_PSYMBOL Nullable!ubyte.init) on error. + */ + override Nullable!ubyte poll(out ubyte[maxGather] output) nothrow + out (length) + { + assert(length <= maxGather); + } + body + { + // int getrandom(void *buf, size_t buflen, unsigned int flags); + auto length = syscall(318, output.ptr, output.length, 0); + Nullable!ubyte ret; - if (length >= 0) - { - ret = cast(ubyte) length; - } - return ret; - } - } + if (length >= 0) + { + ret = cast(ubyte) length; + } + return ret; + } + } } /** @@ -156,165 +156,165 @@ version (linux) * * output = entropy.random; * - * defaultAllocator.finalize(entropy); + * defaultAllocator.dispose(entropy); * --- */ class Entropy { - /// Entropy sources. - protected EntropySource[] sources; + /// Entropy sources. + protected EntropySource[] sources; - private ubyte sourceCount_; + private ubyte sourceCount_; - private shared Allocator allocator; + private shared Allocator allocator; - /// Entropy accumulator. - protected SHA!(maxGather * 8, 512) accumulator; + /// Entropy accumulator. + protected SHA!(maxGather * 8, 512) accumulator; - /** - * Params: - * maxSources = Maximum amount of entropy sources can be set. - * allocator = Allocator to allocate entropy sources available on the - * system. - */ - this(size_t maxSources = 20, shared Allocator allocator = defaultAllocator) - in - { - assert(maxSources > 0 && maxSources <= ubyte.max); - assert(allocator !is null); - } - body - { - allocator.resizeArray(sources, maxSources); + /** + * Params: + * maxSources = Maximum amount of entropy sources can be set. + * allocator = Allocator to allocate entropy sources available on the + * system. + */ + this(size_t maxSources = 20, shared Allocator allocator = defaultAllocator) + in + { + assert(maxSources > 0 && maxSources <= ubyte.max); + assert(allocator !is null); + } + body + { + allocator.resize(sources, maxSources); - version (linux) - { - this ~= allocator.make!PlatformEntropySource; - } - } + version (linux) + { + this ~= allocator.make!PlatformEntropySource; + } + } - /** - * Returns: Amount of the registered entropy sources. - */ - @property ubyte sourceCount() const @safe pure nothrow - { - return sourceCount_; - } + /** + * Returns: Amount of the registered entropy sources. + */ + @property ubyte sourceCount() const @safe pure nothrow + { + return sourceCount_; + } - /** - * Add an entropy source. - * - * Params: - * source = Entropy source. - * - * Returns: $(D_PSYMBOL this). - * - * See_Also: - * $(D_PSYMBOL EntropySource) - */ - Entropy opOpAssign(string Op)(EntropySource source) @safe pure nothrow - if (Op == "~") - in - { - assert(sourceCount_ <= sources.length); - } - body - { - sources[sourceCount_++] = source; - return this; - } + /** + * Add an entropy source. + * + * Params: + * source = Entropy source. + * + * Returns: $(D_PSYMBOL this). + * + * See_Also: + * $(D_PSYMBOL EntropySource) + */ + Entropy opOpAssign(string Op)(EntropySource source) @safe pure nothrow + if (Op == "~") + in + { + assert(sourceCount_ <= sources.length); + } + body + { + sources[sourceCount_++] = source; + return this; + } - /** - * Returns: Generated random sequence. - * - * Throws: $(D_PSYMBOL EntropyException) if no strong entropy source was - * registered or it failed. - */ - @property ubyte[blockSize] random() - in - { - assert(sourceCount_ > 0, "No entropy sources defined."); - } - body - { - bool haveStrong; - ushort done; - ubyte[blockSize] output; + /** + * Returns: Generated random sequence. + * + * Throws: $(D_PSYMBOL EntropyException) if no strong entropy source was + * registered or it failed. + */ + @property ubyte[blockSize] random() + in + { + assert(sourceCount_ > 0, "No entropy sources defined."); + } + body + { + bool haveStrong; + ushort done; + ubyte[blockSize] output; - do - { - ubyte[maxGather] buffer; + do + { + ubyte[maxGather] buffer; - // Run through our entropy sources - for (ubyte i; i < sourceCount; ++i) - { - auto outputLength = sources[i].poll(buffer); + // Run through our entropy sources + for (ubyte i; i < sourceCount; ++i) + { + auto outputLength = sources[i].poll(buffer); - if (!outputLength.isNull) - { - if (outputLength > 0) - { - update(i, buffer, outputLength); - sources[i].size = cast(ushort) (sources[i].size + outputLength); - } - if (sources[i].size < sources[i].threshold) - { - continue; - } - else if (sources[i].strong) - { - haveStrong = true; - } - } - done = 257; - } - } - while (++done < 256); + if (!outputLength.isNull) + { + if (outputLength > 0) + { + update(i, buffer, outputLength); + sources[i].size = cast(ushort) (sources[i].size + outputLength); + } + if (sources[i].size < sources[i].threshold) + { + continue; + } + else if (sources[i].strong) + { + haveStrong = true; + } + } + done = 257; + } + } + while (++done < 256); - if (!haveStrong) - { - throw allocator.make!EntropyException("No strong entropy source defined."); - } + if (!haveStrong) + { + throw allocator.make!EntropyException("No strong entropy source defined."); + } - output = accumulator.finish(); + output = accumulator.finish(); - // Reset accumulator and counters and recycle existing entropy - accumulator.start(); + // Reset accumulator and counters and recycle existing entropy + accumulator.start(); - // Perform second SHA-512 on entropy - output = sha512Of(output); + // Perform second SHA-512 on entropy + output = sha512Of(output); - for (ubyte i = 0; i < sourceCount; ++i) - { - sources[i].size = 0; - } - return output; - } + for (ubyte i = 0; i < sourceCount; ++i) + { + sources[i].size = 0; + } + return output; + } - /** - * Update entropy accumulator. - * - * Params: - * sourceId = Entropy source index in $(D_PSYMBOL sources). - * data = Data got from the entropy source. - * length = Length of the received data. - */ - protected void update(in ubyte sourceId, - ref ubyte[maxGather] data, - ubyte length) @safe pure nothrow - { - ubyte[2] header; + /** + * Update entropy accumulator. + * + * Params: + * sourceId = Entropy source index in $(D_PSYMBOL sources). + * data = Data got from the entropy source. + * length = Length of the received data. + */ + protected void update(in ubyte sourceId, + ref ubyte[maxGather] data, + ubyte length) @safe pure nothrow + { + ubyte[2] header; - if (length > blockSize) - { - data[0..64] = sha512Of(data); - length = blockSize; - } + if (length > blockSize) + { + data[0..64] = sha512Of(data); + length = blockSize; + } - header[0] = sourceId; - header[1] = length; + header[0] = sourceId; + header[1] = length; - accumulator.put(header); - accumulator.put(data[0..length]); - } + accumulator.put(header); + accumulator.put(data[0..length]); + } } diff --git a/source/tanya/memory/package.d b/source/tanya/memory/package.d index 9ecb45b..da53ecf 100644 --- a/source/tanya/memory/package.d +++ b/source/tanya/memory/package.d @@ -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); }