From 484cb13317921c78468dc3f9c16a0fc786b119c0 Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Mon, 18 Mar 2019 13:03:52 +0100 Subject: [PATCH] Separate non-documentation tests from the code --- .travis.yml | 8 +- appveyor.yml | 3 +- dub.json | 17 +- meta/tanya/meta/metafunction.d | 24 -- meta/tanya/meta/trait.d | 165 ---------- meta/tanya/meta/transform.d | 47 --- {memory => middle}/dub.json | 8 +- {memory => middle}/tanya/memory/allocator.d | 2 +- .../tanya/memory/lifetime.d | 179 +---------- {memory => middle}/tanya/memory/mallocator.d | 17 +- {memory => middle}/tanya/memory/mmappool.d | 156 +--------- {memory => middle}/tanya/memory/op.d | 64 +--- {memory => middle}/tanya/memory/package.d | 4 +- {memory => middle}/tanya/memory/smartref.d | 291 +----------------- os/tanya/os/error.d | 6 - source/tanya/algorithm/iteration.d | 2 +- source/tanya/algorithm/mutation.d | 20 +- source/tanya/container/entry.d | 2 +- source/tanya/conv.d | 4 +- source/tanya/exception.d | 4 +- source/tanya/functional.d | 4 +- source/tanya/math/mp.d | 2 +- source/tanya/math/nbtheory.d | 2 +- source/tanya/math/package.d | 3 +- source/tanya/math/random.d | 3 +- source/tanya/net/ip.d | 2 +- source/tanya/range/adapter.d | 2 +- source/tanya/range/array.d | 24 +- source/tanya/range/primitive.d | 2 +- source/tanya/typecons.d | 2 +- test/dub.json | 16 + {memory => test}/tanya/test/assertion.d | 0 {memory => test}/tanya/test/package.d | 0 {memory => test}/tanya/test/stub.d | 0 tests/tanya/memory/tests/lifetime.d | 173 +++++++++++ tests/tanya/memory/tests/mallocator.d | 23 ++ tests/tanya/memory/tests/mmappool.d | 159 ++++++++++ tests/tanya/memory/tests/op.d | 64 ++++ tests/tanya/memory/tests/smartref.d | 250 +++++++++++++++ tests/tanya/meta/tests/metafunction.d | 27 ++ tests/tanya/meta/tests/trait.d | 169 ++++++++++ tests/tanya/meta/tests/transform.d | 50 +++ tests/tanya/os/tests/error.d | 9 + 43 files changed, 1020 insertions(+), 989 deletions(-) rename {memory => middle}/dub.json (56%) rename {memory => middle}/tanya/memory/allocator.d (98%) rename memory/tanya/memory/lifecycle.d => middle/tanya/memory/lifetime.d (85%) rename {memory => middle}/tanya/memory/mallocator.d (92%) rename {memory => middle}/tanya/memory/mmappool.d (77%) rename {memory => middle}/tanya/memory/op.d (87%) rename {memory => middle}/tanya/memory/package.d (97%) rename {memory => middle}/tanya/memory/smartref.d (73%) create mode 100644 test/dub.json rename {memory => test}/tanya/test/assertion.d (100%) rename {memory => test}/tanya/test/package.d (100%) rename {memory => test}/tanya/test/stub.d (100%) create mode 100644 tests/tanya/memory/tests/lifetime.d create mode 100644 tests/tanya/memory/tests/mallocator.d create mode 100644 tests/tanya/memory/tests/mmappool.d create mode 100644 tests/tanya/memory/tests/op.d create mode 100644 tests/tanya/memory/tests/smartref.d create mode 100644 tests/tanya/meta/tests/metafunction.d create mode 100644 tests/tanya/meta/tests/trait.d create mode 100644 tests/tanya/meta/tests/transform.d create mode 100644 tests/tanya/os/tests/error.d diff --git a/.travis.yml b/.travis.yml index ee8283f..682306a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -53,19 +53,21 @@ script: dub build :sys -b ddox --compiler=$DC; dub build :os -b ddox --compiler=$DC; dub build :encoding -b ddox --compiler=$DC; - dub build :memory -b ddox --compiler=$DC; + dub build :middle -b ddox --compiler=$DC; + dub build :test -b ddox --compiler=$DC; dub build -b ddox --compiler=$DC; elif [ -z "$DSCANNER" ]; then dub test :meta -b ${UNITTEST:-unittest} --arch=$ARCH --compiler=$DC; dub test :sys -b ${UNITTEST:-unittest} --arch=$ARCH --compiler=$DC; dub test :os -b ${UNITTEST:-unittest} --arch=$ARCH --compiler=$DC; dub test :encoding -b ${UNITTEST:-unittest} --arch=$ARCH --compiler=$DC; - dub test :memory -b ${UNITTEST:-unittest} --arch=$ARCH --compiler=$DC; + dub test :middle -b ${UNITTEST:-unittest} --arch=$ARCH --compiler=$DC; + dub test :test -b ${UNITTEST:-unittest} --arch=$ARCH --compiler=$DC; dub test -b ${UNITTEST:-unittest} --arch=$ARCH --compiler=$DC; else dub fetch dscanner --version=$DSCANNER; - FILES=$(find source */source -type f); + FILES=$(find */tanya -type f); dub run dscanner -- --styleCheck $FILES; fi diff --git a/appveyor.yml b/appveyor.yml index dc0e5e8..4e0072e 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -61,5 +61,6 @@ test_script: - dub test :sys -b unittest --arch=%Darch% --compiler=%DC% - dub test :os -b unittest --arch=%Darch% --compiler=%DC% - dub test :encoding -b unittest --arch=%Darch% --compiler=%DC% - - dub test :memory -b unittest --arch=%Darch% --compiler=%DC% + - dub test :middle -b unittest --arch=%Darch% --compiler=%DC% + - dub test :test -b unittest --arch=%Darch% --compiler=%DC% - dub test -b unittest --arch=%Darch% --compiler=%DC% diff --git a/dub.json b/dub.json index 3fd1ec6..9883955 100644 --- a/dub.json +++ b/dub.json @@ -14,7 +14,8 @@ "tanya:sys": "*", "tanya:os": "*", "tanya:encoding": "*", - "tanya:memory": "*" + "tanya:middle": "*", + "tanya:test": "*" }, "dependencies-linux": { @@ -26,7 +27,8 @@ "./sys", "./os", "./encoding", - "./memory" + "./middle", + "./test" ], "configurations": [ @@ -47,6 +49,17 @@ "preBuildCommands": ["ninja -C arch"], "lflags": ["arch/tanya.a"], "versions": ["TanyaNative"] + }, + { + "name": "unittest", + "importPaths": [ + "./source", + "./tests" + ], + "sourcePaths": [ + "./source", + "./tests" + ] } ], diff --git a/meta/tanya/meta/metafunction.d b/meta/tanya/meta/metafunction.d index a05b5cf..8ccafbc 100644 --- a/meta/tanya/meta/metafunction.d +++ b/meta/tanya/meta/metafunction.d @@ -1129,30 +1129,6 @@ if (__traits(isTemplate, cmp)) static assert(!isSorted!(cmp, long, byte, ubyte, short, uint)); } -@nogc nothrow pure @safe unittest -{ - enum cmp(int x, int y) = x - y; - static assert(isSorted!(cmp)); - static assert(isSorted!(cmp, 1)); - static assert(isSorted!(cmp, 1, 2, 2)); - static assert(isSorted!(cmp, 1, 2, 2, 4)); - static assert(isSorted!(cmp, 1, 2, 2, 4, 8)); - static assert(!isSorted!(cmp, 32, 2, 2, 4, 8)); - static assert(isSorted!(cmp, 32, 32)); -} - -@nogc nothrow pure @safe unittest -{ - enum cmp(int x, int y) = x < y; - static assert(isSorted!(cmp)); - static assert(isSorted!(cmp, 1)); - static assert(isSorted!(cmp, 1, 2, 2)); - static assert(isSorted!(cmp, 1, 2, 2, 4)); - static assert(isSorted!(cmp, 1, 2, 2, 4, 8)); - static assert(!isSorted!(cmp, 32, 2, 2, 4, 8)); - static assert(isSorted!(cmp, 32, 32)); -} - /** * Params: * T = A template. diff --git a/meta/tanya/meta/trait.d b/meta/tanya/meta/trait.d index ebea9ce..ae83f24 100644 --- a/meta/tanya/meta/trait.d +++ b/meta/tanya/meta/trait.d @@ -549,19 +549,6 @@ template isPointer(T) static assert(!isPointer!bool); } -// typeof(null) is not a pointer. -@nogc nothrow pure @safe unittest -{ - static assert(!isPointer!(typeof(null))); - static assert(!isPointer!(const shared typeof(null))); - - enum typeOfNull : typeof(null) - { - null_ = null, - } - static assert(!isPointer!typeOfNull); -} - /** * Determines whether $(D_PARAM T) is an array type (dynamic or static, but * not an associative one). @@ -1478,20 +1465,6 @@ if (F.length == 1) static assert(!isCallable!I); } -@nogc nothrow pure @safe unittest -{ - static struct S - { - @property int opCall() - { - return 0; - } - } - S s; - static assert(isCallable!S); - static assert(isCallable!s); -} - /** * Determines whether $(D_PARAM T) defines a symbol $(D_PARAM member). * @@ -1676,63 +1649,6 @@ if (isCallable!F) static assert(is(FunctionTypeOf!(() {}) == function)); } -@nogc nothrow pure @safe unittest -{ - static assert(is(FunctionTypeOf!(void delegate()) == function)); - - static void staticFunc() - { - } - auto functionPointer = &staticFunc; - static assert(is(FunctionTypeOf!staticFunc == function)); - static assert(is(FunctionTypeOf!functionPointer == function)); - - void func() - { - } - auto dg = &func; - static assert(is(FunctionTypeOf!func == function)); - static assert(is(FunctionTypeOf!dg == function)); - - interface I - { - @property int prop(); - } - static assert(is(FunctionTypeOf!(I.prop) == function)); - - static struct S - { - void opCall() - { - } - } - class C - { - static void opCall() - { - } - } - S s; - - static assert(is(FunctionTypeOf!s == function)); - static assert(is(FunctionTypeOf!C == function)); - static assert(is(FunctionTypeOf!S == function)); -} - -@nogc nothrow pure @safe unittest -{ - static struct S2 - { - @property int opCall() - { - return 0; - } - } - S2 s2; - static assert(is(FunctionTypeOf!S2 == function)); - static assert(is(FunctionTypeOf!s2 == function)); -} - /** * Determines the return type of the callable $(D_PARAM F). * @@ -2552,44 +2468,6 @@ template hasElaborateAssign(T) } } -@nogc nothrow pure @safe unittest -{ - static assert(!hasElaborateAssign!int); - - static struct S1 - { - void opAssign(S1) - { - } - } - static struct S2 - { - void opAssign(int) - { - } - } - static struct S3 - { - S1 s; - alias s this; - } - static assert(hasElaborateAssign!S1); - static assert(!hasElaborateAssign!(const S1)); - static assert(hasElaborateAssign!(S1[1])); - static assert(!hasElaborateAssign!(S1[0])); - static assert(!hasElaborateAssign!S2); - static assert(hasElaborateAssign!S3); - - static struct S4 - { - void opAssign(S4) - { - } - @disable this(this); - } - static assert(hasElaborateAssign!S4); -} - /** * Returns all members of $(D_KEYWORD enum) $(D_PARAM T). * @@ -2642,16 +2520,6 @@ if (is(T == enum)) static assert([EnumMembers!E] == [E.one, E.two, E.three]); } -// Produces a tuple for an enum with only one member -@nogc nothrow pure @safe unittest -{ - enum E : int - { - one = 0, - } - static assert(EnumMembers!E == AliasSeq!0); -} - /** * Different than $(D_INLINECODE T.alignof), which is the same for all class * types, $(D_PSYMBOL classInstanceOf) determines the alignment of the class @@ -2996,14 +2864,6 @@ template isInnerClass(T) static assert(!isInnerClass!(O.Fake)); } -@nogc nothrow pure @safe unittest -{ - class RefCountedStore(T) - { - } - static assert(!isInnerClass!(RefCountedStore!int)); -} - /** * Returns the types of all members of $(D_PARAM T). * @@ -3131,28 +2991,3 @@ enum bool isOrderingComparable(T) = ifTestable!(T, a => a > a); { static assert(isOrderingComparable!int); } - -@nogc nothrow pure @safe unittest -{ - static struct DisabledOpEquals - { - @disable bool opEquals(typeof(this)) @nogc nothrow pure @safe; - - int opCmp(typeof(this)) @nogc nothrow pure @safe - { - return 0; - } - } - static assert(!isEqualityComparable!DisabledOpEquals); - static assert(isOrderingComparable!DisabledOpEquals); - - static struct OpEquals - { - bool opEquals(typeof(this)) @nogc nothrow pure @safe - { - return true; - } - } - static assert(isEqualityComparable!OpEquals); - static assert(!isOrderingComparable!OpEquals); -} diff --git a/meta/tanya/meta/transform.d b/meta/tanya/meta/transform.d index 083e7ee..209e4fa 100644 --- a/meta/tanya/meta/transform.d +++ b/meta/tanya/meta/transform.d @@ -855,53 +855,6 @@ if (allSatisfy!(isType, Args)) static assert(is(CommonType!(const A, Object) == const Object)); } -@nogc nothrow pure @safe unittest -{ - static assert(is(CommonType!(void*, int*) == void*)); - static assert(is(CommonType!(void*, const(int)*) == const(void)*)); - static assert(is(CommonType!(void*, const(void)*) == const(void)*)); - static assert(is(CommonType!(int*, void*) == void*)); - static assert(is(CommonType!(const(int)*, void*) == const(void)*)); - static assert(is(CommonType!(const(void)*, void*) == const(void)*)); - - static assert(is(CommonType!() == void)); - static assert(is(CommonType!(int*, const(int)*) == const(int)*)); - static assert(is(CommonType!(int**, const(int)**) == const(int*)*)); - - static assert(is(CommonType!(float, double) == double)); - static assert(is(CommonType!(float, int) == void)); - - static assert(is(CommonType!(bool, const bool) == bool)); - static assert(is(CommonType!(int, bool) == void)); - static assert(is(CommonType!(int, void) == void)); - static assert(is(CommonType!(Object, void*) == void)); - - class A - { - } - static assert(is(CommonType!(A, Object) == Object)); - static assert(is(CommonType!(const(A)*, Object*) == const(Object)*)); - static assert(is(CommonType!(A, typeof(null)) == A)); - - class B : A - { - } - class C : A - { - } - static assert(is(CommonType!(B, C) == A)); - - static struct S - { - int opCast(T : int)() - { - return 1; - } - } - static assert(is(CommonType!(S, int) == void)); - static assert(is(CommonType!(const S, S) == const S)); -} - /** * Finds the type with the smallest size in the $(D_PARAM Args) list. If * several types have the same type, the leftmost is returned. diff --git a/memory/dub.json b/middle/dub.json similarity index 56% rename from memory/dub.json rename to middle/dub.json index 7339127..eecf1d4 100644 --- a/memory/dub.json +++ b/middle/dub.json @@ -1,6 +1,6 @@ { - "name": "memory", - "description": "Tools for manual memory management (allocators, smart pointers)", + "name": "middle", + "description": "Runtime, middle-level utilities", "targetType": "library", "dependencies": { @@ -9,6 +9,10 @@ "tanya:sys": "*" }, + "dependencies-linux": { + "mir-linux-kernel": "~>1.0.0" + }, + "sourcePaths": [ "." ], diff --git a/memory/tanya/memory/allocator.d b/middle/tanya/memory/allocator.d similarity index 98% rename from memory/tanya/memory/allocator.d rename to middle/tanya/memory/allocator.d index e161612..bf356af 100644 --- a/memory/tanya/memory/allocator.d +++ b/middle/tanya/memory/allocator.d @@ -12,7 +12,7 @@ * 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/memory/tanya/memory/allocator.d, + * Source: $(LINK2 https://github.com/caraus-ecms/tanya/blob/master/middle/tanya/memory/allocator.d, * tanya/memory/allocator.d) */ module tanya.memory.allocator; diff --git a/memory/tanya/memory/lifecycle.d b/middle/tanya/memory/lifetime.d similarity index 85% rename from memory/tanya/memory/lifecycle.d rename to middle/tanya/memory/lifetime.d index 35d251b..9bdc786 100644 --- a/memory/tanya/memory/lifecycle.d +++ b/middle/tanya/memory/lifetime.d @@ -3,22 +3,21 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /** - * Lifecycle management functions, types and related exceptions. + * Lifetime 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/memory/tanya/memory/lifecycle.d, - * tanya/memory/lifecycle.d) + * Source: $(LINK2 https://github.com/caraus-ecms/tanya/blob/master/middle/tanya/memory/lifetime.d, + * tanya/memory/lifetime.d) */ -module tanya.memory.lifecycle; +module tanya.memory.lifetime; import tanya.memory : defaultAllocator; import tanya.memory.allocator; -import tanya.meta.trait; import tanya.meta.metafunction; -version (unittest) import tanya.test.stub; +import tanya.meta.trait; /** * Error thrown if memory allocation fails. @@ -114,23 +113,6 @@ package(tanya) T[] resize(T)(shared Allocator allocator, 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. @@ -236,35 +218,6 @@ void dispose(T)(shared Allocator allocator, auto ref T 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). @@ -583,71 +536,6 @@ out (result; memory.ptr is result) assert(s.i == 8); } -// Handles "Cannot access frame pointer" error. -@nogc nothrow pure @safe unittest -{ - struct F - { - ~this() @nogc nothrow pure @safe - { - } - } - static assert(is(typeof(emplace!F((void[]).init)))); -} - -// Can emplace structs without a constructor -@nogc nothrow pure @safe unittest -{ - static assert(is(typeof(emplace!WithDtor(null, WithDtor())))); - static assert(is(typeof(emplace!WithDtor(null)))); -} - -// Doesn't call a destructor on uninitialized elements -@nogc nothrow pure @system unittest -{ - static struct SWithDtor - { - private bool canBeInvoked = false; - ~this() @nogc nothrow pure @safe - { - assert(this.canBeInvoked); - } - } - void[SWithDtor.sizeof] memory = void; - auto actual = emplace!SWithDtor(memory[], SWithDtor(true)); - assert(actual.canBeInvoked); -} - -// Initializes structs if no arguments are given -@nogc nothrow pure @safe unittest -{ - static struct SEntry - { - byte content; - } - ubyte[1] mem = [3]; - - assert(emplace!SEntry(cast(void[]) mem[0 .. 1]).content == 0); -} - -// Postblit is called when emplacing a struct -@nogc nothrow pure @system unittest -{ - static struct S - { - bool called = false; - this(this) @nogc nothrow pure @safe - { - this.called = true; - } - } - S target; - S* sp = ⌖ - - emplace!S(sp[0 .. 1], S()); - assert(target.called); -} - private void deinitialize(bool zero, T)(ref T value) { static if (is(T == U[S], U, size_t S)) @@ -764,55 +652,6 @@ do assert(x2 == 5); } -// Is pure. -@nogc nothrow pure @system unittest -{ - struct S - { - this(this) - { - } - } - S source, target = void; - static assert(is(typeof({ moveEmplace(source, target); }))); -} - -// Moves nested. -@nogc nothrow pure @system unittest -{ - struct Nested - { - void method() @nogc nothrow pure @safe - { - } - } - Nested source, target = void; - moveEmplace(source, target); - assert(source == target); -} - -// Emplaces static arrays. -@nogc nothrow pure @system unittest -{ - static struct S - { - size_t member; - this(size_t i) @nogc nothrow pure @safe - { - this.member = i; - } - ~this() @nogc nothrow pure @safe - { - } - } - S[2] source = [ S(5), S(5) ], target = void; - moveEmplace(source, target); - assert(source[0].member == 0); - assert(target[0].member == 5); - assert(source[1].member == 0); - assert(target[1].member == 5); -} - /** * Moves $(D_PARAM source) into $(D_PARAM target) assuming that * $(D_PARAM target) isn't initialized. @@ -888,14 +727,6 @@ T move(T)(ref T source) @trusted assert(move(x2) == 5); } -// Moves if source is target. -@nogc nothrow pure @safe unittest -{ - int x = 5; - move(x, x); - assert(x == 5); -} - /** * Exchanges the values of $(D_PARAM a) and $(D_PARAM b). * diff --git a/memory/tanya/memory/mallocator.d b/middle/tanya/memory/mallocator.d similarity index 92% rename from memory/tanya/memory/mallocator.d rename to middle/tanya/memory/mallocator.d index 858ad40..1103053 100644 --- a/memory/tanya/memory/mallocator.d +++ b/middle/tanya/memory/mallocator.d @@ -10,7 +10,7 @@ * 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/memory/tanya/memory/mallocator.d, + * Source: $(LINK2 https://github.com/caraus-ecms/tanya/blob/master/middle/tanya/memory/mallocator.d, * tanya/memory/mallocator.d) */ module tanya.memory.mallocator; @@ -172,16 +172,6 @@ final class Mallocator : Allocator assert(p is null); } - // Fails with false - @nogc nothrow pure @system unittest - { - void[] p = Mallocator.instance.allocate(20); - void[] oldP = p; - assert(!Mallocator.instance.reallocate(p, size_t.max - Mallocator.psize * 2)); - assert(oldP is p); - Mallocator.instance.deallocate(p); - } - /** * Returns: The alignment offered. */ @@ -190,11 +180,6 @@ final class Mallocator : Allocator return (void*).alignof; } - private nothrow @nogc unittest - { - assert(Mallocator.instance.alignment == (void*).alignof); - } - static private shared(Mallocator) instantiate() @nogc nothrow @system { if (instance_ is null) diff --git a/memory/tanya/memory/mmappool.d b/middle/tanya/memory/mmappool.d similarity index 77% rename from memory/tanya/memory/mmappool.d rename to middle/tanya/memory/mmappool.d index 1bc401b..05f71c6 100644 --- a/memory/tanya/memory/mmappool.d +++ b/middle/tanya/memory/mmappool.d @@ -9,7 +9,7 @@ * 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/memory/tanya/memory/mmappool.d, + * Source: $(LINK2 https://github.com/caraus-ecms/tanya/blob/master/middle/tanya/memory/mmappool.d, * tanya/memory/mmappool.d) */ module tanya.memory.mmappool; @@ -114,33 +114,6 @@ final class MmapPool : Allocator return data is null ? null : data[0 .. size]; } - @nogc nothrow pure @system unittest - { - auto p = MmapPool.instance.allocate(20); - assert(p); - MmapPool.instance.deallocate(p); - - p = MmapPool.instance.allocate(0); - assert(p.length == 0); - } - - @nogc nothrow pure @system unittest - { - // allocate() check. - size_t tooMuchMemory = size_t.max - - MmapPool.alignment_ - - BlockEntry.sizeof * 2 - - RegionEntry.sizeof - - pageSize; - assert(MmapPool.instance.allocate(tooMuchMemory) is null); - - assert(MmapPool.instance.allocate(size_t.max) is null); - - // initializeRegion() check. - tooMuchMemory = size_t.max - MmapPool.alignment_; - assert(MmapPool.instance.allocate(tooMuchMemory) is null); - } - /* * Search for a block large enough to keep $(D_PARAM size) and split it * into two blocks if the block is too large. @@ -257,13 +230,6 @@ final class MmapPool : Allocator return true; } - @nogc nothrow pure @system unittest - { - auto p = MmapPool.instance.allocate(20); - - assert(MmapPool.instance.deallocate(p)); - } - /* * Reallocates a memory block in place if possible or returns * $(D_KEYWORD false). This function cannot be used to allocate or @@ -340,30 +306,6 @@ final class MmapPool : Allocator return true; } - @nogc nothrow pure @system unittest - { - void[] p; - assert(!MmapPool.instance.reallocateInPlace(p, 5)); - assert(p is null); - - p = MmapPool.instance.allocate(1); - auto orig = p.ptr; - - assert(MmapPool.instance.reallocateInPlace(p, 2)); - assert(p.length == 2); - assert(p.ptr == orig); - - assert(MmapPool.instance.reallocateInPlace(p, 4)); - assert(p.length == 4); - assert(p.ptr == orig); - - assert(MmapPool.instance.reallocateInPlace(p, 2)); - assert(p.length == 2); - assert(p.ptr == orig); - - MmapPool.instance.deallocate(p); - } - /* * Increases or decreases the size of a memory block. * @@ -406,34 +348,6 @@ final class MmapPool : Allocator return true; } - @nogc nothrow pure @system unittest - { - void[] p; - MmapPool.instance.reallocate(p, 10 * int.sizeof); - (cast(int[]) p)[7] = 123; - - assert(p.length == 40); - - MmapPool.instance.reallocate(p, 8 * int.sizeof); - - assert(p.length == 32); - assert((cast(int[]) p)[7] == 123); - - MmapPool.instance.reallocate(p, 20 * int.sizeof); - (cast(int[]) p)[15] = 8; - - assert(p.length == 80); - assert((cast(int[]) p)[15] == 8); - assert((cast(int[]) p)[7] == 123); - - MmapPool.instance.reallocate(p, 8 * int.sizeof); - - assert(p.length == 32); - assert((cast(int[]) p)[7] == 123); - - MmapPool.instance.deallocate(p); - } - static private shared(MmapPool) instantiate() @nogc nothrow @system { if (instance_ is null) @@ -463,11 +377,6 @@ final class MmapPool : Allocator return (cast(GetPureInstance!MmapPool) &instantiate)(); } - @nogc nothrow pure @system unittest - { - assert(instance is instance); - } - /* * Initializes a region for one element. * @@ -565,11 +474,6 @@ final class MmapPool : Allocator return alignment_; } - @nogc nothrow pure @system unittest - { - assert(MmapPool.instance.alignment == MmapPool.alignment_); - } - private enum uint alignment_ = 8; private shared static MmapPool instance_; @@ -597,61 +501,3 @@ final class MmapPool : Allocator } private alias Block = shared BlockEntry*; } - -// A lot of allocations/deallocations, but it is the minimum caused a -// segmentation fault because MmapPool reallocateInPlace moves a block wrong. -@nogc nothrow pure @system unittest -{ - auto a = MmapPool.instance.allocate(16); - auto d = MmapPool.instance.allocate(16); - auto b = MmapPool.instance.allocate(16); - auto e = MmapPool.instance.allocate(16); - auto c = MmapPool.instance.allocate(16); - auto f = MmapPool.instance.allocate(16); - - MmapPool.instance.deallocate(a); - MmapPool.instance.deallocate(b); - MmapPool.instance.deallocate(c); - - a = MmapPool.instance.allocate(50); - MmapPool.instance.reallocateInPlace(a, 64); - MmapPool.instance.deallocate(a); - - a = MmapPool.instance.allocate(1); - auto tmp1 = MmapPool.instance.allocate(1); - auto h1 = MmapPool.instance.allocate(1); - auto tmp2 = cast(ubyte[]) MmapPool.instance.allocate(1); - - auto h2 = MmapPool.instance.allocate(2); - tmp1 = MmapPool.instance.allocate(1); - MmapPool.instance.deallocate(h2); - MmapPool.instance.deallocate(h1); - - h2 = MmapPool.instance.allocate(2); - h1 = MmapPool.instance.allocate(1); - MmapPool.instance.deallocate(h2); - - auto rep = cast(void[]) tmp2; - MmapPool.instance.reallocate(rep, tmp1.length); - tmp2 = cast(ubyte[]) rep; - - MmapPool.instance.reallocate(tmp1, 9); - - rep = cast(void[]) tmp2; - MmapPool.instance.reallocate(rep, tmp1.length); - tmp2 = cast(ubyte[]) rep; - MmapPool.instance.reallocate(tmp1, 17); - - tmp2[$ - 1] = 0; - - MmapPool.instance.deallocate(tmp1); - - b = MmapPool.instance.allocate(16); - - MmapPool.instance.deallocate(h1); - MmapPool.instance.deallocate(a); - MmapPool.instance.deallocate(b); - MmapPool.instance.deallocate(d); - MmapPool.instance.deallocate(e); - MmapPool.instance.deallocate(f); -} diff --git a/memory/tanya/memory/op.d b/middle/tanya/memory/op.d similarity index 87% rename from memory/tanya/memory/op.d rename to middle/tanya/memory/op.d index d77f3bb..55a0676 100644 --- a/memory/tanya/memory/op.d +++ b/middle/tanya/memory/op.d @@ -9,7 +9,7 @@ * 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/memory/tanya/memory/op.d, + * Source: $(LINK2 https://github.com/caraus-ecms/tanya/blob/master/middle/tanya/memory/op.d, * tanya/memory/op.d) */ module tanya.memory.op; @@ -32,21 +32,6 @@ else import core.stdc.string; } -version (TanyaNative) -{ - @nogc nothrow pure @system unittest - { - ubyte[2] buffer = 1; - fillMemory(buffer[1 .. $], 0); - assert(buffer[0] == 1 && buffer[1] == 0); - } - - @nogc nothrow pure @safe unittest - { - assert(equal(null, null)); - } -} - private enum alignMask = size_t.sizeof - 1; /** @@ -94,26 +79,6 @@ do assert(equal(source, target)); } -@nogc nothrow pure @safe unittest -{ - { - ubyte[0] source, target; - source.copy(target); - } - { - ubyte[1] source = [1]; - ubyte[1] target; - source.copy(target); - assert(target[0] == 1); - } - { - ubyte[8] source = [1, 2, 3, 4, 5, 6, 7, 8]; - ubyte[8] target; - source.copy(target); - assert(equal(source, target)); - } -} - /* * size_t value each of which bytes is set to `Byte`. */ @@ -215,15 +180,6 @@ do assert(equal(expected, mem)); } -@nogc nothrow pure @safe unittest -{ - ubyte[9] r1 = [ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i' ]; - ubyte[9] r2; - - copyBackward(r1, r2); - assert(equal(r1, r2)); -} - /** * Finds the first occurrence of $(D_PARAM needle) in $(D_PARAM haystack) if * any. @@ -417,21 +373,3 @@ do assert(!equal("asdf", "asd")); assert(!equal("asdf", "qwer")); } - -// Compares unanligned memory -@nogc nothrow pure @safe unittest -{ - ubyte[16] r1 = [ - 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', - 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', - ]; - ubyte[16] r2 = [ - 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', - 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', - ]; - - assert(equal(r1, r2)); - assert(equal(r1[1 .. $], r2[1 .. $])); - assert(equal(r1[0 .. $ - 1], r2[0 .. $ - 1])); - assert(equal(r1[0 .. 8], r2[0 .. 8])); -} diff --git a/memory/tanya/memory/package.d b/middle/tanya/memory/package.d similarity index 97% rename from memory/tanya/memory/package.d rename to middle/tanya/memory/package.d index 98aec48..c87eeb9 100644 --- a/memory/tanya/memory/package.d +++ b/middle/tanya/memory/package.d @@ -9,13 +9,13 @@ * 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/memory/tanya/memory/package.d, + * Source: $(LINK2 https://github.com/caraus-ecms/tanya/blob/master/middle/tanya/memory/package.d, * tanya/memory/package.d) */ module tanya.memory; public import tanya.memory.allocator; -public import tanya.memory.lifecycle; +public import tanya.memory.lifetime; import tanya.meta.trait; deprecated("Use tanya.meta.trait.stateSize instead") public import tanya.meta.trait : stateSize; diff --git a/memory/tanya/memory/smartref.d b/middle/tanya/memory/smartref.d similarity index 73% rename from memory/tanya/memory/smartref.d rename to middle/tanya/memory/smartref.d index 1fe81f3..953513e 100644 --- a/memory/tanya/memory/smartref.d +++ b/middle/tanya/memory/smartref.d @@ -18,14 +18,13 @@ * 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/memory/tanya/memory/smartref.d, + * Source: $(LINK2 https://github.com/caraus-ecms/tanya/blob/master/middle/tanya/memory/smartref.d, * tanya/memory/smartref.d) */ module tanya.memory.smartref; import tanya.memory; import tanya.meta.trait; -version (unittest) import tanya.test.stub; private template Payload(T) { @@ -46,11 +45,7 @@ private final class RefCountedStore(T) size_t opUnary(string op)() if (op == "--" || op == "++") - in - { - assert(this.counter > 0); - } - do + in (this.counter > 0) { mixin("return " ~ op ~ "counter;"); } @@ -131,11 +126,7 @@ struct RefCounted(T) /// ditto this(shared Allocator allocator) - in - { - assert(allocator !is null); - } - do + in (allocator !is null) { this.allocator_ = allocator; } @@ -239,11 +230,7 @@ struct RefCounted(T) * Precondition: $(D_INLINECODE cound > 0). */ inout(Payload!T) get() inout - in - { - assert(count > 0, "Attempted to access an uninitialized reference"); - } - do + in (count > 0, "Attempted to access an uninitialized reference") { return this.storage.payload; } @@ -301,174 +288,14 @@ struct RefCounted(T) auto val = rc.get(); *val = 8; - assert(*rc.storage.payload == 8); + assert(*rc.get == 8); val = null; - assert(rc.storage.payload !is null); - assert(*rc.storage.payload == 8); + assert(rc.get !is null); + assert(*rc.get == 8); *rc = 9; - assert(*rc.storage.payload == 9); -} - -@nogc @system unittest -{ - auto rc = defaultAllocator.refCounted!int(5); - rc = defaultAllocator.make!int(7); - assert(*rc == 7); -} - -@nogc @system unittest -{ - RefCounted!int rc; - assert(!rc.isInitialized); - rc = null; - assert(!rc.isInitialized); -} - -@nogc @system unittest -{ - auto rc = defaultAllocator.refCounted!int(5); - - void func(RefCounted!int param) @nogc - { - assert(param.count == 2); - param = defaultAllocator.make!int(7); - assert(param.count == 1); - assert(*param == 7); - } - func(rc); - assert(rc.count == 1); - assert(*rc == 5); -} - -@nogc @system unittest -{ - RefCounted!int rc; - - void func(RefCounted!int param) @nogc - { - assert(param.count == 0); - param = defaultAllocator.make!int(7); - assert(param.count == 1); - assert(*param == 7); - } - func(rc); - assert(rc.count == 0); -} - -@nogc @system unittest -{ - RefCounted!int rc1, rc2; - static assert(is(typeof(rc1 = rc2))); -} - -version (unittest) -{ - private class A - { - uint *destroyed; - - this(ref uint destroyed) @nogc - { - this.destroyed = &destroyed; - } - - ~this() @nogc - { - ++(*destroyed); - } - } - - private struct B - { - int prop; - @disable this(); - this(int param1) @nogc - { - prop = param1; - } - } -} - -@nogc @system unittest -{ - uint destroyed; - auto a = defaultAllocator.make!A(destroyed); - - assert(destroyed == 0); - { - auto rc = RefCounted!A(a, defaultAllocator); - assert(rc.count == 1); - - void func(RefCounted!A rc) @nogc @system - { - assert(rc.count == 2); - } - func(rc); - - assert(rc.count == 1); - } - assert(destroyed == 1); - - RefCounted!int rc; - assert(rc.count == 0); - rc = defaultAllocator.make!int(8); - assert(rc.count == 1); -} - -@nogc @system unittest -{ - auto rc = RefCounted!int(defaultAllocator); - assert(!rc.isInitialized); - assert(rc.allocator is defaultAllocator); -} - -@nogc @system unittest -{ - auto rc = defaultAllocator.refCounted!int(5); - assert(rc.count == 1); - - void func(RefCounted!int rc) @nogc - { - assert(rc.count == 2); - rc = null; - assert(!rc.isInitialized); - assert(rc.count == 0); - } - - assert(rc.count == 1); - func(rc); - assert(rc.count == 1); - - rc = null; - assert(!rc.isInitialized); - assert(rc.count == 0); -} - -@nogc @system unittest -{ - auto rc = defaultAllocator.refCounted!int(5); - assert(*rc == 5); - - void func(RefCounted!int rc) @nogc - { - assert(rc.count == 2); - rc = defaultAllocator.refCounted!int(4); - assert(*rc == 4); - assert(rc.count == 1); - } - func(rc); - assert(*rc == 5); -} - -@nogc nothrow pure @safe unittest -{ - static assert(is(typeof(RefCounted!int.storage.payload) == int*)); - static assert(is(typeof(RefCounted!A.storage.payload) == A)); - - static assert(is(RefCounted!B)); - static assert(is(RefCounted!A)); + assert(*rc.get == 9); } /** @@ -493,11 +320,7 @@ version (unittest) RefCounted!T refCounted(T, A...)(shared Allocator allocator, auto ref A args) if (!is(T == interface) && !isAbstractClass!T && !isAssociativeArray!T && !isArray!T) -in -{ - assert(allocator !is null); -} -do +in (allocator !is null) { auto rc = typeof(return)(allocator); @@ -565,51 +388,6 @@ in (size <= size_t.max / E.sizeof) assert(rc.count == 1); } -@nogc @system unittest -{ - struct E - { - } - auto b = defaultAllocator.refCounted!B(15); - static assert(is(typeof(b.storage.payload) == B*)); - static assert(is(typeof(b.prop) == int)); - static assert(!is(typeof(defaultAllocator.refCounted!B()))); - - static assert(is(typeof(defaultAllocator.refCounted!E()))); - static assert(!is(typeof(defaultAllocator.refCounted!E(5)))); - { - auto rc = defaultAllocator.refCounted!B(3); - assert(rc.get().prop == 3); - } - { - auto rc = defaultAllocator.refCounted!E(); - assert(rc.count); - } -} - -@nogc @system unittest -{ - auto rc = defaultAllocator.refCounted!(int[])(5); - assert(rc.length == 5); -} - -@nogc @system unittest -{ - auto p1 = defaultAllocator.make!int(5); - auto p2 = p1; - auto rc = RefCounted!int(p1, defaultAllocator); - assert(rc.get() is p2); -} - -@nogc @system unittest -{ - size_t destroyed; - { - auto rc = defaultAllocator.refCounted!WithDtor(destroyed); - } - assert(destroyed == 1); -} - /** * $(D_PSYMBOL Unique) stores an object that gets destroyed at the end of its scope. * @@ -644,11 +422,7 @@ struct Unique(T) /// ditto this(shared Allocator allocator) - in - { - assert(allocator !is null); - } - do + in (allocator !is null) { this.allocator_ = allocator; } @@ -829,11 +603,7 @@ struct Unique(T) Unique!T unique(T, A...)(shared Allocator allocator, auto ref A args) if (!is(T == interface) && !isAbstractClass!T && !isAssociativeArray!T && !isArray!T) -in -{ - assert(allocator !is null); -} -do +in (allocator !is null) { auto payload = allocator.make!(T, A)(args); return Unique!T(payload, allocator); @@ -862,42 +632,3 @@ in (size <= size_t.max / E.sizeof) auto payload = allocator.resize!E(null, size); return Unique!T(payload, allocator); } - -@nogc nothrow pure @safe unittest -{ - static assert(is(typeof(defaultAllocator.unique!B(5)))); - static assert(is(typeof(defaultAllocator.unique!(int[])(5)))); -} - -@nogc nothrow pure @system unittest -{ - auto s = defaultAllocator.unique!int(5); - assert(*s == 5); - - s = null; - assert(s is null); -} - -@nogc nothrow pure @system unittest -{ - auto s = defaultAllocator.unique!int(5); - assert(*s == 5); - - s = defaultAllocator.unique!int(4); - assert(*s == 4); -} - -@nogc nothrow pure @system unittest -{ - auto p1 = defaultAllocator.make!int(5); - auto p2 = p1; - - auto rc = Unique!int(p1, defaultAllocator); - assert(rc.get() is p2); -} - -@nogc nothrow pure @system unittest -{ - auto rc = Unique!int(defaultAllocator); - assert(rc.allocator is defaultAllocator); -} diff --git a/os/tanya/os/error.d b/os/tanya/os/error.d index 31c0102..0fabfc2 100644 --- a/os/tanya/os/error.d +++ b/os/tanya/os/error.d @@ -407,12 +407,6 @@ struct ErrorCode assert(ec.toString() == "An invalid pointer address detected"); } - @nogc nothrow pure @safe unittest - { - ErrorCode ec = cast(ErrorCode.ErrorNo) -1; - assert(ec.toString() is null); - } - private ErrorNo value_ = ErrorNo.success; alias ErrorNo this; diff --git a/source/tanya/algorithm/iteration.d b/source/tanya/algorithm/iteration.d index fcfb1c0..0cca49f 100644 --- a/source/tanya/algorithm/iteration.d +++ b/source/tanya/algorithm/iteration.d @@ -21,7 +21,7 @@ module tanya.algorithm.iteration; import tanya.algorithm.comparison; -import tanya.memory.lifecycle; +import tanya.memory.lifetime; import tanya.meta.trait; import tanya.meta.transform; import tanya.range; diff --git a/source/tanya/algorithm/mutation.d b/source/tanya/algorithm/mutation.d index ddb2743..fd6a9d6 100644 --- a/source/tanya/algorithm/mutation.d +++ b/source/tanya/algorithm/mutation.d @@ -14,21 +14,21 @@ */ module tanya.algorithm.mutation; +static import tanya.memory.lifetime; static import tanya.memory.op; -static import tanya.memory.lifecycle; import tanya.meta.trait; import tanya.meta.transform; import tanya.range; version (unittest) import tanya.test.stub; -deprecated("Use tanya.memory.lifecycle.swap instead") -alias swap = tanya.memory.lifecycle.swap; +deprecated("Use tanya.memory.lifetime.swap instead") +alias swap = tanya.memory.lifetime.swap; -deprecated("Use tanya.memory.lifecycle.moveEmplace instead") -alias moveEmplace = tanya.memory.lifecycle.moveEmplace; +deprecated("Use tanya.memory.lifetime.moveEmplace instead") +alias moveEmplace = tanya.memory.lifetime.moveEmplace; -deprecated("Use tanya.memory.lifecycle.move instead") -alias move = tanya.memory.lifecycle.move; +deprecated("Use tanya.memory.lifetime.move instead") +alias move = tanya.memory.lifetime.move; /** * Copies the $(D_PARAM source) range into the $(D_PARAM target) range. @@ -231,7 +231,7 @@ if (isInputRange!Range && hasLvalueElements!Range for (; !range.empty; range.popFront()) { ElementType!Range* p = &range.front; - tanya.memory.lifecycle.emplace!(ElementType!Range)(cast(void[]) (p[0 .. 1]), value); + tanya.memory.lifetime.emplace!(ElementType!Range)(cast(void[]) (p[0 .. 1]), value); } } else @@ -314,7 +314,7 @@ if (isInputRange!Range && hasLvalueElements!Range) void destroyAll(Range)(Range range) if (isInputRange!Range && hasLvalueElements!Range) { - tanya.memory.lifecycle.destroyAllImpl!(Range, ElementType!Range)(range); + tanya.memory.lifetime.destroyAllImpl!(Range, ElementType!Range)(range); } /// @@ -363,7 +363,7 @@ if (isForwardRange!Range && hasSwappableElements!Range) while (!front.empty && !next.empty && !sameHead(front, next)) { - tanya.memory.lifecycle.swap(front.front, next.front); + tanya.memory.lifetime.swap(front.front, next.front); front.popFront(); next.popFront(); diff --git a/source/tanya/container/entry.d b/source/tanya/container/entry.d index 408849a..cf4484c 100644 --- a/source/tanya/container/entry.d +++ b/source/tanya/container/entry.d @@ -16,7 +16,7 @@ module tanya.container.entry; import tanya.container.array; import tanya.memory.allocator; -import tanya.memory.lifecycle; +import tanya.memory.lifetime; import tanya.meta.trait; import tanya.meta.transform; import tanya.typecons; diff --git a/source/tanya/conv.d b/source/tanya/conv.d index f602e01..4010cb5 100644 --- a/source/tanya/conv.d +++ b/source/tanya/conv.d @@ -16,8 +16,8 @@ module tanya.conv; import tanya.container.string; import tanya.memory; -deprecated("Use tanya.memory.lifecycle.emplace instead") -public import tanya.memory.lifecycle : emplace; +deprecated("Use tanya.memory.lifetime.emplace instead") +public import tanya.memory.lifetime : emplace; import tanya.meta.trait; import tanya.meta.transform; import tanya.range; diff --git a/source/tanya/exception.d b/source/tanya/exception.d index 49a2d40..b65efd1 100644 --- a/source/tanya/exception.d +++ b/source/tanya/exception.d @@ -10,7 +10,7 @@ * Source: $(LINK2 https://github.com/caraus-ecms/tanya/blob/master/source/tanya/exception.d, * tanya/exception.d) */ -deprecated("Use tanya.memory.lifecycle instead") +deprecated("Use tanya.memory.lifetimeinstead") module tanya.exception; -public import tanya.memory.lifecycle : onOutOfMemoryError, OutOfMemoryError; +public import tanya.memory.lifetime : onOutOfMemoryError, OutOfMemoryError; diff --git a/source/tanya/functional.d b/source/tanya/functional.d index 9a1c3a1..cde1b51 100644 --- a/source/tanya/functional.d +++ b/source/tanya/functional.d @@ -12,7 +12,7 @@ * Source: $(LINK2 https://github.com/caraus-ecms/tanya/blob/master/source/tanya/functional.d, * tanya/functional.d) */ -deprecated("Use tanya.memory.lifecycle instead") +deprecated("Use tanya.memory.lifetime instead") module tanya.functional; -public import tanya.memory.lifecycle : forward; +public import tanya.memory.lifetime : forward; diff --git a/source/tanya/math/mp.d b/source/tanya/math/mp.d index b7eb86b..dc470b7 100644 --- a/source/tanya/math/mp.d +++ b/source/tanya/math/mp.d @@ -5,7 +5,7 @@ /** * Arbitrary precision arithmetic. * - * 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/math/nbtheory.d b/source/tanya/math/nbtheory.d index c20cc67..ec5d6c4 100644 --- a/source/tanya/math/nbtheory.d +++ b/source/tanya/math/nbtheory.d @@ -5,7 +5,7 @@ /** * Number theory. * - * 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/math/package.d b/source/tanya/math/package.d index 0fb2456..0ad9caf 100644 --- a/source/tanya/math/package.d +++ b/source/tanya/math/package.d @@ -12,7 +12,7 @@ * be found in its submodules. $(D_PSYMBOL tanya.math) doesn't import any * submodules publically, they should be imported explicitly. * - * 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) @@ -21,7 +21,6 @@ */ module tanya.math; -import tanya.algorithm.mutation; import tanya.math.mp; import tanya.math.nbtheory; import tanya.meta.trait; diff --git a/source/tanya/math/random.d b/source/tanya/math/random.d index cd66950..d5b840b 100644 --- a/source/tanya/math/random.d +++ b/source/tanya/math/random.d @@ -5,7 +5,7 @@ /** * Random number generator. * - * 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,7 +14,6 @@ */ module tanya.math.random; -import std.digest.sha; import tanya.memory; import tanya.typecons; diff --git a/source/tanya/net/ip.d b/source/tanya/net/ip.d index 2afdfe8..2025f15 100644 --- a/source/tanya/net/ip.d +++ b/source/tanya/net/ip.d @@ -21,7 +21,7 @@ import tanya.container.string; import tanya.conv; import tanya.encoding.ascii; import tanya.format; -import tanya.memory.lifecycle; +import tanya.memory.lifetime; import tanya.meta.trait; import tanya.meta.transform; import tanya.net.iface; diff --git a/source/tanya/range/adapter.d b/source/tanya/range/adapter.d index bc20e10..8ab9808 100644 --- a/source/tanya/range/adapter.d +++ b/source/tanya/range/adapter.d @@ -15,7 +15,7 @@ module tanya.range.adapter; import tanya.algorithm.mutation; -import tanya.memory.lifecycle; +import tanya.memory.lifetime; import tanya.meta.trait; import tanya.range; diff --git a/source/tanya/range/array.d b/source/tanya/range/array.d index 97101b9..98cceca 100644 --- a/source/tanya/range/array.d +++ b/source/tanya/range/array.d @@ -55,11 +55,7 @@ module tanya.range.array; * Precondition: $(D_INLINECODE array.length > 0). */ @property ref inout(T) front(T)(return scope inout(T)[] array) -in -{ - assert(array.length > 0); -} -do +in (array.length > 0) { return array[0]; } @@ -95,11 +91,7 @@ do * Precondition: $(D_INLINECODE array.length > 0). */ @property ref inout(T) back(T)(return scope inout(T)[] array) -in -{ - assert(array.length > 0); -} -do +in (array.length > 0) { return array[$ - 1]; } @@ -134,22 +126,14 @@ do * Precondition: $(D_INLINECODE array.length > 0). */ void popFront(T)(scope ref inout(T)[] array) -in -{ - assert(array.length > 0); -} -do +in (array.length > 0) { array = array[1 .. $]; } /// ditto void popBack(T)(scope ref inout(T)[] array) -in -{ - assert(array.length > 0); -} -do +in (array.length > 0) { array = array[0 .. $ - 1]; } diff --git a/source/tanya/range/primitive.d b/source/tanya/range/primitive.d index 0b192b0..21d3584 100644 --- a/source/tanya/range/primitive.d +++ b/source/tanya/range/primitive.d @@ -15,7 +15,7 @@ module tanya.range.primitive; import tanya.algorithm.comparison; -import tanya.memory.lifecycle; +import tanya.memory.lifetime; import tanya.meta.trait; import tanya.meta.transform; import tanya.range.array; diff --git a/source/tanya/typecons.d b/source/tanya/typecons.d index fa09831..700e2dd 100644 --- a/source/tanya/typecons.d +++ b/source/tanya/typecons.d @@ -18,7 +18,7 @@ module tanya.typecons; import tanya.format; -import tanya.memory.lifecycle; +import tanya.memory.lifetime; import tanya.meta.metafunction; import tanya.meta.trait; version (unittest) import tanya.test.stub; diff --git a/test/dub.json b/test/dub.json new file mode 100644 index 0000000..292bd9d --- /dev/null +++ b/test/dub.json @@ -0,0 +1,16 @@ +{ + "name": "test", + "description": "Test suite for unittest-blocks", + "targetType": "library", + + "dependencies": { + "tanya:middle": "*" + }, + + "sourcePaths": [ + "." + ], + "importPaths": [ + "." + ] +} diff --git a/memory/tanya/test/assertion.d b/test/tanya/test/assertion.d similarity index 100% rename from memory/tanya/test/assertion.d rename to test/tanya/test/assertion.d diff --git a/memory/tanya/test/package.d b/test/tanya/test/package.d similarity index 100% rename from memory/tanya/test/package.d rename to test/tanya/test/package.d diff --git a/memory/tanya/test/stub.d b/test/tanya/test/stub.d similarity index 100% rename from memory/tanya/test/stub.d rename to test/tanya/test/stub.d diff --git a/tests/tanya/memory/tests/lifetime.d b/tests/tanya/memory/tests/lifetime.d new file mode 100644 index 0000000..95da527 --- /dev/null +++ b/tests/tanya/memory/tests/lifetime.d @@ -0,0 +1,173 @@ +module tanya.memory.tests.lifetime; + +import tanya.memory; +import tanya.test.stub; + +@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); +} + +@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); +} + +// Handles "Cannot access frame pointer" error. +@nogc nothrow pure @safe unittest +{ + struct F + { + ~this() @nogc nothrow pure @safe + { + } + } + static assert(is(typeof(emplace!F((void[]).init)))); +} + +// Can emplace structs without a constructor +@nogc nothrow pure @safe unittest +{ + static assert(is(typeof(emplace!WithDtor(null, WithDtor())))); + static assert(is(typeof(emplace!WithDtor(null)))); +} + +// Doesn't call a destructor on uninitialized elements +@nogc nothrow pure @system unittest +{ + static struct SWithDtor + { + private bool canBeInvoked = false; + ~this() @nogc nothrow pure @safe + { + assert(this.canBeInvoked); + } + } + void[SWithDtor.sizeof] memory = void; + auto actual = emplace!SWithDtor(memory[], SWithDtor(true)); + assert(actual.canBeInvoked); +} + +// Initializes structs if no arguments are given +@nogc nothrow pure @safe unittest +{ + static struct SEntry + { + byte content; + } + ubyte[1] mem = [3]; + + assert(emplace!SEntry(cast(void[]) mem[0 .. 1]).content == 0); +} + +// Postblit is called when emplacing a struct +@nogc nothrow pure @system unittest +{ + static struct S + { + bool called = false; + this(this) @nogc nothrow pure @safe + { + this.called = true; + } + } + S target; + S* sp = ⌖ + + emplace!S(sp[0 .. 1], S()); + assert(target.called); +} + +// Is pure. +@nogc nothrow pure @system unittest +{ + struct S + { + this(this) + { + } + } + S source, target = void; + static assert(is(typeof({ moveEmplace(source, target); }))); +} + +// Moves nested. +@nogc nothrow pure @system unittest +{ + struct Nested + { + void method() @nogc nothrow pure @safe + { + } + } + Nested source, target = void; + moveEmplace(source, target); + assert(source == target); +} + +// Emplaces static arrays. +@nogc nothrow pure @system unittest +{ + static struct S + { + size_t member; + this(size_t i) @nogc nothrow pure @safe + { + this.member = i; + } + ~this() @nogc nothrow pure @safe + { + } + } + S[2] source = [ S(5), S(5) ], target = void; + moveEmplace(source, target); + assert(source[0].member == 0); + assert(target[0].member == 5); + assert(source[1].member == 0); + assert(target[1].member == 5); +} + +// Moves if source is target. +@nogc nothrow pure @safe unittest +{ + int x = 5; + move(x, x); + assert(x == 5); +} + diff --git a/tests/tanya/memory/tests/mallocator.d b/tests/tanya/memory/tests/mallocator.d new file mode 100644 index 0000000..941f9a8 --- /dev/null +++ b/tests/tanya/memory/tests/mallocator.d @@ -0,0 +1,23 @@ +module tanya.memory.tests.mallocator; + +version (TanyaNative) +{ +} +else: + +import tanya.memory.mallocator; + +// Fails with false +@nogc nothrow pure @system unittest +{ + void[] p = Mallocator.instance.allocate(20); + void[] oldP = p; + assert(!Mallocator.instance.reallocate(p, size_t.max - 16)); + assert(oldP is p); + Mallocator.instance.deallocate(p); +} + +@nogc nothrow pure unittest +{ + assert(Mallocator.instance.alignment == (void*).alignof); +} diff --git a/tests/tanya/memory/tests/mmappool.d b/tests/tanya/memory/tests/mmappool.d new file mode 100644 index 0000000..0e5b257 --- /dev/null +++ b/tests/tanya/memory/tests/mmappool.d @@ -0,0 +1,159 @@ +module tanya.memory.tests.mmappool; + +version (TanyaNative): + +import tanya.memory.mmappool; + +@nogc nothrow pure @system unittest +{ + auto p = MmapPool.instance.allocate(20); + assert(p); + MmapPool.instance.deallocate(p); + + p = MmapPool.instance.allocate(0); + assert(p.length == 0); +} + +@nogc nothrow pure @system unittest +{ + // allocate() check. + size_t tooMuchMemory = size_t.max + - MmapPool.alignment_ + - BlockEntry.sizeof * 2 + - RegionEntry.sizeof + - pageSize; + assert(MmapPool.instance.allocate(tooMuchMemory) is null); + + assert(MmapPool.instance.allocate(size_t.max) is null); + + // initializeRegion() check. + tooMuchMemory = size_t.max - MmapPool.alignment_; + assert(MmapPool.instance.allocate(tooMuchMemory) is null); +} + +@nogc nothrow pure @system unittest +{ + auto p = MmapPool.instance.allocate(20); + + assert(MmapPool.instance.deallocate(p)); +} + +@nogc nothrow pure @system unittest +{ + void[] p; + assert(!MmapPool.instance.reallocateInPlace(p, 5)); + assert(p is null); + + p = MmapPool.instance.allocate(1); + auto orig = p.ptr; + + assert(MmapPool.instance.reallocateInPlace(p, 2)); + assert(p.length == 2); + assert(p.ptr == orig); + + assert(MmapPool.instance.reallocateInPlace(p, 4)); + assert(p.length == 4); + assert(p.ptr == orig); + + assert(MmapPool.instance.reallocateInPlace(p, 2)); + assert(p.length == 2); + assert(p.ptr == orig); + + MmapPool.instance.deallocate(p); +} + +@nogc nothrow pure @system unittest +{ + void[] p; + MmapPool.instance.reallocate(p, 10 * int.sizeof); + (cast(int[]) p)[7] = 123; + + assert(p.length == 40); + + MmapPool.instance.reallocate(p, 8 * int.sizeof); + + assert(p.length == 32); + assert((cast(int[]) p)[7] == 123); + + MmapPool.instance.reallocate(p, 20 * int.sizeof); + (cast(int[]) p)[15] = 8; + + assert(p.length == 80); + assert((cast(int[]) p)[15] == 8); + assert((cast(int[]) p)[7] == 123); + + MmapPool.instance.reallocate(p, 8 * int.sizeof); + + assert(p.length == 32); + assert((cast(int[]) p)[7] == 123); + + MmapPool.instance.deallocate(p); +} + +@nogc nothrow pure @system unittest +{ + assert(instance is instance); +} + +@nogc nothrow pure @system unittest +{ + assert(MmapPool.instance.alignment == MmapPool.alignment_); +} + +// A lot of allocations/deallocations, but it is the minimum caused a +// segmentation fault because MmapPool reallocateInPlace moves a block wrong. +@nogc nothrow pure @system unittest +{ + auto a = MmapPool.instance.allocate(16); + auto d = MmapPool.instance.allocate(16); + auto b = MmapPool.instance.allocate(16); + auto e = MmapPool.instance.allocate(16); + auto c = MmapPool.instance.allocate(16); + auto f = MmapPool.instance.allocate(16); + + MmapPool.instance.deallocate(a); + MmapPool.instance.deallocate(b); + MmapPool.instance.deallocate(c); + + a = MmapPool.instance.allocate(50); + MmapPool.instance.reallocateInPlace(a, 64); + MmapPool.instance.deallocate(a); + + a = MmapPool.instance.allocate(1); + auto tmp1 = MmapPool.instance.allocate(1); + auto h1 = MmapPool.instance.allocate(1); + auto tmp2 = cast(ubyte[]) MmapPool.instance.allocate(1); + + auto h2 = MmapPool.instance.allocate(2); + tmp1 = MmapPool.instance.allocate(1); + MmapPool.instance.deallocate(h2); + MmapPool.instance.deallocate(h1); + + h2 = MmapPool.instance.allocate(2); + h1 = MmapPool.instance.allocate(1); + MmapPool.instance.deallocate(h2); + + auto rep = cast(void[]) tmp2; + MmapPool.instance.reallocate(rep, tmp1.length); + tmp2 = cast(ubyte[]) rep; + + MmapPool.instance.reallocate(tmp1, 9); + + rep = cast(void[]) tmp2; + MmapPool.instance.reallocate(rep, tmp1.length); + tmp2 = cast(ubyte[]) rep; + MmapPool.instance.reallocate(tmp1, 17); + + tmp2[$ - 1] = 0; + + MmapPool.instance.deallocate(tmp1); + + b = MmapPool.instance.allocate(16); + + MmapPool.instance.deallocate(h1); + MmapPool.instance.deallocate(a); + MmapPool.instance.deallocate(b); + MmapPool.instance.deallocate(d); + MmapPool.instance.deallocate(e); + MmapPool.instance.deallocate(f); +} diff --git a/tests/tanya/memory/tests/op.d b/tests/tanya/memory/tests/op.d new file mode 100644 index 0000000..61aa99b --- /dev/null +++ b/tests/tanya/memory/tests/op.d @@ -0,0 +1,64 @@ +module tanya.memory.tests.op; + +import tanya.memory.op; + +@nogc nothrow pure @system unittest +{ + ubyte[2] buffer = 1; + fill!0(buffer[1 .. $]); + assert(buffer[0] == 1 && buffer[1] == 0); +} + +@nogc nothrow pure @safe unittest +{ + assert(equal(null, null)); +} + +@nogc nothrow pure @safe unittest +{ + ubyte[0] source, target; + source.copy(target); +} + +@nogc nothrow pure @safe unittest +{ + ubyte[1] source = [1]; + ubyte[1] target; + source.copy(target); + assert(target[0] == 1); +} + +@nogc nothrow pure @safe unittest +{ + ubyte[8] source = [1, 2, 3, 4, 5, 6, 7, 8]; + ubyte[8] target; + source.copy(target); + assert(equal(source, target)); +} + +@nogc nothrow pure @safe unittest +{ + ubyte[9] r1 = [ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i' ]; + ubyte[9] r2; + + copyBackward(r1, r2); + assert(equal(r1, r2)); +} + +// Compares unanligned memory +@nogc nothrow pure @safe unittest +{ + ubyte[16] r1 = [ + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', + 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', + ]; + ubyte[16] r2 = [ + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', + 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', + ]; + + assert(equal(r1, r2)); + assert(equal(r1[1 .. $], r2[1 .. $])); + assert(equal(r1[0 .. $ - 1], r2[0 .. $ - 1])); + assert(equal(r1[0 .. 8], r2[0 .. 8])); +} diff --git a/tests/tanya/memory/tests/smartref.d b/tests/tanya/memory/tests/smartref.d new file mode 100644 index 0000000..b91e275 --- /dev/null +++ b/tests/tanya/memory/tests/smartref.d @@ -0,0 +1,250 @@ +module tanya.memory.tests.smartref; + +import tanya.memory; +import tanya.memory.smartref; +import tanya.meta.trait; +import tanya.test.stub; + +@nogc @system unittest +{ + auto rc = defaultAllocator.refCounted!int(5); + rc = defaultAllocator.make!int(7); + assert(*rc == 7); +} + +@nogc @system unittest +{ + RefCounted!int rc; + assert(!rc.isInitialized); + rc = null; + assert(!rc.isInitialized); +} + +@nogc @system unittest +{ + auto rc = defaultAllocator.refCounted!int(5); + + void func(RefCounted!int param) @nogc + { + assert(param.count == 2); + param = defaultAllocator.make!int(7); + assert(param.count == 1); + assert(*param == 7); + } + func(rc); + assert(rc.count == 1); + assert(*rc == 5); +} + +@nogc @system unittest +{ + RefCounted!int rc; + + void func(RefCounted!int param) @nogc + { + assert(param.count == 0); + param = defaultAllocator.make!int(7); + assert(param.count == 1); + assert(*param == 7); + } + func(rc); + assert(rc.count == 0); +} + +@nogc @system unittest +{ + RefCounted!int rc1, rc2; + static assert(is(typeof(rc1 = rc2))); +} + +@nogc @system unittest +{ + auto rc = RefCounted!int(defaultAllocator); + assert(!rc.isInitialized); + assert(rc.allocator is defaultAllocator); +} + +@nogc @system unittest +{ + auto rc = defaultAllocator.refCounted!int(5); + assert(rc.count == 1); + + void func(RefCounted!int rc) @nogc + { + assert(rc.count == 2); + rc = null; + assert(!rc.isInitialized); + assert(rc.count == 0); + } + + assert(rc.count == 1); + func(rc); + assert(rc.count == 1); + + rc = null; + assert(!rc.isInitialized); + assert(rc.count == 0); +} + +@nogc @system unittest +{ + auto rc = defaultAllocator.refCounted!int(5); + assert(*rc == 5); + + void func(RefCounted!int rc) @nogc + { + assert(rc.count == 2); + rc = defaultAllocator.refCounted!int(4); + assert(*rc == 4); + assert(rc.count == 1); + } + func(rc); + assert(*rc == 5); +} + +@nogc @system unittest +{ + auto rc = defaultAllocator.refCounted!(int[])(5); + assert(rc.length == 5); +} + +@nogc @system unittest +{ + auto p1 = defaultAllocator.make!int(5); + auto p2 = p1; + auto rc = RefCounted!int(p1, defaultAllocator); + assert(rc.get() is p2); +} + +@nogc @system unittest +{ + size_t destroyed; + { + auto rc = defaultAllocator.refCounted!WithDtor(destroyed); + } + assert(destroyed == 1); +} + +@nogc nothrow pure @system unittest +{ + auto s = defaultAllocator.unique!int(5); + assert(*s == 5); + + s = null; + assert(s is null); +} + +@nogc nothrow pure @system unittest +{ + auto s = defaultAllocator.unique!int(5); + assert(*s == 5); + + s = defaultAllocator.unique!int(4); + assert(*s == 4); +} + +@nogc nothrow pure @system unittest +{ + auto p1 = defaultAllocator.make!int(5); + auto p2 = p1; + + auto rc = Unique!int(p1, defaultAllocator); + assert(rc.get() is p2); +} + +@nogc nothrow pure @system unittest +{ + auto rc = Unique!int(defaultAllocator); + assert(rc.allocator is defaultAllocator); +} + +@nogc @system unittest +{ + uint destroyed; + auto a = defaultAllocator.make!A(destroyed); + + assert(destroyed == 0); + { + auto rc = RefCounted!A(a, defaultAllocator); + assert(rc.count == 1); + + void func(RefCounted!A rc) @nogc @system + { + assert(rc.count == 2); + } + func(rc); + + assert(rc.count == 1); + } + assert(destroyed == 1); + + RefCounted!int rc; + assert(rc.count == 0); + rc = defaultAllocator.make!int(8); + assert(rc.count == 1); +} + +@nogc nothrow pure @safe unittest +{ + static assert(is(ReturnType!(RefCounted!int.get) == inout int*)); + static assert(is(ReturnType!(RefCounted!A.get) == inout A)); + static assert(is(ReturnType!(RefCounted!B.get) == inout B*)); +} + +@nogc nothrow pure @safe unittest +{ + static assert(is(RefCounted!B)); + static assert(is(RefCounted!A)); +} + +@nogc @system unittest +{ + struct E + { + } + auto b = defaultAllocator.refCounted!B(15); + static assert(is(typeof(b.prop) == int)); + static assert(!is(typeof(defaultAllocator.refCounted!B()))); + + static assert(is(typeof(defaultAllocator.refCounted!E()))); + static assert(!is(typeof(defaultAllocator.refCounted!E(5)))); + { + auto rc = defaultAllocator.refCounted!B(3); + assert(rc.get().prop == 3); + } + { + auto rc = defaultAllocator.refCounted!E(); + assert(rc.count); + } +} + +@nogc nothrow pure @safe unittest +{ + static assert(is(typeof(defaultAllocator.unique!B(5)))); + static assert(is(typeof(defaultAllocator.unique!(int[])(5)))); +} + +private class A +{ + uint *destroyed; + + this(ref uint destroyed) @nogc + { + this.destroyed = &destroyed; + } + + ~this() @nogc + { + ++(*destroyed); + } +} + +private struct B +{ + int prop; + @disable this(); + this(int param1) @nogc + { + prop = param1; + } +} diff --git a/tests/tanya/meta/tests/metafunction.d b/tests/tanya/meta/tests/metafunction.d new file mode 100644 index 0000000..bea3014 --- /dev/null +++ b/tests/tanya/meta/tests/metafunction.d @@ -0,0 +1,27 @@ +module tanya.meta.tests.metafunction; + +import tanya.meta.metafunction; + +@nogc nothrow pure @safe unittest +{ + enum cmp(int x, int y) = x - y; + static assert(isSorted!(cmp)); + static assert(isSorted!(cmp, 1)); + static assert(isSorted!(cmp, 1, 2, 2)); + static assert(isSorted!(cmp, 1, 2, 2, 4)); + static assert(isSorted!(cmp, 1, 2, 2, 4, 8)); + static assert(!isSorted!(cmp, 32, 2, 2, 4, 8)); + static assert(isSorted!(cmp, 32, 32)); +} + +@nogc nothrow pure @safe unittest +{ + enum cmp(int x, int y) = x < y; + static assert(isSorted!(cmp)); + static assert(isSorted!(cmp, 1)); + static assert(isSorted!(cmp, 1, 2, 2)); + static assert(isSorted!(cmp, 1, 2, 2, 4)); + static assert(isSorted!(cmp, 1, 2, 2, 4, 8)); + static assert(!isSorted!(cmp, 32, 2, 2, 4, 8)); + static assert(isSorted!(cmp, 32, 32)); +} diff --git a/tests/tanya/meta/tests/trait.d b/tests/tanya/meta/tests/trait.d new file mode 100644 index 0000000..bc06aef --- /dev/null +++ b/tests/tanya/meta/tests/trait.d @@ -0,0 +1,169 @@ +module tanya.meta.tests.trait; + +import tanya.meta.metafunction; +import tanya.meta.trait; + +// typeof(null) is not a pointer. +@nogc nothrow pure @safe unittest +{ + static assert(!isPointer!(typeof(null))); + static assert(!isPointer!(const shared typeof(null))); + + enum typeOfNull : typeof(null) + { + null_ = null, + } + static assert(!isPointer!typeOfNull); +} + +@nogc nothrow pure @safe unittest +{ + static struct S + { + @property int opCall() + { + return 0; + } + } + S s; + static assert(isCallable!S); + static assert(isCallable!s); +} + +@nogc nothrow pure @safe unittest +{ + static assert(is(FunctionTypeOf!(void delegate()) == function)); + + static void staticFunc() + { + } + auto functionPointer = &staticFunc; + static assert(is(FunctionTypeOf!staticFunc == function)); + static assert(is(FunctionTypeOf!functionPointer == function)); + + void func() + { + } + auto dg = &func; + static assert(is(FunctionTypeOf!func == function)); + static assert(is(FunctionTypeOf!dg == function)); + + interface I + { + @property int prop(); + } + static assert(is(FunctionTypeOf!(I.prop) == function)); + + static struct S + { + void opCall() + { + } + } + class C + { + static void opCall() + { + } + } + S s; + + static assert(is(FunctionTypeOf!s == function)); + static assert(is(FunctionTypeOf!C == function)); + static assert(is(FunctionTypeOf!S == function)); +} + +@nogc nothrow pure @safe unittest +{ + static struct S2 + { + @property int opCall() + { + return 0; + } + } + S2 s2; + static assert(is(FunctionTypeOf!S2 == function)); + static assert(is(FunctionTypeOf!s2 == function)); +} + +@nogc nothrow pure @safe unittest +{ + static assert(!hasElaborateAssign!int); + + static struct S1 + { + void opAssign(S1) + { + } + } + static struct S2 + { + void opAssign(int) + { + } + } + static struct S3 + { + S1 s; + alias s this; + } + static assert(hasElaborateAssign!S1); + static assert(!hasElaborateAssign!(const S1)); + static assert(hasElaborateAssign!(S1[1])); + static assert(!hasElaborateAssign!(S1[0])); + static assert(!hasElaborateAssign!S2); + static assert(hasElaborateAssign!S3); + + static struct S4 + { + void opAssign(S4) + { + } + @disable this(this); + } + static assert(hasElaborateAssign!S4); +} + +// Produces a tuple for an enum with only one member +@nogc nothrow pure @safe unittest +{ + enum E : int + { + one = 0, + } + static assert(EnumMembers!E == AliasSeq!0); +} + +@nogc nothrow pure @safe unittest +{ + class RefCountedStore(T) + { + } + static assert(!isInnerClass!(RefCountedStore!int)); +} + +@nogc nothrow pure @safe unittest +{ + static struct DisabledOpEquals + { + @disable bool opEquals(typeof(this)) @nogc nothrow pure @safe; + + int opCmp(typeof(this)) @nogc nothrow pure @safe + { + return 0; + } + } + static assert(!isEqualityComparable!DisabledOpEquals); + static assert(isOrderingComparable!DisabledOpEquals); + + static struct OpEquals + { + bool opEquals(typeof(this)) @nogc nothrow pure @safe + { + return true; + } + } + static assert(isEqualityComparable!OpEquals); + static assert(!isOrderingComparable!OpEquals); +} diff --git a/tests/tanya/meta/tests/transform.d b/tests/tanya/meta/tests/transform.d new file mode 100644 index 0000000..c81232c --- /dev/null +++ b/tests/tanya/meta/tests/transform.d @@ -0,0 +1,50 @@ +module tanya.meta.tests.transform; + +import tanya.meta.transform; + +@nogc nothrow pure @safe unittest +{ + static assert(is(CommonType!(void*, int*) == void*)); + static assert(is(CommonType!(void*, const(int)*) == const(void)*)); + static assert(is(CommonType!(void*, const(void)*) == const(void)*)); + static assert(is(CommonType!(int*, void*) == void*)); + static assert(is(CommonType!(const(int)*, void*) == const(void)*)); + static assert(is(CommonType!(const(void)*, void*) == const(void)*)); + + static assert(is(CommonType!() == void)); + static assert(is(CommonType!(int*, const(int)*) == const(int)*)); + static assert(is(CommonType!(int**, const(int)**) == const(int*)*)); + + static assert(is(CommonType!(float, double) == double)); + static assert(is(CommonType!(float, int) == void)); + + static assert(is(CommonType!(bool, const bool) == bool)); + static assert(is(CommonType!(int, bool) == void)); + static assert(is(CommonType!(int, void) == void)); + static assert(is(CommonType!(Object, void*) == void)); + + class A + { + } + static assert(is(CommonType!(A, Object) == Object)); + static assert(is(CommonType!(const(A)*, Object*) == const(Object)*)); + static assert(is(CommonType!(A, typeof(null)) == A)); + + class B : A + { + } + class C : A + { + } + static assert(is(CommonType!(B, C) == A)); + + static struct S + { + int opCast(T : int)() + { + return 1; + } + } + static assert(is(CommonType!(S, int) == void)); + static assert(is(CommonType!(const S, S) == const S)); +} diff --git a/tests/tanya/os/tests/error.d b/tests/tanya/os/tests/error.d new file mode 100644 index 0000000..c224438 --- /dev/null +++ b/tests/tanya/os/tests/error.d @@ -0,0 +1,9 @@ +module tanya.os.tests.error; + +import tanya.os.error; + +@nogc nothrow pure @safe unittest +{ + ErrorCode ec = cast(ErrorCode.ErrorNo) -1; + assert(ec.toString() is null); +}