mirror of
https://github.com/gcc-mirror/gcc.git
synced 2026-05-06 14:59:39 +02:00
Extracts all public unittests from libphobos/src and emits them as standalone tests in the testsuite using the tests_extractor script. Compiling every module in the Phobos library with unittests included is computationally expensive, and these tests are now only ran when GCC_TEST_RUN_EXPENSIVE is not empty. When instead just compiling the unittests and linking in the module under test, this has been observed to reduce the time spent running the testsuite by more than half. libphobos/ChangeLog: * testsuite/libphobos.phobos/shared/phobos-shared.exp: Require is-effective-target run_expensive_tests. * testsuite/libphobos.phobos/static/phobos-static.exp: Likewise. * testsuite/libphobos.phobos/phobos.exp: New test. * testsuite/libphobos.phobos/std_algorithm_comparison.d: New test. * testsuite/libphobos.phobos/std_algorithm_iteration.d: New test. * testsuite/libphobos.phobos/std_algorithm_mutation.d: New test. * testsuite/libphobos.phobos/std_algorithm_searching.d: New test. * testsuite/libphobos.phobos/std_algorithm_setops.d: New test. * testsuite/libphobos.phobos/std_algorithm_sorting.d: New test. * testsuite/libphobos.phobos/std_array.d: New test. * testsuite/libphobos.phobos/std_ascii.d: New test. * testsuite/libphobos.phobos/std_base64.d: New test. * testsuite/libphobos.phobos/std_bigint.d: New test. * testsuite/libphobos.phobos/std_bitmanip.d: New test. * testsuite/libphobos.phobos/std_checkedint.d: New test. * testsuite/libphobos.phobos/std_complex.d: New test. * testsuite/libphobos.phobos/std_concurrency.d: New test. * testsuite/libphobos.phobos/std_container_array.d: New test. * testsuite/libphobos.phobos/std_container_binaryheap.d: New test. * testsuite/libphobos.phobos/std_container_dlist.d: New test. * testsuite/libphobos.phobos/std_container_rbtree.d: New test. * testsuite/libphobos.phobos/std_container_slist.d: New test. * testsuite/libphobos.phobos/std_container_util.d: New test. * testsuite/libphobos.phobos/std_conv.d: New test. * testsuite/libphobos.phobos/std_csv.d: New test. * testsuite/libphobos.phobos/std_datetime_date.d: New test. * testsuite/libphobos.phobos/std_datetime_interval.d: New test. * testsuite/libphobos.phobos/std_datetime_package.d: New test. * testsuite/libphobos.phobos/std_datetime_stopwatch.d: New test. * testsuite/libphobos.phobos/std_datetime_systime.d: New test. * testsuite/libphobos.phobos/std_datetime_timezone.d: New test. * testsuite/libphobos.phobos/std_demangle.d: New test. * testsuite/libphobos.phobos/std_digest_crc.d: New test. * testsuite/libphobos.phobos/std_digest_hmac.d: New test. * testsuite/libphobos.phobos/std_digest_md.d: New test. * testsuite/libphobos.phobos/std_digest_murmurhash.d: New test. * testsuite/libphobos.phobos/std_digest_package.d: New test. * testsuite/libphobos.phobos/std_digest_ripemd.d: New test. * testsuite/libphobos.phobos/std_digest_sha.d: New test. * testsuite/libphobos.phobos/std_encoding.d: New test. * testsuite/libphobos.phobos/std_exception.d: New test. * testsuite/libphobos.phobos/std_experimental_allocator_building_blocks_affix_allocator.d: New test. * testsuite/libphobos.phobos/std_experimental_allocator_building_blocks_aligned_block_list.d: New test. * testsuite/libphobos.phobos/std_experimental_allocator_building_blocks_allocator_list.d: New test. * testsuite/libphobos.phobos/std_experimental_allocator_building_blocks_ascending_page_allocator.d: New test. * testsuite/libphobos.phobos/std_experimental_allocator_building_blocks_bitmapped_block.d: New test. * testsuite/libphobos.phobos/std_experimental_allocator_building_blocks_bucketizer.d: New test. * testsuite/libphobos.phobos/std_experimental_allocator_building_blocks_fallback_allocator.d: New test. * testsuite/libphobos.phobos/std_experimental_allocator_building_blocks_free_list.d: New test. * testsuite/libphobos.phobos/std_experimental_allocator_building_blocks_kernighan_ritchie.d: New test. * testsuite/libphobos.phobos/std_experimental_allocator_building_blocks_quantizer.d: New test. * testsuite/libphobos.phobos/std_experimental_allocator_building_blocks_region.d: New test. * testsuite/libphobos.phobos/std_experimental_allocator_building_blocks_scoped_allocator.d: New test. * testsuite/libphobos.phobos/std_experimental_allocator_building_blocks_segregator.d: New test. * testsuite/libphobos.phobos/std_experimental_allocator_building_blocks_stats_collector.d: New test. * testsuite/libphobos.phobos/std_experimental_allocator_common.d: New test. * testsuite/libphobos.phobos/std_experimental_allocator_gc_allocator.d: New test. * testsuite/libphobos.phobos/std_experimental_allocator_mallocator.d: New test. * testsuite/libphobos.phobos/std_experimental_allocator_package.d: New test. * testsuite/libphobos.phobos/std_experimental_allocator_showcase.d: New test. * testsuite/libphobos.phobos/std_experimental_allocator_typed.d: New test. * testsuite/libphobos.phobos/std_file.d: New test. * testsuite/libphobos.phobos/std_format_package.d: New test. * testsuite/libphobos.phobos/std_format_read.d: New test. * testsuite/libphobos.phobos/std_format_spec.d: New test. * testsuite/libphobos.phobos/std_format_write.d: New test. * testsuite/libphobos.phobos/std_functional.d: New test. * testsuite/libphobos.phobos/std_getopt.d: New test. * testsuite/libphobos.phobos/std_int128.d: New test. * testsuite/libphobos.phobos/std_internal_cstring.d: New test. * testsuite/libphobos.phobos/std_internal_scopebuffer.d: New test. * testsuite/libphobos.phobos/std_json.d: New test. * testsuite/libphobos.phobos/std_logger_core.d: New test. * testsuite/libphobos.phobos/std_logger_nulllogger.d: New test. * testsuite/libphobos.phobos/std_math_algebraic.d: New test. * testsuite/libphobos.phobos/std_math_exponential.d: New test. * testsuite/libphobos.phobos/std_math_hardware.d: New test. * testsuite/libphobos.phobos/std_math_operations.d: New test. * testsuite/libphobos.phobos/std_math_remainder.d: New test. * testsuite/libphobos.phobos/std_math_rounding.d: New test. * testsuite/libphobos.phobos/std_math_traits.d: New test. * testsuite/libphobos.phobos/std_math_trigonometry.d: New test. * testsuite/libphobos.phobos/std_meta.d: New test. * testsuite/libphobos.phobos/std_mmfile.d: New test. * testsuite/libphobos.phobos/std_numeric.d: New test. * testsuite/libphobos.phobos/std_outbuffer.d: New test. * testsuite/libphobos.phobos/std_package.d: New test. * testsuite/libphobos.phobos/std_parallelism.d: New test. * testsuite/libphobos.phobos/std_path.d: New test. * testsuite/libphobos.phobos/std_random.d: New test. * testsuite/libphobos.phobos/std_range_interfaces.d: New test. * testsuite/libphobos.phobos/std_range_package.d: New test. * testsuite/libphobos.phobos/std_range_primitives.d: New test. * testsuite/libphobos.phobos/std_regex_package.d: New test. * testsuite/libphobos.phobos/std_signals.d: New test. * testsuite/libphobos.phobos/std_socket.d: New test. * testsuite/libphobos.phobos/std_stdio.d: New test. * testsuite/libphobos.phobos/std_string.d: New test. * testsuite/libphobos.phobos/std_sumtype.d: New test. * testsuite/libphobos.phobos/std_traits.d: New test. * testsuite/libphobos.phobos/std_typecons.d: New test. * testsuite/libphobos.phobos/std_typetuple.d: New test. * testsuite/libphobos.phobos/std_uni_package.d: New test. * testsuite/libphobos.phobos/std_uri.d: New test. * testsuite/libphobos.phobos/std_utf.d: New test. * testsuite/libphobos.phobos/std_uuid.d: New test. * testsuite/libphobos.phobos/std_variant.d: New test. * testsuite/libphobos.phobos/std_zlib.d: New test.
455 lines
12 KiB
D
455 lines
12 KiB
D
@safe @nogc unittest
|
|
{
|
|
import std.algorithm.comparison;
|
|
|
|
assert(3.among(1, 42, 24, 3, 2));
|
|
|
|
if (auto pos = "bar".among("foo", "bar", "baz"))
|
|
assert(pos == 2);
|
|
else
|
|
assert(false);
|
|
|
|
// 42 is larger than 24
|
|
assert(42.among!((lhs, rhs) => lhs > rhs)(43, 24, 100) == 2);
|
|
}
|
|
|
|
@safe @nogc unittest
|
|
{
|
|
import std.algorithm.comparison;
|
|
|
|
assert(3.among!(2, 3, 4));
|
|
assert("bar".among!("foo", "bar", "baz") == 2);
|
|
}
|
|
|
|
@system unittest
|
|
{
|
|
import std.algorithm.comparison;
|
|
|
|
import std.algorithm.iteration : map;
|
|
import std.format : format;
|
|
|
|
class A
|
|
{
|
|
int a;
|
|
this(int a) {this.a = a;}
|
|
@property int i() { return a; }
|
|
}
|
|
interface I { }
|
|
class B : I { }
|
|
|
|
Object[] arr = [new A(1), new B(), null];
|
|
|
|
auto results = arr.map!(castSwitch!(
|
|
(A a) => "A with a value of %d".format(a.a),
|
|
(I i) => "derived from I",
|
|
() => "null reference",
|
|
))();
|
|
|
|
// A is handled directly:
|
|
assert(results[0] == "A with a value of 1");
|
|
// B has no handler - it is handled by the handler of I:
|
|
assert(results[1] == "derived from I");
|
|
// null is handled by the null handler:
|
|
assert(results[2] == "null reference");
|
|
}
|
|
|
|
@system unittest
|
|
{
|
|
import std.algorithm.comparison;
|
|
|
|
import std.exception : assertThrown;
|
|
|
|
class A { }
|
|
class B { }
|
|
// Void handlers are allowed if they throw:
|
|
assertThrown!Exception(
|
|
new B().castSwitch!(
|
|
(A a) => 1,
|
|
(B d) { throw new Exception("B is not allowed!"); }
|
|
)()
|
|
);
|
|
|
|
// Void handlers are also allowed if all the handlers are void:
|
|
new A().castSwitch!(
|
|
(A a) { },
|
|
(B b) { assert(false); },
|
|
)();
|
|
}
|
|
|
|
@safe @nogc unittest
|
|
{
|
|
import std.algorithm.comparison;
|
|
|
|
assert(clamp(2, 1, 3) == 2);
|
|
assert(clamp(0, 1, 3) == 1);
|
|
assert(clamp(4, 1, 3) == 3);
|
|
|
|
assert(clamp(1, 1, 1) == 1);
|
|
|
|
assert(clamp(5, -1, 2u) == 2);
|
|
|
|
auto x = clamp(42, uint.max, uint.max);
|
|
static assert(is(typeof(x) == int));
|
|
assert(x == -1);
|
|
}
|
|
|
|
pure @safe unittest
|
|
{
|
|
import std.algorithm.comparison;
|
|
|
|
int result;
|
|
|
|
result = cmp("abc", "abc");
|
|
assert(result == 0);
|
|
result = cmp("", "");
|
|
assert(result == 0);
|
|
result = cmp("abc", "abcd");
|
|
assert(result < 0);
|
|
result = cmp("abcd", "abc");
|
|
assert(result > 0);
|
|
result = cmp("abc"d, "abd");
|
|
assert(result < 0);
|
|
result = cmp("bbc", "abc"w);
|
|
assert(result > 0);
|
|
result = cmp("aaa", "aaaa"d);
|
|
assert(result < 0);
|
|
result = cmp("aaaa", "aaa"d);
|
|
assert(result > 0);
|
|
result = cmp("aaa", "aaa"d);
|
|
assert(result == 0);
|
|
result = cmp("aaa"d, "aaa"d);
|
|
assert(result == 0);
|
|
result = cmp(cast(int[])[], cast(int[])[]);
|
|
assert(result == 0);
|
|
result = cmp([1, 2, 3], [1, 2, 3]);
|
|
assert(result == 0);
|
|
result = cmp([1, 3, 2], [1, 2, 3]);
|
|
assert(result > 0);
|
|
result = cmp([1, 2, 3], [1L, 2, 3, 4]);
|
|
assert(result < 0);
|
|
result = cmp([1L, 2, 3], [1, 2]);
|
|
assert(result > 0);
|
|
}
|
|
|
|
pure @safe unittest
|
|
{
|
|
import std.algorithm.comparison;
|
|
|
|
int result;
|
|
|
|
result = cmp!"a > b"("abc", "abc");
|
|
assert(result == 0);
|
|
result = cmp!"a > b"("", "");
|
|
assert(result == 0);
|
|
result = cmp!"a > b"("abc", "abcd");
|
|
assert(result < 0);
|
|
result = cmp!"a > b"("abcd", "abc");
|
|
assert(result > 0);
|
|
result = cmp!"a > b"("abc"d, "abd");
|
|
assert(result > 0);
|
|
result = cmp!"a > b"("bbc", "abc"w);
|
|
assert(result < 0);
|
|
result = cmp!"a > b"("aaa", "aaaa"d);
|
|
assert(result < 0);
|
|
result = cmp!"a > b"("aaaa", "aaa"d);
|
|
assert(result > 0);
|
|
result = cmp!"a > b"("aaa", "aaa"d);
|
|
assert(result == 0);
|
|
result = cmp("aaa"d, "aaa"d);
|
|
assert(result == 0);
|
|
result = cmp!"a > b"(cast(int[])[], cast(int[])[]);
|
|
assert(result == 0);
|
|
result = cmp!"a > b"([1, 2, 3], [1, 2, 3]);
|
|
assert(result == 0);
|
|
result = cmp!"a > b"([1, 3, 2], [1, 2, 3]);
|
|
assert(result < 0);
|
|
result = cmp!"a > b"([1, 2, 3], [1L, 2, 3, 4]);
|
|
assert(result < 0);
|
|
result = cmp!"a > b"([1L, 2, 3], [1, 2]);
|
|
assert(result > 0);
|
|
}
|
|
|
|
@safe @nogc unittest
|
|
{
|
|
import std.algorithm.comparison;
|
|
|
|
import std.algorithm.comparison : equal;
|
|
import std.math.operations : isClose;
|
|
|
|
int[4] a = [ 1, 2, 4, 3 ];
|
|
assert(!equal(a[], a[1..$]));
|
|
assert(equal(a[], a[]));
|
|
assert(equal!((a, b) => a == b)(a[], a[]));
|
|
|
|
// different types
|
|
double[4] b = [ 1.0, 2, 4, 3];
|
|
assert(!equal(a[], b[1..$]));
|
|
assert(equal(a[], b[]));
|
|
|
|
// predicated: ensure that two vectors are approximately equal
|
|
double[4] c = [ 1.0000000005, 2, 4, 3];
|
|
assert(equal!isClose(b[], c[]));
|
|
}
|
|
|
|
@safe unittest
|
|
{
|
|
import std.algorithm.comparison;
|
|
|
|
import std.algorithm.comparison : equal;
|
|
import std.range : iota, chunks;
|
|
assert(equal!(equal!equal)(
|
|
[[[0, 1], [2, 3]], [[4, 5], [6, 7]]],
|
|
iota(0, 8).chunks(2).chunks(2)
|
|
));
|
|
}
|
|
|
|
@safe unittest
|
|
{
|
|
import std.algorithm.comparison;
|
|
|
|
with(EditOp)
|
|
{
|
|
assert(levenshteinDistanceAndPath("foo", "foobar")[1] == [none, none, none, insert, insert, insert]);
|
|
assert(levenshteinDistanceAndPath("banana", "fazan")[1] == [substitute, none, substitute, none, none, remove]);
|
|
}
|
|
}
|
|
|
|
@safe unittest
|
|
{
|
|
import std.algorithm.comparison;
|
|
|
|
import std.algorithm.iteration : filter;
|
|
import std.uni : toUpper;
|
|
|
|
assert(levenshteinDistance("cat", "rat") == 1);
|
|
assert(levenshteinDistance("parks", "spark") == 2);
|
|
assert(levenshteinDistance("abcde", "abcde") == 0);
|
|
assert(levenshteinDistance("abcde", "abCde") == 1);
|
|
assert(levenshteinDistance("kitten", "sitting") == 3);
|
|
assert(levenshteinDistance!((a, b) => toUpper(a) == toUpper(b))
|
|
("parks", "SPARK") == 2);
|
|
assert(levenshteinDistance("parks".filter!"true", "spark".filter!"true") == 2);
|
|
assert(levenshteinDistance("ID", "I♥D") == 1);
|
|
}
|
|
|
|
@safe unittest
|
|
{
|
|
import std.algorithm.comparison;
|
|
|
|
string a = "Saturday", b = "Sundays";
|
|
auto p = levenshteinDistanceAndPath(a, b);
|
|
assert(p[0] == 4);
|
|
assert(equal(p[1], "nrrnsnnni"));
|
|
}
|
|
|
|
@safe @nogc unittest
|
|
{
|
|
import std.algorithm.comparison;
|
|
|
|
int a = 5;
|
|
short b = 6;
|
|
double c = 2;
|
|
auto d = max(a, b);
|
|
assert(is(typeof(d) == int));
|
|
assert(d == 6);
|
|
auto e = min(a, b, c);
|
|
assert(is(typeof(e) == double));
|
|
assert(e == 2);
|
|
}
|
|
|
|
@safe @nogc unittest
|
|
{
|
|
import std.algorithm.comparison;
|
|
|
|
int a = 5;
|
|
short b = 6;
|
|
double c = 2;
|
|
auto d = min(a, b);
|
|
static assert(is(typeof(d) == int));
|
|
assert(d == 5);
|
|
auto e = min(a, b, c);
|
|
static assert(is(typeof(e) == double));
|
|
assert(e == 2);
|
|
ulong f = 0xffff_ffff_ffff;
|
|
const uint g = min(f, 0xffff_0000);
|
|
assert(g == 0xffff_0000);
|
|
dchar h = 100;
|
|
uint i = 101;
|
|
static assert(is(typeof(min(h, i)) == dchar));
|
|
static assert(is(typeof(min(i, h)) == uint));
|
|
assert(min(h, i) == 100);
|
|
}
|
|
|
|
@safe @nogc unittest
|
|
{
|
|
import std.algorithm.comparison;
|
|
|
|
int a = -10;
|
|
uint f = 10;
|
|
static assert(is(typeof(min(a, f)) == int));
|
|
assert(min(a, f) == -10);
|
|
}
|
|
|
|
@safe unittest
|
|
{
|
|
import std.algorithm.comparison;
|
|
|
|
import std.datetime;
|
|
assert(min(Date(2012, 12, 21), Date(1982, 1, 4)) == Date(1982, 1, 4));
|
|
assert(min(Date(1982, 1, 4), Date(2012, 12, 21)) == Date(1982, 1, 4));
|
|
assert(min(Date(1982, 1, 4), Date.min) == Date.min);
|
|
assert(min(Date.min, Date(1982, 1, 4)) == Date.min);
|
|
assert(min(Date(1982, 1, 4), Date.max) == Date(1982, 1, 4));
|
|
assert(min(Date.max, Date(1982, 1, 4)) == Date(1982, 1, 4));
|
|
assert(min(Date.min, Date.max) == Date.min);
|
|
assert(min(Date.max, Date.min) == Date.min);
|
|
}
|
|
|
|
@safe @nogc unittest
|
|
{
|
|
import std.algorithm.comparison;
|
|
|
|
int[6] x = [ 1, 5, 2, 7, 4, 3 ];
|
|
double[6] y = [ 1.0, 5, 2, 7.3, 4, 8 ];
|
|
auto m = mismatch(x[], y[]);
|
|
assert(m[0] == x[3 .. $]);
|
|
assert(m[1] == y[3 .. $]);
|
|
|
|
auto m2 = mismatch(x[], y[], x[], y[]);
|
|
assert(m2[0] == x[3 .. $]);
|
|
assert(m2[1] == y[3 .. $]);
|
|
assert(m2[2] == x[3 .. $]);
|
|
assert(m2[3] == y[3 .. $]);
|
|
}
|
|
|
|
@safe unittest
|
|
{
|
|
import std.algorithm.comparison;
|
|
|
|
string res = 2.predSwitch!"a < b"(
|
|
1, "less than 1",
|
|
5, "less than 5",
|
|
10, "less than 10",
|
|
"greater or equal to 10");
|
|
|
|
assert(res == "less than 5");
|
|
|
|
//The arguments are lazy, which allows us to use predSwitch to create
|
|
//recursive functions:
|
|
int factorial(int n)
|
|
{
|
|
return n.predSwitch!"a <= b"(
|
|
-1, {throw new Exception("Can not calculate n! for n < 0");}(),
|
|
0, 1, // 0! = 1
|
|
n * factorial(n - 1) // n! = n * (n - 1)! for n >= 0
|
|
);
|
|
}
|
|
assert(factorial(3) == 6);
|
|
|
|
//Void return expressions are allowed if they always throw:
|
|
import std.exception : assertThrown;
|
|
assertThrown!Exception(factorial(-9));
|
|
}
|
|
|
|
@safe nothrow pure unittest
|
|
{
|
|
import std.algorithm.comparison;
|
|
|
|
assert(isSameLength([1, 2, 3], [4, 5, 6]));
|
|
assert(isSameLength([1, 2, 3], [4, 5, 6], [7, 8, 9]));
|
|
assert(isSameLength([0.3, 90.4, 23.7, 119.2], [42.6, 23.6, 95.5, 6.3]));
|
|
assert(isSameLength("abc", "xyz"));
|
|
assert(isSameLength("abc", "xyz", [1, 2, 3]));
|
|
|
|
int[] a;
|
|
int[] b;
|
|
assert(isSameLength(a, b));
|
|
assert(isSameLength(a, b, a, a, b, b, b));
|
|
|
|
assert(!isSameLength([1, 2, 3], [4, 5]));
|
|
assert(!isSameLength([1, 2, 3], [4, 5, 6], [7, 8]));
|
|
assert(!isSameLength([0.3, 90.4, 23.7], [42.6, 23.6, 95.5, 6.3]));
|
|
assert(!isSameLength("abcd", "xyz"));
|
|
assert(!isSameLength("abcd", "xyz", "123"));
|
|
assert(!isSameLength("abcd", "xyz", "1234"));
|
|
}
|
|
|
|
@safe pure unittest
|
|
{
|
|
import std.algorithm.comparison;
|
|
|
|
import std.typecons : Yes;
|
|
|
|
assert(isPermutation([1, 2, 3], [3, 2, 1]));
|
|
assert(isPermutation([1.1, 2.3, 3.5], [2.3, 3.5, 1.1]));
|
|
assert(isPermutation("abc", "bca"));
|
|
|
|
assert(!isPermutation([1, 2], [3, 4]));
|
|
assert(!isPermutation([1, 1, 2, 3], [1, 2, 2, 3]));
|
|
assert(!isPermutation([1, 1], [1, 1, 1]));
|
|
|
|
// Faster, but allocates GC handled memory
|
|
assert(isPermutation!(Yes.allocateGC)([1.1, 2.3, 3.5], [2.3, 3.5, 1.1]));
|
|
assert(!isPermutation!(Yes.allocateGC)([1, 2], [3, 4]));
|
|
}
|
|
|
|
@safe pure unittest
|
|
{
|
|
import std.algorithm.comparison;
|
|
|
|
const a = 1;
|
|
const b = 2;
|
|
auto ab = either(a, b);
|
|
static assert(is(typeof(ab) == const(int)));
|
|
assert(ab == a);
|
|
|
|
auto c = 2;
|
|
const d = 3;
|
|
auto cd = either!(a => a == 3)(c, d); // use predicate
|
|
static assert(is(typeof(cd) == int));
|
|
assert(cd == d);
|
|
|
|
auto e = 0;
|
|
const f = 2;
|
|
auto ef = either(e, f);
|
|
static assert(is(typeof(ef) == int));
|
|
assert(ef == f);
|
|
}
|
|
|
|
@safe pure unittest
|
|
{
|
|
import std.algorithm.comparison;
|
|
|
|
immutable p = 1;
|
|
immutable q = 2;
|
|
auto pq = either(p, q);
|
|
static assert(is(typeof(pq) == immutable(int)));
|
|
assert(pq == p);
|
|
|
|
assert(either(3, 4) == 3);
|
|
assert(either(0, 4) == 4);
|
|
assert(either(0, 0) == 0);
|
|
assert(either("", "a") == "");
|
|
}
|
|
|
|
@safe pure unittest
|
|
{
|
|
import std.algorithm.comparison;
|
|
|
|
string r = null;
|
|
assert(either(r, "a") == "a");
|
|
assert(either("a", "") == "a");
|
|
|
|
immutable s = [1, 2];
|
|
assert(either(s, s) == s);
|
|
|
|
assert(either([0, 1], [1, 2]) == [0, 1]);
|
|
assert(either([0, 1], [1]) == [0, 1]);
|
|
assert(either("a", "b") == "a");
|
|
|
|
static assert(!__traits(compiles, either(1, "a")));
|
|
static assert(!__traits(compiles, either(1.0, "a")));
|
|
static assert(!__traits(compiles, either('a', "a")));
|
|
}
|
|
|