Separate non-documentation tests from the code
This commit is contained in:
parent
5ab99cf887
commit
484cb13317
@ -53,19 +53,21 @@ script:
|
|||||||
dub build :sys -b ddox --compiler=$DC;
|
dub build :sys -b ddox --compiler=$DC;
|
||||||
dub build :os -b ddox --compiler=$DC;
|
dub build :os -b ddox --compiler=$DC;
|
||||||
dub build :encoding -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;
|
dub build -b ddox --compiler=$DC;
|
||||||
elif [ -z "$DSCANNER" ]; then
|
elif [ -z "$DSCANNER" ]; then
|
||||||
dub test :meta -b ${UNITTEST:-unittest} --arch=$ARCH --compiler=$DC;
|
dub test :meta -b ${UNITTEST:-unittest} --arch=$ARCH --compiler=$DC;
|
||||||
dub test :sys -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 :os -b ${UNITTEST:-unittest} --arch=$ARCH --compiler=$DC;
|
||||||
dub test :encoding -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;
|
dub test -b ${UNITTEST:-unittest} --arch=$ARCH --compiler=$DC;
|
||||||
else
|
else
|
||||||
dub fetch dscanner --version=$DSCANNER;
|
dub fetch dscanner --version=$DSCANNER;
|
||||||
|
|
||||||
FILES=$(find source */source -type f);
|
FILES=$(find */tanya -type f);
|
||||||
dub run dscanner -- --styleCheck $FILES;
|
dub run dscanner -- --styleCheck $FILES;
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -61,5 +61,6 @@ test_script:
|
|||||||
- dub test :sys -b unittest --arch=%Darch% --compiler=%DC%
|
- dub test :sys -b unittest --arch=%Darch% --compiler=%DC%
|
||||||
- dub test :os -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 :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%
|
- dub test -b unittest --arch=%Darch% --compiler=%DC%
|
||||||
|
17
dub.json
17
dub.json
@ -14,7 +14,8 @@
|
|||||||
"tanya:sys": "*",
|
"tanya:sys": "*",
|
||||||
"tanya:os": "*",
|
"tanya:os": "*",
|
||||||
"tanya:encoding": "*",
|
"tanya:encoding": "*",
|
||||||
"tanya:memory": "*"
|
"tanya:middle": "*",
|
||||||
|
"tanya:test": "*"
|
||||||
},
|
},
|
||||||
|
|
||||||
"dependencies-linux": {
|
"dependencies-linux": {
|
||||||
@ -26,7 +27,8 @@
|
|||||||
"./sys",
|
"./sys",
|
||||||
"./os",
|
"./os",
|
||||||
"./encoding",
|
"./encoding",
|
||||||
"./memory"
|
"./middle",
|
||||||
|
"./test"
|
||||||
],
|
],
|
||||||
|
|
||||||
"configurations": [
|
"configurations": [
|
||||||
@ -47,6 +49,17 @@
|
|||||||
"preBuildCommands": ["ninja -C arch"],
|
"preBuildCommands": ["ninja -C arch"],
|
||||||
"lflags": ["arch/tanya.a"],
|
"lflags": ["arch/tanya.a"],
|
||||||
"versions": ["TanyaNative"]
|
"versions": ["TanyaNative"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "unittest",
|
||||||
|
"importPaths": [
|
||||||
|
"./source",
|
||||||
|
"./tests"
|
||||||
|
],
|
||||||
|
"sourcePaths": [
|
||||||
|
"./source",
|
||||||
|
"./tests"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
||||||
|
@ -1129,30 +1129,6 @@ if (__traits(isTemplate, cmp))
|
|||||||
static assert(!isSorted!(cmp, long, byte, ubyte, short, uint));
|
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:
|
* Params:
|
||||||
* T = A template.
|
* T = A template.
|
||||||
|
@ -549,19 +549,6 @@ template isPointer(T)
|
|||||||
static assert(!isPointer!bool);
|
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
|
* Determines whether $(D_PARAM T) is an array type (dynamic or static, but
|
||||||
* not an associative one).
|
* not an associative one).
|
||||||
@ -1478,20 +1465,6 @@ if (F.length == 1)
|
|||||||
static assert(!isCallable!I);
|
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).
|
* Determines whether $(D_PARAM T) defines a symbol $(D_PARAM member).
|
||||||
*
|
*
|
||||||
@ -1676,63 +1649,6 @@ if (isCallable!F)
|
|||||||
static assert(is(FunctionTypeOf!(() {}) == function));
|
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).
|
* 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).
|
* 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]);
|
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
|
* Different than $(D_INLINECODE T.alignof), which is the same for all class
|
||||||
* types, $(D_PSYMBOL classInstanceOf) determines the alignment of the class
|
* types, $(D_PSYMBOL classInstanceOf) determines the alignment of the class
|
||||||
@ -2996,14 +2864,6 @@ template isInnerClass(T)
|
|||||||
static assert(!isInnerClass!(O.Fake));
|
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).
|
* 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);
|
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);
|
|
||||||
}
|
|
||||||
|
@ -855,53 +855,6 @@ if (allSatisfy!(isType, Args))
|
|||||||
static assert(is(CommonType!(const A, Object) == const Object));
|
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
|
* Finds the type with the smallest size in the $(D_PARAM Args) list. If
|
||||||
* several types have the same type, the leftmost is returned.
|
* several types have the same type, the leftmost is returned.
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "memory",
|
"name": "middle",
|
||||||
"description": "Tools for manual memory management (allocators, smart pointers)",
|
"description": "Runtime, middle-level utilities",
|
||||||
"targetType": "library",
|
"targetType": "library",
|
||||||
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -9,6 +9,10 @@
|
|||||||
"tanya:sys": "*"
|
"tanya:sys": "*"
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"dependencies-linux": {
|
||||||
|
"mir-linux-kernel": "~>1.0.0"
|
||||||
|
},
|
||||||
|
|
||||||
"sourcePaths": [
|
"sourcePaths": [
|
||||||
"."
|
"."
|
||||||
],
|
],
|
@ -12,7 +12,7 @@
|
|||||||
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
|
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
|
||||||
* Mozilla Public License, v. 2.0).
|
* Mozilla Public License, v. 2.0).
|
||||||
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
|
* 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)
|
* tanya/memory/allocator.d)
|
||||||
*/
|
*/
|
||||||
module tanya.memory.allocator;
|
module tanya.memory.allocator;
|
@ -3,22 +3,21 @@
|
|||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* 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.
|
* Copyright: Eugene Wissner 2019.
|
||||||
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
|
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
|
||||||
* Mozilla Public License, v. 2.0).
|
* Mozilla Public License, v. 2.0).
|
||||||
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
|
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
|
||||||
* Source: $(LINK2 https://github.com/caraus-ecms/tanya/blob/master/memory/tanya/memory/lifecycle.d,
|
* Source: $(LINK2 https://github.com/caraus-ecms/tanya/blob/master/middle/tanya/memory/lifetime.d,
|
||||||
* tanya/memory/lifecycle.d)
|
* tanya/memory/lifetime.d)
|
||||||
*/
|
*/
|
||||||
module tanya.memory.lifecycle;
|
module tanya.memory.lifetime;
|
||||||
|
|
||||||
import tanya.memory : defaultAllocator;
|
import tanya.memory : defaultAllocator;
|
||||||
import tanya.memory.allocator;
|
import tanya.memory.allocator;
|
||||||
import tanya.meta.trait;
|
|
||||||
import tanya.meta.metafunction;
|
import tanya.meta.metafunction;
|
||||||
version (unittest) import tanya.test.stub;
|
import tanya.meta.trait;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Error thrown if memory allocation fails.
|
* Error thrown if memory allocation fails.
|
||||||
@ -114,23 +113,6 @@ package(tanya) T[] resize(T)(shared Allocator allocator,
|
|||||||
return array;
|
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.
|
* Destroys the object.
|
||||||
* Returns the memory should be freed.
|
* Returns the memory should be freed.
|
||||||
@ -236,35 +218,6 @@ void dispose(T)(shared Allocator allocator, auto ref T p)
|
|||||||
p = null;
|
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)
|
* 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).
|
* 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);
|
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)
|
private void deinitialize(bool zero, T)(ref T value)
|
||||||
{
|
{
|
||||||
static if (is(T == U[S], U, size_t S))
|
static if (is(T == U[S], U, size_t S))
|
||||||
@ -764,55 +652,6 @@ do
|
|||||||
assert(x2 == 5);
|
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
|
* Moves $(D_PARAM source) into $(D_PARAM target) assuming that
|
||||||
* $(D_PARAM target) isn't initialized.
|
* $(D_PARAM target) isn't initialized.
|
||||||
@ -888,14 +727,6 @@ T move(T)(ref T source) @trusted
|
|||||||
assert(move(x2) == 5);
|
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).
|
* Exchanges the values of $(D_PARAM a) and $(D_PARAM b).
|
||||||
*
|
*
|
@ -10,7 +10,7 @@
|
|||||||
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
|
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
|
||||||
* Mozilla Public License, v. 2.0).
|
* Mozilla Public License, v. 2.0).
|
||||||
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
|
* 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)
|
* tanya/memory/mallocator.d)
|
||||||
*/
|
*/
|
||||||
module tanya.memory.mallocator;
|
module tanya.memory.mallocator;
|
||||||
@ -172,16 +172,6 @@ final class Mallocator : Allocator
|
|||||||
assert(p is null);
|
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.
|
* Returns: The alignment offered.
|
||||||
*/
|
*/
|
||||||
@ -190,11 +180,6 @@ final class Mallocator : Allocator
|
|||||||
return (void*).alignof;
|
return (void*).alignof;
|
||||||
}
|
}
|
||||||
|
|
||||||
private nothrow @nogc unittest
|
|
||||||
{
|
|
||||||
assert(Mallocator.instance.alignment == (void*).alignof);
|
|
||||||
}
|
|
||||||
|
|
||||||
static private shared(Mallocator) instantiate() @nogc nothrow @system
|
static private shared(Mallocator) instantiate() @nogc nothrow @system
|
||||||
{
|
{
|
||||||
if (instance_ is null)
|
if (instance_ is null)
|
@ -9,7 +9,7 @@
|
|||||||
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
|
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
|
||||||
* Mozilla Public License, v. 2.0).
|
* Mozilla Public License, v. 2.0).
|
||||||
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
|
* 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)
|
* tanya/memory/mmappool.d)
|
||||||
*/
|
*/
|
||||||
module tanya.memory.mmappool;
|
module tanya.memory.mmappool;
|
||||||
@ -114,33 +114,6 @@ final class MmapPool : Allocator
|
|||||||
return data is null ? null : data[0 .. size];
|
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
|
* Search for a block large enough to keep $(D_PARAM size) and split it
|
||||||
* into two blocks if the block is too large.
|
* into two blocks if the block is too large.
|
||||||
@ -257,13 +230,6 @@ final class MmapPool : Allocator
|
|||||||
return true;
|
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
|
* Reallocates a memory block in place if possible or returns
|
||||||
* $(D_KEYWORD false). This function cannot be used to allocate or
|
* $(D_KEYWORD false). This function cannot be used to allocate or
|
||||||
@ -340,30 +306,6 @@ final class MmapPool : Allocator
|
|||||||
return true;
|
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.
|
* Increases or decreases the size of a memory block.
|
||||||
*
|
*
|
||||||
@ -406,34 +348,6 @@ final class MmapPool : Allocator
|
|||||||
return true;
|
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
|
static private shared(MmapPool) instantiate() @nogc nothrow @system
|
||||||
{
|
{
|
||||||
if (instance_ is null)
|
if (instance_ is null)
|
||||||
@ -463,11 +377,6 @@ final class MmapPool : Allocator
|
|||||||
return (cast(GetPureInstance!MmapPool) &instantiate)();
|
return (cast(GetPureInstance!MmapPool) &instantiate)();
|
||||||
}
|
}
|
||||||
|
|
||||||
@nogc nothrow pure @system unittest
|
|
||||||
{
|
|
||||||
assert(instance is instance);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initializes a region for one element.
|
* Initializes a region for one element.
|
||||||
*
|
*
|
||||||
@ -565,11 +474,6 @@ final class MmapPool : Allocator
|
|||||||
return alignment_;
|
return alignment_;
|
||||||
}
|
}
|
||||||
|
|
||||||
@nogc nothrow pure @system unittest
|
|
||||||
{
|
|
||||||
assert(MmapPool.instance.alignment == MmapPool.alignment_);
|
|
||||||
}
|
|
||||||
|
|
||||||
private enum uint alignment_ = 8;
|
private enum uint alignment_ = 8;
|
||||||
|
|
||||||
private shared static MmapPool instance_;
|
private shared static MmapPool instance_;
|
||||||
@ -597,61 +501,3 @@ final class MmapPool : Allocator
|
|||||||
}
|
}
|
||||||
private alias Block = shared BlockEntry*;
|
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);
|
|
||||||
}
|
|
@ -9,7 +9,7 @@
|
|||||||
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
|
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
|
||||||
* Mozilla Public License, v. 2.0).
|
* Mozilla Public License, v. 2.0).
|
||||||
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
|
* 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)
|
* tanya/memory/op.d)
|
||||||
*/
|
*/
|
||||||
module tanya.memory.op;
|
module tanya.memory.op;
|
||||||
@ -32,21 +32,6 @@ else
|
|||||||
import core.stdc.string;
|
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;
|
private enum alignMask = size_t.sizeof - 1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -94,26 +79,6 @@ do
|
|||||||
assert(equal(source, target));
|
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`.
|
* size_t value each of which bytes is set to `Byte`.
|
||||||
*/
|
*/
|
||||||
@ -215,15 +180,6 @@ do
|
|||||||
assert(equal(expected, mem));
|
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
|
* Finds the first occurrence of $(D_PARAM needle) in $(D_PARAM haystack) if
|
||||||
* any.
|
* any.
|
||||||
@ -417,21 +373,3 @@ do
|
|||||||
assert(!equal("asdf", "asd"));
|
assert(!equal("asdf", "asd"));
|
||||||
assert(!equal("asdf", "qwer"));
|
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]));
|
|
||||||
}
|
|
@ -9,13 +9,13 @@
|
|||||||
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
|
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
|
||||||
* Mozilla Public License, v. 2.0).
|
* Mozilla Public License, v. 2.0).
|
||||||
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
|
* 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)
|
* tanya/memory/package.d)
|
||||||
*/
|
*/
|
||||||
module tanya.memory;
|
module tanya.memory;
|
||||||
|
|
||||||
public import tanya.memory.allocator;
|
public import tanya.memory.allocator;
|
||||||
public import tanya.memory.lifecycle;
|
public import tanya.memory.lifetime;
|
||||||
import tanya.meta.trait;
|
import tanya.meta.trait;
|
||||||
deprecated("Use tanya.meta.trait.stateSize instead")
|
deprecated("Use tanya.meta.trait.stateSize instead")
|
||||||
public import tanya.meta.trait : stateSize;
|
public import tanya.meta.trait : stateSize;
|
@ -18,14 +18,13 @@
|
|||||||
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
|
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
|
||||||
* Mozilla Public License, v. 2.0).
|
* Mozilla Public License, v. 2.0).
|
||||||
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
|
* 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)
|
* tanya/memory/smartref.d)
|
||||||
*/
|
*/
|
||||||
module tanya.memory.smartref;
|
module tanya.memory.smartref;
|
||||||
|
|
||||||
import tanya.memory;
|
import tanya.memory;
|
||||||
import tanya.meta.trait;
|
import tanya.meta.trait;
|
||||||
version (unittest) import tanya.test.stub;
|
|
||||||
|
|
||||||
private template Payload(T)
|
private template Payload(T)
|
||||||
{
|
{
|
||||||
@ -46,11 +45,7 @@ private final class RefCountedStore(T)
|
|||||||
|
|
||||||
size_t opUnary(string op)()
|
size_t opUnary(string op)()
|
||||||
if (op == "--" || op == "++")
|
if (op == "--" || op == "++")
|
||||||
in
|
in (this.counter > 0)
|
||||||
{
|
|
||||||
assert(this.counter > 0);
|
|
||||||
}
|
|
||||||
do
|
|
||||||
{
|
{
|
||||||
mixin("return " ~ op ~ "counter;");
|
mixin("return " ~ op ~ "counter;");
|
||||||
}
|
}
|
||||||
@ -131,11 +126,7 @@ struct RefCounted(T)
|
|||||||
|
|
||||||
/// ditto
|
/// ditto
|
||||||
this(shared Allocator allocator)
|
this(shared Allocator allocator)
|
||||||
in
|
in (allocator !is null)
|
||||||
{
|
|
||||||
assert(allocator !is null);
|
|
||||||
}
|
|
||||||
do
|
|
||||||
{
|
{
|
||||||
this.allocator_ = allocator;
|
this.allocator_ = allocator;
|
||||||
}
|
}
|
||||||
@ -239,11 +230,7 @@ struct RefCounted(T)
|
|||||||
* Precondition: $(D_INLINECODE cound > 0).
|
* Precondition: $(D_INLINECODE cound > 0).
|
||||||
*/
|
*/
|
||||||
inout(Payload!T) get() inout
|
inout(Payload!T) get() inout
|
||||||
in
|
in (count > 0, "Attempted to access an uninitialized reference")
|
||||||
{
|
|
||||||
assert(count > 0, "Attempted to access an uninitialized reference");
|
|
||||||
}
|
|
||||||
do
|
|
||||||
{
|
{
|
||||||
return this.storage.payload;
|
return this.storage.payload;
|
||||||
}
|
}
|
||||||
@ -301,174 +288,14 @@ struct RefCounted(T)
|
|||||||
auto val = rc.get();
|
auto val = rc.get();
|
||||||
|
|
||||||
*val = 8;
|
*val = 8;
|
||||||
assert(*rc.storage.payload == 8);
|
assert(*rc.get == 8);
|
||||||
|
|
||||||
val = null;
|
val = null;
|
||||||
assert(rc.storage.payload !is null);
|
assert(rc.get !is null);
|
||||||
assert(*rc.storage.payload == 8);
|
assert(*rc.get == 8);
|
||||||
|
|
||||||
*rc = 9;
|
*rc = 9;
|
||||||
assert(*rc.storage.payload == 9);
|
assert(*rc.get == 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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -493,11 +320,7 @@ version (unittest)
|
|||||||
RefCounted!T refCounted(T, A...)(shared Allocator allocator, auto ref A args)
|
RefCounted!T refCounted(T, A...)(shared Allocator allocator, auto ref A args)
|
||||||
if (!is(T == interface) && !isAbstractClass!T
|
if (!is(T == interface) && !isAbstractClass!T
|
||||||
&& !isAssociativeArray!T && !isArray!T)
|
&& !isAssociativeArray!T && !isArray!T)
|
||||||
in
|
in (allocator !is null)
|
||||||
{
|
|
||||||
assert(allocator !is null);
|
|
||||||
}
|
|
||||||
do
|
|
||||||
{
|
{
|
||||||
auto rc = typeof(return)(allocator);
|
auto rc = typeof(return)(allocator);
|
||||||
|
|
||||||
@ -565,51 +388,6 @@ in (size <= size_t.max / E.sizeof)
|
|||||||
assert(rc.count == 1);
|
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.
|
* $(D_PSYMBOL Unique) stores an object that gets destroyed at the end of its scope.
|
||||||
*
|
*
|
||||||
@ -644,11 +422,7 @@ struct Unique(T)
|
|||||||
|
|
||||||
/// ditto
|
/// ditto
|
||||||
this(shared Allocator allocator)
|
this(shared Allocator allocator)
|
||||||
in
|
in (allocator !is null)
|
||||||
{
|
|
||||||
assert(allocator !is null);
|
|
||||||
}
|
|
||||||
do
|
|
||||||
{
|
{
|
||||||
this.allocator_ = allocator;
|
this.allocator_ = allocator;
|
||||||
}
|
}
|
||||||
@ -829,11 +603,7 @@ struct Unique(T)
|
|||||||
Unique!T unique(T, A...)(shared Allocator allocator, auto ref A args)
|
Unique!T unique(T, A...)(shared Allocator allocator, auto ref A args)
|
||||||
if (!is(T == interface) && !isAbstractClass!T
|
if (!is(T == interface) && !isAbstractClass!T
|
||||||
&& !isAssociativeArray!T && !isArray!T)
|
&& !isAssociativeArray!T && !isArray!T)
|
||||||
in
|
in (allocator !is null)
|
||||||
{
|
|
||||||
assert(allocator !is null);
|
|
||||||
}
|
|
||||||
do
|
|
||||||
{
|
{
|
||||||
auto payload = allocator.make!(T, A)(args);
|
auto payload = allocator.make!(T, A)(args);
|
||||||
return Unique!T(payload, allocator);
|
return Unique!T(payload, allocator);
|
||||||
@ -862,42 +632,3 @@ in (size <= size_t.max / E.sizeof)
|
|||||||
auto payload = allocator.resize!E(null, size);
|
auto payload = allocator.resize!E(null, size);
|
||||||
return Unique!T(payload, allocator);
|
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);
|
|
||||||
}
|
|
@ -407,12 +407,6 @@ struct ErrorCode
|
|||||||
assert(ec.toString() == "An invalid pointer address detected");
|
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;
|
private ErrorNo value_ = ErrorNo.success;
|
||||||
|
|
||||||
alias ErrorNo this;
|
alias ErrorNo this;
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
module tanya.algorithm.iteration;
|
module tanya.algorithm.iteration;
|
||||||
|
|
||||||
import tanya.algorithm.comparison;
|
import tanya.algorithm.comparison;
|
||||||
import tanya.memory.lifecycle;
|
import tanya.memory.lifetime;
|
||||||
import tanya.meta.trait;
|
import tanya.meta.trait;
|
||||||
import tanya.meta.transform;
|
import tanya.meta.transform;
|
||||||
import tanya.range;
|
import tanya.range;
|
||||||
|
@ -14,21 +14,21 @@
|
|||||||
*/
|
*/
|
||||||
module tanya.algorithm.mutation;
|
module tanya.algorithm.mutation;
|
||||||
|
|
||||||
|
static import tanya.memory.lifetime;
|
||||||
static import tanya.memory.op;
|
static import tanya.memory.op;
|
||||||
static import tanya.memory.lifecycle;
|
|
||||||
import tanya.meta.trait;
|
import tanya.meta.trait;
|
||||||
import tanya.meta.transform;
|
import tanya.meta.transform;
|
||||||
import tanya.range;
|
import tanya.range;
|
||||||
version (unittest) import tanya.test.stub;
|
version (unittest) import tanya.test.stub;
|
||||||
|
|
||||||
deprecated("Use tanya.memory.lifecycle.swap instead")
|
deprecated("Use tanya.memory.lifetime.swap instead")
|
||||||
alias swap = tanya.memory.lifecycle.swap;
|
alias swap = tanya.memory.lifetime.swap;
|
||||||
|
|
||||||
deprecated("Use tanya.memory.lifecycle.moveEmplace instead")
|
deprecated("Use tanya.memory.lifetime.moveEmplace instead")
|
||||||
alias moveEmplace = tanya.memory.lifecycle.moveEmplace;
|
alias moveEmplace = tanya.memory.lifetime.moveEmplace;
|
||||||
|
|
||||||
deprecated("Use tanya.memory.lifecycle.move instead")
|
deprecated("Use tanya.memory.lifetime.move instead")
|
||||||
alias move = tanya.memory.lifecycle.move;
|
alias move = tanya.memory.lifetime.move;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copies the $(D_PARAM source) range into the $(D_PARAM target) range.
|
* 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())
|
for (; !range.empty; range.popFront())
|
||||||
{
|
{
|
||||||
ElementType!Range* p = &range.front;
|
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
|
else
|
||||||
@ -314,7 +314,7 @@ if (isInputRange!Range && hasLvalueElements!Range)
|
|||||||
void destroyAll(Range)(Range range)
|
void destroyAll(Range)(Range range)
|
||||||
if (isInputRange!Range && hasLvalueElements!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))
|
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();
|
front.popFront();
|
||||||
next.popFront();
|
next.popFront();
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ module tanya.container.entry;
|
|||||||
|
|
||||||
import tanya.container.array;
|
import tanya.container.array;
|
||||||
import tanya.memory.allocator;
|
import tanya.memory.allocator;
|
||||||
import tanya.memory.lifecycle;
|
import tanya.memory.lifetime;
|
||||||
import tanya.meta.trait;
|
import tanya.meta.trait;
|
||||||
import tanya.meta.transform;
|
import tanya.meta.transform;
|
||||||
import tanya.typecons;
|
import tanya.typecons;
|
||||||
|
@ -16,8 +16,8 @@ module tanya.conv;
|
|||||||
|
|
||||||
import tanya.container.string;
|
import tanya.container.string;
|
||||||
import tanya.memory;
|
import tanya.memory;
|
||||||
deprecated("Use tanya.memory.lifecycle.emplace instead")
|
deprecated("Use tanya.memory.lifetime.emplace instead")
|
||||||
public import tanya.memory.lifecycle : emplace;
|
public import tanya.memory.lifetime : emplace;
|
||||||
import tanya.meta.trait;
|
import tanya.meta.trait;
|
||||||
import tanya.meta.transform;
|
import tanya.meta.transform;
|
||||||
import tanya.range;
|
import tanya.range;
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
* Source: $(LINK2 https://github.com/caraus-ecms/tanya/blob/master/source/tanya/exception.d,
|
* Source: $(LINK2 https://github.com/caraus-ecms/tanya/blob/master/source/tanya/exception.d,
|
||||||
* tanya/exception.d)
|
* tanya/exception.d)
|
||||||
*/
|
*/
|
||||||
deprecated("Use tanya.memory.lifecycle instead")
|
deprecated("Use tanya.memory.lifetimeinstead")
|
||||||
module tanya.exception;
|
module tanya.exception;
|
||||||
|
|
||||||
public import tanya.memory.lifecycle : onOutOfMemoryError, OutOfMemoryError;
|
public import tanya.memory.lifetime : onOutOfMemoryError, OutOfMemoryError;
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
* Source: $(LINK2 https://github.com/caraus-ecms/tanya/blob/master/source/tanya/functional.d,
|
* Source: $(LINK2 https://github.com/caraus-ecms/tanya/blob/master/source/tanya/functional.d,
|
||||||
* tanya/functional.d)
|
* tanya/functional.d)
|
||||||
*/
|
*/
|
||||||
deprecated("Use tanya.memory.lifecycle instead")
|
deprecated("Use tanya.memory.lifetime instead")
|
||||||
module tanya.functional;
|
module tanya.functional;
|
||||||
|
|
||||||
public import tanya.memory.lifecycle : forward;
|
public import tanya.memory.lifetime : forward;
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
/**
|
/**
|
||||||
* Arbitrary precision arithmetic.
|
* Arbitrary precision arithmetic.
|
||||||
*
|
*
|
||||||
* Copyright: Eugene Wissner 2016-2018.
|
* Copyright: Eugene Wissner 2016-2019.
|
||||||
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
|
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
|
||||||
* Mozilla Public License, v. 2.0).
|
* Mozilla Public License, v. 2.0).
|
||||||
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
|
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
/**
|
/**
|
||||||
* Number theory.
|
* Number theory.
|
||||||
*
|
*
|
||||||
* Copyright: Eugene Wissner 2017-2018.
|
* Copyright: Eugene Wissner 2017-2019.
|
||||||
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
|
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
|
||||||
* Mozilla Public License, v. 2.0).
|
* Mozilla Public License, v. 2.0).
|
||||||
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
|
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
* be found in its submodules. $(D_PSYMBOL tanya.math) doesn't import any
|
* be found in its submodules. $(D_PSYMBOL tanya.math) doesn't import any
|
||||||
* submodules publically, they should be imported explicitly.
|
* 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/,
|
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
|
||||||
* Mozilla Public License, v. 2.0).
|
* Mozilla Public License, v. 2.0).
|
||||||
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
|
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
|
||||||
@ -21,7 +21,6 @@
|
|||||||
*/
|
*/
|
||||||
module tanya.math;
|
module tanya.math;
|
||||||
|
|
||||||
import tanya.algorithm.mutation;
|
|
||||||
import tanya.math.mp;
|
import tanya.math.mp;
|
||||||
import tanya.math.nbtheory;
|
import tanya.math.nbtheory;
|
||||||
import tanya.meta.trait;
|
import tanya.meta.trait;
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
/**
|
/**
|
||||||
* Random number generator.
|
* Random number generator.
|
||||||
*
|
*
|
||||||
* Copyright: Eugene Wissner 2016-2018.
|
* Copyright: Eugene Wissner 2016-2019.
|
||||||
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
|
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
|
||||||
* Mozilla Public License, v. 2.0).
|
* Mozilla Public License, v. 2.0).
|
||||||
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
|
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
|
||||||
@ -14,7 +14,6 @@
|
|||||||
*/
|
*/
|
||||||
module tanya.math.random;
|
module tanya.math.random;
|
||||||
|
|
||||||
import std.digest.sha;
|
|
||||||
import tanya.memory;
|
import tanya.memory;
|
||||||
import tanya.typecons;
|
import tanya.typecons;
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ import tanya.container.string;
|
|||||||
import tanya.conv;
|
import tanya.conv;
|
||||||
import tanya.encoding.ascii;
|
import tanya.encoding.ascii;
|
||||||
import tanya.format;
|
import tanya.format;
|
||||||
import tanya.memory.lifecycle;
|
import tanya.memory.lifetime;
|
||||||
import tanya.meta.trait;
|
import tanya.meta.trait;
|
||||||
import tanya.meta.transform;
|
import tanya.meta.transform;
|
||||||
import tanya.net.iface;
|
import tanya.net.iface;
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
module tanya.range.adapter;
|
module tanya.range.adapter;
|
||||||
|
|
||||||
import tanya.algorithm.mutation;
|
import tanya.algorithm.mutation;
|
||||||
import tanya.memory.lifecycle;
|
import tanya.memory.lifetime;
|
||||||
import tanya.meta.trait;
|
import tanya.meta.trait;
|
||||||
import tanya.range;
|
import tanya.range;
|
||||||
|
|
||||||
|
@ -55,11 +55,7 @@ module tanya.range.array;
|
|||||||
* Precondition: $(D_INLINECODE array.length > 0).
|
* Precondition: $(D_INLINECODE array.length > 0).
|
||||||
*/
|
*/
|
||||||
@property ref inout(T) front(T)(return scope inout(T)[] array)
|
@property ref inout(T) front(T)(return scope inout(T)[] array)
|
||||||
in
|
in (array.length > 0)
|
||||||
{
|
|
||||||
assert(array.length > 0);
|
|
||||||
}
|
|
||||||
do
|
|
||||||
{
|
{
|
||||||
return array[0];
|
return array[0];
|
||||||
}
|
}
|
||||||
@ -95,11 +91,7 @@ do
|
|||||||
* Precondition: $(D_INLINECODE array.length > 0).
|
* Precondition: $(D_INLINECODE array.length > 0).
|
||||||
*/
|
*/
|
||||||
@property ref inout(T) back(T)(return scope inout(T)[] array)
|
@property ref inout(T) back(T)(return scope inout(T)[] array)
|
||||||
in
|
in (array.length > 0)
|
||||||
{
|
|
||||||
assert(array.length > 0);
|
|
||||||
}
|
|
||||||
do
|
|
||||||
{
|
{
|
||||||
return array[$ - 1];
|
return array[$ - 1];
|
||||||
}
|
}
|
||||||
@ -134,22 +126,14 @@ do
|
|||||||
* Precondition: $(D_INLINECODE array.length > 0).
|
* Precondition: $(D_INLINECODE array.length > 0).
|
||||||
*/
|
*/
|
||||||
void popFront(T)(scope ref inout(T)[] array)
|
void popFront(T)(scope ref inout(T)[] array)
|
||||||
in
|
in (array.length > 0)
|
||||||
{
|
|
||||||
assert(array.length > 0);
|
|
||||||
}
|
|
||||||
do
|
|
||||||
{
|
{
|
||||||
array = array[1 .. $];
|
array = array[1 .. $];
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ditto
|
/// ditto
|
||||||
void popBack(T)(scope ref inout(T)[] array)
|
void popBack(T)(scope ref inout(T)[] array)
|
||||||
in
|
in (array.length > 0)
|
||||||
{
|
|
||||||
assert(array.length > 0);
|
|
||||||
}
|
|
||||||
do
|
|
||||||
{
|
{
|
||||||
array = array[0 .. $ - 1];
|
array = array[0 .. $ - 1];
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
module tanya.range.primitive;
|
module tanya.range.primitive;
|
||||||
|
|
||||||
import tanya.algorithm.comparison;
|
import tanya.algorithm.comparison;
|
||||||
import tanya.memory.lifecycle;
|
import tanya.memory.lifetime;
|
||||||
import tanya.meta.trait;
|
import tanya.meta.trait;
|
||||||
import tanya.meta.transform;
|
import tanya.meta.transform;
|
||||||
import tanya.range.array;
|
import tanya.range.array;
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
module tanya.typecons;
|
module tanya.typecons;
|
||||||
|
|
||||||
import tanya.format;
|
import tanya.format;
|
||||||
import tanya.memory.lifecycle;
|
import tanya.memory.lifetime;
|
||||||
import tanya.meta.metafunction;
|
import tanya.meta.metafunction;
|
||||||
import tanya.meta.trait;
|
import tanya.meta.trait;
|
||||||
version (unittest) import tanya.test.stub;
|
version (unittest) import tanya.test.stub;
|
||||||
|
16
test/dub.json
Normal file
16
test/dub.json
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"name": "test",
|
||||||
|
"description": "Test suite for unittest-blocks",
|
||||||
|
"targetType": "library",
|
||||||
|
|
||||||
|
"dependencies": {
|
||||||
|
"tanya:middle": "*"
|
||||||
|
},
|
||||||
|
|
||||||
|
"sourcePaths": [
|
||||||
|
"."
|
||||||
|
],
|
||||||
|
"importPaths": [
|
||||||
|
"."
|
||||||
|
]
|
||||||
|
}
|
173
tests/tanya/memory/tests/lifetime.d
Normal file
173
tests/tanya/memory/tests/lifetime.d
Normal file
@ -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);
|
||||||
|
}
|
||||||
|
|
23
tests/tanya/memory/tests/mallocator.d
Normal file
23
tests/tanya/memory/tests/mallocator.d
Normal file
@ -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);
|
||||||
|
}
|
159
tests/tanya/memory/tests/mmappool.d
Normal file
159
tests/tanya/memory/tests/mmappool.d
Normal file
@ -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);
|
||||||
|
}
|
64
tests/tanya/memory/tests/op.d
Normal file
64
tests/tanya/memory/tests/op.d
Normal file
@ -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]));
|
||||||
|
}
|
250
tests/tanya/memory/tests/smartref.d
Normal file
250
tests/tanya/memory/tests/smartref.d
Normal file
@ -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;
|
||||||
|
}
|
||||||
|
}
|
27
tests/tanya/meta/tests/metafunction.d
Normal file
27
tests/tanya/meta/tests/metafunction.d
Normal file
@ -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));
|
||||||
|
}
|
169
tests/tanya/meta/tests/trait.d
Normal file
169
tests/tanya/meta/tests/trait.d
Normal file
@ -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);
|
||||||
|
}
|
50
tests/tanya/meta/tests/transform.d
Normal file
50
tests/tanya/meta/tests/transform.d
Normal file
@ -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));
|
||||||
|
}
|
9
tests/tanya/os/tests/error.d
Normal file
9
tests/tanya/os/tests/error.d
Normal file
@ -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);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user