summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/tanya/bitmanip.d43
-rw-r--r--source/tanya/conv.d204
-rw-r--r--source/tanya/format.d251
-rw-r--r--source/tanya/typecons.d227
4 files changed, 1 insertions, 724 deletions
diff --git a/source/tanya/bitmanip.d b/source/tanya/bitmanip.d
index 98e7042..c4526d8 100644
--- a/source/tanya/bitmanip.d
+++ b/source/tanya/bitmanip.d
@@ -5,7 +5,7 @@
/**
* Bit manipulation.
*
- * Copyright: Eugene Wissner 2018.
+ * Copyright: Eugene Wissner 2018-2019.
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
* Mozilla Public License, v. 2.0).
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
@@ -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).
*
diff --git a/source/tanya/conv.d b/source/tanya/conv.d
index 4010cb5..13e9235 100644
--- a/source/tanya/conv.d
+++ b/source/tanya/conv.d
@@ -22,12 +22,6 @@ import tanya.meta.trait;
import tanya.meta.transform;
import tanya.range;
-version (unittest)
-{
- import tanya.test.assertion;
- import tanya.test.stub;
-}
-
/**
* Thrown if a type conversion fails.
*/
@@ -143,86 +137,6 @@ do
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
* 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));
}
-@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
* 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.
*
@@ -449,13 +280,6 @@ if (isFloatingPoint!From
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
* $(D_KEYWORD enum).
@@ -497,16 +321,6 @@ if (isIntegral!From && is(To == enum))
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.
*
@@ -558,12 +372,6 @@ if (isNumeric!From && is(Unqual!To == bool) && !is(Unqual!To == Unqual!From))
assert(1.to!bool);
}
-@nogc pure @safe unittest
-{
- assertThrown!ConvException(&to!(bool, int), -1);
- assertThrown!ConvException(&to!(bool, int), 2);
-}
-
/// ditto
To to(To, From)(auto ref const From from)
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).
*
@@ -761,12 +564,5 @@ if (isInputRange!From && isSomeChar!(ElementType!From) && isIntegral!To)
assert("010".to!int() == 8);
assert("-010".to!int() == -8);
-
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);
}
diff --git a/source/tanya/format.d b/source/tanya/format.d
index db372c4..5c63a5e 100644
--- a/source/tanya/format.d
+++ b/source/tanya/format.d
@@ -124,18 +124,6 @@ if (isIntegral!T)
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
{
const FloatBits!double bits = { x };
@@ -2419,245 +2407,6 @@ if (isOutputRange!(R, const(char)[]))
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
{
const size_t position;
diff --git a/source/tanya/typecons.d b/source/tanya/typecons.d
index 700e2dd..507cd3c 100644
--- a/source/tanya/typecons.d
+++ b/source/tanya/typecons.d
@@ -21,7 +21,6 @@ import tanya.format;
import tanya.memory.lifetime;
import tanya.meta.metafunction;
import tanya.meta.trait;
-version (unittest) import tanya.test.stub;
/**
* $(D_PSYMBOL Tuple) can store two or more heterogeneous objects.
@@ -117,25 +116,6 @@ template Tuple(Specs...)
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).
*
@@ -428,112 +408,6 @@ struct Option(T)
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).
*
@@ -829,104 +703,3 @@ if (isTypeTuple!Specs && NoDuplicates!Specs.length == Specs.length)
assert(!variant.peek!int);
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)));
-}