blob: c413ade029a6327b209bdd63de75e52264430976 [file] [log] [blame]
/*
REQUIRED_ARGS: -preview=rvaluerefparam
EXTRA_SOURCES: imports/ovs1528a.d imports/ovs1528b.d
EXTRA_SOURCES: imports/template_ovs1.d imports/template_ovs2.d imports/template_ovs3.d
EXTRA_FILES: imports/m8668a.d imports/m8668b.d imports/m8668c.d
RUN_OUTPUT:
---
Success
---
*/
import imports.template_ovs1;
import imports.template_ovs2;
import imports.template_ovs3;
extern(C) int printf(const char* fmt, ...);
template TypeTuple(T...){ alias T TypeTuple; }
template Id( T){ alias T Id; }
template Id(alias A){ alias A Id; }
/***************************************************/
// https://issues.dlang.org/show_bug.cgi?id=1528
int foo1528(long){ return 1; }
int foo1528(int[]){ return 2; }
int foo1528(T)(T) if ( is(T:real)) { return 3; }
int foo1528(T)(T) if (!is(T:real)) { return 4; }
int bar1528(T)(T) if (!is(T:real)) { return 4; }
int bar1528(T)(T) if ( is(T:real)) { return 3; }
int bar1528(int[]){ return 2; }
int bar1528(long){ return 1; }
@property auto getfoo1528 () { return 1; }
@property auto getfoo1528(T)() { return 2; }
@property auto getbar1528(T)() { return 2; }
@property auto getbar1528 () { return 1; }
@property auto setfoo1528 (int) { return 1; }
@property auto setfoo1528(T)(int) { return 2; }
@property auto setbar1528(T)(int) { return 2; }
@property auto setbar1528 (int) { return 1; }
struct S1528
{
int foo(long){ return 1; }
int foo(int[]){ return 2; }
int foo(T)(T) if ( is(T:real)) { return 3; }
int foo(T)(T) if (!is(T:real)) { return 4; }
int bar(T)(T) if (!is(T:real)) { return 4; }
int bar(T)(T) if ( is(T:real)) { return 3; }
int bar(int[]){ return 2; }
int bar(long){ return 1; }
@property auto getfoo () { return 1; }
@property auto getfoo(T)() { return 2; }
@property auto getbar(T)() { return 2; }
@property auto getbar () { return 1; }
@property auto setfoo (int) { return 1; }
@property auto setfoo(T)(int) { return 2; }
@property auto setbar(T)(int) { return 2; }
@property auto setbar (int) { return 1; }
@property auto propboo () { return 1; }
@property auto propboo(T)(T) { return 2; }
@property auto propbaz(T)(T) { return 2; }
@property auto propbaz () { return 1; }
}
auto ufoo1528 (S1528) { return 1; }
auto ufoo1528(T)(S1528) { return 2; }
auto ubar1528(T)(S1528) { return 2; }
auto ubar1528 (S1528) { return 1; }
@property auto ugetfoo1528 (S1528) { return 1; }
@property auto ugetfoo1528(T)(S1528) { return 2; }
@property auto ugetbar1528(T)(S1528) { return 2; }
@property auto ugetbar1528 (S1528) { return 1; }
@property auto usetfoo1528 (S1528, int) { return 1; }
@property auto usetfoo1528(T)(S1528, int) { return 2; }
@property auto usetbar1528(T)(S1528, int) { return 2; }
@property auto usetbar1528 (S1528, int) { return 1; }
@property auto upropboo1528 (S1528) { return 1; }
@property auto upropboo1528(T)(S1528, T) { return 2; }
@property auto upropbaz1528(T)(S1528, T) { return 2; }
@property auto upropbaz1528 (S1528) { return 1; }
void test1528a()
{
// global
assert(foo1528(100) == 1);
assert(foo1528(10L) == 1);
assert(foo1528([1]) == 2);
assert(foo1528(1.0) == 3);
assert(foo1528("a") == 4);
assert(bar1528(100) == 1);
assert(bar1528(10L) == 1);
assert(bar1528([1]) == 2);
assert(bar1528(1.0) == 3);
assert(bar1528("a") == 4);
assert(getfoo1528 == 1);
assert(getfoo1528!string == 2);
assert(getbar1528 == 1);
assert(getbar1528!string == 2);
assert((setfoo1528 = 1) == 1);
assert((setfoo1528!string = 1) == 2);
assert((setbar1528 = 1) == 1);
assert((setbar1528!string = 1) == 2);
S1528 s;
// member
assert(s.foo(100) == 1);
assert(s.foo(10L) == 1);
assert(s.foo([1]) == 2);
assert(s.foo(1.0) == 3);
assert(s.foo("a") == 4);
assert(s.bar(100) == 1);
assert(s.bar(10L) == 1);
assert(s.bar([1]) == 2);
assert(s.bar(1.0) == 3);
assert(s.bar("a") == 4);
assert(s.getfoo == 1);
assert(s.getfoo!string == 2);
assert(s.getbar == 1);
assert(s.getbar!string == 2);
assert((s.setfoo = 1) == 1);
assert((s.setfoo!string = 1) == 2);
assert((s.setbar = 1) == 1);
assert((s.setbar!string = 1) == 2);
assert((s.propboo = 1) == 2);
assert( s.propboo == 1);
assert((s.propbaz = 1) == 2);
assert( s.propbaz == 1);
// UFCS
assert(s.ufoo1528 () == 1);
assert(s.ufoo1528!string() == 2);
assert(s.ubar1528 () == 1);
assert(s.ubar1528!string() == 2);
assert(s.ugetfoo1528 == 1);
assert(s.ugetfoo1528!string == 2);
assert(s.ugetbar1528 == 1);
assert(s.ugetbar1528!string == 2);
assert((s.usetfoo1528 = 1) == 1);
assert((s.usetfoo1528!string = 1) == 2);
assert((s.usetbar1528 = 1) == 1);
assert((s.usetbar1528!string = 1) == 2);
assert((s.upropboo1528 = 1) == 2);
assert( s.upropboo1528 == 1);
assert((s.upropbaz1528 = 1) == 2);
assert( s.upropbaz1528 == 1);
// overload set
import imports.ovs1528a, imports.ovs1528b;
assert(func1528() == 1);
assert(func1528(1.0) == 2);
assert(func1528("a") == 3);
assert(func1528([1.0]) == 4);
assert(bunc1528() == 1);
assert(bunc1528(1.0) == 2);
assert(bunc1528("a") == 3);
assert(bunc1528([1.0]) == 4);
assert(vunc1528(100) == 1);
assert(vunc1528("a") == 2);
assert(wunc1528(100) == 1);
assert(wunc1528("a") == 2);
//assert(opUnary1528!"+"(10) == 1);
//assert(opUnary1528!"-"(10) == 2);
}
// ----
int doo1528a(int a, double=10) { return 1; }
int doo1528a(int a, string="") { return 2; }
int doo1528b(int a) { return 1; }
int doo1528b(T:int)(T b) { return 2; }
int doo1528c(T:int)(T b, double=10) { return 2; }
int doo1528c(T:int)(T b, string="") { return 2; }
int doo1528d(int a) { return 1; }
int doo1528d(T)(T b) { return 2; }
void test1528b()
{
// MatchLevel by tiargs / by fargs
static assert(!__traits(compiles, doo1528a(1)));
// 1: MATCHexact / MATCHexact
// 2: MATCHexact / MATCHexact
static assert(!__traits(compiles, doo1528a(1L)));
// 1: MATCHexact / MATCHconvert
// 2: MATCHexact / MATCHconvert
static assert(!__traits(compiles, doo1528b(1)));
// 1: MATCHexact / MATCHexact
// 2: MATCHexact / MATCHexact
assert(doo1528b(1L) == 1);
// 1: MATCHexact / MATCHconvert
// 2: MATCHnomatch / -
static assert(!__traits(compiles, doo1528c(1)));
// 1: MATCHexact / MATCHexact
// 2: MATCHexact / MATCHexact
static assert(!__traits(compiles, doo1528c(1L)));
// 1: MATCHnomatch / -
// 2: MATCHnomatch / -
assert(doo1528d(1) == 1);
// 1: MATCHexact / MATCHexact
// 2: MATCHconvert / MATCHexact
assert(doo1528d(1L) == 1);
// 1: MATCHexact / MATCHconvert
// 2: MATCHconvert / MATCHexact
// -> not sure, may be ambiguous...?
}
// ----
char[num*2] toHexString1528(int order, size_t num)(in ubyte[num] digest) { return typeof(return).init; }
string toHexString1528(int order)(in ubyte[] digest) { assert(0); }
char[8] test1528c()
{
ubyte[4] foo() { return typeof(return).init; }
return toHexString1528!10(foo);
}
// ----
int f1528d1(int a, double=10) { return 1; }
int f1528d1(int a, string="") { return 2; }
int f1528d2(T:int)(T b, double=10) { return 1; }
int f1528d2(T:int)(T b, string="") { return 2; }
// vs deduced parameter
int f1528d3(int a) { return 1; }
int f1528d3(T)(T b) { return 2; }
// vs specialized parameter
int f1528d4(int a) { return 1; }
int f1528d4(T:int)(T b) { return 2; }
// vs deduced parameter + template constraint (1)
int f1528d5(int a) { return 1; }
int f1528d5(T)(T b) if (is(T == int)) { return 2; }
// vs deduced parameter + template constraint (2)
int f1528d6(int a) { return 1; }
int f1528d6(T)(T b) if (is(T : int)) { return 2; }
// vs nallowing conversion
int f1528d7(ubyte a) { return 1; }
int f1528d7(T)(T b) if (is(T : int)) { return 2; }
int f1528d10(int, int) { return 1; }
int f1528d10(T)(T, int) { return 2; }
void test1528d()
{
static assert(!__traits(compiles, f1528d1(1))); // ambiguous
static assert(!__traits(compiles, f1528d1(1L))); // ambiguous
static assert(!__traits(compiles, f1528d2(1))); // ambiguous
static assert(!__traits(compiles, f1528d2(1L))); // no match
assert(f1528d3(1) == 1);
assert(f1528d3(1L) == 1); // '1L' matches int
short short_val = 42;
assert(f1528d3(cast(short) 42) == 1);
assert(f1528d3(short_val) == 1);
static assert(!__traits(compiles, f1528d4(1)));
assert(f1528d4(1L) == 1);
assert(f1528d5(1) == 1);
assert(f1528d5(1L) == 1);
assert(f1528d6(1) == 1);
assert(f1528d6(1L) == 1);
static assert(!__traits(compiles, f1528d6(ulong.max))); // no match
// needs to fix bug 9617
ulong ulval = 1;
static assert(!__traits(compiles, f1528d6(ulval))); // no match
assert(f1528d7(200u) == 1); // '200u' matches ubyte
assert(f1528d7(400u) == 2);
uint uival = 400; // TDPL-like range knowledge lost here.
assert(f1528d7(uival) == 2);
uival = 200; // Ditto.
assert(f1528d7(uival) == 2);
assert(f1528d10( 1, 9) == 1);
assert(f1528d10( 1U, 9) == 1);
assert(f1528d10( 1L, 9) == 1);
assert(f1528d10( 1LU, 9) == 1);
assert(f1528d10( long.max, 9) == 2);
assert(f1528d10(ulong.max, 9) == 2);
assert(f1528d10( 1, 9L) == 1);
assert(f1528d10( 1U, 9L) == 1);
assert(f1528d10( 1L, 9L) == 1);
assert(f1528d10( 1LU, 9L) == 1);
assert(f1528d10( long.max, 9L) == 2);
assert(f1528d10(ulong.max, 9L) == 2);
}
/***************************************************/
// https://issues.dlang.org/show_bug.cgi?id=1680
struct S1680
{
ulong _y;
ulong blah1() { return _y; }
static S1680 blah1(ulong n) { return S1680(n); }
static S1680 blah2(ulong n) { return S1680(n); }
static S1680 blah2(char[] n) { return S1680(n.length); }
}
class C1680
{
ulong _y;
this(ulong n){}
ulong blah1() { return _y; }
static C1680 blah1(ulong n) { return new C1680(n); }
static C1680 blah2(ulong n) { return new C1680(n); }
static C1680 blah2(char[] n) { return new C1680(n.length); }
}
void test1680()
{
// OK
S1680 s = S1680.blah1(5);
void fs()
{
S1680 s1 = S1680.blah2(5); // OK
S1680 s2 = S1680.blah2("hello".dup); // OK
S1680 s3 = S1680.blah1(5);
// Error: 'this' is only allowed in non-static member functions, not f
}
C1680 c = C1680.blah1(5);
void fc()
{
C1680 c1 = C1680.blah2(5);
C1680 c2 = C1680.blah2("hello".dup);
C1680 c3 = C1680.blah1(5);
}
}
/***************************************************/
// https://issues.dlang.org/show_bug.cgi?id=7418
int foo7418(uint a) { return 1; }
int foo7418(char[] a) { return 2; }
alias foo7418 foo7418a;
template foo7418b(T = void) { alias foo7418 foo7418b; }
void test7418()
{
assert(foo7418a(1U) == 1);
assert(foo7418a("a".dup) == 2);
assert(foo7418b!()(1U) == 1);
assert(foo7418b!()("a".dup) == 2);
}
/***************************************************/
// https://issues.dlang.org/show_bug.cgi?id=7552
struct S7552
{
static void foo(){}
static void foo(int){}
}
struct T7552
{
alias TypeTuple!(__traits(getOverloads, S7552, "foo")) FooInS;
alias FooInS[0] foo; // should be S7552.foo()
static void foo(string){}
}
struct U7552
{
alias TypeTuple!(__traits(getOverloads, S7552, "foo")) FooInS;
alias FooInS[1] foo; // should be S7552.foo(int)
static void foo(string){}
}
void test7552()
{
alias TypeTuple!(__traits(getOverloads, S7552, "foo")) FooInS;
static assert(FooInS.length == 2);
FooInS[0]();
static assert(!__traits(compiles, FooInS[0](0)));
static assert(!__traits(compiles, FooInS[1]()));
FooInS[1](0);
Id!(FooInS[0])();
static assert(!__traits(compiles, Id!(FooInS[0])(0)));
static assert(!__traits(compiles, Id!(FooInS[1])()));
Id!(FooInS[1])(0);
alias TypeTuple!(__traits(getOverloads, T7552, "foo")) FooInT;
static assert(FooInT.length == 2); // fail
FooInT[0]();
static assert(!__traits(compiles, FooInT[0](0)));
static assert(!__traits(compiles, FooInT[0]("")));
static assert(!__traits(compiles, FooInT[1]()));
static assert(!__traits(compiles, FooInT[1](0))); // fail
FooInT[1](""); // fail
alias TypeTuple!(__traits(getOverloads, U7552, "foo")) FooInU;
static assert(FooInU.length == 2);
static assert(!__traits(compiles, FooInU[0]()));
FooInU[0](0);
static assert(!__traits(compiles, FooInU[0]("")));
static assert(!__traits(compiles, FooInU[1]()));
static assert(!__traits(compiles, FooInU[1](0)));
FooInU[1]("");
}
/***************************************************/
// https://issues.dlang.org/show_bug.cgi?id=8668
import imports.m8668a;
import imports.m8668c; //replace with m8668b to make it work
void test8668()
{
split8668("abc");
split8668(123);
}
/***************************************************/
// https://issues.dlang.org/show_bug.cgi?id=8943
void test8943()
{
struct S
{
void foo();
}
alias TypeTuple!(__traits(getOverloads, S, "foo")) Overloads;
alias TypeTuple!(__traits(parent, Overloads[0])) P; // fail
static assert(is(P[0] == S));
}
/***************************************************/
// https://issues.dlang.org/show_bug.cgi?id=9410
struct S {}
int foo(float f, ref S s) { return 1; }
int foo(float f, S s) { return 2; }
void test9410()
{
S s;
assert(foo(1, s ) == 1); // works fine. Print: ref
/* With the rvalue to ref param change, this calls the 'ref' version
* because both are the same match level, but the 'ref' version is
* considered "more specialized", as the non-ref version undergoes
* a "conversion" to call the ref version.
*/
assert(foo(1, S()) == 1);
}
/***************************************************/
// https://issues.dlang.org/show_bug.cgi?id=10171
struct B10171(T) { static int x; }
void test10171()
{
auto mp = &B10171!(B10171!int).x;
}
/***************************************************/
// https://issues.dlang.org/show_bug.cgi?id=1900
// template overload set
void test1900a()
{
// function vs function template with IFTI call
assert(foo1900a(100) == 1);
assert(foo1900a("s") == 2);
assert(foo1900b(100) == 1);
assert(foo1900b("s") == 2);
// function template call with explicit template arguments
assert(foo1900a!string("s") == 2);
assert(foo1900b!string("s") == 2);
// function template overloaded set call with IFTI
assert(bar1900a(100) == 1);
assert(bar1900a("s") == 2);
assert(bar1900b(100) == 1);
assert(bar1900b("s") == 2);
// function template overloaded set call with explicit template arguments
assert(bar1900a!double(100) == 1);
assert(bar1900a!string("s") == 2);
assert(bar1900b!double(100) == 1);
assert(bar1900b!string("s") == 2);
// function template overloaded set call with IFTI
assert(baz1900(1234567890) == 1);
assert(baz1900([1:1, 2:2]) == 2);
assert(baz1900(new Object) == 3);
assert(baz1900("deadbeaf") == 4);
// function template overloaded set call with explicit template arguments
assert(baz1900!(double)(14142135) == 1);
assert(baz1900!(int[int])([12:34]) == 2);
assert(baz1900!(Object)(new Object) == 3);
assert(baz1900!(string)("cafe babe") == 4);
static assert(!__traits(compiles, bad1900!"++"()));
}
void test1900b()
{
S1900 s;
// function vs function template with IFTI call
assert(s.foo1900a(100) == 1);
assert(s.foo1900a("s") == 2);
assert(s.foo1900b(100) == 1);
assert(s.foo1900b("s") == 2);
// function template call with explicit template arguments
assert(s.foo1900a!string("s") == 2);
assert(s.foo1900b!string("s") == 2);
// function template overloaded set call with IFTI
assert(s.bar1900a(100) == 1);
assert(s.bar1900a("s") == 2);
assert(s.bar1900b(100) == 1);
assert(s.bar1900b("s") == 2);
// function template overloaded set call with explicit template arguments
assert(s.bar1900a!double(100) == 1);
assert(s.bar1900a!string("s") == 2);
assert(s.bar1900b!double(100) == 1);
assert(s.bar1900b!string("s") == 2);
// function template overloaded set call with IFTI
assert(s.baz1900(1234567890) == 1);
assert(s.baz1900([1:1, 2:2]) == 2);
assert(s.baz1900(new Object) == 3);
assert(s.baz1900("deadbeaf") == 4);
// function template overloaded set call with explicit template arguments
assert(s.baz1900!(double)(14142135) == 1);
assert(s.baz1900!(int[int])([12:34]) == 2);
assert(s.baz1900!(Object)(new Object) == 3);
assert(s.baz1900!(string)("cafe babe") == 4);
static assert(!__traits(compiles, s.bad1900!"++"()));
}
void test1900c()
{
S1900 s;
// This is a kind of Issue 1528 - [tdpl] overloading template and non-template functions
//s.funca();
//s.funca(10);
//s.funcb();
//s.funcb(10);
// Call function template overload set through mixin member lookup
assert(s.mixfooa() == 1);
assert(s.mixfooa(10) == 2);
assert(s.mixfoob() == 1);
assert(s.mixfoob(10) == 2);
// Call function template overload set through mixin^2 member lookup
assert(s.mixsubfooa() == 1);
assert(s.mixsubfooa(10) == 2);
assert(s.mixsubfoob() == 1);
assert(s.mixsubfoob(10) == 2);
// Using mixin identifier can limit overload set
assert(s.a.mixfooa() == 1); static assert(!__traits(compiles, s.a.mixfooa(10)));
assert(s.b.mixfooa(10) == 2); static assert(!__traits(compiles, s.b.mixfooa()));
assert(s.b.mixfoob() == 1); static assert(!__traits(compiles, s.b.mixfoob(10)));
assert(s.a.mixfoob(10) == 2); static assert(!__traits(compiles, s.a.mixfoob()));
}
alias merge1900 = imports.template_ovs1.merge1900;
alias merge1900 = imports.template_ovs2.merge1900;
void test1900d()
{
assert( merge1900!double(100) == 1);
assert(.merge1900!double(100) == 1);
}
mixin template Foo1900e(T)
{
void foo(U : T)() { v++;}
}
void test1900e()
{
struct S
{
int v;
mixin Foo1900e!double;
mixin Foo1900e!string;
void test()
{
foo!(int); // ScopeExp(ti->tempovers != NULL)
foo!(typeof(null)); // ScopeExp(ti->tempovers != NULL)
}
}
S s;
assert(s.v == 0);
s.test();
assert(s.v == 2);
}
/***************************************************/
// https://issues.dlang.org/show_bug.cgi?id=1900
void test1900()
{
AClass1900 a;
BClass1900 b;
static assert(Traits1900!(AClass1900).name == "AClass");
static assert(Traits1900!(BClass1900).name == "BClass");
static assert(Traits1900!(int).name == "any");
Traits1900!(long) obj;
static assert(Value1900a!double == 1);
static assert(Value1900b!double == 1);
static assert(Value1900a!string == 2);
static assert(Value1900b!string == 2);
}
alias imports.template_ovs1.Traits1900 Traits1900X;
alias imports.template_ovs2.Traits1900 Traits1900X;
alias imports.template_ovs3.Traits1900 Traits1900X;
static assert(Traits1900X!(AClass1900).name == "AClass");
static assert(Traits1900X!(BClass1900).name == "BClass");
static assert(Traits1900X!(int).name == "any");
// Traits1900Y is exact same as imports.template_ovs1.Traits1900.
alias imports.template_ovs1.Traits1900 Traits1900Y1;
alias imports.template_ovs1.Traits1900 Traits1900Y2;
alias Traits1900Y1 Traits1900Y;
alias Traits1900Y2 Traits1900Y;
static assert(Traits1900Y!(AClass1900).name == "AClass");
static assert(!__traits(compiles, Traits1900Y!(BClass1900)));
static assert(!__traits(compiles, Traits1900Y!(int)));
template Foo1900(T)
{
template Bar1900(U : T)
{
}
}
mixin Foo1900!(int) A1900;
mixin Foo1900!(char) B1900;
alias Bar1900!(int) bar1900; // error
/***************************************************/
// https://issues.dlang.org/show_bug.cgi?id=7780
mixin template A7780()
{
template C(int n : 0) { int C = 0; }
}
mixin template B7780()
{
template C(int n : 1) { int C = 1; }
}
class Foo7780
{
mixin A7780!();
mixin B7780!();
}
void test7780()
{
assert(Foo7780.C!0 == 0);
}
/***************************************************/
auto foo7849(string) { return 1; }
auto foo7849(dstring) { return 2; }
enum str7849a = "string";
immutable str7849ai = "string";
immutable str7849bi = str7849ai;
enum str7849b = str7849ai;
enum str7849c = str7849bi;
void test7849()
{
assert(foo7849(str7849a) == 1);
assert(foo7849(str7849b) == 1);
assert(foo7849(str7849c) == 1);
}
/***************************************************/
// https://issues.dlang.org/show_bug.cgi?id=8352
void test8352()
{
[1, 2].remove8352a!(x => x == 2)();
[1, 2].remove8352b!(x => x == 2)();
remove8352a("deleteme");
remove8352b("deleteme");
}
/***************************************************/
// https://issues.dlang.org/show_bug.cgi?id=8441
mixin template T8441a(string i)
{
auto j(string s = "a", U)(U u1, U u2)
{
return 0;
}
auto j(int i,string s = "a", W)(W u1, W u2)
{
return i;
}
mixin("
class F" ~ i ~ "
{
auto j(string s = \"a\", U)(U u1, U u2)
{
return this.outer.t" ~ i ~ ".j!(s, U)(u1, u2);
}
auto j(int i, string s = \"a\", W)(W u1, W u2)
{
return this.outer.t" ~ i ~ ".j!(i, s, W)(u1, u2); // <- dmd is giving error for j!(...).j's type
}
}
auto f" ~ i ~ "()
{
return new F" ~ i ~ "();
}
");
}
class X8441a
{
mixin T8441a!("1") t0;
alias t0 t1;
}
void test8441a()
{
auto x = new X8441a();
x.f1().j!(3,"a")(2.2, 3.3);
}
// ----
mixin template T8441b()
{
void k()() {}
void j()() {}
void j(int i)() {}
}
class X8441b
{
mixin T8441b t0;
}
void test8441b()
{
auto x = new X8441b();
x.k!()(); // Fine
x.j!()(); // Fine
x.t0.k!()(); // Fine
x.t0.j!()(); // Derp
}
// ----
mixin template Signal8441c(Args...)
{
bool call = false;
final void connect(string method, ClassType)(ClassType obj)
if (is(ClassType == class) && __traits(compiles, { void delegate(Args) dg = mixin("&obj."~method); }))
{
call = true;
}
}
void test8441c()
{
class Observer
{
void watchInt(string str, int i) {}
}
class Bar
{
mixin Signal8441c!(string, int) s1;
mixin Signal8441c!(string, int) s2;
mixin Signal8441c!(string, long) s3;
}
auto a = new Bar;
auto o1 = new Observer;
a.s1.connect!"watchInt"(o1);
assert( a.s1.call);
assert(!a.s2.call);
assert(!a.s3.call);
}
/***************************************************/
// https://issues.dlang.org/show_bug.cgi?id=9235
template FlowEvaluator9235()
{
// if control flow
bool execute(Command cmd)()
if (cmd == Command.Jump ||
cmd == Command.Fork)
{
return false;
}
}
template MatchEvaluator9235()
{
// if operation
bool execute(Command cmd)()
if (cmd == Command.Char ||
cmd == Command.Any ||
cmd == Command.End)
{
return true;
}
}
void test9235a()
{
enum Command
{
Char, Any, Fork, Jump, End
}
struct Machine
{
mixin FlowEvaluator9235;
mixin MatchEvaluator9235;
bool exec_flow()
{
return execute!(Command.Jump)();
}
bool exec_match()
{
return execute!(Command.Any)();
}
}
Machine m;
assert(!m.exec_flow());
assert( m.exec_match());
}
// ----
mixin template mixA9235()
{
int foo(string s)() if (s == "a") { return 1; }
}
mixin template mixB9235()
{
int foo(string s)() if (s == "b") { return 2; }
}
struct Foo9235
{
mixin mixA9235 A;
mixin mixB9235 B;
alias A.foo foo;
alias B.foo foo;
}
void test9235b()
{
Foo9235 f;
assert(f.foo!"a"() == 1);
assert(f.foo!"b"() == 2);
}
/***************************************************/
// https://issues.dlang.org/show_bug.cgi?id=10658
alias Val10658 = imports.template_ovs1.Val10658;
alias Val10658 = imports.template_ovs2.Val10658;
static assert(Val10658!1 == 1);
static assert(Val10658!1L == 2);
// ----
template Foo10658(T) if (is(T == double)) { enum Foo10658 = 1; }
template Bar10658(T) if (is(T == string)) { enum Bar10658 = 2; }
alias Baz10658 = Foo10658;
alias Baz10658 = Bar10658;
template Voo10658(T) if (is(T == cfloat)) { enum Voo10658 = 5; }
template Voo10658(T) if (is(T == Object)) { enum Voo10658 = 6; }
alias Vaz10658 = Baz10658; // OvarDeclaration
alias Vaz10658 = Voo10658; // TemplateDeclaration (overnext != NULL)
template Merge10658a(alias A)
{
enum Merge10658a = A!double + A!string;
}
template Merge10658b(alias A)
{
enum Merge10658b = A!double + A!string + A!cfloat + A!Object;
}
void test10658a()
{
static assert(Baz10658!double == 1);
static assert(Baz10658!string == 2);
static assert(Voo10658!cfloat == 5);
static assert(Voo10658!Object == 6);
// pass OverDeclaration through TemplateAliasParameter
static assert(Merge10658a!Baz10658 == 1 + 2);
static assert(Merge10658b!Vaz10658 == 1 + 2 + 5 + 6);
}
// ----
mixin template mix10658A()
{
int f10658(string s)() if (s == "a") { return 1; }
}
mixin template mix10658B()
{
int f10658(string s)() if (s == "b") { return 2; }
}
mixin mix10658A A10658;
mixin mix10658B B10658;
alias A10658.f10658 foo10658;
alias B10658.f10658 foo10658;
mixin template mix10658C()
{
int f10658(string s, T)(T arg) if (s == "c") { return 3; }
}
mixin template mix10658D()
{
int f10658(string s, T)(T arg) if (s == "d") { return 4; }
}
struct S10658
{
mixin mix10658C C10658;
mixin mix10658D D10658;
alias C10658.f10658 foo10658;
alias D10658.f10658 foo10658;
}
void test10658b()
{
assert( foo10658!"a"() == 1);
assert(.foo10658!"b"() == 2);
S10658 s;
assert(s.foo10658!"c"(0) == 3);
assert(s.foo10658!"d"(0) == 4);
}
/***************************************************/
class InputStream11785
{
long read(ubyte* bytes, long len)
{
return 0;
}
void read(T)(ref T val)
{
read(cast(ubyte*)&val, cast(long)val.sizeof);
}
}
long read11785(ubyte* bytes, long len)
{
return 0;
}
void read11785(T)(ref T val)
{
read11785(cast(ubyte*)&val, cast(long)val.sizeof);
}
void test11785()
{
int v;
read11785(v);
auto input = new InputStream11785();
input.read(v);
}
/***************************************************/
// https://issues.dlang.org/show_bug.cgi?id=11915
int f11915( int) { return 1; }
int f11915(ref int) { return 2; }
int g11915( int) { return 1; }
int g11915(out int) { return 2; }
void test11915()
{
const int n = 1;
assert(f11915(n) == 1);
assert(g11915(n) == 1);
}
/***************************************************/
// https://issues.dlang.org/show_bug.cgi?id=11916
auto f11916(T)( T) { return 1; }
auto f11916(T)(out T) if (false) { return 2; }
auto g11916(T)( T) { return 1; }
auto g11916(T)(out T) { return 2; }
void test11916()
{
const int c = 1;
int m = 2;
// 'out const int' is invalid function parameter, so (out T) version will be dropped
// from overload candidates before template constraint evaluated.
assert(f11916(c) == 1);
// Both (T) and (out T) have valid signatures with T == int, but the 2nd overload will be
// dropped from overload candidates because of the template constraint.
assert(f11916(m) == 1);
// 'out const int' parameter is invalid, so non-out version is selected.
assert(g11916(c) == 1);
// MATCHconst for (T) version, and MATCHexact for (out T) version.
assert(g11916(m) == 2);
}
/***************************************************/
// https://issues.dlang.org/show_bug.cgi?id=13783
enum E13783 { a = 5 }
inout(int) f( inout(int) t) { return t * 2; }
ref inout(int) f(return ref inout(int) t) { return t; }
void test13783()
{
const E13783 e = E13783.a;
assert(f(e) == 10);
}
/***************************************************/
// https://issues.dlang.org/show_bug.cgi?id=14858
int foo14858()() { return 1; }
int bar14858(int) { return 2; }
alias foobar14858 = foo14858;
alias foobar14858 = bar14858;
void test14858()
{
assert(foobar14858() == 1);
assert(foobar14858(1) == 2); // OK <- NG
}
/***************************************************/
// https://issues.dlang.org/show_bug.cgi?id=14989
template Foo14989(T) if (is(T == int)) { enum Foo14989 = 1; }
template Bar14989(T) if (is(T == double)) { enum Bar14989 = 2; }
template Baz14989(T) if (is(T == string)) { enum Baz14989 = 3; }
alias X14989 = Foo14989;
alias X14989 = Bar14989;
// X is an alias to is OverDeclaration
alias A14989 = X14989;
// first, A->aliassym == X
static if (true)
{
alias A14989 = Baz14989;
// A->aliassym = new OverDeclaration('A')
// then, A->aliassym->overloadInsert(Baz)
}
template Mix14989a() { alias M14989 = Foo14989; }
template Mix14989b() { alias M14989 = Bar14989; }
mixin Mix14989a;
mixin Mix14989b;
alias Y14989 = M14989;
// Y is an alias to OverloadSet
alias B14989 = Y14989;
// first, B->aliassym == Y
static if (true)
{
alias B14989 = Baz14989;
// (B->aliassym = new OverloadSet('B')
// then, B->aliassym->overloadInsert(Baz)
}
void test14989()
{
static assert(X14989!int == 1);
static assert(X14989!double == 2);
static assert(!__traits(compiles, X14989!string)); // Baz is not in X
static assert(A14989!int == 1);
static assert(A14989!double == 2);
static assert(A14989!string == 3); // OK <- error
static assert(Y14989!int == 1);
static assert(Y14989!double == 2);
static assert(!__traits(compiles, Y14989!string)); // Baz is not in Y
static assert(B14989!int == 1);
static assert(B14989!double == 2);
static assert(B14989!string == 3); // OK <- error
}
/***************************************************/
// https://issues.dlang.org/show_bug.cgi?id=14965
auto f14965a1() { return f14965a1(123); }
int f14965a1(int x) { return x; }
int f14965a2(int x) { return x; }
auto f14965a2() { return f14965a2(123); }
auto f14965b1() { int function(int) fp = &f14965b1; return fp(123); }
int f14965b1(int x) { return x; }
int f14965b2(int x) { return x; }
auto f14965b2() { int function(int) fp = &f14965b2; return fp(123); }
auto f14965c1() { auto fp = cast(int function(int))&f14965c1; return fp(123); }
int f14965c1(int x) { return x; }
int f14965c2(int x) { return x; }
auto f14965c2() { auto fp = cast(int function(int))&f14965c2; return fp(123); }
int function(int) f14965d1() { return &f14965d1; }
int f14965d1(int n) { return 10 + n; }
int f14965d2(int n) { return 10 + n; }
int function(int) f14965d2() { return &f14965d2; }
class C
{
auto fa1() { return this.fa1(123); }
int fa1(int x) { return x; }
int fa2(int x) { return x; }
auto fa2() { return this.fa2(123); }
auto fb1() { int delegate(int) dg = &this.fb1; return dg(123); }
int fb1(int x) { return x; }
int fb2(int x) { return x; }
auto fb2() { int delegate(int) dg = &this.fb2; return dg(123); }
auto fc1() { auto dg = cast(int delegate(int))&this.fc1; return dg(123); }
int fc1(int x) { return x; }
int fc2(int x) { return x; }
auto fc2() { auto dg = cast(int delegate(int))&this.fc2; return dg(123); }
int delegate(int) fd1() { return &fd1; }
int fd1(int n) { return 10 + n; }
int fd2(int n) { return 10 + n; }
int delegate(int) fd2() { return &fd2; }
}
void test14965()
{
assert(f14965a1() == 123);
assert(f14965b1() == 123);
assert(f14965c1() == 123);
assert(f14965d1()(113) == 123);
assert(f14965a2() == 123);
assert(f14965b2() == 123);
assert(f14965c2() == 123);
assert(f14965d2()(113) == 123);
auto c = new C();
assert(c.fa1() == 123);
assert(c.fb1() == 123);
assert(c.fc1() == 123);
assert(c.fd1()(113) == 123);
assert(c.fa2() == 123);
assert(c.fb2() == 123);
assert(c.fc2() == 123);
assert(c.fd2()(113) == 123);
}
/***************************************************/
// https://issues.dlang.org/show_bug.cgi?id=21481
struct S21481
{
void funB2(char a) {}
alias funB = funB2;
// template as first symbol in overload set and overloading an alias
void funB()(float t) {}
void funB(int b) {} // function was lost -> OK now
}
void test21481()
{
static assert(__traits(getOverloads, S21481, "funB", true).length == 3);
}
/***************************************************/
// https://issues.dlang.org/show_bug.cgi?id=21522
struct S21522
{
// alias to template as first symbol in overload set
void funA2()(int a) {}
void funA2(char a) {} // function was lost -> OK now
alias funA = funA2;
void funA(float b) {}
}
void test21522()
{
static assert(__traits(getOverloads, S21522, "funA", true).length == 3);
}
/***************************************************/
int main()
{
test1528a();
test1528b();
test1528c();
test1528d();
test1680();
test7418();
test7552();
test8668();
test8943();
test9410();
test10171();
test1900a();
test1900b();
test1900c();
test1900d();
test1900e();
test7780();
test7849();
test8352();
test8441a();
test8441b();
test8441c();
test9235a();
test9235b();
test10658a();
test10658b();
test11785();
test11915();
test11916();
test13783();
test14858();
test14965();
test21481();
test21522();
printf("Success\n");
return 0;
}