| /* |
| RUN_OUTPUT: |
| --- |
| Success |
| --- |
| */ |
| extern (C) int printf(const char* fmt, ...); |
| |
| int pass(int n){ return n; } |
| |
| struct X |
| { |
| int m; |
| |
| int opIndex(int m, int n) |
| { |
| return n; |
| } |
| } |
| |
| /**********************************************/ |
| |
| struct S1f |
| { |
| int opDispatch(string name, A...)(A args) |
| { |
| static if (args.length) |
| return args[0]; |
| else |
| return 0; |
| } |
| } |
| struct S1p |
| { |
| @property int opDispatch(string name, A...)(A args) |
| { |
| static if (args.length) |
| return args[0]; |
| else |
| return 0; |
| } |
| } |
| void test1() |
| { |
| S1f s1f; |
| assert(s1f.func() == 0); // ok -> ok |
| assert(s1f.func(1) == 1); // ok -> ok |
| assert(pass(s1f.func()) == 0); // ok -> ok |
| assert(pass(s1f.func(1)) == 1); // ok -> ok |
| assert(X(s1f.func()).m == 0); |
| assert(X()[0, s1f.func()] == 0); |
| |
| S1p s1p; |
| assert(s1p.prop == 0); // ok -> ok |
| assert((s1p.prop = 1) == 1); // CTng -> CTng |
| assert(pass(s1p.prop) == 0); // ok -> ok |
| assert(pass(s1p.prop = 2) == 2); // CTng -> CTng |
| assert(X(s1p.prop).m == 0); |
| assert(X()[0, s1p.prop] == 0); |
| } |
| |
| /**********************************************/ |
| |
| struct S2f |
| { |
| template opDispatch(string name) |
| { |
| int opDispatch(A...)(A args) |
| { |
| static if (args.length) |
| return args[0]; |
| else |
| return 0; |
| } |
| } |
| } |
| struct S2p |
| { |
| template opDispatch(string name) |
| { |
| @property int opDispatch(A...)(A args) |
| { |
| static if (args.length) |
| return args[0]; |
| else |
| return 0; |
| } |
| } |
| } |
| void test2() |
| { |
| S2f s2f; |
| assert(s2f.func() == 0); // ok -> ok |
| assert(s2f.func(1) == 1); // ok -> ok |
| assert(pass(s2f.func()) == 0); // ok -> ok |
| assert(pass(s2f.func(1)) == 1); // ok -> ok |
| assert(X(s2f.func()).m == 0); |
| assert(X()[0, s2f.func()] == 0); |
| |
| S2p s2p; |
| assert(s2p.prop == 0); // CTng -> ok |
| assert((s2p.prop = 1) == 1); // ok -> ok |
| assert(pass(s2p.prop) == 0); // CTng -> ok |
| assert(pass(s2p.prop = 2) == 2); // ok -> ok |
| assert(X(s2p.prop).m == 0); |
| assert(X()[0, s2p.prop] == 0); |
| } |
| |
| /**********************************************/ |
| |
| struct S3f |
| { |
| template opDispatch(string name) |
| { |
| template opDispatch(T) |
| { |
| int opDispatch(A...)(A args) |
| { |
| static if (args.length) |
| return args[0]; |
| else |
| return 0; |
| } |
| } |
| } |
| } |
| struct S3p |
| { |
| template opDispatch(string name) |
| { |
| template opDispatch(T) |
| { |
| @property int opDispatch(A...)(A args) |
| { |
| static if (args.length) |
| return args[0]; |
| else |
| return 0; |
| } |
| } |
| } |
| } |
| void test3() |
| { |
| S3f s3f; |
| assert(s3f.func!int() == 0); // ok -> ok |
| assert(s3f.func!int(1) == 1); // ok -> ok |
| assert(pass(s3f.func!int()) == 0); // ok -> ok |
| assert(pass(s3f.func!int(1)) == 1); // ok -> ok |
| assert(X(s3f.func!int()).m == 0); |
| assert(X()[0, s3f.func!int()] == 0); |
| |
| S3p s3p; |
| assert(s3p.prop!int == 0); // CTng -> ok |
| assert((s3p.prop!int = 1) == 1); // ok -> ok |
| assert(pass(s3p.prop!int) == 0); // CTng -> ok |
| assert(pass(s3p.prop!int = 2) == 2); // ok -> ok |
| assert(X(s3p.prop!int).m == 0); |
| assert(X()[0, s3p.prop!int] == 0); |
| } |
| |
| /**********************************************/ |
| |
| struct S4f |
| { |
| ref int opDispatch(string name, A...)(A args) |
| { |
| static int n; |
| n = args.length; |
| return n; |
| } |
| } |
| struct S4p |
| { |
| @property ref int opDispatch(string name, A...)(A args) |
| { |
| static int n; |
| n = args.length; |
| return n; |
| } |
| } |
| void test4() |
| { |
| S4f s4f; |
| assert(s4f.func == 0); // getter |
| assert((s4f.func = 1) == 1); // setter |
| |
| S4p s4p; |
| assert(s4p.prop == 0); // getter |
| assert((s4p.prop = 1) == 1); // setter |
| } |
| |
| /**********************************************/ |
| |
| struct S5f |
| { |
| template opDispatch(string name) |
| { |
| ref int opDispatch(A...)(A args) |
| { |
| static int n; |
| n = args.length; |
| return n; |
| } |
| } |
| } |
| struct S5p |
| { |
| template opDispatch(string name) |
| { |
| @property ref int opDispatch(A...)(A args) |
| { |
| static int n; |
| n = args.length; |
| return n; |
| } |
| } |
| } |
| void test5() |
| { |
| S5f s5f; |
| assert(s5f.prop == 0); // getter ng -> ok |
| assert((s5f.prop = 1) == 1); // setter |
| |
| S5p s5p; |
| assert(s5p.prop == 0); // getter ng -> ok |
| assert((s5p.prop = 1) == 1); // setter |
| } |
| |
| /**********************************************/ |
| |
| struct S6f |
| { |
| template opDispatch(string name) |
| { |
| template opDispatch(T) |
| { |
| ref int opDispatch(A...)(A args) |
| { |
| static int n; |
| n = args.length; |
| return n; |
| } |
| } |
| } |
| } |
| struct S6p |
| { |
| template opDispatch(string name) |
| { |
| template opDispatch(T) |
| { |
| @property ref int opDispatch(A...)(A args) |
| { |
| static int n; |
| n = args.length; |
| return n; |
| } |
| } |
| } |
| } |
| void test6() |
| { |
| S6f s6f; |
| assert(s6f.prop!int == 0); // getter ng -> ok |
| assert((s6f.prop!int = 1) == 1); // setter |
| |
| S6p s6p; |
| assert(s6p.prop!int == 0); // getter ng -> ok |
| assert((s6p.prop!int = 1) == 1); // setter |
| } |
| |
| /**********************************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=7578 |
| |
| struct Foo7578 |
| { |
| static int[] opDispatch(string op, Args...)(Args) |
| { |
| return [0]; |
| } |
| } |
| |
| void test7578() |
| { |
| Foo7578.attrs[0] = 1; |
| } |
| |
| /**********************************************/ |
| |
| int main() |
| { |
| test1(); |
| test2(); |
| test3(); |
| test4(); |
| test5(); |
| test6(); |
| test7578(); |
| |
| printf("Success\n"); |
| return 0; |
| } |