1 extern (C) int printf(const scope char*, ...);
2 
3 struct S {
4     int x = 3;
funS5     void fun(T)(T x) { printf("S.fun(%s)(%d)\n", T.stringof.ptr, x); this.x += x; }
6 }
7 
8 class Tst(TST, int v = 2) {
9     int x = 3;
10     int z = 4;
11 
proc(int x)12     final private void proc(int x) { printf("proc(%d) -> %d\n", x, this.x); }
fun(T)13     void fun(T)(T x) { printf("fun(%s)(%d) -> %d\n", T.stringof.ptr, x, this.x);}
fun()14     void fun()() { printf("fun()() -> %d\n", this.x); }
fun2()15     void fun2()() { printf("fun2\n"); }
16 
17     class Inner {
18         int y = 99;
19         Tst outer;
f3()20         void f3() { z = 55; }
21         // Make sure the correct this-ptr is used
f1()22         void f1() { printf("Inner.f1\n"); proc(-11); outer.proc(-11); }
f2()23         void f2() { printf("Inner.f2\n"); fun(-17); outer.fun(-17); }
24     }
25     Inner inner;
26 
this()27     this() {
28         inner = new Inner;
29         inner.outer = this;
30     }
31 
callInnerf1()32     void callInnerf1() { printf("callInnerf1\n"); inner.f1(); }
callInnerf2()33     void callInnerf2() { printf("callInnerf2\n"); inner.f2(); }
34 
35 
36 //
37     void opBinary(string op : "+", T)(T x) { this.x += x; printf("opAdd(%d)\n", x); }
38     void opUnary(string op : "+")() { printf("opPos()\n"); }
39     //void opPos() { printf("xxx"); }
opIndex(T)40     void opIndex(T)(T x) { printf("opIndex[%d]\n",x); }
41 
opIndex(A,B,C)42     void opIndex(A,B,C)(A a, B b, C c) {
43         printf("opIndex[(%s) %d, (%s) %d, (%s) %d]\n", A.stringof.ptr, a,
44                  B.stringof.ptr,b,C.stringof.ptr,c);
45     }
46 
47     static if (v > 1) {
48         void opCall(A = int, B = float)(A a = 1, B b = 8.2) { printf("opCall(%d, %d)\n",a,b); this.x++; }
49     }
opSlice(A,B)50     void opSlice(A,B)(A a, B b) { printf("opSlice(%d, %d)\n",a,b); }
opSlice()51     void opSlice()() { printf("opSlice()\n"); }
52 
opIndexAssign(A,B)53     void opIndexAssign(A,B)(A a, B b) {
54         printf("opIndexAssign((%s) %d, (%s) %d)\n", A.stringof.ptr, a, B.stringof.ptr, b);
55     }
56 
opSliceAssign(A,B,C)57     void opSliceAssign(A,B,C)(A a, B b, C c) {
58         printf("opSliceAssign(%.s, %d, %d)\n", a.length, a.ptr, b, c);
59     }
60 
opEquals(A)61     bool opEquals(A)(A x) { printf("opEquals((%s))\n", A.stringof.ptr); return true; }
62 
opApply(T)63     int opApply(T)(int delegate(ref T)dg) {
64         for (int i = 0; i < 5; i++) {
65             T d = cast(T)(i+0.1);
66             if (auto result = dg(d))
67                 return result;
68         }
69         return 0;
70     }
71 }
72 
73 class Y : Tst!(float) {}
74 
main()75 void main() {
76     Tst!(int) t = new Tst!(int);
77     Y u = new Y;
78     S s;
79     t.x = 7;
80     t.proc(5);
81     t.fun(5);
82     t.fun();
83     t.callInnerf1();
84     t.callInnerf2();
85     u.fun(5);
86     u.fun();
87     u.callInnerf1();
88     u.callInnerf2();
89     s.fun(5);
90     t.fun2();
91 
92     +t;
93     t+5;
94     t[55];
95     t[1,2,3.0];
96     u[1,2,3.0];
97     t(1,2.5);
98     t(2);
99     t();
100     t[];
101     t[1..2];
102     u[1..2.5];
103     t == t;
104     auto b = t != t; // without assignment -> "! has no effect in expression"
105     t == u;
106     u == t;
107     u == u;
108     b = u != u;
109     foreach(int i;t) {
110         printf("%d\n", i);
111     }
112     foreach(double i;t) {
113         printf("%g\n", i);
114     }
115 
116 }
117