mirror of
https://github.com/dlang/dmd.git
synced 2025-04-26 13:10:12 +03:00

Following the [alias this change](https://dlang.org/changelog/2.105.0.html#dmd.alias-this-syntax), I think mixin instantiation was the last place not using assignment syntax.
1518 lines
22 KiB
D
1518 lines
22 KiB
D
/*
|
|
RUN_OUTPUT:
|
|
---
|
|
Foo3.func()
|
|
Code3.func()
|
|
Foo4.func()
|
|
Foo5.func()
|
|
b.x = 5
|
|
x = 5
|
|
duff_for(1, 11)
|
|
fid = 1, 2
|
|
foo12
|
|
foo12
|
|
foo13 j = 1
|
|
foo13 j = 1
|
|
x14 = 6
|
|
x15 = 6
|
|
bar15() = 5
|
|
x16 = 6
|
|
bar() = 5
|
|
x17 = 5
|
|
b.x17 = 5
|
|
x17 = 3
|
|
x17 = 5
|
|
x17 = 4
|
|
x17 = 3
|
|
x17 = 5
|
|
in C20.f()
|
|
B22.foo()
|
|
5
|
|
5
|
|
a = 0
|
|
int
|
|
int
|
|
int
|
|
int
|
|
foo 1
|
|
foo 2
|
|
0 0
|
|
two
|
|
one
|
|
one
|
|
Class39 dtor
|
|
Mixed-in dtor
|
|
Mixed-in dtor
|
|
Base39 dtor
|
|
Success
|
|
---
|
|
*/
|
|
|
|
module mixin1;
|
|
|
|
import core.stdc.stdio;
|
|
|
|
alias TypeTuple(T...) = T;
|
|
|
|
/*******************************************/
|
|
|
|
mixin template Foo(T)
|
|
{
|
|
T x;
|
|
}
|
|
|
|
mixin Foo!(uint);
|
|
|
|
struct Bar
|
|
{
|
|
template Abc(T)
|
|
{
|
|
T y;
|
|
}
|
|
|
|
template Def(T)
|
|
{
|
|
T z;
|
|
}
|
|
}
|
|
|
|
mixin Bar.Abc!(int);
|
|
|
|
Bar b;
|
|
mixin typeof(b).Def!(int);
|
|
|
|
void test1()
|
|
{
|
|
x = 3;
|
|
assert(x == 3);
|
|
y = 4;
|
|
assert(y == 4);
|
|
z = 5;
|
|
assert(z == 5);
|
|
}
|
|
|
|
/*******************************************/
|
|
|
|
template Foo2(T)
|
|
{
|
|
T x2 = T.sizeof;
|
|
}
|
|
|
|
mixin Foo2!(uint) B2;
|
|
mixin Foo2!(long) C2;
|
|
mixin D2 = Foo2!(wchar);
|
|
mixin Foo2!(int);
|
|
|
|
void test2()
|
|
{
|
|
B2.x2 = 3;
|
|
assert(B2.x2 == 3);
|
|
assert(C2.x2 == long.sizeof);
|
|
assert(D2.x2 == 2);
|
|
// assert(x2 == int.sizeof);
|
|
}
|
|
|
|
/*******************************************/
|
|
|
|
template Foo3(T)
|
|
{
|
|
int func() { printf("Foo3.func()\n"); return 1; }
|
|
}
|
|
|
|
class Bar3
|
|
{
|
|
mixin Foo3!(int);
|
|
}
|
|
|
|
class Code3 : Bar3
|
|
{
|
|
override int func() { printf("Code3.func()\n"); return 2; }
|
|
}
|
|
|
|
void test3()
|
|
{
|
|
int i;
|
|
|
|
Bar3 b = new Bar3();
|
|
i = b.func();
|
|
assert(i == 1);
|
|
|
|
b = new Code3();
|
|
i = b.func();
|
|
assert(i == 2);
|
|
}
|
|
|
|
/*******************************************/
|
|
|
|
template Foo4(T)
|
|
{
|
|
int func() { printf("Foo4.func()\n"); return 1; }
|
|
}
|
|
|
|
struct Bar4
|
|
{
|
|
mixin Foo4!(int);
|
|
}
|
|
|
|
void test4()
|
|
{
|
|
int i;
|
|
|
|
Bar4 b;
|
|
i = b.func();
|
|
assert(i == 1);
|
|
}
|
|
|
|
/*******************************************/
|
|
|
|
template Foo5()
|
|
{
|
|
int func() { printf("Foo5.func()\n"); return 1; }
|
|
}
|
|
|
|
struct Bar5
|
|
{
|
|
mixin Foo5;
|
|
}
|
|
|
|
void test5()
|
|
{
|
|
int i;
|
|
|
|
Bar5 b;
|
|
i = b.func();
|
|
assert(i == 1);
|
|
}
|
|
|
|
/*******************************************/
|
|
|
|
template Foo6()
|
|
{
|
|
int x = 5;
|
|
}
|
|
|
|
struct Bar6
|
|
{
|
|
mixin Foo6;
|
|
}
|
|
|
|
void test6()
|
|
{
|
|
int i;
|
|
|
|
Bar6 b;
|
|
i = b.x;
|
|
assert(i == 5);
|
|
assert(b.sizeof == int.sizeof);
|
|
}
|
|
|
|
/*******************************************/
|
|
|
|
template Foo7()
|
|
{
|
|
int x = 5;
|
|
}
|
|
|
|
class Bar7
|
|
{
|
|
int y = 6;
|
|
mixin Foo7;
|
|
}
|
|
|
|
void test7()
|
|
{
|
|
int i;
|
|
|
|
Bar7 b = new Bar7();
|
|
i = b.x;
|
|
printf("b.x = %d\n", b.x);
|
|
assert(i == 5);
|
|
}
|
|
|
|
/*******************************************/
|
|
|
|
template Foo8()
|
|
{
|
|
int x = 5;
|
|
int bar() { return 7; }
|
|
}
|
|
|
|
void test8()
|
|
{
|
|
mixin Foo8;
|
|
printf("x = %d\n", x);
|
|
assert(x == 5);
|
|
assert(bar() == 7);
|
|
}
|
|
|
|
/*******************************************/
|
|
|
|
template Foo9()
|
|
{
|
|
int abc() { return y; }
|
|
}
|
|
|
|
void test9()
|
|
{
|
|
int y = 8;
|
|
mixin Foo9;
|
|
assert(abc() == 8);
|
|
}
|
|
|
|
/*******************************************/
|
|
|
|
template Foo10(alias b)
|
|
{
|
|
typeof(b) abc() { return b; }
|
|
}
|
|
|
|
void test10()
|
|
{
|
|
int y = 8;
|
|
mixin Foo10!(y);
|
|
assert(abc() == 8);
|
|
}
|
|
|
|
|
|
/*******************************************/
|
|
|
|
template Foo11(alias b)
|
|
{
|
|
int abc() { return b; }
|
|
}
|
|
|
|
void test11()
|
|
{
|
|
int y = 8;
|
|
mixin Foo11!(y) B;
|
|
assert(B.abc() == 8);
|
|
|
|
mixin C = Foo11!2;
|
|
assert(C.abc() == 2);
|
|
}
|
|
|
|
/*******************************************/
|
|
|
|
template duff_for(alias id1, alias id2, alias s)
|
|
{
|
|
|
|
void duff_for()
|
|
{
|
|
printf("duff_for(%d, %d)\n", id1, id2);
|
|
typeof(id1) id = id1;
|
|
printf("fid = %d, %d\n", id, (id2 - id) % 8);
|
|
switch ((id2 - id) % 8)
|
|
{
|
|
case 0:
|
|
while (id != id2)
|
|
{
|
|
printf("wid = %d\n", id);
|
|
s(); ++id;
|
|
goto case;
|
|
case 7: s(); ++id; goto case;
|
|
case 6: s(); ++id; goto case;
|
|
case 5: s(); ++id; goto case;
|
|
case 4: s(); ++id; goto case;
|
|
case 3: s(); ++id; goto case;
|
|
case 2: s(); ++id; goto case;
|
|
case 1: s(); ++id;
|
|
break;
|
|
default: assert(0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void foo12() { printf("foo12\n"); }
|
|
|
|
void test12()
|
|
{
|
|
int i = 1;
|
|
int j = 11;
|
|
|
|
mixin duff_for!(i, j, delegate void() { foo12(); });
|
|
duff_for();
|
|
}
|
|
|
|
/*******************************************/
|
|
|
|
template duff(alias id1, alias id2, alias s)
|
|
{
|
|
|
|
void duff()
|
|
{
|
|
s();
|
|
s();
|
|
}
|
|
}
|
|
|
|
void foo13(int j)
|
|
{
|
|
printf("foo13 j = %d\n", j);
|
|
assert(j == 1);
|
|
}
|
|
|
|
void test13()
|
|
{
|
|
int i = 1;
|
|
int j = 11;
|
|
|
|
mixin duff!(i, j, delegate { foo13(i); });
|
|
duff();
|
|
}
|
|
|
|
/*******************************************/
|
|
|
|
template Foo14()
|
|
{
|
|
int x14 = 5;
|
|
}
|
|
|
|
void test14()
|
|
{
|
|
int x14 = 6;
|
|
mixin Foo14;
|
|
printf("x14 = %d\n", x14);
|
|
assert(x14 == 6);
|
|
}
|
|
|
|
/*******************************************/
|
|
|
|
template Foo15()
|
|
{
|
|
int x15 = 5;
|
|
|
|
int bar15() { return x15; }
|
|
}
|
|
|
|
int x15 = 6;
|
|
mixin Foo15;
|
|
|
|
void test15()
|
|
{
|
|
|
|
printf("x15 = %d\n", x15);
|
|
printf("bar15() = %d\n", bar15());
|
|
assert(x15 == 6);
|
|
assert(bar15() == 5);
|
|
}
|
|
|
|
/*******************************************/
|
|
|
|
template Foo16()
|
|
{
|
|
int x16 = 5;
|
|
|
|
int bar() { return x16; }
|
|
}
|
|
|
|
mixin Foo16 A16;
|
|
int x16 = 6;
|
|
mixin Foo16 B16;
|
|
|
|
void test16()
|
|
{
|
|
|
|
printf("x16 = %d\n", x16);
|
|
printf("bar() = %d\n", A16.bar());
|
|
assert(x16 == 6);
|
|
assert(A16.x16 == 5);
|
|
assert(B16.x16 == 5);
|
|
assert(A16.bar() == 5);
|
|
assert(B16.bar() == 5);
|
|
}
|
|
|
|
/*******************************************/
|
|
|
|
template Foo17()
|
|
{
|
|
int x17 = 5;
|
|
}
|
|
|
|
mixin Foo17;
|
|
|
|
struct Bar17
|
|
{
|
|
mixin Foo17;
|
|
}
|
|
|
|
void test17()
|
|
{
|
|
printf("x17 = %d\n", x17); // prints 5
|
|
assert(x17 == 5);
|
|
{ Bar17 b;
|
|
int x17 = 3;
|
|
|
|
printf("b.x17 = %d\n", b.x17); // prints 5
|
|
assert(b.x17 == 5);
|
|
printf("x17 = %d\n", x17); // prints 3
|
|
assert(x17 == 3);
|
|
{
|
|
mixin Foo17;
|
|
printf("x17 = %d\n", x17); // prints 5
|
|
assert(x17 == 5);
|
|
x17 = 4;
|
|
printf("x17 = %d\n", x17); // prints 4
|
|
assert(x17 == 4);
|
|
}
|
|
printf("x17 = %d\n", x17); // prints 3
|
|
assert(x17 == 3);
|
|
}
|
|
printf("x17 = %d\n", x17); // prints 5
|
|
assert(x17 == 5);
|
|
}
|
|
|
|
/*******************************************/
|
|
|
|
template Foo18() { int z = 3; }
|
|
|
|
struct Bar18(alias Tmpl)
|
|
{
|
|
mixin Tmpl;
|
|
}
|
|
|
|
Bar18!(Foo18) b18;
|
|
|
|
void test18()
|
|
{
|
|
assert(b18.z == 3);
|
|
}
|
|
|
|
/*******************************************/
|
|
|
|
template Mix1(T)
|
|
{
|
|
int foo19(T a) { return 2*a; }
|
|
}
|
|
|
|
template Mix2(T)
|
|
{
|
|
mixin Mix1!(T);
|
|
|
|
int bar19(T a) { return foo19(a); }
|
|
}
|
|
|
|
mixin Mix2!(int);
|
|
|
|
void test19()
|
|
{
|
|
int i;
|
|
|
|
i = bar19(7);
|
|
assert(i == 14);
|
|
}
|
|
|
|
/*******************************************/
|
|
|
|
interface A20 { int f(); }
|
|
|
|
template Foo20()
|
|
{
|
|
int f()
|
|
{
|
|
printf("in C20.f()\n");
|
|
return 6;
|
|
}
|
|
}
|
|
|
|
class C20 : A20
|
|
{
|
|
mixin Foo20;
|
|
// void f() { printf("in C20.f()\n"); }
|
|
}
|
|
|
|
void test20()
|
|
{
|
|
C20 c = new C20();
|
|
int i = c.f();
|
|
assert(i == 6);
|
|
}
|
|
|
|
/*******************************************/
|
|
|
|
template Mix21() { this(int x) { printf("mix1\n"); }}
|
|
|
|
class Bar21
|
|
{
|
|
int myx;
|
|
mixin Mix21; // wouldn't compile
|
|
|
|
this() { myx = 15; }
|
|
|
|
// mixin Mix21; // placing it here compiles
|
|
}
|
|
|
|
void test21()
|
|
{
|
|
Bar21 bar = new Bar21();
|
|
}
|
|
|
|
/*******************************************/
|
|
|
|
template A22(T)
|
|
{
|
|
this()
|
|
{ int i;
|
|
i = super.foo();
|
|
assert(i == 67);
|
|
}
|
|
}
|
|
|
|
|
|
class B22
|
|
{
|
|
int foo() { printf("B22.foo()\n"); return 67; }
|
|
}
|
|
|
|
class C22 : B22
|
|
{
|
|
mixin A22!(C22);
|
|
}
|
|
|
|
void test22()
|
|
{
|
|
C22 c = new C22;
|
|
}
|
|
|
|
|
|
/*******************************************/
|
|
|
|
template Foo23()
|
|
{
|
|
const int x = 5;
|
|
}
|
|
|
|
class C23
|
|
{
|
|
mixin Foo23 F;
|
|
}
|
|
|
|
struct D23
|
|
{
|
|
mixin Foo23 F;
|
|
}
|
|
|
|
void test23()
|
|
{
|
|
C23 c = new C23;
|
|
|
|
printf("%d\n",c.F.x);
|
|
assert(c.F.x == 5);
|
|
|
|
D23 d;
|
|
|
|
printf("%d\n",d.F.x);
|
|
assert(d.F.x == 5);
|
|
}
|
|
|
|
/*******************************************/
|
|
|
|
template T24()
|
|
{
|
|
void foo24() { return cast(void)0; }
|
|
// alias foo24 foo24;
|
|
}
|
|
|
|
mixin T24;
|
|
|
|
void test24()
|
|
{
|
|
foo24();
|
|
}
|
|
|
|
|
|
/*******************************************/
|
|
|
|
template ctor25()
|
|
{
|
|
this() { this(null); }
|
|
this( Object o ) {}
|
|
}
|
|
|
|
class Foo25
|
|
{
|
|
mixin ctor25;
|
|
}
|
|
|
|
void test25()
|
|
{
|
|
Foo25 foo = new Foo25();
|
|
}
|
|
|
|
|
|
/*******************************************/
|
|
|
|
template Get26(T)
|
|
{
|
|
Reader get (ref T x)
|
|
{
|
|
return this;
|
|
}
|
|
}
|
|
|
|
class Reader
|
|
{
|
|
mixin Get26!(byte) bar;
|
|
alias bar.get get;
|
|
mixin Get26!(int) beq;
|
|
alias beq.get get;
|
|
}
|
|
|
|
void test26()
|
|
{
|
|
Reader r = new Reader;
|
|
Reader s;
|
|
byte q;
|
|
s = r.get (q);
|
|
assert(s == r);
|
|
}
|
|
|
|
/*******************************************/
|
|
|
|
template Template(int L)
|
|
{
|
|
int i = L;
|
|
int foo(int b = Template!(9).i) {
|
|
return b;
|
|
}
|
|
}
|
|
|
|
void test27()
|
|
{
|
|
int i = 10;
|
|
int foo(int b = Template!(9).i) {
|
|
return b;
|
|
}
|
|
assert(foo()==9);
|
|
}
|
|
|
|
/*******************************************/
|
|
|
|
template Blah28(int a, alias B)
|
|
{
|
|
mixin Blah28!(a-1, B);
|
|
//mixin Blah28!(0, B);
|
|
}
|
|
|
|
template Blah28(int a:0, alias B)
|
|
{
|
|
}
|
|
|
|
void test28()
|
|
{
|
|
int a;
|
|
mixin Blah28!(5,a);
|
|
printf("a = %d\n", a);
|
|
}
|
|
|
|
/*******************************************/
|
|
|
|
template T29()
|
|
{
|
|
int x;
|
|
}
|
|
|
|
struct S29
|
|
{
|
|
mixin T29;
|
|
int y;
|
|
}
|
|
|
|
const S29 s29 = { x:2, y:3 };
|
|
|
|
void test29()
|
|
{
|
|
assert(s29.x == 2);
|
|
assert(s29.y == 3);
|
|
}
|
|
|
|
/*******************************************/
|
|
|
|
class A30
|
|
{
|
|
template ctor(Type)
|
|
{
|
|
this(Type[] arr)
|
|
{
|
|
foreach(Type v; arr)
|
|
{
|
|
const str = typeid(typeof(v)).toString();
|
|
printf("%.*s\n", cast(int)str.length, str.ptr);
|
|
}
|
|
}
|
|
}
|
|
|
|
mixin ctor!(int);
|
|
}
|
|
|
|
void test30()
|
|
{
|
|
static int[] ints = [0,1,2,3];
|
|
A30 a = new A30(ints);
|
|
}
|
|
|
|
/*******************************************/
|
|
|
|
template Share(T) {
|
|
const bool opEquals(ref const T x) { return true; }
|
|
}
|
|
|
|
struct List31(T) {
|
|
|
|
//int opEquals(List31 x) { return 0; }
|
|
mixin Share!(List31);
|
|
}
|
|
|
|
void test31()
|
|
{
|
|
List31!(int) x;
|
|
List31!(int) y;
|
|
int i = x == y;
|
|
assert(i == 1);
|
|
}
|
|
|
|
/*******************************************/
|
|
|
|
template Blah(int a, alias B)
|
|
{
|
|
mixin Blah!(a-1, B);
|
|
}
|
|
|
|
template Blah(int a:0, alias B)
|
|
{
|
|
int foo()
|
|
{ return B + 1;
|
|
}
|
|
}
|
|
|
|
void test32()
|
|
{
|
|
int a = 3;
|
|
mixin Blah!(5,a);
|
|
|
|
assert(foo() == 4);
|
|
}
|
|
|
|
/*******************************************/
|
|
|
|
template T33( int i )
|
|
{
|
|
int foo()
|
|
{
|
|
printf("foo %d\n", i );
|
|
return i;
|
|
}
|
|
}
|
|
|
|
|
|
class C33
|
|
{
|
|
mixin T33!( 1 ) t1;
|
|
mixin T33!( 2 ) t2;
|
|
}
|
|
|
|
void test33()
|
|
{
|
|
int i;
|
|
C33 c1 = new C33;
|
|
i = c1.t1.foo();
|
|
assert(i == 1);
|
|
i = c1.t2.foo();
|
|
assert(i == 2);
|
|
}
|
|
|
|
|
|
/*******************************************/
|
|
|
|
template mix34()
|
|
{
|
|
int i;
|
|
void print()
|
|
{
|
|
printf( "%d %d\n", i, j );
|
|
assert(i == 0);
|
|
assert(j == 0);
|
|
}
|
|
}
|
|
|
|
void test34()
|
|
{
|
|
int j;
|
|
mixin mix34!();
|
|
|
|
print();
|
|
//printf( "%i\n", i );
|
|
}
|
|
|
|
/*******************************************/
|
|
|
|
mixin T35!(int) m35;
|
|
|
|
template T35(t)
|
|
{
|
|
t a;
|
|
}
|
|
|
|
void test35()
|
|
{
|
|
m35.a = 3;
|
|
}
|
|
|
|
/*******************************************/
|
|
|
|
struct Foo36
|
|
{
|
|
int a;
|
|
mixin T!(int) m;
|
|
template T(t)
|
|
{
|
|
t b;
|
|
}
|
|
int c;
|
|
}
|
|
|
|
void test36()
|
|
{
|
|
Foo36 f;
|
|
assert(f.sizeof == 12);
|
|
|
|
f.a = 1;
|
|
f.m.b = 2;
|
|
f.c = 3;
|
|
|
|
assert(f.a == 1);
|
|
assert(f.m.b == 2);
|
|
assert(f.c == 3);
|
|
}
|
|
|
|
/*******************************************/
|
|
|
|
template Foo37()
|
|
{
|
|
template func() {
|
|
int func() {
|
|
return 6;
|
|
}
|
|
}
|
|
}
|
|
|
|
class Baz37
|
|
{
|
|
mixin Foo37 bar;
|
|
}
|
|
|
|
void test37()
|
|
{
|
|
Baz37 b = new Baz37;
|
|
auto i = b.bar.func!()();
|
|
assert(i == 6);
|
|
i = (new Baz37).bar.func!()();
|
|
assert(i == 6);
|
|
}
|
|
|
|
/*******************************************/
|
|
|
|
template Foo38()
|
|
{
|
|
int a = 4;
|
|
|
|
~this()
|
|
{
|
|
printf("one\n");
|
|
assert(a == 4);
|
|
assert(b == 5);
|
|
c++;
|
|
}
|
|
}
|
|
|
|
class Outer38
|
|
{ int b = 5;
|
|
|
|
static int c;
|
|
|
|
mixin Foo38!() bar;
|
|
mixin Foo38!() abc;
|
|
|
|
~this()
|
|
{
|
|
printf("two\n");
|
|
assert(b == 5);
|
|
assert(c == 0);
|
|
c++;
|
|
}
|
|
}
|
|
|
|
void test38()
|
|
{
|
|
Outer38 o = new Outer38();
|
|
destroy(o);
|
|
assert(Outer38.c == 3);
|
|
}
|
|
|
|
/*******************************************/
|
|
|
|
template TDtor()
|
|
{
|
|
~this()
|
|
{
|
|
printf("Mixed-in dtor\n");
|
|
}
|
|
}
|
|
|
|
class Base39
|
|
{
|
|
~this()
|
|
{
|
|
printf("Base39 dtor\n");
|
|
}
|
|
}
|
|
|
|
class Class39 : Base39
|
|
{
|
|
mixin TDtor A;
|
|
mixin TDtor B;
|
|
|
|
~this()
|
|
{
|
|
printf("Class39 dtor\n");
|
|
}
|
|
}
|
|
|
|
void test39()
|
|
{
|
|
scope test = new Class39;
|
|
}
|
|
|
|
|
|
/*******************************************/
|
|
|
|
template Mix40()
|
|
{
|
|
int i;
|
|
}
|
|
|
|
struct Z40
|
|
{
|
|
union { mixin Mix40; }
|
|
}
|
|
|
|
void test40()
|
|
{
|
|
Z40 z;
|
|
z.i = 3;
|
|
}
|
|
|
|
/*******************************************/
|
|
|
|
|
|
class X41(P...)
|
|
{
|
|
alias P[0] Q;
|
|
mixin Q!();
|
|
}
|
|
|
|
template MYP()
|
|
{
|
|
void foo() { }
|
|
}
|
|
|
|
void test41()
|
|
{
|
|
X41!(MYP) x;
|
|
}
|
|
|
|
/*******************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=2245
|
|
|
|
template TCALL2245a(ARGS...)
|
|
{
|
|
int makecall(ARGS args)
|
|
{
|
|
return args.length;
|
|
}
|
|
}
|
|
|
|
template TCALL2245b(int n)
|
|
{
|
|
int makecall2(ARGS...)(ARGS args) if (ARGS.length == n)
|
|
{
|
|
return args.length;
|
|
}
|
|
}
|
|
|
|
class C2245
|
|
{
|
|
mixin TCALL2245a!();
|
|
mixin TCALL2245a!(int);
|
|
mixin TCALL2245a!(int,int);
|
|
|
|
mixin TCALL2245b!(0);
|
|
mixin TCALL2245b!(1);
|
|
mixin TCALL2245b!(2);
|
|
}
|
|
|
|
struct S2245
|
|
{
|
|
mixin TCALL2245a!();
|
|
mixin TCALL2245a!(int);
|
|
mixin TCALL2245a!(int,int);
|
|
|
|
mixin TCALL2245b!(0);
|
|
mixin TCALL2245b!(1);
|
|
mixin TCALL2245b!(2);
|
|
}
|
|
|
|
void test2245()
|
|
{
|
|
auto c = new C2245;
|
|
assert(c.makecall() == 0);
|
|
assert(c.makecall(0) == 1);
|
|
assert(c.makecall(0,1) == 2);
|
|
|
|
assert(c.makecall2() == 0);
|
|
assert(c.makecall2(0) == 1);
|
|
assert(c.makecall2(0,1) == 2);
|
|
|
|
assert(c.makecall2!()() == 0);
|
|
assert(c.makecall2!(int)(0) == 1);
|
|
assert(c.makecall2!(int, int)(0,1) == 2);
|
|
|
|
auto s = S2245();
|
|
assert(s.makecall() == 0);
|
|
assert(s.makecall(0) == 1);
|
|
assert(s.makecall(0,1) == 2);
|
|
|
|
assert(s.makecall2() == 0);
|
|
assert(s.makecall2(0) == 1);
|
|
assert(s.makecall2(0,1) == 2);
|
|
|
|
assert(s.makecall2!()() == 0);
|
|
assert(s.makecall2!(int)(0) == 1);
|
|
assert(s.makecall2!(int, int)(0,1) == 2);
|
|
}
|
|
|
|
/*******************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=2481
|
|
|
|
template M2481() { int i; }
|
|
class Z2481a { struct { mixin M2481!(); } }
|
|
class Z2481b { struct { int i; } }
|
|
|
|
void test2481()
|
|
{
|
|
Z2481a z1;
|
|
Z2481b z2;
|
|
static assert(z1.i.offsetof == z2.i.offsetof);
|
|
}
|
|
|
|
/*******************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=2740
|
|
|
|
interface IFooable2740
|
|
{
|
|
bool foo();
|
|
}
|
|
abstract class CFooable2740
|
|
{
|
|
bool foo();
|
|
}
|
|
|
|
mixin template MFoo2740()
|
|
{
|
|
override bool foo() { return true; }
|
|
}
|
|
|
|
class Foo2740i1 : IFooable2740
|
|
{
|
|
override bool foo() { return false; }
|
|
mixin MFoo2740;
|
|
}
|
|
class Foo2740i2 : IFooable2740
|
|
{
|
|
mixin MFoo2740;
|
|
override bool foo() { return false; }
|
|
}
|
|
|
|
class Foo2740c1 : CFooable2740
|
|
{
|
|
override bool foo() { return false; }
|
|
mixin MFoo2740;
|
|
}
|
|
class Foo2740c2 : CFooable2740
|
|
{
|
|
mixin MFoo2740;
|
|
override bool foo() { return false; }
|
|
}
|
|
|
|
void test2740()
|
|
{
|
|
{
|
|
auto p = new Foo2740i1();
|
|
IFooable2740 i = p;
|
|
assert(p.foo() == false);
|
|
assert(i.foo() == false);
|
|
}
|
|
{
|
|
auto p = new Foo2740i2();
|
|
IFooable2740 i = p;
|
|
assert(p.foo() == false);
|
|
assert(i.foo() == false);
|
|
}
|
|
|
|
{
|
|
auto p = new Foo2740c1();
|
|
CFooable2740 i = p;
|
|
assert(p.foo() == false);
|
|
assert(i.foo() == false);
|
|
}
|
|
{
|
|
auto p = new Foo2740c2();
|
|
CFooable2740 i = p;
|
|
assert(p.foo() == false);
|
|
assert(i.foo() == false);
|
|
}
|
|
}
|
|
|
|
/*******************************************/
|
|
|
|
mixin template MTestFoo()
|
|
{
|
|
int foo(){ return 2; }
|
|
}
|
|
class TestFoo
|
|
{
|
|
mixin MTestFoo!() test;
|
|
int foo(){ return 1; }
|
|
}
|
|
void test42()
|
|
{
|
|
auto p = new TestFoo();
|
|
assert(p.foo() == 1);
|
|
assert(p.test.foo() == 2);
|
|
}
|
|
|
|
/*******************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=7744
|
|
|
|
class ZeroOrMore7744(Expr)
|
|
{
|
|
enum name = "ZeroOrMore7744!("~Expr.name~")";
|
|
}
|
|
class Range7744(char begin, char end)
|
|
{
|
|
enum name = "Range7744!("~begin~","~end~")";
|
|
}
|
|
|
|
mixin(q{
|
|
class RubySource7744 : ZeroOrMore7744!(DecLiteral7744)
|
|
{
|
|
}
|
|
class DecLiteral7744 : Range7744!('0','9')
|
|
{
|
|
}
|
|
});
|
|
|
|
/*******************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=8032
|
|
|
|
mixin template T8032()
|
|
{
|
|
void f() { }
|
|
}
|
|
|
|
class A8032a
|
|
{
|
|
mixin T8032; // Named mixin causes the error too
|
|
void f() { }
|
|
}
|
|
class B8032a : A8032a
|
|
{
|
|
override void f() { }
|
|
}
|
|
|
|
class A8032b
|
|
{
|
|
void f() { }
|
|
mixin T8032; // Named mixin causes the error too
|
|
}
|
|
class B8032b : A8032b
|
|
{
|
|
override void f() { }
|
|
}
|
|
|
|
/*********************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=9417
|
|
|
|
mixin template Foo9417()
|
|
{
|
|
void foo() {}
|
|
}
|
|
|
|
void test9417()
|
|
{
|
|
struct B
|
|
{
|
|
mixin Foo9417;
|
|
}
|
|
}
|
|
|
|
/*******************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=11487
|
|
|
|
template X11487()
|
|
{
|
|
struct R()
|
|
{
|
|
C11487 c;
|
|
|
|
~this()
|
|
{
|
|
static assert(is(typeof(c.front) == void));
|
|
}
|
|
}
|
|
template Mix(alias R)
|
|
{
|
|
R!() range;
|
|
@property front() inout {}
|
|
}
|
|
}
|
|
|
|
class C11487
|
|
{
|
|
alias X11487!() M;
|
|
mixin M.Mix!(M.R);
|
|
}
|
|
|
|
/*******************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=11767
|
|
|
|
mixin template M11767()
|
|
{
|
|
struct S11767 {}
|
|
}
|
|
mixin M11767!();
|
|
mixin M11767!(); // OK
|
|
static assert(!__traits(compiles, S11767));
|
|
|
|
void test11767()
|
|
{
|
|
mixin M11767!();
|
|
alias S1 = S11767;
|
|
{
|
|
mixin M11767!();
|
|
alias S2 = S11767;
|
|
static assert(!is(S1 == S2));
|
|
static assert(S1.mangleof == "S6mixin19test11767FZ8__mixin16S11767");
|
|
static assert(S2.mangleof == "S6mixin19test11767FZ8__mixin26S11767");
|
|
}
|
|
mixin M11767!();
|
|
static assert(!__traits(compiles, S11767));
|
|
}
|
|
|
|
/*******************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=12023
|
|
|
|
void Delete12023(Object obj) {}
|
|
|
|
template MessageCode12023()
|
|
{
|
|
alias typeof(this) C;
|
|
|
|
struct MessageDeinitHelper
|
|
{
|
|
C m_outer;
|
|
|
|
~this()
|
|
{
|
|
m_outer.DoDeinitMessaging();
|
|
}
|
|
}
|
|
|
|
CToClient toClient = null;
|
|
TypeTuple!(CToClient) toClients;
|
|
|
|
class CToClient {}
|
|
|
|
void DoDeinitMessaging()
|
|
{
|
|
Delete12023(toClient);
|
|
Delete12023(toClients);
|
|
}
|
|
}
|
|
|
|
class TurretCannon12023(ProjectileClass)
|
|
{
|
|
mixin MessageCode12023;
|
|
}
|
|
|
|
void test12023()
|
|
{
|
|
auto tc = new TurretCannon12023!Object();
|
|
}
|
|
|
|
/*******************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=14243
|
|
|
|
mixin template Mix14243a(int n)
|
|
{
|
|
static assert(n > 0);
|
|
import core.stdc.stdio;
|
|
enum { enumMember = 1 }
|
|
|
|
auto a = A14243(n);
|
|
}
|
|
|
|
mixin template Mix14243b(int n)
|
|
{
|
|
static if (n > 0)
|
|
{
|
|
auto b = A14243(n);
|
|
}
|
|
}
|
|
|
|
template foo14243(alias v) { auto bar() { return &v; } }
|
|
mixin template Mix14243c(alias v)
|
|
{
|
|
// instantiate template in TemplateMixin
|
|
auto c = foo14243!v.bar();
|
|
}
|
|
|
|
mixin template Mix14243d(int n)
|
|
{
|
|
// Type declaration in TemplateMixin
|
|
struct NS { int x = n; }
|
|
mixin("auto d" ~ ('0' + n) ~ " = NS();");
|
|
}
|
|
|
|
mixin template Mix14243e(int n)
|
|
{
|
|
@safe:
|
|
nothrow:
|
|
int foo() { return var; }
|
|
|
|
static:
|
|
struct S { int x; void f() {} }
|
|
int bar() { return n; }
|
|
}
|
|
|
|
int test14243()
|
|
{
|
|
int[] ctor;
|
|
int[] dtor;
|
|
struct A14243
|
|
{
|
|
int x;
|
|
this(int x) { ctor ~= x; this.x = x; }
|
|
~this() { dtor ~= x; }
|
|
}
|
|
|
|
{
|
|
/**/
|
|
assert(ctor == [] && dtor == []); mixin Mix14243a!(1);
|
|
assert(ctor == [1] && dtor == []); mixin Mix14243b!(12) b1;
|
|
assert(ctor == [1,12] && dtor == []); mixin Mix14243b!(24) b2;
|
|
assert(ctor == [1,12,24] && dtor == []);
|
|
assert(a.x == 1);
|
|
static assert(!__traits(compiles, b > 0)); // ambiguous symbol access
|
|
assert(b1.b.x == 12);
|
|
assert(b2.b.x == 24);
|
|
|
|
int x;
|
|
mixin Mix14243c!(x);
|
|
assert(c == &x);
|
|
|
|
mixin Mix14243d!(1);
|
|
mixin Mix14243d!(2);
|
|
static assert(!is(typeof(d1) == typeof(d2)));
|
|
assert(d1.x == 1);
|
|
assert(d2.x == 2);
|
|
|
|
assert(ctor == [1,12,24] && dtor == []);
|
|
}
|
|
assert(ctor == [1,12,24] && dtor == [24,12,1]);
|
|
|
|
{
|
|
int var = 1;
|
|
mixin Mix14243e!12;
|
|
static assert(is(typeof(&foo) == int delegate() @safe nothrow pure @nogc));
|
|
static assert(is(typeof(&bar) == int function() @safe nothrow pure @nogc));
|
|
static assert(S.sizeof == int.sizeof); // s is static struct
|
|
assert(foo() == 1);
|
|
assert(bar() == 12);
|
|
}
|
|
return 1;
|
|
}
|
|
static assert(test14243()); // changed to be workable
|
|
|
|
/*******************************************/
|
|
// https://issues.dlang.org/show_bug.cgi?id=10492
|
|
|
|
class TestClass10492 {}
|
|
|
|
mixin template mix10492(string name)
|
|
{
|
|
mixin("scope " ~ name ~ " = new TestClass10492;" );
|
|
}
|
|
|
|
void test10492()
|
|
{
|
|
mixin mix10492!("var");
|
|
}
|
|
|
|
/*******************************************/
|
|
|
|
int main()
|
|
{
|
|
test1();
|
|
test2();
|
|
test3();
|
|
test4();
|
|
test5();
|
|
test6();
|
|
test7();
|
|
test8();
|
|
test9();
|
|
test10();
|
|
test11();
|
|
test12();
|
|
test13();
|
|
test14();
|
|
test15();
|
|
test16();
|
|
test17();
|
|
test18();
|
|
test19();
|
|
test20();
|
|
test21();
|
|
test22();
|
|
test23();
|
|
test24();
|
|
test25();
|
|
test26();
|
|
test27();
|
|
test28();
|
|
test29();
|
|
test30();
|
|
test31();
|
|
test32();
|
|
test33();
|
|
test34();
|
|
test35();
|
|
test36();
|
|
test37();
|
|
test38();
|
|
test39();
|
|
test40();
|
|
test41();
|
|
test2245();
|
|
test2740();
|
|
test42();
|
|
test9417();
|
|
test11767();
|
|
test12023();
|
|
test14243();
|
|
test10492();
|
|
|
|
printf("Success\n");
|
|
return 0;
|
|
}
|