| // EXTRA_FILES: imports/testlambda1.d imports/testlambda2.d |
| module testlambdacomp; |
| |
| void test1() |
| { |
| static assert(__traits(isSame, (a, b) => a + b, (c, d) => c + d)); |
| static assert(__traits(isSame, a => ++a, b => ++b)); |
| static assert(!__traits(isSame, (int a, int b) => a + b, (a, b) => a + b)); |
| static assert(__traits(isSame, (a, b) => a + b + 10, (c, d) => c + d + 10)); |
| } |
| |
| class Y |
| { |
| static int r = 5; |
| int x; |
| this(int x) |
| { |
| this.x = x; |
| } |
| } |
| |
| class A |
| { |
| Y a; |
| this(Y a) |
| { |
| this.a = a; |
| } |
| } |
| |
| void foo3(alias pred)() |
| { |
| static assert(!__traits(isSame, pred, (A x, A y) => ++x.a.x + (--y.a.x))); |
| } |
| |
| void test2() |
| { |
| |
| int b; |
| static assert(!__traits(isSame, a => a + b, a => a + b)); |
| |
| int f() { return 3;} |
| static assert(__traits(isSame, a => a + f(), a => a + f())); |
| |
| class A |
| { |
| Y a; |
| this(Y a) |
| { |
| this.a = a; |
| } |
| } |
| |
| class B |
| { |
| int a; |
| this(int a) |
| { |
| this.a = a; |
| } |
| } |
| |
| B q = new B(7); |
| alias pred = (A a, A b) => ++a.a.x + (--b.a.x); |
| foo3!pred(); |
| static assert(!__traits(isSame, (A a) => ++a.a.x + 2, (A b) => ++b.a.x + 3)); |
| static assert(__traits(isSame, pred, (A x, A y) => ++x.a.x + (--y.a.x))); |
| static assert(!__traits(isSame, (B a) => ++a.a + 2, (B b) => ++b.a + 3)); |
| static assert(__traits(isSame, (B a) => ++a.a, (B a) => ++a.a)); |
| |
| B cl = new B(7); |
| static assert(!__traits(isSame, a => a + q.a, c => c + cl.a)); |
| |
| class C(G) |
| { |
| G a; |
| this(int a) |
| { |
| this.a = a; |
| } |
| } |
| static assert(!__traits(isSame, (C!int a) => ++a.a, (C!int a) => ++a.a)); |
| |
| struct X |
| { |
| int a; |
| } |
| static assert(__traits(isSame, (X a) => a.a + 2, (X b) => b.a + 2)); |
| |
| struct T(G) |
| { |
| G a; |
| } |
| static assert(!__traits(isSame, (T!int a) => ++a.a, (T!int a) => ++a.a)); |
| |
| } |
| |
| void test3() |
| { |
| enum q = 10; |
| static assert(__traits(isSame, (a, b) => a + b + q, (c, d) => c + d + 10)); |
| |
| struct Bar |
| { |
| int a; |
| } |
| enum r1 = Bar(1); |
| enum r2 = Bar(1); |
| static assert(__traits(isSame, a => a + r1.a, b => b + r2.a)); |
| |
| enum X { A, B, C} |
| static assert(__traits(isSame, a => a + X.A, a => a + 0)); |
| } |
| |
| void foo(alias pred)() |
| { |
| static assert(__traits(isSame, pred, (c, d) => c + d)); |
| static assert(__traits(isSame, (c, d) => c + d, pred)); |
| } |
| |
| void bar(alias pred)() |
| { |
| static assert(__traits(isSame, pred, (c, d) => c < d + 7)); |
| |
| enum q = 7; |
| static assert(__traits(isSame, pred, (c, d) => c < d + q)); |
| |
| int r = 7; |
| static assert(!__traits(isSame, pred, (c, d) => c < d + r)); |
| } |
| void test4() |
| { |
| foo!((a, b) => a + b)(); |
| bar!((a, b) => a < b + 7); |
| } |
| |
| int bar() |
| { |
| return 2; |
| } |
| |
| void testImportedFunctions(alias pred)() |
| { |
| // imports.testalambda1.bar != imports.testlambda2.bar |
| import imports.testlambda2 : bar; |
| static assert(!__traits(isSame, pred, (int a) => a + bar())); |
| } |
| |
| void testLocalGlobalFunctionScopes(alias pred)() |
| { |
| // testlambdacomp.bar != testlambdacomp.test5.bar |
| static assert(!__traits(isSame, pred, (int a) => a + bar())); |
| |
| // imports.testlambda1.bar != testlambdacomp.test5.bar |
| import imports.testlambda1 : bar; |
| static assert(!__traits(isSame, pred, (int a) => a + bar())); |
| |
| // functions imported from different modules are not equal |
| testImportedFunctions!((int a) => a + bar())(); |
| } |
| |
| // lambda functions which contain function calls |
| void test5() |
| { |
| |
| int bar() |
| { |
| return 3; |
| } |
| |
| // functions in the same scope |
| alias pred = a => a + bar(); |
| alias pred2 = b => b + bar(); |
| static assert(__traits(isSame, pred, pred2)); |
| |
| // functions in different scopes |
| testLocalGlobalFunctionScopes!((int a) => a + bar())(); |
| |
| int foo(int a, int b) |
| { |
| return 2 + a + b; |
| } |
| |
| // functions with different kind of parameters |
| alias preda23 = a => a + foo(2, 3); |
| alias predb23 = b => b + foo(2, 3); |
| alias predc24 = c => c + foo(2, 4); |
| alias predd23 = (int d) => d + foo(2, 3); |
| alias prede23 = (int e) => e + foo(2, 3); |
| alias predf24 = (int f) => f + foo(2, 4); |
| static assert(__traits(isSame, preda23, predb23)); |
| static assert(!__traits(isSame, predc24, predd23)); |
| static assert(__traits(isSame, predd23, prede23)); |
| static assert(!__traits(isSame, prede23, predf24)); |
| |
| // functions with function calls as parameters |
| static assert(!__traits(isSame, (int a, int b) => foo(foo(1, a), foo(1, b)), (int a, int b) => foo(foo(1, a), foo(2, b)))); |
| static assert(!__traits(isSame, (a, b) => foo(foo(1, a), foo(1, b)), (int a, int b) => foo(foo(1, a), foo(2, b)))); |
| |
| float floatFunc(float a, float b) |
| { |
| return a + b; |
| } |
| |
| static assert(__traits(isSame, a => floatFunc(a, 1.0), b => floatFunc(b, 1.0))); |
| static assert(!__traits(isSame, a => floatFunc(a, 1.0), b => floatFunc(b, 2.0))); |
| } |
| |
| void main() |
| { |
| test1(); |
| test2(); |
| test3(); |
| test4(); |
| test5(); |
| } |