Fix MmapPool private tests; move remaining tests
This commit is contained in:
parent
0fe7308a22
commit
a36b51f0c3
16
dub.json
16
dub.json
@ -52,6 +52,22 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "unittest",
|
"name": "unittest",
|
||||||
|
"versions": ["TanyaPhobos"],
|
||||||
|
"importPaths": [
|
||||||
|
"./source",
|
||||||
|
"./tests"
|
||||||
|
],
|
||||||
|
"sourcePaths": [
|
||||||
|
"./source",
|
||||||
|
"./tests"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "unittest-native",
|
||||||
|
"platforms": ["linux-x86_64-gdc"],
|
||||||
|
"preBuildCommands": ["ninja -C arch"],
|
||||||
|
"lflags": ["arch/tanya.a"],
|
||||||
|
"versions": ["TanyaNative"],
|
||||||
"importPaths": [
|
"importPaths": [
|
||||||
"./source",
|
"./source",
|
||||||
"./tests"
|
"./tests"
|
||||||
|
@ -501,3 +501,20 @@ final class MmapPool : Allocator
|
|||||||
}
|
}
|
||||||
private alias Block = shared BlockEntry*;
|
private alias Block = shared BlockEntry*;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@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);
|
||||||
|
}
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
/**
|
/**
|
||||||
* Bit manipulation.
|
* Bit manipulation.
|
||||||
*
|
*
|
||||||
* Copyright: Eugene Wissner 2018.
|
* Copyright: Eugene Wissner 2018-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)
|
||||||
@ -276,47 +276,6 @@ if (isBitFlagEnum!E)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@nogc nothrow pure @safe unittest
|
|
||||||
{
|
|
||||||
enum E : int
|
|
||||||
{
|
|
||||||
one = 1,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Casts to a boolean
|
|
||||||
assert(BitFlags!E(E.one));
|
|
||||||
assert(!BitFlags!E());
|
|
||||||
|
|
||||||
// Assigns to and compares with a single value
|
|
||||||
{
|
|
||||||
BitFlags!E bitFlags;
|
|
||||||
bitFlags = E.one;
|
|
||||||
assert(bitFlags == E.one);
|
|
||||||
}
|
|
||||||
// Assigns to and compares with the same type
|
|
||||||
{
|
|
||||||
auto bitFlags1 = BitFlags!E(E.one);
|
|
||||||
BitFlags!E bitFlags2;
|
|
||||||
bitFlags2 = bitFlags1;
|
|
||||||
assert(bitFlags1 == bitFlags2);
|
|
||||||
}
|
|
||||||
assert((BitFlags!E() | E.one) == BitFlags!E(E.one));
|
|
||||||
assert((BitFlags!E() | BitFlags!E(E.one)) == BitFlags!E(E.one));
|
|
||||||
|
|
||||||
assert(!(BitFlags!E() & BitFlags!E(E.one)));
|
|
||||||
|
|
||||||
assert(!(BitFlags!E(E.one) ^ E.one));
|
|
||||||
assert(BitFlags!E() ^ BitFlags!E(E.one));
|
|
||||||
|
|
||||||
assert(~BitFlags!E());
|
|
||||||
|
|
||||||
assert(BitFlags!E().toHash() == 0);
|
|
||||||
assert(BitFlags!E(E.one).toHash() != 0);
|
|
||||||
|
|
||||||
// opBinaryRight is allowed
|
|
||||||
static assert(is(typeof({ E.one | BitFlags!E(); })));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a $(D_PSYMBOL BitFlags) object initialized with $(D_PARAM field).
|
* Creates a $(D_PSYMBOL BitFlags) object initialized with $(D_PARAM field).
|
||||||
*
|
*
|
||||||
|
@ -22,12 +22,6 @@ import tanya.meta.trait;
|
|||||||
import tanya.meta.transform;
|
import tanya.meta.transform;
|
||||||
import tanya.range;
|
import tanya.range;
|
||||||
|
|
||||||
version (unittest)
|
|
||||||
{
|
|
||||||
import tanya.test.assertion;
|
|
||||||
import tanya.test.stub;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Thrown if a type conversion fails.
|
* Thrown if a type conversion fails.
|
||||||
*/
|
*/
|
||||||
@ -143,86 +137,6 @@ do
|
|||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ':' is not a hex value
|
|
||||||
@nogc nothrow pure @safe unittest
|
|
||||||
{
|
|
||||||
string colon = ":";
|
|
||||||
auto actual = readIntegral!ubyte(colon, 16);
|
|
||||||
assert(actual == 0);
|
|
||||||
assert(colon.length == 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// reads ubyte.max
|
|
||||||
@nogc nothrow pure @safe unittest
|
|
||||||
{
|
|
||||||
string number = "255";
|
|
||||||
assert(readIntegral!ubyte(number) == 255);
|
|
||||||
assert(number.empty);
|
|
||||||
}
|
|
||||||
|
|
||||||
// detects integer overflow
|
|
||||||
@nogc nothrow pure @safe unittest
|
|
||||||
{
|
|
||||||
string number = "500";
|
|
||||||
readIntegral!ubyte(number);
|
|
||||||
assert(number.front == '0');
|
|
||||||
assert(number.length == 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// stops on a non-digit
|
|
||||||
@nogc nothrow pure @safe unittest
|
|
||||||
{
|
|
||||||
string number = "10-";
|
|
||||||
readIntegral!ubyte(number);
|
|
||||||
assert(number.front == '-');
|
|
||||||
}
|
|
||||||
|
|
||||||
// returns false if the number string is empty
|
|
||||||
@nogc nothrow pure @safe unittest
|
|
||||||
{
|
|
||||||
string number = "";
|
|
||||||
readIntegral!ubyte(number);
|
|
||||||
assert(number.empty);
|
|
||||||
}
|
|
||||||
|
|
||||||
@nogc nothrow pure @safe unittest
|
|
||||||
{
|
|
||||||
string number = "29";
|
|
||||||
assert(readIntegral!ubyte(number) == 29);
|
|
||||||
assert(number.empty);
|
|
||||||
}
|
|
||||||
|
|
||||||
@nogc nothrow pure @safe unittest
|
|
||||||
{
|
|
||||||
string number = "25467";
|
|
||||||
readIntegral!ubyte(number);
|
|
||||||
assert(number.front == '6');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Converts lower case hexadecimals
|
|
||||||
@nogc nothrow pure @safe unittest
|
|
||||||
{
|
|
||||||
string number = "a";
|
|
||||||
assert(readIntegral!ubyte(number, 16) == 10);
|
|
||||||
assert(number.empty);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Converts upper case hexadecimals
|
|
||||||
@nogc nothrow pure @safe unittest
|
|
||||||
{
|
|
||||||
string number = "FF";
|
|
||||||
assert(readIntegral!ubyte(number, 16) == 255);
|
|
||||||
assert(number.empty);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handles small overflows
|
|
||||||
@nogc nothrow pure @safe unittest
|
|
||||||
{
|
|
||||||
string number = "256";
|
|
||||||
assert(readIntegral!ubyte(number, 10) == 25);
|
|
||||||
assert(number.front == '6');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If the source type $(D_PARAM From) and the target type $(D_PARAM To) are
|
* If the source type $(D_PARAM From) and the target type $(D_PARAM To) are
|
||||||
* equal, does nothing. If $(D_PARAM From) can be implicitly converted to
|
* equal, does nothing. If $(D_PARAM From) can be implicitly converted to
|
||||||
@ -262,12 +176,6 @@ template to(To)
|
|||||||
static assert(is(typeof(val) == int));
|
static assert(is(typeof(val) == int));
|
||||||
}
|
}
|
||||||
|
|
||||||
@nogc nothrow pure @safe unittest
|
|
||||||
{
|
|
||||||
int val = 5;
|
|
||||||
assert(val.to!int() == 5);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Performs checked conversion from an integral type $(D_PARAM From) to an
|
* Performs checked conversion from an integral type $(D_PARAM From) to an
|
||||||
* integral type $(D_PARAM To).
|
* integral type $(D_PARAM To).
|
||||||
@ -330,83 +238,6 @@ if (isIntegral!From
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@nogc nothrow pure @safe unittest
|
|
||||||
{
|
|
||||||
// ubyte -> ushort
|
|
||||||
assert((cast(ubyte) 0).to!ushort == 0);
|
|
||||||
assert((cast(ubyte) 1).to!ushort == 1);
|
|
||||||
assert((cast(ubyte) (ubyte.max - 1)).to!ushort == ubyte.max - 1);
|
|
||||||
assert((cast(ubyte) ubyte.max).to!ushort == ubyte.max);
|
|
||||||
|
|
||||||
// ubyte -> short
|
|
||||||
assert((cast(ubyte) 0).to!short == 0);
|
|
||||||
assert((cast(ubyte) 1).to!short == 1);
|
|
||||||
assert((cast(ubyte) (ubyte.max - 1)).to!short == ubyte.max - 1);
|
|
||||||
assert((cast(ubyte) ubyte.max).to!short == ubyte.max);
|
|
||||||
}
|
|
||||||
|
|
||||||
@nogc pure @safe unittest
|
|
||||||
{
|
|
||||||
// ubyte <- ushort
|
|
||||||
assert((cast(ushort) 0).to!ubyte == 0);
|
|
||||||
assert((cast(ushort) 1).to!ubyte == 1);
|
|
||||||
assert((cast(ushort) (ubyte.max - 1)).to!ubyte == ubyte.max - 1);
|
|
||||||
assert((cast(ushort) ubyte.max).to!ubyte == ubyte.max);
|
|
||||||
|
|
||||||
// ubyte <- short
|
|
||||||
assert((cast(short) 0).to!ubyte == 0);
|
|
||||||
assert((cast(short) 1).to!ubyte == 1);
|
|
||||||
assert((cast(short) (ubyte.max - 1)).to!ubyte == ubyte.max - 1);
|
|
||||||
assert((cast(short) ubyte.max).to!ubyte == ubyte.max);
|
|
||||||
|
|
||||||
// short <-> int
|
|
||||||
assert(short.min.to!int == short.min);
|
|
||||||
assert((short.min + 1).to!int == short.min + 1);
|
|
||||||
assert((cast(short) -1).to!int == -1);
|
|
||||||
assert((cast(short) 0).to!int == 0);
|
|
||||||
assert((cast(short) 1).to!int == 1);
|
|
||||||
assert((short.max - 1).to!int == short.max - 1);
|
|
||||||
assert(short.max.to!int == short.max);
|
|
||||||
|
|
||||||
assert((cast(int) short.min).to!short == short.min);
|
|
||||||
assert((cast(int) short.min + 1).to!short == short.min + 1);
|
|
||||||
assert((cast(int) -1).to!short == -1);
|
|
||||||
assert((cast(int) 0).to!short == 0);
|
|
||||||
assert((cast(int) 1).to!short == 1);
|
|
||||||
assert((cast(int) short.max - 1).to!short == short.max - 1);
|
|
||||||
assert((cast(int) short.max).to!short == short.max);
|
|
||||||
|
|
||||||
// uint <-> int
|
|
||||||
assert((cast(uint) 0).to!int == 0);
|
|
||||||
assert((cast(uint) 1).to!int == 1);
|
|
||||||
assert((cast(uint) (int.max - 1)).to!int == int.max - 1);
|
|
||||||
assert((cast(uint) int.max).to!int == int.max);
|
|
||||||
|
|
||||||
assert((cast(int) 0).to!uint == 0);
|
|
||||||
assert((cast(int) 1).to!uint == 1);
|
|
||||||
assert((cast(int) (int.max - 1)).to!uint == int.max - 1);
|
|
||||||
assert((cast(int) int.max).to!uint == int.max);
|
|
||||||
}
|
|
||||||
|
|
||||||
@nogc pure @safe unittest
|
|
||||||
{
|
|
||||||
assertThrown!ConvException(&to!(short, int), int.min);
|
|
||||||
assertThrown!ConvException(&to!(short, int), int.max);
|
|
||||||
assertThrown!ConvException(&to!(ushort, uint), uint.max);
|
|
||||||
assertThrown!ConvException(&to!(uint, int), -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@nogc nothrow pure @safe unittest
|
|
||||||
{
|
|
||||||
enum Test : int
|
|
||||||
{
|
|
||||||
one,
|
|
||||||
two,
|
|
||||||
}
|
|
||||||
assert(Test.one.to!int == 0);
|
|
||||||
assert(Test.two.to!int == 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts a floating point number to an integral type.
|
* Converts a floating point number to an integral type.
|
||||||
*
|
*
|
||||||
@ -449,13 +280,6 @@ if (isFloatingPoint!From
|
|||||||
assert(2147483646.5.to!uint == 2147483646);
|
assert(2147483646.5.to!uint == 2147483646);
|
||||||
}
|
}
|
||||||
|
|
||||||
@nogc pure @safe unittest
|
|
||||||
{
|
|
||||||
assertThrown!ConvException(&to!(int, double), 2147483647.5);
|
|
||||||
assertThrown!ConvException(&to!(int, double), -2147483648.5);
|
|
||||||
assertThrown!ConvException(&to!(uint, double), -21474.5);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Performs checked conversion from an integral type $(D_PARAM From) to an
|
* Performs checked conversion from an integral type $(D_PARAM From) to an
|
||||||
* $(D_KEYWORD enum).
|
* $(D_KEYWORD enum).
|
||||||
@ -497,16 +321,6 @@ if (isIntegral!From && is(To == enum))
|
|||||||
assert(1.to!Test == Test.two);
|
assert(1.to!Test == Test.two);
|
||||||
}
|
}
|
||||||
|
|
||||||
@nogc pure @safe unittest
|
|
||||||
{
|
|
||||||
enum Test : uint
|
|
||||||
{
|
|
||||||
one,
|
|
||||||
two,
|
|
||||||
}
|
|
||||||
assertThrown!ConvException(&to!(Test, int), 5);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts $(D_PARAM from) to a boolean.
|
* Converts $(D_PARAM from) to a boolean.
|
||||||
*
|
*
|
||||||
@ -558,12 +372,6 @@ if (isNumeric!From && is(Unqual!To == bool) && !is(Unqual!To == Unqual!From))
|
|||||||
assert(1.to!bool);
|
assert(1.to!bool);
|
||||||
}
|
}
|
||||||
|
|
||||||
@nogc pure @safe unittest
|
|
||||||
{
|
|
||||||
assertThrown!ConvException(&to!(bool, int), -1);
|
|
||||||
assertThrown!ConvException(&to!(bool, int), 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// ditto
|
/// ditto
|
||||||
To to(To, From)(auto ref const From from)
|
To to(To, From)(auto ref const From from)
|
||||||
if ((is(From == String) || isSomeString!From) && is(Unqual!To == bool))
|
if ((is(From == String) || isSomeString!From) && is(Unqual!To == bool))
|
||||||
@ -590,11 +398,6 @@ if ((is(From == String) || isSomeString!From) && is(Unqual!To == bool))
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@nogc pure @safe unittest
|
|
||||||
{
|
|
||||||
assertThrown!ConvException(() => "1".to!bool);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts a boolean to $(D_PARAM To).
|
* Converts a boolean to $(D_PARAM To).
|
||||||
*
|
*
|
||||||
@ -761,12 +564,5 @@ if (isInputRange!From && isSomeChar!(ElementType!From) && isIntegral!To)
|
|||||||
assert("010".to!int() == 8);
|
assert("010".to!int() == 8);
|
||||||
assert("-010".to!int() == -8);
|
assert("-010".to!int() == -8);
|
||||||
|
|
||||||
|
|
||||||
assert("-128".to!byte == cast(byte) -128);
|
assert("-128".to!byte == cast(byte) -128);
|
||||||
|
|
||||||
assertThrown!ConvException(() => "".to!int);
|
|
||||||
assertThrown!ConvException(() => "-".to!int);
|
|
||||||
assertThrown!ConvException(() => "-5".to!uint);
|
|
||||||
assertThrown!ConvException(() => "-129".to!byte);
|
|
||||||
assertThrown!ConvException(() => "256".to!ubyte);
|
|
||||||
}
|
}
|
||||||
|
@ -124,18 +124,6 @@ if (isIntegral!T)
|
|||||||
return buffer[$ - l - 1 .. $ - 1];
|
return buffer[$ - l - 1 .. $ - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Converting an integer to string.
|
|
||||||
@nogc nothrow pure @system unittest
|
|
||||||
{
|
|
||||||
char[21] buf;
|
|
||||||
|
|
||||||
assert(integral2String(80, buf) == "80");
|
|
||||||
assert(integral2String(-80, buf) == "-80");
|
|
||||||
assert(integral2String(0, buf) == "0");
|
|
||||||
assert(integral2String(uint.max, buf) == "4294967295");
|
|
||||||
assert(integral2String(int.min, buf) == "-2147483648");
|
|
||||||
}
|
|
||||||
|
|
||||||
private int frexp(const double x) @nogc nothrow pure @safe
|
private int frexp(const double x) @nogc nothrow pure @safe
|
||||||
{
|
{
|
||||||
const FloatBits!double bits = { x };
|
const FloatBits!double bits = { x };
|
||||||
@ -2419,245 +2407,6 @@ if (isOutputRange!(R, const(char)[]))
|
|||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
// doesn't print the first argument repeatedly
|
|
||||||
@nogc nothrow pure @safe unittest
|
|
||||||
{
|
|
||||||
assert(format!"{}{}"(1, 2) == "12");
|
|
||||||
}
|
|
||||||
|
|
||||||
@nogc nothrow pure @safe unittest
|
|
||||||
{
|
|
||||||
assert(format!"Without arguments"() == "Without arguments");
|
|
||||||
assert(format!""().length == 0);
|
|
||||||
|
|
||||||
static assert(!is(typeof(format!"{}"())));
|
|
||||||
static assert(!is(typeof(format!"{j}"(5))));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Enum.
|
|
||||||
@nogc nothrow pure @safe unittest
|
|
||||||
{
|
|
||||||
enum E1 : int
|
|
||||||
{
|
|
||||||
one,
|
|
||||||
two,
|
|
||||||
}
|
|
||||||
assert(format!"{}"(E1.one) == "one");
|
|
||||||
|
|
||||||
const E1 e1;
|
|
||||||
assert(format!"{}"(e1) == "one");
|
|
||||||
}
|
|
||||||
|
|
||||||
// One argument tests.
|
|
||||||
@nogc pure @safe unittest
|
|
||||||
{
|
|
||||||
// Modifiers.
|
|
||||||
assert(format!"{}"(8.5) == "8.5");
|
|
||||||
assert(format!"{}"(8.6) == "8.6");
|
|
||||||
assert(format!"{}"(1000) == "1000");
|
|
||||||
assert(format!"{}"(1) == "1");
|
|
||||||
assert(format!"{}"(10.25) == "10.25");
|
|
||||||
assert(format!"{}"(1) == "1");
|
|
||||||
assert(format!"{}"(0.01) == "0.01");
|
|
||||||
|
|
||||||
// String printing.
|
|
||||||
assert(format!"{}"("Some weired string") == "Some weired string");
|
|
||||||
assert(format!"{}"(cast(string) null) == "");
|
|
||||||
assert(format!"{}"('c') == "c");
|
|
||||||
|
|
||||||
// Integer.
|
|
||||||
assert(format!"{}"(8) == "8");
|
|
||||||
assert(format!"{}"(8) == "8");
|
|
||||||
assert(format!"{}"(-8) == "-8");
|
|
||||||
assert(format!"{}"(-8L) == "-8");
|
|
||||||
assert(format!"{}"(8) == "8");
|
|
||||||
assert(format!"{}"(100000001) == "100000001");
|
|
||||||
assert(format!"{}"(99999999L) == "99999999");
|
|
||||||
assert(format!"{}"(10) == "10");
|
|
||||||
assert(format!"{}"(10L) == "10");
|
|
||||||
|
|
||||||
// Floating point.
|
|
||||||
assert(format!"{}"(0.1234) == "0.1234");
|
|
||||||
assert(format!"{}"(0.3) == "0.3");
|
|
||||||
assert(format!"{}"(0.333333333333) == "0.333333");
|
|
||||||
assert(format!"{}"(38234.1234) == "38234.1");
|
|
||||||
assert(format!"{}"(-0.3) == "-0.3");
|
|
||||||
assert(format!"{}"(0.000000000000000006) == "6e-18");
|
|
||||||
assert(format!"{}"(0.0) == "0");
|
|
||||||
assert(format!"{}"(double.init) == "NaN");
|
|
||||||
assert(format!"{}"(-double.init) == "-NaN");
|
|
||||||
assert(format!"{}"(double.infinity) == "Inf");
|
|
||||||
assert(format!"{}"(-double.infinity) == "-Inf");
|
|
||||||
assert(format!"{}"(0.000000000000000000000000003) == "3e-27");
|
|
||||||
assert(format!"{}"(0.23432e304) == "2.3432e+303");
|
|
||||||
assert(format!"{}"(-0.23432e8) == "-2.3432e+07");
|
|
||||||
assert(format!"{}"(1e-307) == "1e-307");
|
|
||||||
assert(format!"{}"(1e+8) == "1e+08");
|
|
||||||
assert(format!"{}"(111234.1) == "111234");
|
|
||||||
assert(format!"{}"(0.999) == "0.999");
|
|
||||||
assert(format!"{}"(0x1p-16382L) == "0");
|
|
||||||
assert(format!"{}"(1e+3) == "1000");
|
|
||||||
assert(format!"{}"(38234.1234) == "38234.1");
|
|
||||||
assert(format!"{}"(double.max) == "1.79769e+308");
|
|
||||||
|
|
||||||
// typeof(null).
|
|
||||||
assert(format!"{}"(null) == "null");
|
|
||||||
|
|
||||||
// Boolean.
|
|
||||||
assert(format!"{}"(true) == "true");
|
|
||||||
assert(format!"{}"(false) == "false");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unsafe tests with pointers.
|
|
||||||
@nogc pure @system unittest
|
|
||||||
{
|
|
||||||
// Pointer convesions
|
|
||||||
assert(format!"{}"(cast(void*) 1) == "0x1");
|
|
||||||
assert(format!"{}"(cast(void*) 20) == "0x14");
|
|
||||||
assert(format!"{}"(cast(void*) null) == "0x0");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Structs.
|
|
||||||
@nogc pure @safe unittest
|
|
||||||
{
|
|
||||||
static struct WithoutStringify1
|
|
||||||
{
|
|
||||||
int a;
|
|
||||||
void func()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
assert(format!"{}"(WithoutStringify1(6)) == "WithoutStringify1(6)");
|
|
||||||
|
|
||||||
static struct WithoutStringify2
|
|
||||||
{
|
|
||||||
}
|
|
||||||
assert(format!"{}"(WithoutStringify2()) == "WithoutStringify2()");
|
|
||||||
|
|
||||||
static struct WithoutStringify3
|
|
||||||
{
|
|
||||||
int a = -2;
|
|
||||||
int b = 8;
|
|
||||||
}
|
|
||||||
assert(format!"{}"(WithoutStringify3()) == "WithoutStringify3(-2, 8)");
|
|
||||||
|
|
||||||
struct Nested
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
void func()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
assert(format!"{}"(Nested()) == "Nested(0)");
|
|
||||||
|
|
||||||
static struct WithToString
|
|
||||||
{
|
|
||||||
OR toString(OR)(OR range) const
|
|
||||||
{
|
|
||||||
put(range, "toString method");
|
|
||||||
return range;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
assert(format!"{}"(WithToString()) == "toString method");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Aggregate types.
|
|
||||||
@system unittest // Object.toString has no attributes.
|
|
||||||
{
|
|
||||||
import tanya.memory;
|
|
||||||
import tanya.memory.smartref;
|
|
||||||
|
|
||||||
interface I
|
|
||||||
{
|
|
||||||
}
|
|
||||||
class A : I
|
|
||||||
{
|
|
||||||
}
|
|
||||||
auto instance = defaultAllocator.unique!A();
|
|
||||||
assert(format!"{}"(instance.get()) == instance.get().toString());
|
|
||||||
assert(format!"{}"(cast(I) instance.get()) == I.classinfo.name);
|
|
||||||
assert(format!"{}"(cast(A) null) == "null");
|
|
||||||
|
|
||||||
class B
|
|
||||||
{
|
|
||||||
OR toString(OR)(OR range) const
|
|
||||||
{
|
|
||||||
put(range, "Class B");
|
|
||||||
return range;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
assert(format!"{}"(cast(B) null) == "null");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unions.
|
|
||||||
unittest
|
|
||||||
{
|
|
||||||
union U
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
char c;
|
|
||||||
}
|
|
||||||
assert(format!"{}"(U(2)) == "U");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ranges.
|
|
||||||
@nogc pure @safe unittest
|
|
||||||
{
|
|
||||||
static struct Stringish
|
|
||||||
{
|
|
||||||
private string content = "Some content";
|
|
||||||
|
|
||||||
immutable(char) front() const @nogc nothrow pure @safe
|
|
||||||
{
|
|
||||||
return this.content[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
void popFront() @nogc nothrow pure @safe
|
|
||||||
{
|
|
||||||
this.content = this.content[1 .. $];
|
|
||||||
}
|
|
||||||
|
|
||||||
bool empty() const @nogc nothrow pure @safe
|
|
||||||
{
|
|
||||||
return this.content.length == 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
assert(format!"{}"(Stringish()) == "Some content");
|
|
||||||
|
|
||||||
static struct Intish
|
|
||||||
{
|
|
||||||
private int front_ = 3;
|
|
||||||
|
|
||||||
int front() const @nogc nothrow pure @safe
|
|
||||||
{
|
|
||||||
return this.front_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void popFront() @nogc nothrow pure @safe
|
|
||||||
{
|
|
||||||
--this.front_;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool empty() const @nogc nothrow pure @safe
|
|
||||||
{
|
|
||||||
return this.front == 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
assert(format!"{}"(Intish()) == "[3, 2, 1]");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Typeid.
|
|
||||||
nothrow pure @safe unittest
|
|
||||||
{
|
|
||||||
assert(format!"{}"(typeid(int[])) == "int[]");
|
|
||||||
|
|
||||||
class C
|
|
||||||
{
|
|
||||||
}
|
|
||||||
assert(format!"{}"(typeid(C)) == typeid(C).toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
private struct FormatSpec
|
private struct FormatSpec
|
||||||
{
|
{
|
||||||
const size_t position;
|
const size_t position;
|
||||||
|
@ -21,7 +21,6 @@ import tanya.format;
|
|||||||
import tanya.memory.lifetime;
|
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;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* $(D_PSYMBOL Tuple) can store two or more heterogeneous objects.
|
* $(D_PSYMBOL Tuple) can store two or more heterogeneous objects.
|
||||||
@ -117,25 +116,6 @@ template Tuple(Specs...)
|
|||||||
assert(pair[1] == "second");
|
assert(pair[1] == "second");
|
||||||
}
|
}
|
||||||
|
|
||||||
@nogc nothrow pure @safe unittest
|
|
||||||
{
|
|
||||||
static assert(is(Tuple!(int, int)));
|
|
||||||
static assert(!is(Tuple!(int, 5)));
|
|
||||||
|
|
||||||
static assert(is(Tuple!(int, "first", int)));
|
|
||||||
static assert(is(Tuple!(int, "first", int, "second")));
|
|
||||||
static assert(is(Tuple!(int, "first", int)));
|
|
||||||
|
|
||||||
static assert(is(Tuple!(int, int, "second")));
|
|
||||||
static assert(!is(Tuple!("first", int, "second", int)));
|
|
||||||
static assert(!is(Tuple!(int, int, int)));
|
|
||||||
|
|
||||||
static assert(!is(Tuple!(int, "first")));
|
|
||||||
|
|
||||||
static assert(!is(Tuple!(int, double, char)));
|
|
||||||
static assert(!is(Tuple!(int, "first", double, "second", char, "third")));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new $(D_PSYMBOL Tuple).
|
* Creates a new $(D_PSYMBOL Tuple).
|
||||||
*
|
*
|
||||||
@ -428,112 +408,6 @@ struct Option(T)
|
|||||||
assert(option.isNothing);
|
assert(option.isNothing);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assigns a new value
|
|
||||||
@nogc nothrow pure @safe unittest
|
|
||||||
{
|
|
||||||
{
|
|
||||||
Option!int option = 5;
|
|
||||||
option = 8;
|
|
||||||
assert(!option.isNothing);
|
|
||||||
assert(option == 8);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
Option!int option;
|
|
||||||
const int newValue = 8;
|
|
||||||
assert(option.isNothing);
|
|
||||||
option = newValue;
|
|
||||||
assert(!option.isNothing);
|
|
||||||
assert(option == newValue);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
Option!int option1;
|
|
||||||
Option!int option2 = 5;
|
|
||||||
assert(option1.isNothing);
|
|
||||||
option1 = option2;
|
|
||||||
assert(!option1.isNothing);
|
|
||||||
assert(option1.get == 5);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Constructs with a value passed by reference
|
|
||||||
@nogc nothrow pure @safe unittest
|
|
||||||
{
|
|
||||||
int i = 5;
|
|
||||||
assert(Option!int(i).get == 5);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Moving
|
|
||||||
@nogc nothrow pure @safe unittest
|
|
||||||
{
|
|
||||||
static assert(is(typeof(Option!NonCopyable(NonCopyable()))));
|
|
||||||
// The value cannot be returned by reference because the default value
|
|
||||||
// isn't passed by reference
|
|
||||||
static assert(!is(typeof(Option!DisabledPostblit().or(NonCopyable()))));
|
|
||||||
{
|
|
||||||
NonCopyable notCopyable;
|
|
||||||
static assert(is(typeof(Option!NonCopyable().or(notCopyable))));
|
|
||||||
}
|
|
||||||
{
|
|
||||||
Option!NonCopyable option;
|
|
||||||
assert(option.isNothing);
|
|
||||||
option = NonCopyable();
|
|
||||||
assert(!option.isNothing);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
Option!NonCopyable option;
|
|
||||||
assert(option.isNothing);
|
|
||||||
option = Option!NonCopyable(NonCopyable());
|
|
||||||
assert(!option.isNothing);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cast to bool is done before touching the encapsulated value
|
|
||||||
@nogc nothrow pure @safe unittest
|
|
||||||
{
|
|
||||||
assert(Option!bool(false));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Option can be const
|
|
||||||
@nogc nothrow pure @safe unittest
|
|
||||||
{
|
|
||||||
assert((const Option!int(5)).get == 5);
|
|
||||||
assert((const Option!int()).or(5) == 5);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Equality
|
|
||||||
@nogc nothrow pure @safe unittest
|
|
||||||
{
|
|
||||||
assert(Option!int() == Option!int());
|
|
||||||
assert(Option!int(0) != Option!int());
|
|
||||||
assert(Option!int(5) == Option!int(5));
|
|
||||||
assert(Option!int(5) == 5);
|
|
||||||
assert(Option!int(5) == cast(ubyte) 5);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns default value
|
|
||||||
@nogc nothrow pure @safe unittest
|
|
||||||
{
|
|
||||||
int i = 5;
|
|
||||||
assert(((ref e) => e)(Option!int().or(i)) == 5);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Implements toHash() for nothing
|
|
||||||
@nogc nothrow pure @safe unittest
|
|
||||||
{
|
|
||||||
alias OptionT = Option!Hashable;
|
|
||||||
assert(OptionT().toHash() == 0U);
|
|
||||||
assert(OptionT(Hashable(1U)).toHash() == 1U);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Can assign Option that is nothing
|
|
||||||
@nogc nothrow pure @safe unittest
|
|
||||||
{
|
|
||||||
auto option1 = Option!int(5);
|
|
||||||
Option!int option2;
|
|
||||||
option1 = option2;
|
|
||||||
assert(option1.isNothing);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new $(D_PSYMBOL Option).
|
* Creates a new $(D_PSYMBOL Option).
|
||||||
*
|
*
|
||||||
@ -829,104 +703,3 @@ if (isTypeTuple!Specs && NoDuplicates!Specs.length == Specs.length)
|
|||||||
assert(!variant.peek!int);
|
assert(!variant.peek!int);
|
||||||
assert(variant.get!double == 5.4);
|
assert(variant.get!double == 5.4);
|
||||||
}
|
}
|
||||||
|
|
||||||
@nogc nothrow pure @safe unittest
|
|
||||||
{
|
|
||||||
Variant!(int, double) variant;
|
|
||||||
variant = 5;
|
|
||||||
assert(variant.peek!int);
|
|
||||||
}
|
|
||||||
|
|
||||||
@nogc nothrow pure @safe unittest
|
|
||||||
{
|
|
||||||
Variant!(int, double) variant;
|
|
||||||
variant = 5.0;
|
|
||||||
assert(!variant.peek!int);
|
|
||||||
}
|
|
||||||
|
|
||||||
@nogc nothrow pure @safe unittest
|
|
||||||
{
|
|
||||||
Variant!(int, double) variant = 5;
|
|
||||||
assert(variant.get!int == 5);
|
|
||||||
}
|
|
||||||
|
|
||||||
@nogc nothrow pure @safe unittest
|
|
||||||
{
|
|
||||||
static assert(is(Variant!(int, float)));
|
|
||||||
static assert(is(Variant!int));
|
|
||||||
}
|
|
||||||
|
|
||||||
@nogc nothrow pure @safe unittest
|
|
||||||
{
|
|
||||||
static struct WithDestructorAndCopy
|
|
||||||
{
|
|
||||||
this(this) @nogc nothrow pure @safe
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
~this() @nogc nothrow pure @safe
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
static assert(is(Variant!WithDestructorAndCopy));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Equality compares the underlying objects
|
|
||||||
@nogc nothrow pure @safe unittest
|
|
||||||
{
|
|
||||||
Variant!(int, double) variant1 = 5;
|
|
||||||
Variant!(int, double) variant2 = 5;
|
|
||||||
assert(variant1 == variant2);
|
|
||||||
}
|
|
||||||
|
|
||||||
@nogc nothrow pure @safe unittest
|
|
||||||
{
|
|
||||||
Variant!(int, double) variant1 = 5;
|
|
||||||
Variant!(int, double) variant2 = 6;
|
|
||||||
assert(variant1 != variant2);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Differently typed variants aren't equal
|
|
||||||
@nogc nothrow pure @safe unittest
|
|
||||||
{
|
|
||||||
Variant!(int, double) variant1 = 5;
|
|
||||||
Variant!(int, double) variant2 = 5.0;
|
|
||||||
assert(variant1 != variant2);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Uninitialized variants are equal
|
|
||||||
@nogc nothrow pure @safe unittest
|
|
||||||
{
|
|
||||||
Variant!(int, double) variant1, variant2;
|
|
||||||
assert(variant1 == variant2);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calls postblit constructor of the active type
|
|
||||||
@nogc nothrow pure @safe unittest
|
|
||||||
{
|
|
||||||
static struct S
|
|
||||||
{
|
|
||||||
bool called;
|
|
||||||
|
|
||||||
this(this)
|
|
||||||
{
|
|
||||||
this.called = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Variant!(int, S) variant1 = S();
|
|
||||||
auto variant2 = variant1;
|
|
||||||
assert(variant2.get!S.called);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Variant.type is null if the Variant doesn't have a value
|
|
||||||
@nogc nothrow pure @safe unittest
|
|
||||||
{
|
|
||||||
Variant!(int, uint) variant;
|
|
||||||
assert(variant.type is null);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Variant can contain only distinct types
|
|
||||||
@nogc nothrow pure @safe unittest
|
|
||||||
{
|
|
||||||
static assert(!is(Variant!(int, int)));
|
|
||||||
}
|
|
||||||
|
@ -17,23 +17,6 @@ import tanya.memory.mmappool;
|
|||||||
assert(p.length == 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
|
@nogc nothrow pure @system unittest
|
||||||
{
|
{
|
||||||
auto p = MmapPool.instance.allocate(20);
|
auto p = MmapPool.instance.allocate(20);
|
||||||
@ -93,16 +76,6 @@ import tanya.memory.mmappool;
|
|||||||
MmapPool.instance.deallocate(p);
|
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
|
// A lot of allocations/deallocations, but it is the minimum caused a
|
||||||
// segmentation fault because MmapPool reallocateInPlace moves a block wrong.
|
// segmentation fault because MmapPool reallocateInPlace moves a block wrong.
|
||||||
@nogc nothrow pure @system unittest
|
@nogc nothrow pure @system unittest
|
||||||
|
54
tests/tanya/tests/bitmanip.d
Normal file
54
tests/tanya/tests/bitmanip.d
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
module tanya.tests.bitmanip;
|
||||||
|
|
||||||
|
import tanya.bitmanip;
|
||||||
|
|
||||||
|
// Casts to a boolean
|
||||||
|
@nogc nothrow pure @safe unittest
|
||||||
|
{
|
||||||
|
assert(BitFlags!One(One.one));
|
||||||
|
assert(!BitFlags!One());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assigns to and compares with a single value
|
||||||
|
@nogc nothrow pure @safe unittest
|
||||||
|
{
|
||||||
|
BitFlags!One bitFlags;
|
||||||
|
bitFlags = One.one;
|
||||||
|
assert(bitFlags == One.one);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assigns to and compares with the same type
|
||||||
|
@nogc nothrow pure @safe unittest
|
||||||
|
{
|
||||||
|
auto bitFlags1 = BitFlags!One(One.one);
|
||||||
|
BitFlags!One bitFlags2;
|
||||||
|
bitFlags2 = bitFlags1;
|
||||||
|
assert(bitFlags1 == bitFlags2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@nogc nothrow pure @safe unittest
|
||||||
|
{
|
||||||
|
assert((BitFlags!One() | One.one) == BitFlags!One(One.one));
|
||||||
|
assert((BitFlags!One() | BitFlags!One(One.one)) == BitFlags!One(One.one));
|
||||||
|
|
||||||
|
assert(!(BitFlags!One() & BitFlags!One(One.one)));
|
||||||
|
|
||||||
|
assert(!(BitFlags!One(One.one) ^ One.one));
|
||||||
|
assert(BitFlags!One() ^ BitFlags!One(One.one));
|
||||||
|
|
||||||
|
assert(~BitFlags!One());
|
||||||
|
|
||||||
|
assert(BitFlags!One().toHash() == 0);
|
||||||
|
assert(BitFlags!One(One.one).toHash() != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// opBinaryRight is allowed
|
||||||
|
@nogc nothrow pure @safe unittest
|
||||||
|
{
|
||||||
|
static assert(is(typeof({ One.one | BitFlags!One(); })));
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum One : int
|
||||||
|
{
|
||||||
|
one = 1,
|
||||||
|
}
|
206
tests/tanya/tests/conv.d
Normal file
206
tests/tanya/tests/conv.d
Normal file
@ -0,0 +1,206 @@
|
|||||||
|
module tanya.tests.conv;
|
||||||
|
|
||||||
|
import tanya.conv;
|
||||||
|
import tanya.range;
|
||||||
|
import tanya.test.assertion;
|
||||||
|
import tanya.test.stub;
|
||||||
|
|
||||||
|
// ':' is not a hex value
|
||||||
|
@nogc nothrow pure @safe unittest
|
||||||
|
{
|
||||||
|
string colon = ":";
|
||||||
|
auto actual = readIntegral!ubyte(colon, 16);
|
||||||
|
assert(actual == 0);
|
||||||
|
assert(colon.length == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// reads ubyte.max
|
||||||
|
@nogc nothrow pure @safe unittest
|
||||||
|
{
|
||||||
|
string number = "255";
|
||||||
|
assert(readIntegral!ubyte(number) == 255);
|
||||||
|
assert(number.empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
// detects integer overflow
|
||||||
|
@nogc nothrow pure @safe unittest
|
||||||
|
{
|
||||||
|
string number = "500";
|
||||||
|
readIntegral!ubyte(number);
|
||||||
|
assert(number.front == '0');
|
||||||
|
assert(number.length == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// stops on a non-digit
|
||||||
|
@nogc nothrow pure @safe unittest
|
||||||
|
{
|
||||||
|
string number = "10-";
|
||||||
|
readIntegral!ubyte(number);
|
||||||
|
assert(number.front == '-');
|
||||||
|
}
|
||||||
|
|
||||||
|
// returns false if the number string is empty
|
||||||
|
@nogc nothrow pure @safe unittest
|
||||||
|
{
|
||||||
|
string number = "";
|
||||||
|
readIntegral!ubyte(number);
|
||||||
|
assert(number.empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
@nogc nothrow pure @safe unittest
|
||||||
|
{
|
||||||
|
string number = "29";
|
||||||
|
assert(readIntegral!ubyte(number) == 29);
|
||||||
|
assert(number.empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
@nogc nothrow pure @safe unittest
|
||||||
|
{
|
||||||
|
string number = "25467";
|
||||||
|
readIntegral!ubyte(number);
|
||||||
|
assert(number.front == '6');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Converts lower case hexadecimals
|
||||||
|
@nogc nothrow pure @safe unittest
|
||||||
|
{
|
||||||
|
string number = "a";
|
||||||
|
assert(readIntegral!ubyte(number, 16) == 10);
|
||||||
|
assert(number.empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Converts upper case hexadecimals
|
||||||
|
@nogc nothrow pure @safe unittest
|
||||||
|
{
|
||||||
|
string number = "FF";
|
||||||
|
assert(readIntegral!ubyte(number, 16) == 255);
|
||||||
|
assert(number.empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handles small overflows
|
||||||
|
@nogc nothrow pure @safe unittest
|
||||||
|
{
|
||||||
|
string number = "256";
|
||||||
|
assert(readIntegral!ubyte(number, 10) == 25);
|
||||||
|
assert(number.front == '6');
|
||||||
|
}
|
||||||
|
|
||||||
|
@nogc nothrow pure @safe unittest
|
||||||
|
{
|
||||||
|
int val = 5;
|
||||||
|
assert(val.to!int() == 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
@nogc nothrow pure @safe unittest
|
||||||
|
{
|
||||||
|
// ubyte -> ushort
|
||||||
|
assert((cast(ubyte) 0).to!ushort == 0);
|
||||||
|
assert((cast(ubyte) 1).to!ushort == 1);
|
||||||
|
assert((cast(ubyte) (ubyte.max - 1)).to!ushort == ubyte.max - 1);
|
||||||
|
assert((cast(ubyte) ubyte.max).to!ushort == ubyte.max);
|
||||||
|
|
||||||
|
// ubyte -> short
|
||||||
|
assert((cast(ubyte) 0).to!short == 0);
|
||||||
|
assert((cast(ubyte) 1).to!short == 1);
|
||||||
|
assert((cast(ubyte) (ubyte.max - 1)).to!short == ubyte.max - 1);
|
||||||
|
assert((cast(ubyte) ubyte.max).to!short == ubyte.max);
|
||||||
|
}
|
||||||
|
|
||||||
|
@nogc pure @safe unittest
|
||||||
|
{
|
||||||
|
// ubyte <- ushort
|
||||||
|
assert((cast(ushort) 0).to!ubyte == 0);
|
||||||
|
assert((cast(ushort) 1).to!ubyte == 1);
|
||||||
|
assert((cast(ushort) (ubyte.max - 1)).to!ubyte == ubyte.max - 1);
|
||||||
|
assert((cast(ushort) ubyte.max).to!ubyte == ubyte.max);
|
||||||
|
|
||||||
|
// ubyte <- short
|
||||||
|
assert((cast(short) 0).to!ubyte == 0);
|
||||||
|
assert((cast(short) 1).to!ubyte == 1);
|
||||||
|
assert((cast(short) (ubyte.max - 1)).to!ubyte == ubyte.max - 1);
|
||||||
|
assert((cast(short) ubyte.max).to!ubyte == ubyte.max);
|
||||||
|
|
||||||
|
// short <-> int
|
||||||
|
assert(short.min.to!int == short.min);
|
||||||
|
assert((short.min + 1).to!int == short.min + 1);
|
||||||
|
assert((cast(short) -1).to!int == -1);
|
||||||
|
assert((cast(short) 0).to!int == 0);
|
||||||
|
assert((cast(short) 1).to!int == 1);
|
||||||
|
assert((short.max - 1).to!int == short.max - 1);
|
||||||
|
assert(short.max.to!int == short.max);
|
||||||
|
|
||||||
|
assert((cast(int) short.min).to!short == short.min);
|
||||||
|
assert((cast(int) short.min + 1).to!short == short.min + 1);
|
||||||
|
assert((cast(int) -1).to!short == -1);
|
||||||
|
assert((cast(int) 0).to!short == 0);
|
||||||
|
assert((cast(int) 1).to!short == 1);
|
||||||
|
assert((cast(int) short.max - 1).to!short == short.max - 1);
|
||||||
|
assert((cast(int) short.max).to!short == short.max);
|
||||||
|
|
||||||
|
// uint <-> int
|
||||||
|
assert((cast(uint) 0).to!int == 0);
|
||||||
|
assert((cast(uint) 1).to!int == 1);
|
||||||
|
assert((cast(uint) (int.max - 1)).to!int == int.max - 1);
|
||||||
|
assert((cast(uint) int.max).to!int == int.max);
|
||||||
|
|
||||||
|
assert((cast(int) 0).to!uint == 0);
|
||||||
|
assert((cast(int) 1).to!uint == 1);
|
||||||
|
assert((cast(int) (int.max - 1)).to!uint == int.max - 1);
|
||||||
|
assert((cast(int) int.max).to!uint == int.max);
|
||||||
|
}
|
||||||
|
|
||||||
|
@nogc pure @safe unittest
|
||||||
|
{
|
||||||
|
assertThrown!ConvException(&to!(short, int), int.min);
|
||||||
|
assertThrown!ConvException(&to!(short, int), int.max);
|
||||||
|
assertThrown!ConvException(&to!(ushort, uint), uint.max);
|
||||||
|
assertThrown!ConvException(&to!(uint, int), -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@nogc nothrow pure @safe unittest
|
||||||
|
{
|
||||||
|
enum Test : int
|
||||||
|
{
|
||||||
|
one,
|
||||||
|
two,
|
||||||
|
}
|
||||||
|
assert(Test.one.to!int == 0);
|
||||||
|
assert(Test.two.to!int == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@nogc pure @safe unittest
|
||||||
|
{
|
||||||
|
assertThrown!ConvException(&to!(int, double), 2147483647.5);
|
||||||
|
assertThrown!ConvException(&to!(int, double), -2147483648.5);
|
||||||
|
assertThrown!ConvException(&to!(uint, double), -21474.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
@nogc pure @safe unittest
|
||||||
|
{
|
||||||
|
enum Test : uint
|
||||||
|
{
|
||||||
|
one,
|
||||||
|
two,
|
||||||
|
}
|
||||||
|
assertThrown!ConvException(&to!(Test, int), 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
@nogc pure @safe unittest
|
||||||
|
{
|
||||||
|
assertThrown!ConvException(&to!(bool, int), -1);
|
||||||
|
assertThrown!ConvException(&to!(bool, int), 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@nogc pure @safe unittest
|
||||||
|
{
|
||||||
|
assertThrown!ConvException(() => "1".to!bool);
|
||||||
|
}
|
||||||
|
|
||||||
|
@nogc pure @safe unittest
|
||||||
|
{
|
||||||
|
assertThrown!ConvException(() => "".to!int);
|
||||||
|
assertThrown!ConvException(() => "-".to!int);
|
||||||
|
assertThrown!ConvException(() => "-5".to!uint);
|
||||||
|
assertThrown!ConvException(() => "-129".to!byte);
|
||||||
|
assertThrown!ConvException(() => "256".to!ubyte);
|
||||||
|
}
|
269
tests/tanya/tests/format.d
Normal file
269
tests/tanya/tests/format.d
Normal file
@ -0,0 +1,269 @@
|
|||||||
|
module tanya.tests.format;
|
||||||
|
|
||||||
|
import tanya.format;
|
||||||
|
import tanya.range;
|
||||||
|
|
||||||
|
// Converting an integer to string.
|
||||||
|
@nogc nothrow pure @system unittest
|
||||||
|
{
|
||||||
|
char[21] buf;
|
||||||
|
|
||||||
|
assert(integral2String(80, buf) == "80");
|
||||||
|
assert(integral2String(-80, buf) == "-80");
|
||||||
|
assert(integral2String(0, buf) == "0");
|
||||||
|
assert(integral2String(uint.max, buf) == "4294967295");
|
||||||
|
assert(integral2String(int.min, buf) == "-2147483648");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Doesn't print the first argument repeatedly
|
||||||
|
@nogc nothrow pure @safe unittest
|
||||||
|
{
|
||||||
|
assert(format!"{}{}"(1, 2) == "12");
|
||||||
|
}
|
||||||
|
|
||||||
|
@nogc nothrow pure @safe unittest
|
||||||
|
{
|
||||||
|
assert(format!"Without arguments"() == "Without arguments");
|
||||||
|
assert(format!""().length == 0);
|
||||||
|
|
||||||
|
static assert(!is(typeof(format!"{}"())));
|
||||||
|
static assert(!is(typeof(format!"{j}"(5))));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enum
|
||||||
|
@nogc nothrow pure @safe unittest
|
||||||
|
{
|
||||||
|
enum E1 : int
|
||||||
|
{
|
||||||
|
one,
|
||||||
|
two,
|
||||||
|
}
|
||||||
|
assert(format!"{}"(E1.one) == "one");
|
||||||
|
|
||||||
|
const E1 e1;
|
||||||
|
assert(format!"{}"(e1) == "one");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Modifiers
|
||||||
|
@nogc pure @safe unittest
|
||||||
|
{
|
||||||
|
assert(format!"{}"(8.5) == "8.5");
|
||||||
|
assert(format!"{}"(8.6) == "8.6");
|
||||||
|
assert(format!"{}"(1000) == "1000");
|
||||||
|
assert(format!"{}"(1) == "1");
|
||||||
|
assert(format!"{}"(10.25) == "10.25");
|
||||||
|
assert(format!"{}"(1) == "1");
|
||||||
|
assert(format!"{}"(0.01) == "0.01");
|
||||||
|
}
|
||||||
|
|
||||||
|
// String printing
|
||||||
|
@nogc pure @safe unittest
|
||||||
|
{
|
||||||
|
assert(format!"{}"("Some weired string") == "Some weired string");
|
||||||
|
assert(format!"{}"(cast(string) null) == "");
|
||||||
|
assert(format!"{}"('c') == "c");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Integer
|
||||||
|
@nogc pure @safe unittest
|
||||||
|
{
|
||||||
|
assert(format!"{}"(8) == "8");
|
||||||
|
assert(format!"{}"(8) == "8");
|
||||||
|
assert(format!"{}"(-8) == "-8");
|
||||||
|
assert(format!"{}"(-8L) == "-8");
|
||||||
|
assert(format!"{}"(8) == "8");
|
||||||
|
assert(format!"{}"(100000001) == "100000001");
|
||||||
|
assert(format!"{}"(99999999L) == "99999999");
|
||||||
|
assert(format!"{}"(10) == "10");
|
||||||
|
assert(format!"{}"(10L) == "10");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Floating point
|
||||||
|
@nogc pure @safe unittest
|
||||||
|
{
|
||||||
|
assert(format!"{}"(0.1234) == "0.1234");
|
||||||
|
assert(format!"{}"(0.3) == "0.3");
|
||||||
|
assert(format!"{}"(0.333333333333) == "0.333333");
|
||||||
|
assert(format!"{}"(38234.1234) == "38234.1");
|
||||||
|
assert(format!"{}"(-0.3) == "-0.3");
|
||||||
|
assert(format!"{}"(0.000000000000000006) == "6e-18");
|
||||||
|
assert(format!"{}"(0.0) == "0");
|
||||||
|
assert(format!"{}"(double.init) == "NaN");
|
||||||
|
assert(format!"{}"(-double.init) == "-NaN");
|
||||||
|
assert(format!"{}"(double.infinity) == "Inf");
|
||||||
|
assert(format!"{}"(-double.infinity) == "-Inf");
|
||||||
|
assert(format!"{}"(0.000000000000000000000000003) == "3e-27");
|
||||||
|
assert(format!"{}"(0.23432e304) == "2.3432e+303");
|
||||||
|
assert(format!"{}"(-0.23432e8) == "-2.3432e+07");
|
||||||
|
assert(format!"{}"(1e-307) == "1e-307");
|
||||||
|
assert(format!"{}"(1e+8) == "1e+08");
|
||||||
|
assert(format!"{}"(111234.1) == "111234");
|
||||||
|
assert(format!"{}"(0.999) == "0.999");
|
||||||
|
assert(format!"{}"(0x1p-16382L) == "0");
|
||||||
|
assert(format!"{}"(1e+3) == "1000");
|
||||||
|
assert(format!"{}"(38234.1234) == "38234.1");
|
||||||
|
assert(format!"{}"(double.max) == "1.79769e+308");
|
||||||
|
}
|
||||||
|
|
||||||
|
// typeof(null)
|
||||||
|
@nogc pure @safe unittest
|
||||||
|
{
|
||||||
|
assert(format!"{}"(null) == "null");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Boolean
|
||||||
|
@nogc pure @safe unittest
|
||||||
|
{
|
||||||
|
assert(format!"{}"(true) == "true");
|
||||||
|
assert(format!"{}"(false) == "false");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unsafe tests with pointers
|
||||||
|
@nogc pure @system unittest
|
||||||
|
{
|
||||||
|
// Pointer convesions
|
||||||
|
assert(format!"{}"(cast(void*) 1) == "0x1");
|
||||||
|
assert(format!"{}"(cast(void*) 20) == "0x14");
|
||||||
|
assert(format!"{}"(cast(void*) null) == "0x0");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Structs
|
||||||
|
@nogc pure @safe unittest
|
||||||
|
{
|
||||||
|
static struct WithoutStringify1
|
||||||
|
{
|
||||||
|
int a;
|
||||||
|
void func()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert(format!"{}"(WithoutStringify1(6)) == "WithoutStringify1(6)");
|
||||||
|
|
||||||
|
static struct WithoutStringify2
|
||||||
|
{
|
||||||
|
}
|
||||||
|
assert(format!"{}"(WithoutStringify2()) == "WithoutStringify2()");
|
||||||
|
|
||||||
|
static struct WithoutStringify3
|
||||||
|
{
|
||||||
|
int a = -2;
|
||||||
|
int b = 8;
|
||||||
|
}
|
||||||
|
assert(format!"{}"(WithoutStringify3()) == "WithoutStringify3(-2, 8)");
|
||||||
|
|
||||||
|
struct Nested
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
void func()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert(format!"{}"(Nested()) == "Nested(0)");
|
||||||
|
|
||||||
|
static struct WithToString
|
||||||
|
{
|
||||||
|
OR toString(OR)(OR range) const
|
||||||
|
{
|
||||||
|
put(range, "toString method");
|
||||||
|
return range;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert(format!"{}"(WithToString()) == "toString method");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Aggregate types
|
||||||
|
@system unittest // Object.toString has no attributes.
|
||||||
|
{
|
||||||
|
import tanya.memory;
|
||||||
|
import tanya.memory.smartref;
|
||||||
|
|
||||||
|
interface I
|
||||||
|
{
|
||||||
|
}
|
||||||
|
class A : I
|
||||||
|
{
|
||||||
|
}
|
||||||
|
auto instance = defaultAllocator.unique!A();
|
||||||
|
assert(format!"{}"(instance.get()) == instance.get().toString());
|
||||||
|
assert(format!"{}"(cast(I) instance.get()) == I.classinfo.name);
|
||||||
|
assert(format!"{}"(cast(A) null) == "null");
|
||||||
|
|
||||||
|
class B
|
||||||
|
{
|
||||||
|
OR toString(OR)(OR range) const
|
||||||
|
{
|
||||||
|
put(range, "Class B");
|
||||||
|
return range;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert(format!"{}"(cast(B) null) == "null");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unions
|
||||||
|
unittest
|
||||||
|
{
|
||||||
|
union U
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
char c;
|
||||||
|
}
|
||||||
|
assert(format!"{}"(U(2)) == "U");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ranges
|
||||||
|
@nogc pure @safe unittest
|
||||||
|
{
|
||||||
|
static struct Stringish
|
||||||
|
{
|
||||||
|
private string content = "Some content";
|
||||||
|
|
||||||
|
immutable(char) front() const @nogc nothrow pure @safe
|
||||||
|
{
|
||||||
|
return this.content[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
void popFront() @nogc nothrow pure @safe
|
||||||
|
{
|
||||||
|
this.content = this.content[1 .. $];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool empty() const @nogc nothrow pure @safe
|
||||||
|
{
|
||||||
|
return this.content.length == 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert(format!"{}"(Stringish()) == "Some content");
|
||||||
|
|
||||||
|
static struct Intish
|
||||||
|
{
|
||||||
|
private int front_ = 3;
|
||||||
|
|
||||||
|
int front() const @nogc nothrow pure @safe
|
||||||
|
{
|
||||||
|
return this.front_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void popFront() @nogc nothrow pure @safe
|
||||||
|
{
|
||||||
|
--this.front_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool empty() const @nogc nothrow pure @safe
|
||||||
|
{
|
||||||
|
return this.front == 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert(format!"{}"(Intish()) == "[3, 2, 1]");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Typeid
|
||||||
|
nothrow pure @safe unittest
|
||||||
|
{
|
||||||
|
assert(format!"{}"(typeid(int[])) == "int[]");
|
||||||
|
|
||||||
|
class C
|
||||||
|
{
|
||||||
|
}
|
||||||
|
assert(format!"{}"(typeid(C)) == typeid(C).toString());
|
||||||
|
}
|
238
tests/tanya/tests/typecons.d
Normal file
238
tests/tanya/tests/typecons.d
Normal file
@ -0,0 +1,238 @@
|
|||||||
|
module tanya.tests.typecons;
|
||||||
|
|
||||||
|
import tanya.test.stub;
|
||||||
|
import tanya.typecons;
|
||||||
|
|
||||||
|
@nogc nothrow pure @safe unittest
|
||||||
|
{
|
||||||
|
static assert(is(Tuple!(int, int)));
|
||||||
|
static assert(!is(Tuple!(int, 5)));
|
||||||
|
|
||||||
|
static assert(is(Tuple!(int, "first", int)));
|
||||||
|
static assert(is(Tuple!(int, "first", int, "second")));
|
||||||
|
static assert(is(Tuple!(int, "first", int)));
|
||||||
|
|
||||||
|
static assert(is(Tuple!(int, int, "second")));
|
||||||
|
static assert(!is(Tuple!("first", int, "second", int)));
|
||||||
|
static assert(!is(Tuple!(int, int, int)));
|
||||||
|
|
||||||
|
static assert(!is(Tuple!(int, "first")));
|
||||||
|
|
||||||
|
static assert(!is(Tuple!(int, double, char)));
|
||||||
|
static assert(!is(Tuple!(int, "first", double, "second", char, "third")));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assigns a new value
|
||||||
|
@nogc nothrow pure @safe unittest
|
||||||
|
{
|
||||||
|
Option!int option = 5;
|
||||||
|
option = 8;
|
||||||
|
assert(!option.isNothing);
|
||||||
|
assert(option == 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
@nogc nothrow pure @safe unittest
|
||||||
|
{
|
||||||
|
Option!int option;
|
||||||
|
const int newValue = 8;
|
||||||
|
assert(option.isNothing);
|
||||||
|
option = newValue;
|
||||||
|
assert(!option.isNothing);
|
||||||
|
assert(option == newValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
@nogc nothrow pure @safe unittest
|
||||||
|
{
|
||||||
|
Option!int option1;
|
||||||
|
Option!int option2 = 5;
|
||||||
|
assert(option1.isNothing);
|
||||||
|
option1 = option2;
|
||||||
|
assert(!option1.isNothing);
|
||||||
|
assert(option1.get == 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Constructs with a value passed by reference
|
||||||
|
@nogc nothrow pure @safe unittest
|
||||||
|
{
|
||||||
|
int i = 5;
|
||||||
|
assert(Option!int(i).get == 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Moving
|
||||||
|
@nogc nothrow pure @safe unittest
|
||||||
|
{
|
||||||
|
static assert(is(typeof(Option!NonCopyable(NonCopyable()))));
|
||||||
|
// The value cannot be returned by reference because the default value
|
||||||
|
// isn't passed by reference
|
||||||
|
static assert(!is(typeof(Option!DisabledPostblit().or(NonCopyable()))));
|
||||||
|
}
|
||||||
|
|
||||||
|
@nogc nothrow pure @safe unittest
|
||||||
|
{
|
||||||
|
NonCopyable notCopyable;
|
||||||
|
static assert(is(typeof(Option!NonCopyable().or(notCopyable))));
|
||||||
|
}
|
||||||
|
|
||||||
|
@nogc nothrow pure @safe unittest
|
||||||
|
{
|
||||||
|
Option!NonCopyable option;
|
||||||
|
assert(option.isNothing);
|
||||||
|
option = NonCopyable();
|
||||||
|
assert(!option.isNothing);
|
||||||
|
}
|
||||||
|
|
||||||
|
@nogc nothrow pure @safe unittest
|
||||||
|
{
|
||||||
|
Option!NonCopyable option;
|
||||||
|
assert(option.isNothing);
|
||||||
|
option = Option!NonCopyable(NonCopyable());
|
||||||
|
assert(!option.isNothing);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cast to bool is done before touching the encapsulated value
|
||||||
|
@nogc nothrow pure @safe unittest
|
||||||
|
{
|
||||||
|
assert(Option!bool(false));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Option can be const
|
||||||
|
@nogc nothrow pure @safe unittest
|
||||||
|
{
|
||||||
|
assert((const Option!int(5)).get == 5);
|
||||||
|
assert((const Option!int()).or(5) == 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Equality
|
||||||
|
@nogc nothrow pure @safe unittest
|
||||||
|
{
|
||||||
|
assert(Option!int() == Option!int());
|
||||||
|
assert(Option!int(0) != Option!int());
|
||||||
|
assert(Option!int(5) == Option!int(5));
|
||||||
|
assert(Option!int(5) == 5);
|
||||||
|
assert(Option!int(5) == cast(ubyte) 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns default value
|
||||||
|
@nogc nothrow pure @safe unittest
|
||||||
|
{
|
||||||
|
int i = 5;
|
||||||
|
assert(((ref e) => e)(Option!int().or(i)) == 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implements toHash() for nothing
|
||||||
|
@nogc nothrow pure @safe unittest
|
||||||
|
{
|
||||||
|
alias OptionT = Option!Hashable;
|
||||||
|
assert(OptionT().toHash() == 0U);
|
||||||
|
assert(OptionT(Hashable(1U)).toHash() == 1U);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Can assign Option that is nothing
|
||||||
|
@nogc nothrow pure @safe unittest
|
||||||
|
{
|
||||||
|
auto option1 = Option!int(5);
|
||||||
|
Option!int option2;
|
||||||
|
option1 = option2;
|
||||||
|
assert(option1.isNothing);
|
||||||
|
}
|
||||||
|
|
||||||
|
@nogc nothrow pure @safe unittest
|
||||||
|
{
|
||||||
|
Variant!(int, double) variant;
|
||||||
|
variant = 5;
|
||||||
|
assert(variant.peek!int);
|
||||||
|
}
|
||||||
|
|
||||||
|
@nogc nothrow pure @safe unittest
|
||||||
|
{
|
||||||
|
Variant!(int, double) variant;
|
||||||
|
variant = 5.0;
|
||||||
|
assert(!variant.peek!int);
|
||||||
|
}
|
||||||
|
|
||||||
|
@nogc nothrow pure @safe unittest
|
||||||
|
{
|
||||||
|
Variant!(int, double) variant = 5;
|
||||||
|
assert(variant.get!int == 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
@nogc nothrow pure @safe unittest
|
||||||
|
{
|
||||||
|
static assert(is(Variant!(int, float)));
|
||||||
|
static assert(is(Variant!int));
|
||||||
|
}
|
||||||
|
|
||||||
|
@nogc nothrow pure @safe unittest
|
||||||
|
{
|
||||||
|
static struct WithDestructorAndCopy
|
||||||
|
{
|
||||||
|
this(this) @nogc nothrow pure @safe
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~this() @nogc nothrow pure @safe
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static assert(is(Variant!WithDestructorAndCopy));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Equality compares the underlying objects
|
||||||
|
@nogc nothrow pure @safe unittest
|
||||||
|
{
|
||||||
|
Variant!(int, double) variant1 = 5;
|
||||||
|
Variant!(int, double) variant2 = 5;
|
||||||
|
assert(variant1 == variant2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@nogc nothrow pure @safe unittest
|
||||||
|
{
|
||||||
|
Variant!(int, double) variant1 = 5;
|
||||||
|
Variant!(int, double) variant2 = 6;
|
||||||
|
assert(variant1 != variant2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Differently typed variants aren't equal
|
||||||
|
@nogc nothrow pure @safe unittest
|
||||||
|
{
|
||||||
|
Variant!(int, double) variant1 = 5;
|
||||||
|
Variant!(int, double) variant2 = 5.0;
|
||||||
|
assert(variant1 != variant2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uninitialized variants are equal
|
||||||
|
@nogc nothrow pure @safe unittest
|
||||||
|
{
|
||||||
|
Variant!(int, double) variant1, variant2;
|
||||||
|
assert(variant1 == variant2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calls postblit constructor of the active type
|
||||||
|
@nogc nothrow pure @safe unittest
|
||||||
|
{
|
||||||
|
static struct S
|
||||||
|
{
|
||||||
|
bool called;
|
||||||
|
|
||||||
|
this(this)
|
||||||
|
{
|
||||||
|
this.called = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Variant!(int, S) variant1 = S();
|
||||||
|
auto variant2 = variant1;
|
||||||
|
assert(variant2.get!S.called);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Variant.type is null if the Variant doesn't have a value
|
||||||
|
@nogc nothrow pure @safe unittest
|
||||||
|
{
|
||||||
|
Variant!(int, uint) variant;
|
||||||
|
assert(variant.type is null);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Variant can contain only distinct types
|
||||||
|
@nogc nothrow pure @safe unittest
|
||||||
|
{
|
||||||
|
static assert(!is(Variant!(int, int)));
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user