| /* |
| 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; |
| } |