| // PERMUTE_ARGS: -unittest -O -release -inline -fPIC -g |
| // REQUIRED_ARGS: -preview=dtorfields |
| /* |
| TEST_OUTPUT: |
| --- |
| S7353 |
| --- |
| */ |
| |
| import core.vararg; |
| // FIXME: Shouldn't tests that use this go in core.memory now that `delete` has been removed? |
| import core.memory : __delete; |
| |
| extern (C) int printf(const(char*) fmt, ...) nothrow; |
| |
| template TypeTuple(T...) { alias TypeTuple = T; } |
| |
| /**********************************/ |
| |
| int sdtor; |
| |
| struct S1 |
| { |
| ~this() { printf("~S()\n"); sdtor++; } |
| } |
| |
| void test1() |
| { |
| S1* s = new S1(); |
| __delete(s); |
| assert(sdtor == 1); |
| } |
| |
| /**********************************/ |
| |
| int sdtor3; |
| |
| struct S3 |
| { int a; |
| ~this() { printf("~S3()\n"); sdtor3++; assert(a == 3); } |
| } |
| |
| struct T3 |
| { |
| int i; |
| S3 s; |
| } |
| |
| void test3() |
| { |
| T3* s = new T3(); |
| s.s.a = 3; |
| __delete(s); |
| assert(sdtor3 == 1); |
| } |
| |
| /**********************************/ |
| |
| int sdtor4; |
| |
| struct S4 |
| { int a = 3; |
| ~this() |
| { printf("~S4()\n"); |
| if (a == 4) |
| assert(sdtor4 == 2); |
| else |
| { assert(a == 3); |
| assert(sdtor4 == 1); |
| } |
| sdtor4++; |
| } |
| } |
| |
| struct T4 |
| { |
| int i; |
| S4 s; |
| ~this() { printf("~T4()\n"); assert(sdtor4 == 0); sdtor4++; } |
| S4 t; |
| } |
| |
| void test4() |
| { |
| T4* s = new T4(); |
| s.s.a = 4; |
| __delete(s); |
| assert(sdtor4 == 3); |
| } |
| |
| /**********************************/ |
| |
| int sdtor5; |
| |
| template M5() |
| { ~this() |
| { |
| printf("~M5()\n"); assert(sdtor5 == 1); sdtor5++; |
| } |
| } |
| |
| struct T5 |
| { |
| mixin M5 m; |
| ~this() { printf("~T5()\n"); assert(sdtor5 == 0); sdtor5++; } |
| } |
| |
| void test5() |
| { |
| T5* s = new T5(); |
| __delete(s); |
| assert(sdtor5 == 2); |
| } |
| |
| /**********************************/ |
| |
| int sdtor6; |
| |
| struct S6 |
| { int b = 7; |
| ~this() |
| { |
| printf("~S6()\n"); assert(b == 7); assert(sdtor6 == 1); sdtor6++; |
| } |
| } |
| |
| class T6 |
| { |
| int a = 3; |
| S6 s; |
| ~this() { printf("~T6()\n"); assert(a == 3); assert(sdtor6 == 0); sdtor6++; } |
| } |
| |
| void test6() |
| { |
| T6 s = new T6(); |
| __delete(s); |
| assert(sdtor6 == 2); |
| } |
| |
| /**********************************/ |
| |
| int sdtor7; |
| |
| struct S7 |
| { int b = 7; |
| ~this() |
| { |
| printf("~S7()\n"); |
| assert(b == 7); |
| assert(sdtor7 >= 1 && sdtor7 <= 3); |
| sdtor7++; |
| } |
| } |
| |
| struct T7 |
| { |
| int a = 3; |
| S7[3] s; |
| ~this() |
| { printf("~T7() %d\n", sdtor7); |
| assert(a == 3); |
| assert(sdtor7 == 0); |
| sdtor7++; |
| } |
| } |
| |
| void test7() |
| { |
| T7* s = new T7(); |
| __delete(s); |
| assert(sdtor7 == 4); |
| } |
| |
| /**********************************/ |
| |
| int sdtor8; |
| |
| struct S8 |
| { int b = 7; |
| int c; |
| ~this() |
| { |
| printf("~S8() %d\n", sdtor8); |
| assert(b == 7); |
| assert(sdtor8 == c); |
| sdtor8++; |
| } |
| } |
| |
| void test8() |
| { |
| S8[] s = new S8[3]; |
| s[0].c = 2; |
| s[1].c = 1; |
| s[2].c = 0; |
| __delete(s); |
| assert(sdtor8 == 3); |
| } |
| |
| /**********************************/ |
| |
| int sdtor9; |
| |
| struct S9 |
| { int b = 7; |
| ~this() |
| { |
| printf("~S9() %d\n", sdtor9); |
| assert(b == 7); |
| sdtor9++; |
| } |
| } |
| |
| void test9() |
| { |
| { |
| S9 s; |
| } |
| assert(sdtor9 == 1); |
| } |
| |
| /**********************************/ |
| |
| int sdtor10; |
| |
| struct S10 |
| { int b = 7; |
| int c; |
| ~this() |
| { |
| printf("~S10() %d\n", sdtor10); |
| assert(b == 7); |
| assert(sdtor10 == c); |
| sdtor10++; |
| } |
| } |
| |
| void test10() |
| { |
| { |
| S10[3] s; |
| s[0].c = 2; |
| s[1].c = 1; |
| s[2].c = 0; |
| } |
| assert(sdtor10 == 3); |
| } |
| |
| /**********************************/ |
| |
| int sdtor11; |
| |
| template M11() |
| { ~this() |
| { |
| printf("~M11()\n"); assert(sdtor11 == 1); sdtor11++; |
| } |
| } |
| |
| class T11 |
| { |
| mixin M11 m; |
| ~this() { printf("~T11()\n"); assert(sdtor11 == 0); sdtor11++; } |
| } |
| |
| void test11() |
| { |
| T11 s = new T11(); |
| __delete(s); |
| assert(sdtor11 == 2); |
| } |
| |
| /**********************************/ |
| |
| int sdtor12; |
| |
| struct S12 |
| { int a = 3; |
| ~this() { printf("~S12() %d\n", sdtor12); sdtor12++; } |
| } |
| |
| void foo12(S12 s) |
| { |
| } |
| |
| void test12() |
| { |
| { |
| S12 s; |
| foo12(s); |
| s.a = 4; |
| } |
| assert(sdtor12 == 2); |
| } |
| |
| /**********************************/ |
| |
| struct S13 |
| { int a = 3; |
| int opAssign(S13 s) |
| { |
| printf("S13.opAssign(%p)\n", &this); |
| a = 4; |
| return s.a + 2; |
| } |
| } |
| |
| void test13() |
| { |
| S13 s; |
| S13 t; |
| assert((s = t) == 5); |
| assert(s.a == 4); |
| } |
| |
| /**********************************/ |
| |
| struct S14 |
| { int a = 3; |
| int opAssign(ref S14 s) |
| { |
| printf("S14.opAssign(%p)\n", &this); |
| a = 4; |
| return s.a + 2; |
| } |
| } |
| |
| void test14() |
| { |
| S14 s; |
| S14 t; |
| assert((s = t) == 5); |
| assert(s.a == 4); |
| } |
| |
| /**********************************/ |
| |
| struct S15 |
| { int a = 3; |
| int opAssign(ref const S15 s) |
| { |
| printf("S15.opAssign(%p)\n", &this); |
| a = 4; |
| return s.a + 2; |
| } |
| } |
| |
| void test15() |
| { |
| S15 s; |
| S15 t; |
| assert((s = t) == 5); |
| assert(s.a == 4); |
| } |
| |
| /**********************************/ |
| |
| struct S16 |
| { int a = 3; |
| int opAssign(S16 s, ...) |
| { |
| printf("S16.opAssign(%p)\n", &this); |
| a = 4; |
| return s.a + 2; |
| } |
| } |
| |
| void test16() |
| { |
| S16 s; |
| S16 t; |
| assert((s = t) == 5); |
| assert(s.a == 4); |
| } |
| |
| /**********************************/ |
| |
| struct S17 |
| { int a = 3; |
| int opAssign(...) |
| { |
| printf("S17.opAssign(%p)\n", &this); |
| a = 4; |
| return 5; |
| } |
| } |
| |
| void test17() |
| { |
| S17 s; |
| S17 t; |
| assert((s = t) == 5); |
| assert(s.a == 4); |
| } |
| |
| /**********************************/ |
| |
| struct S18 |
| { int a = 3; |
| int opAssign(S18 s, int x = 7) |
| { |
| printf("S18.opAssign(%p)\n", &this); |
| a = 4; |
| assert(x == 7); |
| return s.a + 2; |
| } |
| } |
| |
| void test18() |
| { |
| S18 s; |
| S18 t; |
| assert((s = t) == 5); |
| assert(s.a == 4); |
| } |
| |
| /**********************************/ |
| |
| struct S19 |
| { |
| int a,b,c,d; |
| this(this) { printf("this(this) %p\n", &this); } |
| ~this() { printf("~this() %p\n", &this); } |
| } |
| |
| S19 foo19() |
| { |
| S19 s; |
| void bar() { s.a++; } |
| bar(); |
| return s; |
| } |
| |
| void test19() |
| { |
| S19 t = foo19(); |
| printf("-main()\n"); |
| } |
| |
| /**********************************/ |
| |
| struct S20 |
| { |
| static char[] r; |
| int a,b,c=2,d; |
| this(this) { printf("this(this) %p\n", &this); r ~= '='; } |
| ~this() { printf("~this() %p\n", &this); r ~= '~'; } |
| } |
| |
| void foo20() |
| { |
| S20 s; |
| S20[3] a; |
| assert(S20.r == ""); |
| a = s; |
| assert(S20.r == "=~=~=~"); |
| } |
| |
| void test20() |
| { |
| foo20(); |
| assert(S20.r == "=~=~=~~~~~"); |
| printf("-main()\n"); |
| } |
| |
| /**********************************/ |
| |
| struct S21 |
| { |
| static char[] r; |
| int a,b,c=2,d; |
| this(this) { printf("this(this) %p\n", &this); r ~= '='; } |
| ~this() { printf("~this() %p\n", &this); r ~= '~'; } |
| } |
| |
| void foo21() |
| { |
| S21 s; |
| S21[3] a = s; |
| assert(S21.r == "==="); |
| S21.r = null; |
| S21[3][2] b = s; |
| assert(S21.r == "======"); |
| S21.r = null; |
| } |
| |
| void test21() |
| { |
| foo21(); |
| assert(S21.r == "~~~~~~~~~~"); |
| printf("-main()\n"); |
| } |
| |
| /**********************************/ |
| |
| struct S22 |
| { |
| static char[] r; |
| int a,b,c=2,d; |
| this(this) { printf("this(this) %p\n", &this); r ~= '='; } |
| ~this() { printf("~this() %p\n", &this); r ~= '~'; } |
| } |
| |
| void foo22() |
| { |
| S22[3] s; |
| S22[3][2] a; |
| assert(S22.r == ""); |
| a = s; |
| assert(S22.r == "===~~~===~~~"); |
| S22.r = null; |
| } |
| |
| void test22() |
| { |
| foo22(); |
| assert(S22.r == "~~~~~~~~~"); |
| printf("-main()\n"); |
| } |
| |
| |
| /************************************************/ |
| |
| struct S23 |
| { |
| int m = 4, n, o, p, q; |
| |
| this(int x) |
| { |
| printf("S23(%d)\n", x); |
| assert(x == 3); |
| assert(m == 4 && n == 0 && o == 0 && p == 0 && q == 0); |
| q = 7; |
| } |
| } |
| |
| void test23() |
| { |
| { |
| auto s = S23(3); |
| printf("s.m = %d, s.n = %d, s.q = %d\n", s.m, s.n, s.q); |
| assert(s.m == 4 && s.n == 0 && s.o == 0 && s.p == 0 && s.q == 7); |
| } |
| { |
| auto s = new S23(3); |
| printf("s.m = %d, s.n = %d, s.q = %d\n", s.m, s.n, s.q); |
| assert(s.m == 4 && s.n == 0 && s.o == 0 && s.p == 0 && s.q == 7); |
| } |
| { |
| S23 s; |
| s = S23(3); |
| printf("s.m = %d, s.n = %d, s.q = %d\n", s.m, s.n, s.q); |
| assert(s.m == 4 && s.n == 0 && s.o == 0 && s.p == 0 && s.q == 7); |
| } |
| } |
| |
| /************************************************/ |
| |
| struct S24 |
| { |
| int m, n, o, p, q; |
| |
| this(int x) |
| { |
| printf("S24(%d)\n", x); |
| assert(x == 3); |
| assert(m == 0 && n == 0 && o == 0 && p == 0 && q == 0); |
| q = 7; |
| } |
| } |
| |
| void test24() |
| { |
| { |
| auto s = S24(3); |
| printf("s.m = %d, s.n = %d, s.q = %d\n", s.m, s.n, s.q); |
| assert(s.m == 0 && s.n == 0 && s.o == 0 && s.p == 0 && s.q == 7); |
| } |
| { |
| auto s = new S24(3); |
| printf("s.m = %d, s.n = %d, s.q = %d\n", s.m, s.n, s.q); |
| assert(s.m == 0 && s.n == 0 && s.o == 0 && s.p == 0 && s.q == 7); |
| } |
| { |
| S24 s; |
| s = S24(3); |
| printf("s.m = %d, s.n = %d, s.q = %d\n", s.m, s.n, s.q); |
| assert(s.m == 0 && s.n == 0 && s.o == 0 && s.p == 0 && s.q == 7); |
| } |
| } |
| |
| /**********************************/ |
| |
| struct S25 |
| { |
| this(int s) {} |
| } |
| |
| void test25() |
| { |
| auto a = S25(); |
| } |
| |
| /**********************************/ |
| |
| int z26; |
| |
| struct A26 |
| { |
| int id; |
| this(int x) { id = x; printf("Created A from scratch: %d\n", x); z26++; } |
| this(this) { printf("Copying A: %d\n", id); z26 += 10; } |
| ~this() { printf("Destroying A: %d\n", id); z26 += 100; } |
| } |
| |
| struct B26 |
| { |
| A26 member; |
| this(this) { printf("Copying B: %d\n", member.id); assert(0); } |
| } |
| |
| B26 foo26() |
| { |
| A26 a = A26(45); |
| printf("1\n"); |
| assert(z26 == 1); |
| return B26(a); |
| } |
| |
| void test26() |
| { |
| { |
| auto b = foo26(); |
| assert(z26 == 111); |
| printf("2\n"); |
| } |
| assert(z26 == 211); |
| } |
| |
| /**********************************/ |
| |
| int z27; |
| |
| struct A27 |
| { |
| int id; |
| this(int x) { id = x; printf("Ctor A27: %d\n", x); z27++; } |
| this(this) { printf("Copying A27: %d\n", id); z27 += 10; } |
| ~this() { printf("Destroying A27: %d\n", id); z27 += 100; } |
| } |
| |
| struct B27 |
| { |
| A27[2][3] member; |
| } |
| |
| void test27() |
| { |
| { |
| A27[2][3] a; |
| assert(z27 == 0); |
| B27 b = B27(a); |
| assert(z27 == 60); |
| } |
| assert(z27 == 1260); |
| } |
| |
| |
| /**********************************/ |
| |
| string s28; |
| |
| struct A28 |
| { |
| this(this) |
| { |
| printf("A's copy\n"); |
| s28 ~= "A"; |
| } |
| } |
| |
| struct B28 |
| { |
| A28 member; |
| this(this) |
| { |
| printf("B's copy\n"); |
| s28 ~= "B"; |
| } |
| } |
| |
| void test28() |
| { |
| B28 b1; |
| B28 b2 = b1; |
| assert(s28 == "AB"); |
| } |
| |
| |
| /**********************************/ |
| |
| string s29; |
| |
| template Templ29 () |
| { |
| this(int i) { this(0.0); s29 ~= "i"; } |
| this(double d) { s29 ~= "d"; } |
| } |
| |
| class C29 { mixin Templ29; } |
| struct S29 { mixin Templ29; } |
| |
| void test29() |
| { |
| auto r = S29(1); |
| assert(s29 == "di"); |
| |
| r = S29(2.0); |
| assert(s29 == "did"); |
| |
| auto c = new C29(2); |
| assert(s29 == "diddi"); |
| |
| auto c2 = new C29(2.0); |
| assert(s29 == "diddid"); |
| } |
| |
| /**********************************/ |
| |
| struct S30 |
| { |
| int x; |
| this(T)(T args) { x = args + 1; } |
| } |
| |
| void test30() |
| { |
| auto s = S30(3); |
| assert(s.x == 4); |
| } |
| |
| /**********************************/ |
| |
| struct S31 |
| { |
| int x; |
| this(T...)(T args) { x = args[0] + 1; } |
| } |
| |
| void test31() |
| { |
| auto s = S31(3); |
| assert(s.x == 4); |
| } |
| |
| /**********************************/ |
| |
| struct S32 |
| { |
| static int x; |
| |
| this(int i) |
| { |
| printf("ctor %p(%d)\n", &this, i); |
| x += 1; |
| } |
| |
| this(this) |
| { |
| printf("postblit %p\n", &this); |
| x += 0x10; |
| } |
| |
| ~this() |
| { |
| printf("dtor %p\n", &this); |
| x += 0x100; |
| } |
| } |
| |
| S32 foo32() |
| { |
| printf("test1\n"); |
| return S32(1); |
| } |
| |
| S32 bar32() |
| { |
| printf("test1\n"); |
| S32 f = S32(1); |
| printf("test2\n"); |
| return f; |
| } |
| |
| void test32() |
| { |
| { |
| S32 s = foo32(); |
| } |
| assert(S32.x == 0x101); |
| |
| S32.x = 0; |
| { |
| S32 s = bar32(); |
| } |
| assert(S32.x == 0x101); |
| } |
| |
| /**********************************/ |
| |
| struct S33 |
| { |
| static int x; |
| |
| this(int i) |
| { |
| printf("ctor %p(%d)\n", &this, i); |
| x += 1; |
| } |
| |
| this(this) |
| { |
| printf("postblit %p\n", &this); |
| x += 0x10; |
| } |
| |
| ~this() |
| { |
| printf("dtor %p\n", &this); |
| x += 0x100; |
| } |
| } |
| |
| struct T33 |
| { |
| S33 foo() |
| { |
| return t; |
| } |
| |
| S33 t; |
| } |
| |
| void test33() |
| { |
| { |
| T33 t; |
| S33 s = t.foo(); |
| } |
| printf("S.x = %x\n", S33.x); |
| assert(S33.x == 0x210); |
| } |
| |
| /**********************************/ |
| |
| struct X34 { |
| int i; |
| this(this) { |
| printf("postblit %p\n", &this); |
| ++i; |
| } |
| |
| ~this() { |
| printf("dtor %p\n", &this); |
| } |
| } |
| |
| void test34() |
| { |
| X34[2] xs; |
| // xs[0][0] = X34(); |
| printf("foreach\n"); |
| for (int j = 0; j < xs.length; j++) { |
| j++,j--; |
| auto x = xs[j]; |
| //foreach(x; xs) |
| //printf("foreach x.i = %d\n", x[0].i); |
| //assert(x[0].i == 1); |
| printf("foreach x.i = %d\n", x.i); |
| assert(x.i == 1); |
| } |
| printf("loop done\n"); |
| } |
| |
| /**********************************/ |
| |
| struct X35 { |
| __gshared int k; |
| int i; |
| this(this) { |
| printf("postblit %p\n", &this); |
| ++i; |
| } |
| |
| ~this() { |
| printf("dtor %p\n", &this); |
| k++; |
| } |
| } |
| |
| void test35() |
| { |
| { |
| X35[2] xs; |
| printf("foreach\n"); |
| foreach(ref x; xs) { |
| printf("foreach x.i = %d\n", x.i); |
| assert(x.i == 0); |
| } |
| printf("loop done\n"); |
| } |
| assert(X35.k == 2); |
| } |
| |
| /**********************************/ |
| |
| struct X36 { |
| __gshared int k; |
| int i; |
| this(this) { |
| printf("postblit %p\n", &this); |
| ++i; |
| } |
| |
| ~this() { |
| printf("dtor %p\n", &this); |
| k++; |
| } |
| } |
| |
| void test36() |
| { |
| { |
| X36[2] xs; |
| printf("foreach\n"); |
| foreach(x; xs) { |
| printf("foreach x.i = %d\n", x.i); |
| assert(x.i == 1); |
| } |
| printf("loop done\n"); |
| } |
| assert(X36.k == 4); |
| } |
| |
| /**********************************/ |
| |
| struct X37 { |
| __gshared int k; |
| int i; |
| this(this) { |
| printf("postblit %p\n", &this); |
| ++i; |
| } |
| |
| ~this() { |
| printf("dtor %p\n", &this); |
| k++; |
| } |
| } |
| |
| void test37() { |
| { |
| X37[2][3] xs; |
| printf("foreach\n"); |
| foreach(ref x; xs) { |
| printf("foreach x.i = %d\n", x[0].i); |
| assert(x[0].i == 0); |
| } |
| printf("loop done\n"); |
| } |
| assert(X37.k == 6); |
| } |
| |
| /**********************************/ |
| |
| struct S38 { |
| __gshared int count; |
| __gshared int postblit; |
| |
| this(int x) { |
| printf("this(%d)\n", x); |
| assert(this.x == 0); |
| this.x = x; |
| count++; |
| } |
| this(this) { |
| printf("this(this) with %d\n", x); |
| assert(x == 1 || x == 2); |
| count++; |
| postblit++; |
| } |
| ~this() { |
| printf("~this(%d)\n", x); |
| assert(x == 1 || x == 2); |
| x = 0; |
| count--; |
| } |
| int x; |
| } |
| |
| S38 foo38() { |
| auto s = S38(1); |
| return s; |
| } |
| |
| S38 bar38() { |
| return S38(2); |
| } |
| |
| void test38() |
| { |
| { |
| auto s1 = foo38(); |
| assert(S38.count == 1); |
| assert(S38.postblit == 0); |
| } |
| assert(S38.count == 0); |
| S38.postblit = 0; |
| |
| { |
| auto s2 = bar38(); |
| assert(S38.count == 1); |
| assert(S38.postblit == 0); |
| } |
| assert(S38.count == 0); |
| } |
| |
| |
| /**********************************/ |
| |
| struct Foo39 |
| { |
| int x; |
| this(int v){ x = v + 1; } |
| void opAssign(int v){ |
| x = v + 3; |
| } |
| } |
| |
| void test39() |
| { |
| int y = 5; |
| Foo39 f = y; |
| assert(f.x == 6); |
| f = y; |
| assert(f.x == 8); |
| // f = Foo39(y); |
| |
| } |
| |
| /**********************************/ |
| |
| bool approxEqual(float a, float b) |
| { |
| return a < b ? b-a < .001 : a-b < .001; |
| } |
| |
| struct Point { |
| float x = 0, y = 0; |
| const bool opEquals(const ref Point rhs) |
| { |
| return approxEqual(x, rhs.x) && approxEqual(y, rhs.y); |
| } |
| } |
| |
| struct Rectangle { |
| Point leftBottom, rightTop; |
| } |
| |
| void test40() |
| { |
| Rectangle a, b; |
| assert(a == b); |
| a.leftBottom.x = 1e-8; |
| assert(a == b); |
| a.rightTop.y = 5; |
| assert(a != b); |
| } |
| |
| /**********************************/ |
| |
| struct S41 { |
| this(int) immutable { } |
| } |
| |
| void test41() |
| { |
| auto s = new immutable S41(3); |
| //writeln(typeid(typeof(s))); |
| static assert(is(typeof(s) == immutable(S41)*)); |
| |
| auto t = immutable S41(3); |
| //writeln(typeid(typeof(t))); |
| static assert(is(typeof(t) == immutable(S41))); |
| } |
| |
| /**********************************/ |
| |
| class C42 { |
| this(int) immutable { |
| } |
| } |
| |
| void test42() |
| { |
| static assert(!__traits(compiles, new C42(3))); |
| //writeln(typeid(typeof(c))); |
| //static assert(is(typeof(c) == immutable(C42))); |
| |
| auto d = new immutable(C42)(3); |
| //writeln(typeid(typeof(d))); |
| static assert(is(typeof(d) == immutable(C42))); |
| } |
| |
| /**********************************/ |
| |
| struct S43 { |
| int i; |
| int* p; |
| // this(int i, int* t) immutable { this.i = i; p = t; } |
| } |
| |
| void test43() |
| { |
| int i; |
| assert(!__traits(compiles, immutable(S43)(3, &i))); |
| immutable int j = 4; |
| auto s = immutable(S43)(3, &j); |
| //writeln(typeid(typeof(s))); |
| static assert(is(typeof(s) == immutable(S43))); |
| } |
| |
| /**********************************/ |
| |
| struct S44 { |
| int i; |
| immutable(int)* p; |
| this(int i, immutable(int)* t) immutable { this.i = i; this.p = t; } |
| } |
| |
| void test44() |
| { |
| int i; |
| assert(!__traits(compiles, immutable(S44)(3, &i))); |
| immutable int j = 4; |
| auto s = immutable(S44)(3, &j); |
| //writeln(typeid(typeof(s))); |
| static assert(is(typeof(s) == immutable(S44))); |
| } |
| |
| /**********************************/ |
| |
| class C45 { |
| C45 next; |
| this(int[] data) immutable { |
| next = new immutable(C45)(data[1 .. $]); |
| } |
| } |
| |
| void test45() |
| { |
| } |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=3986 |
| |
| struct SiberianHamster |
| { |
| int rat = 813; |
| this(string z) { } |
| } |
| |
| void test46() |
| { |
| SiberianHamster basil = "cybil"; |
| assert(basil.rat == 813); |
| } |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=8741 |
| |
| struct Vec8741 |
| { |
| this(float x) |
| { |
| m[0] = x; |
| m[1] = 58; |
| } |
| float[2] m; |
| static Vec8741 zzz = Vec8741(7); |
| } |
| |
| void test8741() |
| { |
| assert(Vec8741.zzz.m[0] == 7); |
| assert(Vec8741.zzz.m[1] == 58); |
| } |
| |
| /**********************************/ |
| |
| struct Segfault3984 |
| { |
| int a; |
| this(int x){ |
| a = x; |
| } |
| } |
| |
| void test47() |
| { |
| //static |
| assert(Segfault3984(3).a == 3); |
| } |
| |
| /**********************************/ |
| |
| void test48() |
| { |
| struct B { |
| void foo() { } |
| } |
| B x = B.init; |
| } |
| |
| /**********************************/ |
| |
| struct Foo49 { |
| int z; |
| this(int a){z=a;} |
| } |
| |
| void bar49(Foo49 a = Foo49(1)) |
| { |
| assert(a.z == 1); |
| } |
| |
| void test49() |
| { |
| bar49(); |
| bar49(); |
| } |
| |
| /**********************************/ |
| |
| struct aStruct{ |
| int m_Int; |
| |
| this(int a){ |
| m_Int = a; |
| } |
| } |
| |
| class aClass{ |
| void aFunc(aStruct a = aStruct(44)) |
| { |
| assert(a.m_Int == 44); |
| } |
| } |
| |
| void test50() |
| { |
| aClass a = new aClass(); |
| a.aFunc(); |
| a.aFunc(); |
| } |
| |
| /**********************************/ |
| |
| int A51_a; |
| |
| struct A51 |
| { |
| ~this() { ++A51_a; } |
| } |
| |
| void test51() |
| { |
| A51_a = 0; { while(0) A51 a; } assert(A51_a == 0); |
| A51_a = 0; { if(0) A51 a; } assert(A51_a == 0); |
| A51_a = 0; { if(1){} else A51 a; } assert(A51_a == 0); |
| A51_a = 0; { for(;0;) A51 a; } assert(A51_a == 0); |
| A51_a = 0; { if (1) { A51 a; } } assert(A51_a == 1); |
| A51_a = 0; { if (1) A51 a; } assert(A51_a == 1); |
| A51_a = 0; { if(0) {} else A51 a; } assert(A51_a == 1); |
| A51_a = 0; { if (0) for(A51 a;;) {} } assert(A51_a == 0); |
| A51_a = 0; { if (0) for(;;) A51 a; } assert(A51_a == 0); |
| A51_a = 0; { do A51 a; while(0); } assert(A51_a == 1); |
| A51_a = 0; { if (0) while(1) A51 a; } assert(A51_a == 0); |
| A51_a = 0; { try A51 a; catch(Error e) {} } assert(A51_a == 1); |
| A51_a = 0; { if (0) final switch(1) A51 a; } assert(A51_a == 0); // should fail to build |
| // A51_a = 0; { if (0) switch(1) { A51 a; default: } } assert(A51_a == 0); |
| A51_a = 0; { if (0) switch(1) { default: A51 a; } } assert(A51_a == 0); |
| // A51_a = 0; { if (1) switch(1) { A51 a; default: } } assert(A51_a == 1); // should be 0, right? |
| A51_a = 0; { if (1) switch(1) { default: A51 a; } } assert(A51_a == 1); |
| // A51_a = 0; { final switch(0) A51 a; } assert(A51_a == 0); |
| A51_a = 0; { A51 a; with(a) A51 b; } assert(A51_a == 2); |
| } |
| |
| /**********************************/ |
| |
| string s52; |
| |
| struct A52 |
| { |
| int m; |
| this(this) |
| { |
| printf("this(this) %p\n", &this); |
| s52 ~= 'a'; |
| } |
| ~this() |
| { |
| printf("~this() %p\n", &this); |
| s52 ~= 'b'; |
| } |
| A52 copy() |
| { |
| s52 ~= 'c'; |
| A52 another = this; |
| return another; |
| } |
| } |
| |
| void test52() |
| { |
| { |
| A52 a; |
| A52 b = a.copy(); |
| printf("a: %p, b: %p\n", &a, &b); |
| } |
| printf("s = '%.*s'\n", cast(int)s52.length, s52.ptr); |
| assert(s52 == "cabb"); |
| } |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=4339 |
| |
| struct A53 { |
| invariant() { } |
| ~this() { } |
| void opAssign(A53 a) {} |
| int blah(A53 a) { return 0; } |
| } |
| |
| /**********************************/ |
| |
| struct S54 |
| { |
| int x = 1; |
| |
| int bar() { return x; } |
| |
| this(int i) |
| { |
| printf("ctor %p(%d)\n", &this, i); |
| t ~= "a"; |
| } |
| |
| this(this) |
| { |
| printf("postblit %p\n", &this); |
| t ~= "b"; |
| } |
| |
| ~this() |
| { |
| printf("dtor %p\n", &this); |
| t ~= "c"; |
| } |
| |
| static string t; |
| } |
| |
| void bar54(S54 s) { } |
| |
| S54 abc54() { return S54(1); } |
| |
| void test54() |
| { |
| { S54.t = null; |
| S54 s = S54(1); |
| } |
| assert(S54.t == "ac"); |
| |
| { S54.t = null; |
| S54 s = S54(); |
| } |
| assert(S54.t == "c"); |
| |
| { S54.t = null; |
| int b = 1 && (){ bar54(S54(1)); return 1;}(); |
| } |
| assert(S54.t == "ac"); |
| |
| { S54.t = null; |
| int b = 0 && (){ bar54(S54(1)); return 1;}(); |
| } |
| assert(S54.t == ""); |
| |
| { S54.t = null; |
| int b = 0 || (){ bar54(S54(1)); return 1;}(); |
| } |
| assert(S54.t == "ac"); |
| |
| { S54.t = null; |
| int b = 1 || (){ bar54(S54(1)); return 1;}(); |
| } |
| assert(S54.t == ""); |
| |
| { |
| S54.t = null; |
| { const S54 s = S54(1); } |
| assert(S54.t == "ac"); |
| } |
| { |
| S54.t = null; |
| abc54(); |
| assert(S54.t == "ac"); |
| } |
| { |
| S54.t = null; |
| abc54().x += 1; |
| assert(S54.t == "ac"); |
| } |
| } |
| |
| /**********************************/ |
| |
| void test55() |
| { |
| S55 s; |
| auto t = s.copy(); |
| assert(t.count == 1); // (5) |
| } |
| |
| struct S55 |
| { |
| int count; |
| this(this) { ++count; } |
| S55 copy() { return this; } |
| } |
| |
| /**********************************/ |
| |
| struct S56 |
| { |
| int x = 1; |
| |
| int bar() { return x; } |
| |
| this(int i) |
| { |
| printf("ctor %p(%d)\n", &this, i); |
| t ~= "a"; |
| } |
| |
| this(this) |
| { |
| printf("postblit %p\n", &this); |
| t ~= "b"; |
| } |
| |
| ~this() |
| { |
| printf("dtor %p\n", &this); |
| t ~= "c"; |
| } |
| |
| static string t; |
| } |
| |
| int foo56() |
| { |
| throw new Throwable("hello"); |
| return 5; |
| } |
| |
| |
| void test56() |
| { |
| int i; |
| int j; |
| try |
| { |
| j |= 1; |
| i = S56(1).x + foo56() + 1; |
| j |= 2; |
| } |
| catch (Throwable o) |
| { |
| printf("caught\n"); |
| j |= 4; |
| } |
| printf("i = %d, j = %d\n", i, j); |
| assert(i == 0); |
| assert(j == 5); |
| } |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=5859 |
| |
| int dtor_cnt = 0; |
| struct S57 |
| { |
| int v; |
| this(int n){ v = n; printf("S.ctor v=%d\n", v); } |
| ~this(){ ++dtor_cnt; printf("S.dtor v=%d\n", v); } |
| bool opCast(T:bool)(){ printf("S.cast v=%d\n", v); return true; } |
| } |
| S57 f(int n){ return S57(n); } |
| |
| void test57() |
| { |
| printf("----\n"); |
| dtor_cnt = 0; |
| if (auto s = S57(10)) |
| { |
| printf("ifbody\n"); |
| } |
| else assert(0); |
| assert(dtor_cnt == 1); |
| |
| printf("----\n"); //+ |
| dtor_cnt = 0; |
| S57(1), S57(2); |
| if (auto s = S57(10)) |
| { |
| assert(dtor_cnt == 2); |
| printf("ifbody\n"); |
| } |
| else assert(0); |
| assert(dtor_cnt == 3); // +/ |
| |
| printf("----\n"); |
| dtor_cnt = 0; |
| try{ |
| if (auto s = S57(10)) |
| { |
| printf("ifbody\n"); |
| throw new Exception("test"); |
| } |
| else assert(0); |
| }catch (Exception e){} |
| assert(dtor_cnt == 1); |
| |
| |
| |
| printf("----\n"); |
| dtor_cnt = 0; |
| if (auto s = f(10)) |
| { |
| printf("ifbody\n"); |
| } |
| else assert(0); |
| assert(dtor_cnt == 1); |
| |
| printf("----\n"); //+ |
| dtor_cnt = 0; |
| f(1), f(2); |
| if (auto s = f(10)) |
| { |
| assert(dtor_cnt == 2); |
| printf("ifbody\n"); |
| } |
| else assert(0); |
| assert(dtor_cnt == 3); // +/ |
| |
| printf("----\n"); |
| dtor_cnt = 0; |
| try{ |
| if (auto s = f(10)) |
| { |
| printf("ifbody\n"); |
| throw new Exception("test"); |
| } |
| else assert(0); |
| }catch (Exception e){} |
| assert(dtor_cnt == 1); |
| |
| |
| |
| |
| printf("----\n"); |
| dtor_cnt = 0; |
| if (S57(10)) |
| { |
| assert(dtor_cnt == 1); |
| printf("ifbody\n"); |
| } |
| else assert(0); |
| |
| printf("----\n"); |
| dtor_cnt = 0; |
| S57(1), S57(2); |
| if (S57(10)) |
| { |
| assert(dtor_cnt == 3); |
| printf("ifbody\n"); |
| } |
| else assert(0); |
| |
| printf("----\n"); |
| dtor_cnt = 0; |
| try{ |
| if (auto s = S57(10)) |
| { |
| printf("ifbody\n"); |
| throw new Exception("test"); |
| } |
| else assert(0); |
| }catch (Exception e){} |
| assert(dtor_cnt == 1); |
| |
| |
| |
| printf("----\n"); |
| dtor_cnt = 0; |
| if (f(10)) |
| { |
| assert(dtor_cnt == 1); |
| printf("ifbody\n"); |
| } |
| else assert(0); |
| |
| printf("----\n"); |
| dtor_cnt = 0; |
| f(1), f(2); |
| if (f(10)) |
| { |
| assert(dtor_cnt == 3); |
| printf("ifbody\n"); |
| } |
| else assert(0); |
| |
| printf("----\n"); |
| dtor_cnt = 0; |
| try{ |
| if (auto s = f(10)) |
| { |
| printf("ifbody\n"); |
| throw new Exception("test"); |
| } |
| else assert(0); |
| }catch (Exception e){} |
| assert(dtor_cnt == 1); |
| } |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=5574 |
| |
| struct foo5574a |
| { |
| ~this() {} |
| } |
| class bar5574a |
| { |
| foo5574a[1] frop; |
| } |
| |
| struct foo5574b |
| { |
| this(this){} |
| } |
| struct bar5574b |
| { |
| foo5574b[1] frop; |
| } |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=5777 |
| |
| int sdtor58 = 0; |
| S58* ps58; |
| |
| struct S58 |
| { |
| @disable this(this); |
| ~this(){ ++sdtor58; } |
| } |
| |
| S58 makeS58() |
| { |
| S58 s; |
| ps58 = &s; |
| return s; |
| } |
| |
| void test58() |
| { |
| auto s1 = makeS58(); |
| assert(ps58 == &s1); |
| assert(sdtor58 == 0); |
| } |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=6308 |
| |
| struct C59 |
| { |
| void oops() |
| { |
| throw new Throwable("Oops!"); |
| } |
| |
| ~this() |
| { |
| } |
| } |
| |
| void foo59() |
| { |
| C59().oops(); |
| // auto c = C(); c.oops(); |
| } |
| |
| |
| void test59() |
| { |
| int i = 0; |
| try |
| foo59(); |
| catch (Throwable) |
| { i = 1; |
| } |
| assert(i == 1); |
| } |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=5737 |
| |
| void test5737() |
| { |
| static struct S |
| { |
| static int destroyed; |
| static int copied; |
| |
| this(this) |
| { |
| copied++; |
| } |
| |
| ~this() |
| { |
| destroyed++; |
| } |
| } |
| |
| static S s; |
| |
| ref S foo() |
| { |
| return s; |
| } |
| |
| { |
| auto s2 = foo(); |
| } |
| |
| assert(S.copied == 1); // fail, s2 was not copied; |
| assert(S.destroyed == 1); // ok, s2 was destroyed |
| } |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=6119 |
| |
| void test6119() |
| { |
| int postblit = 0; |
| int dtor = 0; |
| |
| struct Test |
| { |
| this(this) { ++postblit; } |
| ~this() { ++dtor; } |
| } |
| |
| void takesVal(Test x) {} |
| ref Test returnsRef(ref Test x) { return x; } |
| |
| void f(ref Test x) { takesVal( x ); } |
| |
| Test x; |
| |
| postblit = dtor = 0; |
| takesVal(returnsRef(x)); |
| assert(postblit == 1); |
| assert(dtor == 1); |
| |
| postblit = dtor = 0; |
| f(x); |
| assert(postblit == 1); |
| assert(dtor == 1); |
| } |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=6364 |
| |
| struct Foo6364 |
| { |
| int state = 1; |
| |
| ~this() |
| { |
| state = 0; |
| } |
| } |
| |
| void testfoo6364() |
| { |
| static Foo6364 foo; |
| printf("%d\n", foo.state); |
| assert(foo.state == 1); |
| } |
| |
| void test6364() |
| { |
| testfoo6364(); |
| testfoo6364(); |
| } |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=6499 |
| |
| struct S6499 |
| { |
| string m = "<not set>"; |
| |
| this(string s) |
| { |
| m = s; |
| printf("Constructor - %.*s\n", cast(int)m.length, m.ptr); |
| if (m == "foo") { ++sdtor; assert(sdtor == 1); } |
| if (m == "bar") { ++sdtor; assert(sdtor == 2); } |
| } |
| this(this) |
| { |
| printf("Postblit - %.*s\n", cast(int)m.length, m.ptr); |
| assert(0); |
| } |
| ~this() |
| { |
| printf("Destructor - %.*s\n", cast(int)m.length, m.ptr); |
| if (m == "bar") { assert(sdtor == 2); --sdtor; } |
| if (m == "foo") { assert(sdtor == 1); --sdtor; } |
| } |
| S6499 bar() { return S6499("bar"); } |
| S6499 baz()() { return S6499("baz"); } |
| } |
| |
| void test6499() |
| { |
| S6499 foo() { return S6499("foo"); } |
| |
| { |
| sdtor = 0; |
| scope(exit) assert(sdtor == 0); |
| foo().bar(); |
| } |
| { |
| sdtor = 0; |
| scope(exit) assert(sdtor == 0); |
| foo().baz(); |
| } |
| } |
| |
| /**********************************/ |
| |
| template isImplicitlyConvertible(From, To) |
| { |
| enum bool isImplicitlyConvertible = is(typeof({ |
| void fun(ref From v) { |
| void gun(To) {} |
| gun(v); |
| } |
| }())); |
| } |
| |
| void test60() |
| { |
| static struct X1 |
| { |
| void* ptr; |
| this(this){} |
| } |
| static struct S1 |
| { |
| X1 x; |
| } |
| |
| static struct X2 |
| { |
| int ptr; |
| this(this){} |
| } |
| static struct S2 |
| { |
| X2 x; |
| } |
| |
| { |
| S1 ms; |
| S1 ms2 = ms; // mutable to mutable |
| const(S1) cs2 = ms; // mutable to const // NG -> OK |
| } |
| { |
| const(S1) cs; |
| static assert(!__traits(compiles,{ // NG -> OK |
| S1 ms2 = cs; // field has reference, then const to mutable is invalid |
| })); |
| const(S1) cs2 = cs; // const to const // NG -> OK |
| } |
| static assert( isImplicitlyConvertible!( S1 , S1 ) ); |
| static assert( isImplicitlyConvertible!( S1 , const(S1)) ); // NG -> OK |
| static assert(!isImplicitlyConvertible!(const(S1), S1 ) ); |
| static assert( isImplicitlyConvertible!(const(S1), const(S1)) ); // NG -> OK |
| |
| |
| { |
| S2 ms; |
| S2 ms2 = ms; // mutable to mutable |
| const(S2) cs2 = ms; // mutable to const // NG -> OK |
| } |
| { |
| const(S2) cs; |
| S2 ms2 = cs; // all fields are value, then const to mutable is OK |
| const(S2) cs2 = cs; // const to const // NG -> OK |
| } |
| |
| static assert( isImplicitlyConvertible!( S2 , S2 ) ); |
| static assert( isImplicitlyConvertible!( S2 , const(S2)) ); // NG -> OK |
| static assert( isImplicitlyConvertible!(const(S2), S2 ) ); |
| static assert( isImplicitlyConvertible!(const(S2), const(S2)) ); // NG -> OK |
| } |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=4316 |
| |
| struct A4316 |
| { |
| this(this) @safe { } |
| } |
| |
| @safe void test4316() |
| { |
| A4316 a; |
| auto b = a; // Error: safe function 'main' cannot call system function'__cpctor' |
| } |
| |
| /**********************************/ |
| |
| struct F6177 |
| { |
| ~this() {} |
| } |
| |
| struct G6177 |
| { |
| this(F6177[] p...) {} |
| } |
| |
| void test6177() |
| { |
| F6177 c; |
| auto g = G6177(c); |
| } |
| |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=6470 |
| |
| struct S6470 |
| { |
| static int spblit; |
| |
| this(this){ ++spblit; } |
| } |
| |
| void test6470() |
| { |
| S6470[] a1; |
| S6470[] a2; |
| a1.length = 3; |
| a2.length = 3; |
| a1[] = a2[]; |
| assert(S6470.spblit == 3); |
| |
| S6470 s; |
| |
| S6470[] a3; |
| a3.length = 3; |
| a3 = [s, s, s]; |
| assert(S6470.spblit == 6); |
| |
| void func(S6470[] a){} |
| func([s, s, s]); |
| assert(S6470.spblit == 9); |
| } |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=6636 |
| |
| struct S6636 |
| { |
| ~this() |
| { |
| ++sdtor; |
| } |
| } |
| |
| void func6636(S6636[3] sa) {} |
| |
| void test6636() |
| { |
| sdtor = 0; |
| |
| S6636[3] sa; |
| func6636(sa); |
| assert(sdtor == 3); |
| } |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=6637 |
| |
| struct S6637 |
| { |
| static int spblit; |
| |
| this(this){ ++spblit; } |
| } |
| |
| void test6637() |
| { |
| void func(S6637[3] sa){} |
| |
| S6637[3] sa; |
| func(sa); |
| assert(S6637.spblit == 3); |
| } |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=7353 |
| |
| struct S7353 |
| { |
| static uint ci = 0; |
| uint i; |
| |
| this(int x) { i = ci++; /*writeln("new: ", i);*/ } |
| this(this) { i = ci++; /*writeln("copy ", i);*/ } |
| ~this() { /*writeln("del ", i);*/ } |
| |
| S7353 save1() // produces 2 copies in total |
| { |
| S7353 s = this; |
| return s; |
| } |
| auto save2() // produces 3 copies in total |
| { |
| S7353 s = this; |
| return s; |
| pragma(msg, typeof(return)); |
| } |
| } |
| void test7353() |
| { |
| { |
| auto s = S7353(1), t = S7353(1); |
| t = s.save1(); |
| assert(S7353.ci == 3); |
| } |
| S7353.ci = 0; //writeln("-"); |
| { |
| auto s = S7353(1), t = S7353(1); |
| t = s.save2(); |
| assert(S7353.ci == 3); |
| } |
| } |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=8036 |
| |
| struct S8036a |
| { |
| ~this() {} |
| } |
| struct S8036b // or class |
| { |
| S8036a[0] s; |
| } |
| |
| /**********************************/ |
| |
| struct S61 |
| { |
| this(long length) |
| { |
| this.length = length; |
| } |
| |
| long length; |
| } |
| |
| |
| const(S61) copy(const S61 s) |
| { |
| return s; |
| } |
| |
| |
| void test61() |
| { |
| S61 t = S61(42); |
| const S61 u = t; |
| |
| assert(t == u); |
| assert(copy(t) == u); |
| assert(t == copy(u)); |
| } |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=7506 |
| |
| void test7506() |
| { |
| static struct S |
| { |
| static uint ci = 0; |
| static uint di = 0; |
| uint i; |
| |
| this(int x) { i = ci++; /*writeln("new: ", i);*/ } |
| this(this) { i = ci++; /*writeln("copy ", i);*/ } |
| ~this() { ++di; /*writeln("del: ", i);*/ } |
| |
| S save3() |
| { |
| return this; |
| } |
| } |
| |
| { |
| auto s = S(1), t = S(1); |
| assert(S.ci == 2); |
| t = s.save3(); |
| assert(S.ci == 3); // line 23 |
| } |
| assert(S.di == 3); |
| } |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=7516 |
| |
| struct S7516 |
| { |
| int val; |
| |
| this(int n) { val = n; } |
| this(this) { val *= 3; } |
| } |
| |
| // CondExp on return statement |
| void test7516a() |
| { |
| alias S = S7516; |
| S s1 = S(1); |
| S s2 = S(2); |
| |
| S foo(bool f) { return f ? s1 : s2; } |
| S hoo(bool f) { return f ? S(1) : S(2); } |
| S bar(bool f) { return f ? s1 : S(2); } |
| S baz(bool f) { return f ? S(1) : s2; } |
| |
| auto r1 = foo(true); assert(r1.val == 3); |
| auto r2 = foo(false); assert(r2.val == 6); |
| auto r3 = hoo(true); assert(r3.val == 1); |
| auto r4 = hoo(false); assert(r4.val == 2); |
| auto r5 = bar(true); assert(r5.val == 3); |
| auto r6 = bar(false); assert(r6.val == 2); |
| auto r7 = baz(true); assert(r7.val == 1); |
| auto r8 = baz(false); assert(r8.val == 6); |
| } |
| |
| // CondExp on function argument |
| void test7516b() |
| { |
| alias S = S7516; |
| S s1 = S(1); |
| S s2 = S(2); |
| S func(S s) { return s; } |
| |
| S foo(bool f) { return func(f ? s1 : s2 ); } |
| S hoo(bool f) { return func(f ? S(1) : S(2)); } |
| S bar(bool f) { return func(f ? s1 : S(2)); } |
| S baz(bool f) { return func(f ? S(1) : s2 ); } |
| |
| auto r1 = foo(true); assert(r1.val == 3 * 3); |
| auto r2 = foo(false); assert(r2.val == 6 * 3); |
| auto r3 = hoo(true); assert(r3.val == 1 * 3); |
| auto r4 = hoo(false); assert(r4.val == 2 * 3); |
| auto r5 = bar(true); assert(r5.val == 3 * 3); |
| auto r6 = bar(false); assert(r6.val == 2 * 3); |
| auto r7 = baz(true); assert(r7.val == 1 * 3); |
| auto r8 = baz(false); assert(r8.val == 6 * 3); |
| } |
| |
| // CondExp on array literal |
| void test7516c() |
| { |
| alias S = S7516; |
| S s1 = S(1); |
| S s2 = S(2); |
| |
| S[] foo(bool f) { return [f ? s1 : s2 ]; } |
| S[] hoo(bool f) { return [f ? S(1) : S(2)]; } |
| S[] bar(bool f) { return [f ? s1 : S(2)]; } |
| S[] baz(bool f) { return [f ? S(1) : s2 ]; } |
| |
| auto r1 = foo(true); assert(r1[0].val == 3); |
| auto r2 = foo(false); assert(r2[0].val == 6); |
| auto r3 = hoo(true); assert(r3[0].val == 1); |
| auto r4 = hoo(false); assert(r4[0].val == 2); |
| auto r5 = bar(true); assert(r5[0].val == 3); |
| auto r6 = bar(false); assert(r6[0].val == 2); |
| auto r7 = baz(true); assert(r7[0].val == 1); |
| auto r8 = baz(false); assert(r8[0].val == 6); |
| } |
| |
| // CondExp on rhs of cat assign |
| void test7516d() |
| { |
| alias S = S7516; |
| S s1 = S(1); |
| S s2 = S(2); |
| |
| S[] foo(bool f) { S[] a; a ~= f ? s1 : s2 ; return a; } |
| S[] hoo(bool f) { S[] a; a ~= f ? S(1) : S(2); return a; } |
| S[] bar(bool f) { S[] a; a ~= f ? s1 : S(2); return a; } |
| S[] baz(bool f) { S[] a; a ~= f ? S(1) : s2 ; return a; } |
| |
| auto r1 = foo(true); assert(r1[0].val == 3); |
| auto r2 = foo(false); assert(r2[0].val == 6); |
| auto r3 = hoo(true); assert(r3[0].val == 1); |
| auto r4 = hoo(false); assert(r4[0].val == 2); |
| auto r5 = bar(true); assert(r5[0].val == 3); |
| auto r6 = bar(false); assert(r6[0].val == 2); |
| auto r7 = baz(true); assert(r7[0].val == 1); |
| auto r8 = baz(false); assert(r8[0].val == 6); |
| } |
| |
| // CondExp on struct literal element |
| void test7516e() |
| { |
| alias S = S7516; |
| S s1 = S(1); |
| S s2 = S(2); |
| struct X { S s; } |
| |
| X foo(bool f) { return X(f ? s1 : s2 ); } |
| X hoo(bool f) { return X(f ? S(1) : S(2)); } |
| X bar(bool f) { return X(f ? s1 : S(2)); } |
| X baz(bool f) { return X(f ? S(1) : s2 ); } |
| |
| auto r1 = foo(true); assert(r1.s.val == 3); |
| auto r2 = foo(false); assert(r2.s.val == 6); |
| auto r3 = hoo(true); assert(r3.s.val == 1); |
| auto r4 = hoo(false); assert(r4.s.val == 2); |
| auto r5 = bar(true); assert(r5.s.val == 3); |
| auto r6 = bar(false); assert(r6.s.val == 2); |
| auto r7 = baz(true); assert(r7.s.val == 1); |
| auto r8 = baz(false); assert(r8.s.val == 6); |
| } |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=7530 |
| |
| void test7530() |
| { |
| static struct S |
| { |
| int val; |
| |
| this(int n) { val = n; } |
| this(this) { val *= 3; } |
| } |
| |
| S[] sa = new S[](1); |
| sa[0].val = 1; |
| S foo() |
| { |
| return sa[0]; |
| } |
| auto s = foo(); |
| assert(s.val == 3); |
| } |
| |
| /**********************************/ |
| |
| struct S62 |
| { |
| this(int length) |
| { |
| _length = length; |
| } |
| |
| int opBinary(string op)(in S62 rhs) const |
| if(op == "-") |
| { |
| return this.length - rhs.length; |
| } |
| |
| @property int length() const |
| { |
| return _length; |
| } |
| |
| invariant() |
| { |
| assert(_length == 1); |
| } |
| |
| int _length = 1; |
| } |
| |
| |
| void test62() |
| { |
| immutable result = S62.init - S62.init; |
| } |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=7579 |
| |
| void test7579a() |
| { |
| static struct S |
| { |
| // postblit can also have no body because isn't called |
| @disable this(this) { assert(0); } |
| } |
| |
| @property S fs() { return S(); } |
| @property S[3] fsa() { return [S(), S(), S()]; } |
| |
| S s0; |
| S s1 = S(); |
| static assert(!__traits(compiles, { S s2 = s1; })); // OK |
| S s2 = fs; |
| static assert(!__traits(compiles, { s2 = s1; })); // OK |
| |
| // static array |
| S[3] sa0; |
| S[3] sa1 = [S(), S(), S()]; |
| static assert(!__traits(compiles, { S[3] sa2 = sa1; })); // fixed |
| S[3] sa2 = fsa; |
| static assert(!__traits(compiles, { sa2 = sa1; })); // fixed |
| sa2 = [S(), S(), S()]; |
| sa2 = fsa; |
| |
| S[] da1 = new S[3]; |
| S[] da2 = new S[3]; |
| static assert(!__traits(compiles, { da2[] = da1[]; })); // fixed |
| |
| // concatenation and appending |
| static assert(!__traits(compiles, { da1 ~= s1; })); // fixed |
| static assert(!__traits(compiles, { da1 ~= S(); })); |
| static assert(!__traits(compiles, { da1 ~= fsa; })); |
| static assert(!__traits(compiles, { da1 ~= fsa[]; })); |
| static assert(!__traits(compiles, { da1 = da1 ~ s1; })); // fixed |
| static assert(!__traits(compiles, { da1 = s1 ~ da1; })); // fixed |
| static assert(!__traits(compiles, { da1 = da1 ~ S(); })); |
| static assert(!__traits(compiles, { da1 = da1 ~ fsa; })); |
| static assert(!__traits(compiles, { da1 = da1 ~ da; })); |
| } |
| |
| void test7579b() |
| { |
| static struct S |
| { |
| // postblit asserts in runtime |
| this(this) { assert(0); } |
| } |
| |
| @property S fs() { return S(); } |
| @property S[3] fsa() { return [S(), S(), S()]; } |
| |
| S s0; |
| S s1 = S(); |
| S s2 = fs; |
| |
| // static array |
| S[3] sa0; |
| S[3] sa1 = [S(), S(), S()]; |
| S[3] sa2 = fsa; |
| sa2 = [S(), S(), S()]; |
| sa2 = fsa; |
| |
| S[] da1 = new S[3]; |
| S[] da2 = new S[3]; |
| |
| // concatenation and appending always run postblits |
| } |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=8335 |
| |
| struct S8335 |
| { |
| static int postblit; |
| |
| int i; |
| this(this) { ++postblit; } |
| } |
| |
| void f8335(ref S8335[3] arr) |
| { |
| arr[0].i = 7; |
| } |
| |
| void g8335(lazy S8335[3] arr) |
| { |
| assert(S8335.postblit == 0); |
| auto x = arr; |
| assert(S8335.postblit == 3); |
| } |
| |
| void h8335(lazy S8335 s) |
| { |
| assert(S8335.postblit == 0); |
| auto x = s; |
| assert(S8335.postblit == 1); |
| } |
| |
| void test8335() |
| { |
| S8335[3] arr; |
| f8335(arr); |
| assert(S8335.postblit == 0); |
| assert(arr[0].i == 7); |
| |
| g8335(arr); |
| assert(S8335.postblit == 3); |
| |
| S8335.postblit = 0; |
| S8335 s; |
| h8335(s); |
| assert(S8335.postblit == 1); |
| } |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=8356 |
| |
| void test8356() |
| { |
| static struct S |
| { |
| @disable this(this) { assert(0); } |
| } |
| |
| S s; |
| S[3] sa; |
| |
| static assert(!__traits(compiles, { |
| S fs() { return s; } |
| })); |
| |
| static assert(!__traits(compiles, { |
| S[3] fsa() { return sa; } |
| })); |
| } |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=8475 |
| |
| T func8475(T)(T x) @safe pure |
| { |
| return T(); |
| } |
| |
| template X8475(bool something) |
| { |
| struct XY |
| { |
| this(this) @safe pure {} |
| void func(XY x) @safe pure |
| { |
| XY y = x; //Error: see below |
| func8475(x); |
| func8475(y); |
| } |
| } |
| } |
| |
| alias X8475!(true).XY Xtrue; |
| |
| /**********************************/ |
| |
| struct Foo9320 { |
| real x; |
| |
| this(real x) { |
| this.x = x; |
| } |
| |
| Foo9320 opBinary(string op)(Foo9320 other) { |
| return Foo9320(mixin("x" ~ op ~ "other.x")); |
| } |
| } |
| |
| Foo9320 test9320(Foo9320 a, Foo9320 b, Foo9320 c) { |
| return (a + b) / (a * b) - c; |
| } |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=9386 |
| |
| struct Test9386 |
| { |
| string name; |
| static char[25] op; |
| static size_t i; |
| |
| static @property string sop() { return cast(string)op[0..i]; } |
| |
| this(string name) |
| { |
| this.name = name; |
| printf("Created %.*s...\n", cast(int)name.length, name.ptr); |
| assert(i + 1 < op.length); |
| op[i++] = 'a'; |
| } |
| |
| this(this) |
| { |
| printf("Copied %.*s...\n", cast(int)name.length, name.ptr); |
| assert(i + 1 < op.length); |
| op[i++] = 'b'; |
| } |
| |
| ~this() |
| { |
| printf("Deleted %.*s\n", cast(int)name.length, name.ptr); |
| assert(i + 1 < op.length); |
| op[i++] = 'c'; |
| } |
| |
| const int opCmp(ref const Test9386 t) |
| { |
| return op[0] - t.op[0]; |
| } |
| } |
| |
| void test9386() |
| { |
| { |
| Test9386.op[] = 0; |
| Test9386.i = 0; |
| |
| Test9386[] tests = |
| [ Test9386("one"), |
| Test9386("two"), |
| Test9386("three"), |
| Test9386("four") ]; |
| |
| assert(Test9386.sop == "aaaa"); |
| Test9386.op[] = 0; |
| Test9386.i = 0; |
| |
| printf("----\n"); |
| foreach (Test9386 test; tests) |
| { |
| printf("\tForeach %.*s\n", cast(int)test.name.length, test.name.ptr); |
| Test9386.op[Test9386.i++] = 'x'; |
| } |
| |
| assert(Test9386.sop == "bxcbxcbxcbxc"); |
| Test9386.op[] = 0; |
| Test9386.i = 0; |
| |
| printf("----\n"); |
| foreach (ref Test9386 test; tests) |
| { |
| printf("\tForeach %.*s\n", cast(int)test.name.length, test.name.ptr); |
| Test9386.op[Test9386.i++] = 'x'; |
| } |
| assert(Test9386.sop == "xxxx"); |
| } |
| printf("====\n"); |
| { |
| Test9386.op[] = 0; |
| Test9386.i = 0; |
| |
| Test9386[Test9386] tests = |
| [ Test9386("1") : Test9386("one"), |
| Test9386("2") : Test9386("two"), |
| Test9386("3") : Test9386("three"), |
| Test9386("4") : Test9386("four") ]; |
| |
| Test9386.op[] = 0; |
| Test9386.i = 0; |
| |
| printf("----\n"); |
| foreach (Test9386 k, Test9386 v; tests) |
| { |
| printf("\tForeach %.*s : %.*s\n", cast(int)k.name.length, k.name.ptr, |
| cast(int)v.name.length, v.name.ptr); |
| Test9386.op[Test9386.i++] = 'x'; |
| } |
| |
| assert(Test9386.sop == "bbxccbbxccbbxccbbxcc"); |
| Test9386.op[] = 0; |
| Test9386.i = 0; |
| |
| printf("----\n"); |
| foreach (Test9386 k, ref Test9386 v; tests) |
| { |
| printf("\tForeach %.*s : %.*s\n", cast(int)k.name.length, k.name.ptr, |
| cast(int)v.name.length, v.name.ptr); |
| Test9386.op[Test9386.i++] = 'x'; |
| } |
| assert(Test9386.sop == "bxcbxcbxcbxc"); |
| Test9386.op[] = 0; |
| Test9386.i = 0; |
| } |
| } |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=9441 |
| |
| auto x9441 = X9441(0.123); |
| |
| struct X9441 |
| { |
| int a; |
| this(double x) { a = cast(int)(x * 100); } |
| } |
| |
| void test9441() |
| { |
| assert(x9441.a == 12); |
| } |
| |
| /**********************************/ |
| |
| struct Payload |
| { |
| size_t _capacity; //Comment me |
| int[] _pay; //Comment me |
| |
| size_t insertBack(Data d) |
| { |
| immutable newLen = _pay.length + 3; |
| _pay.length = newLen; |
| _pay = _pay[0 .. newLen]; //Comment me |
| return 3; |
| } |
| } |
| |
| struct Impl |
| { |
| Payload _payload; |
| size_t _count; |
| } |
| |
| struct Data |
| { |
| Impl* _store; |
| |
| this(int i) |
| { |
| _store = new Impl; |
| _store._payload = Payload.init; |
| } |
| |
| ~this() |
| { |
| printf("%zd\n", _store._count); |
| --_store._count; |
| } |
| } |
| |
| |
| void test9720() |
| { |
| auto a = Data(1); |
| auto b = Data(1); |
| a._store._payload.insertBack(b); //Fails |
| } |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=9899 |
| |
| struct S9899 |
| { |
| @safe pure nothrow ~this() {} |
| } |
| |
| struct MemberS9899 |
| { |
| S9899 s; |
| } |
| |
| void test9899() @safe pure nothrow |
| { |
| MemberS9899 s; // 11 |
| } |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=9907 |
| |
| void test9907() |
| { |
| static struct SX(bool hasCtor, bool hasDtor) |
| { |
| int i; |
| static size_t assign; |
| static size_t dtor; |
| |
| static if (hasCtor) |
| { |
| this(int i) { this.i = i; } |
| } |
| |
| void opAssign(SX rhs) |
| { |
| printf("%08zX(%d) from Rvalue %08zX(%d)\n", cast(size_t)&this.i, this.i, cast(size_t)&rhs.i, rhs.i); |
| ++assign; |
| } |
| |
| void opAssign(ref SX rhs) |
| { |
| printf("%08zX(%d) from Lvalue %08zX(%d)\n", cast(size_t)&this.i, this.i, cast(size_t)&rhs.i, rhs.i); |
| assert(0); |
| } |
| |
| static if (hasDtor) |
| { |
| ~this() |
| { |
| printf("destroying %08zX(%d)\n", cast(size_t)&this.i, this.i); |
| ++dtor; |
| } |
| } |
| } |
| |
| S test(S)(int i) |
| { |
| return S(i); |
| } |
| |
| foreach (hasCtor; TypeTuple!(false, true)) |
| foreach (hasDtor; TypeTuple!(false, true)) |
| { |
| alias S = SX!(hasCtor, hasDtor); |
| alias test!S foo; |
| |
| printf("----\n"); |
| auto s = S(1); |
| |
| // Assignment from two kinds of rvalues |
| assert(S.assign == 0); |
| s = foo(2); |
| static if (hasDtor) assert(S.dtor == 1); |
| assert(S.assign == 1); |
| s = S(3); |
| assert(S.assign == 2); |
| static if (hasDtor) assert(S.dtor == 2); |
| } |
| printf("----\n"); |
| } |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=9985 |
| |
| struct S9985 |
| { |
| ubyte* b; |
| ubyte[128] buf; |
| this(this) { assert(0); } |
| |
| static void* ptr; |
| } |
| auto ref makeS9985() @system |
| { |
| S9985 s; |
| s.b = s.buf.ptr; |
| S9985.ptr = &s; |
| return s; |
| } |
| void test9985() |
| { |
| S9985 s = makeS9985(); |
| assert(S9985.ptr == &s); // NRVO |
| |
| static const int n = 1; |
| static auto ref retN() |
| { |
| return n; |
| } |
| auto p = &(retN()); // OK |
| assert(p == &n); |
| alias pure nothrow @nogc @safe ref const(int) F1(); |
| static assert(is(typeof(retN) == F1)); |
| |
| enum const(int) x = 1; |
| static auto ref retX() |
| { |
| return x; |
| } |
| static assert(!__traits(compiles, { auto q = &(retX()); })); |
| alias pure nothrow @nogc @safe const(int) F2(); |
| static assert(is(typeof(retX) == F2)); |
| } |
| |
| /**********************************/ |
| |
| // https://issues.dlang.org/show_bug.cgi?id=17457 |
| |
| void delegate() dg17457; |
| |
| struct S17457 { |
| ulong[10] data; |
| |
| this(int seconds) { |
| dg17457 = &mfunc; |
| } |
| @disable this(this); |
| void mfunc() {} |
| } |
| |
| auto foo17457() { |
| pragma(inline, false); |
| return S17457(18); |
| } |
| |
| void test17457() |
| { |
| auto x = foo17457(); |
| //printf("%p vs %p\n", &x, dg17457.ptr); |
| assert(&x == dg17457.ptr); |
| } |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=9994 |
| |
| void test9994() |
| { |
| static struct S |
| { |
| static int dtor; |
| ~this() { ++dtor; } |
| } |
| |
| S s; |
| static assert( __traits(compiles, s.opAssign(s))); |
| static assert(!__traits(compiles, s.__postblit())); |
| |
| assert(S.dtor == 0); |
| s = s; |
| assert(S.dtor == 1); |
| } |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=10053 |
| |
| struct S10053A |
| { |
| pure ~this() {} |
| } |
| |
| struct S10053B |
| { |
| S10053A sa; |
| ~this() {} |
| } |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=10055 |
| |
| void test10055a() |
| { |
| static struct SX { pure nothrow @safe ~this() {} } |
| static struct SY { pure nothrow @safe ~this() {} } |
| static struct SZ { @disable ~this() {} } |
| |
| // function to check merge result of the dtor attributes |
| static void check(S)() { S s; } |
| |
| static struct S1 { } |
| static struct S2 { ~this() {} } |
| static struct SA { SX sx; SY sy; } |
| static struct SB { SX sx; SY sy; pure nothrow @safe ~this() {} } |
| static struct SC { SX sx; SY sy; nothrow @safe ~this() {} } |
| static struct SD { SX sx; SY sy; pure @safe ~this() {} } |
| static struct SE { SX sx; SY sy; pure nothrow ~this() {} } |
| static struct SF { SX sx; SY sy; @safe ~this() {} } |
| static struct SG { SX sx; SY sy; nothrow ~this() {} } |
| static struct SH { SX sx; SY sy; pure ~this() {} } |
| static struct SI { SX sx; SY sy; ~this() {} } |
| static assert(is( typeof(&check!S1) == void function() pure nothrow @nogc @safe )); |
| static assert(is( typeof(&check!S2) == void function() )); |
| static assert(is( typeof(&check!SA) == void function() pure nothrow @safe )); |
| static assert(is( typeof(&check!SB) == void function() pure nothrow @safe )); |
| static assert(is( typeof(&check!SC) == void function() nothrow @safe )); |
| static assert(is( typeof(&check!SD) == void function() pure @safe )); |
| static assert(is( typeof(&check!SE) == void function() pure nothrow )); |
| static assert(is( typeof(&check!SF) == void function() @safe )); |
| static assert(is( typeof(&check!SG) == void function() nothrow )); |
| static assert(is( typeof(&check!SH) == void function() pure )); |
| static assert(is( typeof(&check!SI) == void function() )); |
| |
| static struct S1x { SZ sz; } |
| static struct S2x { ~this() {} SZ sz; } |
| static struct SAx { SX sx; SY sy; SZ sz; } |
| static struct SBx { SX sx; SY sy; pure nothrow @safe ~this() {} SZ sz; } |
| static struct SCx { SX sx; SY sy; nothrow @safe ~this() {} SZ sz; } |
| static struct SDx { SX sx; SY sy; pure @safe ~this() {} SZ sz; } |
| static struct SEx { SX sx; SY sy; pure nothrow ~this() {} SZ sz; } |
| static struct SFx { SX sx; SY sy; @safe ~this() {} SZ sz; } |
| static struct SGx { SX sx; SY sy; nothrow ~this() {} SZ sz; } |
| static struct SHx { SX sx; SY sy; pure ~this() {} SZ sz; } |
| static struct SIx { SX sx; SY sy; ~this() {} SZ sz; } |
| foreach (Sx; TypeTuple!(S1x, S2x, SAx, SBx, SCx, SDx, SEx, SFx, SGx, SHx, SIx)) |
| { |
| static assert(!__traits(compiles, &check!Sx)); |
| } |
| } |
| |
| void test10055b() |
| { |
| static struct SX { pure nothrow @safe this(this) {} } |
| static struct SY { pure nothrow @safe this(this) {} } |
| static struct SZ { @disable this(this) {} } |
| |
| // function to check merge result of the postblit attributes |
| static void check(S)() { S s; S s2 = s; } |
| |
| static struct S1 { } |
| static struct S2 { this(this) {} } |
| static struct SA { SX sx; SY sy; } |
| static struct SB { SX sx; SY sy; pure nothrow @safe this(this) {} } |
| static struct SC { SX sx; SY sy; nothrow @safe this(this) {} } |
| static struct SD { SX sx; SY sy; pure @safe this(this) {} } |
| static struct SE { SX sx; SY sy; pure nothrow this(this) {} } |
| static struct SF { SX sx; SY sy; @safe this(this) {} } |
| static struct SG { SX sx; SY sy; nothrow this(this) {} } |
| static struct SH { SX sx; SY sy; pure this(this) {} } |
| static struct SI { SX sx; SY sy; this(this) {} } |
| static assert(is( typeof(&check!S1) == void function() pure nothrow @nogc @safe )); |
| static assert(is( typeof(&check!S2) == void function() )); |
| static assert(is( typeof(&check!SA) == void function() pure nothrow @safe )); |
| static assert(is( typeof(&check!SB) == void function() pure nothrow @safe )); |
| static assert(is( typeof(&check!SC) == void function() nothrow @safe )); |
| static assert(is( typeof(&check!SD) == void function() pure @safe )); |
| static assert(is( typeof(&check!SE) == void function() pure nothrow )); |
| static assert(is( typeof(&check!SF) == void function() @safe )); |
| static assert(is( typeof(&check!SG) == void function() nothrow )); |
| static assert(is( typeof(&check!SH) == void function() pure )); |
| static assert(is( typeof(&check!SI) == void function() )); |
| |
| static struct S1x { SZ sz; } |
| static struct S2x { this(this) {} SZ sz; } |
| static struct SAx { SX sx; SY sy; SZ sz; } |
| static struct SBx { SX sx; SY sy; pure nothrow @safe this(this) {} SZ sz; } |
| static struct SCx { SX sx; SY sy; nothrow @safe this(this) {} SZ sz; } |
| static struct SDx { SX sx; SY sy; pure @safe this(this) {} SZ sz; } |
| static struct SEx { SX sx; SY sy; pure nothrow this(this) {} SZ sz; } |
| static struct SFx { SX sx; SY sy; @safe this(this) {} SZ sz; } |
| static struct SGx { SX sx; SY sy; nothrow this(this) {} SZ sz; } |
| static struct SHx { SX sx; SY sy; pure this(this) {} SZ sz; } |
| static struct SIx { SX sx; SY sy; this(this) {} SZ sz; } |
| foreach (Sx; TypeTuple!(S1x, S2x, SAx, SBx, SCx, SDx, SEx, SFx, SGx, SHx, SIx)) |
| { |
| static assert(!__traits(compiles, &check!Sx)); |
| } |
| } |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=10160 |
| |
| struct S10160 { this(this) {} } |
| |
| struct X10160a { S10160 s; const int x; } |
| struct X10160b { S10160 s; enum int x = 1; } |
| |
| void test10160() |
| { |
| X10160a xa; |
| X10160b xb; |
| } |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=10094 |
| |
| void test10094() |
| { |
| static void* p; |
| const string[4] i2s = () |
| { |
| string[4] tmp; |
| p = &tmp[0]; |
| for (int i = 0; i < 4; ++i) |
| { |
| char[1] buf = [cast(char)('0' + i)]; |
| string str = buf.idup; |
| tmp[i] = str; |
| } |
| return tmp; // NRVO should work |
| }(); |
| assert(p == cast(void*)&i2s[0]); |
| assert(i2s == ["0", "1", "2", "3"]); |
| } |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=10079 |
| |
| // dtor || postblit |
| struct S10079a |
| { |
| this(this) pure nothrow @safe {} |
| } |
| struct S10079b |
| { |
| ~this() pure nothrow @safe {} |
| } |
| struct S10079c |
| { |
| this(this) pure nothrow @safe {} |
| ~this() pure nothrow @safe {} |
| } |
| struct S10079d |
| { |
| this(this) {} |
| } |
| struct S10079e |
| { |
| this(this) {} |
| ~this() pure nothrow @safe {} |
| } |
| |
| // memberwise |
| struct S10079f |
| { |
| S10079a a; |
| S10079b b; |
| S10079c c; |
| S10079d d; |
| S10079e e; |
| } |
| |
| void check10079(S)(ref S s) pure nothrow @safe { s = S(); } |
| |
| // Assignment is pure, nothrow, and @safe in all cases. |
| static assert(__traits(compiles, &check10079!S10079a)); |
| static assert(__traits(compiles, &check10079!S10079b)); |
| static assert(__traits(compiles, &check10079!S10079c)); |
| static assert(__traits(compiles, &check10079!S10079d)); |
| static assert(__traits(compiles, &check10079!S10079e)); |
| static assert(__traits(compiles, &check10079!S10079f)); |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=10244 |
| |
| void test10244() |
| { |
| static struct Foo |
| { |
| string _str; |
| long _num; |
| |
| template DeclareConstructor(string fieldName) |
| { |
| enum code = |
| `this(typeof(_` ~ fieldName ~ `) value)` ~ |
| `{ this._` ~ fieldName ~ ` = value; }`; |
| mixin(code); |
| } |
| |
| mixin DeclareConstructor!"str"; |
| mixin DeclareConstructor!"num"; |
| } |
| |
| Foo value1 = Foo("D"); |
| Foo value2 = Foo(128); |
| assert(value1._str == "D"); |
| assert(value2._num == 128); |
| } |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=10694 |
| |
| struct Foo10694 { ~this() { } } |
| |
| void test10694() pure |
| { |
| static Foo10694 i1; |
| __gshared Foo10694 i2; |
| void foo() pure |
| { |
| static Foo10694 j1; |
| __gshared Foo10694 j2; |
| } |
| } |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=10787 |
| |
| int global10787; |
| |
| static ~this() nothrow pure @safe |
| { |
| int* p; |
| static assert(!__traits(compiles, ++p)); |
| static assert(!__traits(compiles, ++global10787)); |
| } |
| |
| shared static ~this() nothrow pure @safe |
| { |
| int* p; |
| static assert(!__traits(compiles, ++p)); |
| static assert(!__traits(compiles, ++global10787)); |
| } |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=10789 |
| |
| struct S10789 |
| { |
| static int count; |
| int value; |
| |
| this(int) { value = ++count; } |
| ~this() { --count; } |
| this(this) { value = ++count; assert(value == 3); } |
| } |
| |
| S10789 fun10789a(bool isCondExp)(bool cond) |
| { |
| S10789 s1 = S10789(42), s2 = S10789(24); |
| assert(S10789.count == 2); |
| static if (isCondExp) |
| { |
| return cond ? s1 : s2; |
| } |
| else |
| { |
| if (cond) |
| return s1; |
| else |
| return s2; |
| } |
| } |
| |
| auto fun10789b(bool isCondExp)(bool cond) |
| { |
| S10789 s1 = S10789(42), s2 = S10789(24); |
| assert(S10789.count == 2); |
| static if (isCondExp) |
| { |
| return cond ? s1 : s2; |
| } |
| else |
| { |
| if (cond) |
| return s1; |
| else |
| return s2; |
| } |
| } |
| |
| void test10789() |
| { |
| foreach (fun; TypeTuple!(fun10789a, fun10789b)) |
| foreach (isCondExp; TypeTuple!(false, true)) |
| { |
| { |
| S10789 s = fun!isCondExp(true); |
| assert(S10789.count == 1); |
| assert(s.value == 3); |
| } |
| assert(S10789.count == 0); |
| { |
| S10789 s = fun!isCondExp(false); |
| assert(S10789.count == 1); |
| assert(s.value == 3); |
| } |
| assert(S10789.count == 0); |
| } |
| } |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=10972 |
| |
| int test10972() |
| { |
| string result; |
| |
| struct A |
| { |
| this(this) { result ~= "pA"; version(none) printf("copied A\n"); } |
| ~this() { result ~= "dA"; version(none) printf("destroy A\n"); } |
| } |
| struct B |
| { |
| this(this) |
| { |
| result ~= "(pB)"; version(none) printf("B says what?\n"); |
| throw new Exception("BOOM!"); |
| } |
| ~this() { result ~= "dB"; version(none) printf("destroy B\n"); } |
| } |
| struct S |
| { |
| A a; |
| B b; |
| } |
| |
| result = "{"; |
| { |
| S s1; |
| result ~= "["; |
| try |
| { |
| S s3 = s1; |
| assert(0); |
| } |
| catch (Exception e) |
| {} |
| result ~= "]"; |
| } |
| result ~= "}"; |
| assert(result == "{[pA(pB)dA]dBdA}", result); |
| |
| result = "{"; |
| { |
| S s1; |
| S s2; |
| result ~= "["; |
| try |
| { |
| s2 = s1; |
| assert(0); |
| } |
| catch (Exception e) |
| {} |
| result ~= "]"; |
| } |
| result ~= "}"; |
| assert(result == "{[pA(pB)dA]dBdAdBdA}", result); |
| |
| return 1; |
| } |
| static assert(test10972()); // CTFE |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=11134 |
| |
| void test11134() |
| { |
| void test(S)() |
| { |
| S s; |
| S[2] sa; |
| S[2][] dsa = [[S(), S()]]; |
| dsa.reserve(dsa.length + 2); // avoid postblit calls by GC |
| |
| S.count = 0; |
| dsa ~= sa; |
| assert(S.count == 2); |
| |
| S.count = 0; |
| dsa ~= [s, s]; |
| assert(S.count == 2); |
| } |
| |
| static struct SS |
| { |
| static int count; |
| this(this) { ++count; } |
| } |
| test!SS(); |
| |
| struct NS |
| { |
| static int count; |
| this(this) { ++count; } |
| } |
| test!NS(); |
| } |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=11197 |
| |
| struct S11197a |
| { |
| this(bool) {} |
| this(this) {} |
| } |
| |
| struct S11197b |
| { |
| //this(bool) {} |
| this(this) {} |
| } |
| |
| void test11197() |
| { |
| S11197a[][string] aa1; |
| aa1["test"] ~= S11197a.init; |
| |
| S11197b[][string] aa2; |
| aa2["test"] ~= S11197b.init; |
| } |
| |
| /**********************************/ |
| |
| struct S7474 { |
| float x; |
| ~this() {} |
| } |
| |
| void fun7474(T...)() { T x; } |
| void test7474() { fun7474!S7474(); } |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=11286 |
| |
| struct A11286 |
| { |
| ~this() {} |
| } |
| |
| A11286 getA11286() pure nothrow |
| { |
| return A11286(); |
| } |
| |
| void test11286() |
| { |
| A11286 a = getA11286(); |
| } |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=11505 |
| |
| struct Foo11505 |
| { |
| Bar11505 b; |
| } |
| |
| struct Bar11505 |
| { |
| ~this() @safe { } |
| void* p; |
| } |
| |
| void test11505() |
| { |
| Foo11505 f; |
| f = Foo11505(); |
| } |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=12045 |
| |
| bool test12045() |
| { |
| string dtor; |
| void* ptr; |
| |
| struct S12045 |
| { |
| string val; |
| |
| this(this) { assert(0); } |
| ~this() { dtor ~= val; } |
| } |
| |
| auto makeS12045(bool thrown) |
| { |
| auto s1 = S12045("1"); |
| auto s2 = S12045("2"); |
| ptr = &s1; |
| |
| if (thrown) |
| throw new Exception(""); |
| |
| return s1; // NRVO |
| } |
| |
| dtor = null, ptr = null; |
| try |
| { |
| S12045 s = makeS12045(true); |
| assert(0); |
| } |
| catch (Exception e) |
| { |
| assert(dtor == "21", dtor); |
| } |
| |
| dtor = null, ptr = null; |
| { |
| S12045 s = makeS12045(false); |
| assert(dtor == "2"); |
| if (!__ctfe) assert(ptr is &s); // NRVO |
| } |
| assert(dtor == "21"); |
| |
| return true; |
| } |
| static assert(test12045()); |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=12591 |
| |
| struct S12591(T) |
| { |
| this(this) |
| {} |
| } |
| |
| struct Tuple12591(Types...) |
| { |
| Types expand; |
| this(Types values) |
| { |
| expand[] = values[]; |
| } |
| } |
| |
| void test12591() |
| { |
| alias T1 = Tuple12591!(S12591!int); |
| } |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=12660 |
| |
| struct X12660 |
| { |
| this(this) @nogc {} |
| ~this() @nogc {} |
| void opAssign(X12660) @nogc {} |
| @nogc invariant() {} |
| } |
| struct Y12660 |
| { |
| X12660 x; |
| |
| this(this) @nogc {} |
| ~this() @nogc {} |
| @nogc invariant() {} |
| } |
| struct Z12660 |
| { |
| Y12660 y; |
| } |
| |
| class C12660 |
| { |
| this() @nogc {} |
| @nogc invariant() {} |
| } |
| |
| void test12660() @nogc |
| { |
| X12660 x; |
| x = x; |
| |
| Y12660 y = { x }; |
| y = y; |
| |
| Z12660 z = { y }; |
| z = z; |
| } |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=12686 |
| |
| struct Foo12686 |
| { |
| static int count; |
| |
| invariant() { ++count; } |
| |
| @disable this(this); |
| |
| Foo12686 bar() |
| { |
| Foo12686 f; |
| return f; |
| } |
| } |
| |
| void test12686() |
| { |
| Foo12686 f; |
| Foo12686 f2 = f.bar(); |
| version (unittest) |
| { } |
| else |
| assert(Foo12686.count == 2); |
| } |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=13089 |
| |
| struct S13089 |
| { |
| @disable this(this); // non nothrow |
| int val; |
| } |
| |
| void* p13089; |
| |
| S13089[1000] foo13089() nothrow |
| { |
| typeof(return) data; |
| p13089 = &data; |
| return data; |
| } |
| |
| void test13089() nothrow |
| { |
| immutable data = foo13089(); |
| assert(p13089 == &data); |
| } |
| |
| /**********************************/ |
| |
| struct NoDtortest11763 {} |
| |
| struct HasDtortest11763 |
| { |
| NoDtortest11763 func() |
| { |
| return NoDtortest11763(); |
| } |
| ~this() {} |
| } |
| |
| void test11763() |
| { |
| HasDtortest11763().func(); |
| } |
| |
| /**********************************/ |
| |
| struct Buf { } |
| |
| struct Variant |
| { |
| ~this() { } |
| |
| Buf get() { Buf b; return b; } |
| } |
| |
| Variant value() { Variant v; return v; } |
| |
| void test13303() |
| { |
| value.get(); |
| } |
| |
| /**********************************/ |
| |
| struct S13673 |
| { |
| string _name; |
| ~this() {} |
| } |
| |
| string name13673; |
| |
| void test13673() |
| { |
| S13673(name13673); |
| S13673(name13673); |
| } |
| |
| /**********************************/ |
| |
| void test13586() |
| { |
| static struct S { |
| __gshared int count; |
| ~this() { ++count; printf("~S\n"); } |
| } |
| |
| static struct T { |
| __gshared int count; |
| ~this() { ++count; printf("~T\n"); } |
| } |
| |
| static int foo(bool flag) |
| { |
| if (flag) |
| throw new Exception("hello"); |
| return 1; |
| } |
| |
| static void func(S s, int f, T t) |
| { |
| printf("func()\n"); |
| } |
| |
| static class C |
| { |
| this(S s, int f, T t) |
| { |
| printf("C()\n"); |
| } |
| } |
| |
| { |
| bool threw = false; |
| try |
| { |
| func(S(), foo(true), T()); |
| printf("not reach\n"); |
| } |
| catch (Exception e) |
| { |
| threw = true; |
| } |
| printf("threw %d S %d T %d\n", threw, S.count, T.count); |
| assert(threw && S.count == 1 && T.count == 0); |
| S.count = 0; |
| T.count = 0; |
| } |
| { |
| bool threw = false; |
| try |
| { |
| func(S(), foo(false), T()); |
| printf("reached\n"); |
| } |
| catch (Exception e) |
| { |
| threw = true; |
| } |
| printf("threw %d S %d T %d\n", threw, S.count, T.count); |
| assert(!threw && S.count == 1 && T.count == 1); |
| S.count = 0; |
| T.count = 0; |
| } |
| { |
| bool threw = false; |
| try |
| { |
| new C(S(), foo(true), T()); |
| printf("not reach\n"); |
| } |
| catch (Exception e) |
| { |
| threw = true; |
| } |
| printf("threw %d S %d T %d\n", threw, S.count, T.count); |
| assert(threw && S.count == 1 && T.count == 0); |
| S.count = 0; |
| T.count = 0; |
| } |
| } |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=14443 |
| |
| T enforce14443(E : Throwable = Exception, T)(T value) |
| { |
| if (!value) |
| throw new E("Enforcement failed"); |
| return value; |
| } |
| |
| struct RefCounted14443(T) |
| if (!is(T == class) && !(is(T == interface))) |
| { |
| struct RefCountedStore |
| { |
| private struct Impl |
| { |
| T _payload; |
| size_t _count; |
| } |
| |
| private Impl* _store; |
| |
| private void initialize(A...)(auto ref A args) |
| { |
| import core.stdc.stdlib : malloc; |
| |
| // enforce is necessary |
| _store = cast(Impl*) enforce14443(malloc(Impl.sizeof)); |
| |
| // emulate 'emplace' |
| static if (args.length > 0) |
| _store._payload.tupleof = args; |
| else |
| _store._payload = T.init; |
| |
| _store._count = 1; |
| } |
| |
| @property bool isInitialized() const nothrow @safe |
| { |
| return _store !is null; |
| } |
| |
| void ensureInitialized() |
| { |
| if (!isInitialized) initialize(); |
| } |
| |
| } |
| RefCountedStore _refCounted; |
| |
| this(A...)(auto ref A args) if (A.length > 0) |
| { |
| _refCounted.initialize(args); |
| } |
| |
| this(this) |
| { |
| if (!_refCounted.isInitialized) |
| return; |
| ++_refCounted._store._count; |
| //printf("RefCounted count = %d (inc)\n", _refCounted._store._count); |
| } |
| |
| ~this() |
| { |
| if (!_refCounted.isInitialized) |
| return; |
| assert(_refCounted._store._count > 0); |
| if (--_refCounted._store._count) |
| { |
| //printf("RefCounted count = %u\n", _refCounted._store._count); |
| return; |
| } |
| |
| import core.stdc.stdlib : free; |
| free(_refCounted._store); |
| _refCounted._store = null; |
| } |
| |
| void opAssign(typeof(this) rhs) { assert(0); } |
| void opAssign(T rhs) { assert(0); } |
| |
| @property ref T refCountedPayload() |
| { |
| _refCounted.ensureInitialized(); |
| return _refCounted._store._payload; |
| } |
| |
| alias refCountedPayload this; |
| } |
| |
| struct Path14443 |
| { |
| struct Payload |
| { |
| int p; |
| } |
| RefCounted14443!Payload data; |
| } |
| |
| struct PathRange14443 |
| { |
| Path14443 path; |
| size_t i; |
| |
| @property PathElement14443 front() |
| { |
| return PathElement14443(this, path.data.p); |
| } |
| } |
| |
| struct PathElement14443 |
| { |
| PathRange14443 range; |
| |
| this(PathRange14443 range, int) |
| { |
| this.range = range; |
| } |
| } |
| |
| void test14443() |
| { |
| auto path = Path14443(RefCounted14443!(Path14443.Payload)(12)); |
| assert(path.data.p == 12); |
| |
| @property refCount() { return path.data._refCounted._store._count; } |
| assert(refCount == 1); |
| |
| { |
| auto _r = PathRange14443(path); |
| assert(refCount == 2); |
| // foreach |
| { |
| auto element = _r.front; |
| assert(refCount == 3); // fail with 2.067 |
| } |
| assert(refCount == 2); |
| } |
| assert(refCount == 1); |
| } |
| |
| /**********************************/ |
| // postblit/dtor call on static array assignment |
| // https://issues.dlang.org/show_bug.cgi?id=13661 |
| // https://issues.dlang.org/show_bug.cgi?id=14022 |
| // https://issues.dlang.org/show_bug.cgi?id=14023 |
| |
| bool test13661() |
| { |
| string op; |
| |
| struct S |
| { |
| char x = 'x'; |
| this(this) { op ~= x-0x20; } // upper case |
| ~this() { op ~= x; } // lower case |
| |
| ref auto opAssign(T)(T arg) |
| { |
| assert(0); |
| return this; |
| } |
| } |
| |
| { |
| S[2] a; |
| |
| a[0].x = 'a'; |
| a[1].x = 'b'; |
| a = a.init; |
| assert(op == "ab"); |
| assert(a[0].x == 'x' && a[1].x == 'x'); |
| |
| a[0].x = 'c'; |
| a[1].x = 'd'; |
| a = [S(), S()]; // equivalent a = a.init |
| assert(op == "abcd"); |
| assert(a[0].x == 'x' && a[1].x == 'x'); |
| } |
| assert(op == "abcdxx"); |
| |
| return true; |
| } |
| bool test13661a() |
| { |
| string op; |
| |
| struct S |
| { |
| char x = 'x'; |
| this(this) { op ~= x-0x20; } // upper case |
| ~this() { op ~= x; } // lower case |
| } |
| |
| { |
| S[3] sa = [S('a'), S('b'), S('c')]; |
| S[2] sb = sa[1..3]; |
| assert(sa == [S('a'), S('b'), S('c')]); |
| assert(sb == [S('b'), S('c')]); |
| sb[0].x = 'x'; |
| sb[1].x = 'y'; |
| assert(sa != [S('a'), S('x'), S('y')]); // OK <- incorrectly fails |
| assert(sa == [S('a'), S('b'), S('c')]); // OK <- incorrectly fails |
| assert(sb == [S('x'), S('y')]); |
| } |
| return true; |
| } |
| static assert(test13661()); // CTFE |
| static assert(test13661a()); |
| |
| bool test14022() |
| { |
| string op; |
| |
| struct S |
| { |
| char x = 'x'; |
| this(this) { op ~= x-0x20; } // upper case |
| ~this() { op ~= x; } // lower case |
| } |
| |
| S[2] makeSA() { return [S('p'), S('q')]; } |
| |
| struct T |
| { |
| S[2] sb; |
| |
| this(ref S[2] sa) |
| { |
| assert(op == ""); |
| this.sb = sa; // TOKconstruct |
| assert(op == "BC", op); |
| assert(sb == [S('b'), S('c')]); |
| } |
| void test(ref S[2] sa) |
| { |
| this.sb = sa; // dotvar: resolveSlice(newva) |
| assert(op == "BxCy"); |
| } |
| } |
| |
| op = null; |
| { |
| S[2] sa = [S('a'), S('b')]; |
| T t; t.sb[0].x = 'x'; |
| t.sb[1].x = 'y'; |
| assert(op == ""); |
| t.sb = sa; |
| assert(op == "AxBy"); |
| t.sb = makeSA(); |
| assert(op == "AxByab"); |
| } |
| assert(op == "AxByabqpba"); |
| |
| op = null; |
| { |
| S[3] sa = [S('a'), S('b'), S('c')]; |
| T t = T(sa[1..3]); |
| t.sb[0].x = 'x'; |
| t.sb[1].x = 'y'; |
| assert(sa == [S('a'), S('b'), S('c')]); |
| assert(t.sb == [S('x'), S('y')]); |
| assert(op == "BC"); |
| } |
| assert(op == "BCyxcba"); |
| |
| op = null; |
| { |
| S[3] sx = [S('a'), S('b'), S('c')]; |
| T t; t.sb[0].x = 'x'; |
| t.sb[1].x = 'y'; |
| t.test(sx[1..3]); |
| assert(op == "BxCy"); |
| assert(t.sb == [S('b'), S('c')]); |
| } |
| assert(op == "BxCycbcba"); |
| |
| return true; |
| } |
| static assert(test14022()); |
| |
| bool test14023() |
| { |
| string op; |
| |
| struct S |
| { |
| char x = 'x'; |
| this(this) { op ~= x-0x20; } // upper case |
| ~this() { op ~= x; } // lower case |
| } |
| |
| S[2] makeSA() { return [S('p'), S('q')]; } |
| |
| struct T |
| { |
| S[2][1] sb; |
| this(ref S[2] sa) |
| { |
| assert(op == ""); |
| this.sb[0] = sa; // TOKconstruct |
| assert(sa == [S('b'), S('c')]); |
| assert(sb[0] == [S('b'), S('c')]); |
| } |
| } |
| |
| void test(ref S[2] sa) |
| { |
| S[2][] a; |
| //a.length = 1; // will cause runtine AccessViolation |
| a ~= (S[2]).init; |
| assert(op == ""); |
| a[0] = sa; // index <-- resolveSlice(newva) |
| assert(op == "BxCx"); |
| assert(a[0] == [S('b'), S('c')]); |
| } |
| |
| op = null; |
| { |
| S[3] sa = [S('a'), S('b'), S('c')]; |
| T t = T(sa[1..3]); |
| t.sb[0][0].x = 'x'; |
| t.sb[0][1].x = 'y'; |
| assert(sa != [S('a'), S('x'), S('y')]); // OK <- incorrectly fails |
| assert(sa == [S('a'), S('b'), S('c')]); // OK <- incorrectly fails |
| assert(t.sb[0] == [S('x'), S('y')]); |
| } |
| |
| op = null; |
| { |
| S[2] sa = [S('a'), S('b')]; |
| S[2][] a = [[S('x'), S('y')]]; |
| assert(op == ""); |
| a[0] = sa; |
| assert(op == "AxBy"); |
| a[0] = makeSA(); |
| assert(op == "AxByab"); |
| } |
| assert(op == "AxByabba"); |
| |
| op = null; |
| { |
| S[3] sa = [S('a'), S('b'), S('c')]; |
| test(sa[1..3]); |
| assert(op == "BxCx"); |
| } |
| assert(op == "BxCxcba"); |
| |
| return true; |
| } |
| static assert(test14023()); |
| |
| /************************************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=13669 - dtor call on static array variable |
| |
| bool test13669() |
| { |
| string dtor; |
| |
| struct S |
| { |
| char x = 'x'; |
| ~this() { dtor ~= x; } |
| } |
| |
| { S[2] a; } |
| assert(dtor == "xx"); |
| dtor = ""; |
| |
| { S[2] a = [S('a'), S('b')]; } |
| assert(dtor == "ba"); // reverse order. See also: TypeInfo_StaticArray.destroy() |
| |
| return true; |
| } |
| static assert(test13669()); |
| |
| /**********************************/ |
| |
| __gshared bool b13095 = false; |
| |
| void bar13095() { throw new Exception(""); } |
| |
| struct S13095 |
| { |
| this(int) { printf("ctor %p\n", &this); bar13095(); } |
| |
| ~this() { b13095 = true; printf("dtor %p\n", &this); } |
| } |
| |
| void test13095() |
| { |
| try { |
| S13095(0); |
| } catch(Exception) { printf("catch\n"); } |
| assert(!b13095); |
| } |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=14264 |
| |
| void test14264() |
| { |
| static int dtor; |
| static struct Foo |
| { |
| ~this() { ++dtor; } |
| T opCast(T:bool)() { return true; } |
| } |
| |
| Foo makeFoo() |
| { |
| return Foo(); |
| } |
| |
| assert(dtor == 0); |
| |
| makeFoo(); |
| assert(dtor == 1); |
| |
| makeFoo; |
| assert(dtor == 2); |
| |
| if (makeFoo()) {} |
| assert(dtor == 3); |
| |
| if (makeFoo) {} |
| assert(dtor == 4); |
| } |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=14686 |
| |
| int test14686() |
| { |
| string r; |
| |
| struct S |
| { |
| int n; |
| this(this) { r ~= cast(char)('0' + n); } |
| } |
| |
| S s1 = S(1); |
| S s2 = S(2); |
| S[] a1 = [S(1)]; |
| |
| S[2] sa1 = [s1, s2]; |
| assert(r == "12", r); // OK |
| |
| r = ""; |
| S[] a2 = a1 ~ s2; // runtime concatenation |
| assert(r == "12", r); // OK <- NG only in CTFE |
| |
| r = ""; |
| S[2] sa2a = [s1] ~ s2; |
| assert(r == "12", r); // OK <- NG, s2 is not copied |
| |
| r = ""; |
| S[2] sa2b = s2 ~ [s1]; |
| assert(r == "21", r); // OK <- NG, s2 is not copied |
| |
| r = ""; |
| S[3] sa3a = ([s1] ~ [s1]) ~ s2; |
| assert(r == "112", r); // OK <- NG, s2 is not copied |
| |
| r = ""; |
| S[3] sa3b = s2 ~ ([s1] ~ [s1]); |
| assert(r == "211", r); // OK <- NG, s2 is not copied |
| |
| return 1; |
| } |
| static assert(test14686()); |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=14815 |
| |
| int test14815() |
| { |
| uint dtorCount; |
| |
| struct S |
| { |
| uint x; |
| ~this() { ++dtorCount; } |
| } |
| |
| S[2] sa1; |
| sa1[0].x = 42; |
| sa1 = (S[2]).init; // S[2] <- rvalue |
| assert(sa1[0].x == 0); |
| assert(dtorCount == 2); |
| |
| S[2] sa2; |
| sa2[0].x = 42; |
| S[] da2 = sa2[]; |
| da2[] = (S[2]).init[]; // S[] <- rvalue slice |
| assert(sa2[0].x == 0); |
| assert(dtorCount == 4); |
| |
| S[2] sa3; |
| S[2] sa4; |
| sa3[0].x = 42; |
| sa3 = sa4; // S[2] <- lvalue |
| assert(sa3[0].x == 0); |
| assert(dtorCount == 6); |
| |
| S[2] sa5; |
| S[] da4 = sa4[]; |
| da4[] = sa5[]; // S[] <- lvalue slice |
| assert(sa4[0].x == 0); |
| assert(dtorCount == 8); |
| |
| return 1; |
| } |
| static assert(test14815()); |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=16197 |
| |
| struct Elem { |
| static string r; |
| int x = -1; |
| this(this) { r ~= 'p'; printf("POSTBLIT %d\n", x++); } |
| ~this() { r ~= 'd'; printf("DTOR %d\n" , x++); } |
| } |
| |
| struct Ctr { |
| Elem[3] arr; |
| } |
| |
| void test16197() { |
| { auto p = Ctr(); } |
| assert(Elem.r == "ddd"); |
| } |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=14860 |
| |
| int test14860() |
| { |
| uint dtorCount; |
| |
| struct S |
| { |
| uint x; |
| ~this() { ++dtorCount; } |
| } |
| |
| S[] a = [S(42)]; |
| a[] = S(); |
| |
| assert(a[0].x == 0); |
| assert(dtorCount == 1); |
| |
| return 1; |
| } |
| static assert(test14860()); |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=14246 |
| |
| struct A14246 { |
| int a = 3; |
| static string s; |
| this( int var ) { printf("A()\n"); a += var; s ~= "a"; } |
| |
| ~this() { printf("~A()\n"); s ~= "b"; } |
| } |
| |
| struct B14246 { |
| int i; |
| A14246 a; |
| |
| this( int var ) { |
| A14246.s ~= "c"; |
| a = A14246(var+1); |
| throw new Exception("An exception"); |
| } |
| } |
| |
| void test14246() { |
| try { |
| auto b = B14246(2); |
| } catch( Exception ex ) { |
| printf("Caught ex\n"); |
| A14246.s ~= "d"; |
| } |
| assert(A14246.s == "cabd"); |
| } |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=14696 |
| |
| void test14696(int len = 2) |
| { |
| string result; |
| |
| struct S |
| { |
| int n; |
| |
| void* get(void* p = null) |
| { |
| result ~= "get(" ~ cast(char)(n+'0') ~ ")."; |
| return null; |
| } |
| |
| ~this() |
| { |
| result ~= "dtor(" ~ cast(char)(n+'0') ~ ")."; |
| } |
| } |
| |
| S makeS(int n) |
| { |
| result ~= "makeS(" ~ cast(char)(n+'0') ~ ")."; |
| return S(n); |
| } |
| void foo(void* x, void* y = null) |
| { |
| result ~= "foo."; |
| } |
| void fooThrow(void* x, void* y = null) |
| { |
| result ~= "fooThrow."; |
| throw new Exception("fail!"); |
| } |
| |
| void check(void delegate() dg, string r, string file = __FILE__, size_t line = __LINE__) |
| { |
| import core.exception; |
| |
| result = null; |
| try { dg(); } catch (Exception e) {} |
| if (result != r) |
| throw new AssertError(result, file, line); |
| } |
| |
| // temporary in condition |
| check({ foo(len == 2 ? makeS(1).get() : null); }, "makeS(1).get(1).foo.dtor(1)."); |
| check({ foo(len == 2 ? null : makeS(1).get() ); }, "foo."); |
| check({ foo(len != 2 ? makeS(1).get() : null); }, "foo."); |
| check({ foo(len != 2 ? null : makeS(1).get() ); }, "makeS(1).get(1).foo.dtor(1)."); |
| |
| // temporary in nesting conditions |
| check({ foo(len >= 2 ? (len == 2 ? makeS(1).get() : null) : null); }, "makeS(1).get(1).foo.dtor(1)."); |
| check({ foo(len >= 2 ? (len == 2 ? null : makeS(1).get() ) : null); }, "foo."); |
| check({ foo(len >= 2 ? (len != 2 ? makeS(1).get() : null) : null); }, "foo."); |
| check({ foo(len >= 2 ? (len != 2 ? null : makeS(1).get() ) : null); }, "makeS(1).get(1).foo.dtor(1)."); |
| check({ foo(len >= 2 ? null : (len == 2 ? makeS(1).get() : null) ); }, "foo."); |
| check({ foo(len >= 2 ? null : (len == 2 ? null : makeS(1).get() ) ); }, "foo."); |
| check({ foo(len >= 2 ? null : (len != 2 ? makeS(1).get() : null) ); }, "foo."); |
| check({ foo(len >= 2 ? null : (len != 2 ? null : makeS(1).get() ) ); }, "foo."); |
| check({ foo(len > 2 ? (len == 2 ? makeS(1).get() : null) : null); }, "foo."); |
| check({ foo(len > 2 ? (len == 2 ? null : makeS(1).get() ) : null); }, "foo."); |
| check({ foo(len > 2 ? (len != 2 ? makeS(1).get() : null) : null); }, "foo."); |
| check({ foo(len > 2 ? (len != 2 ? null : makeS(1).get() ) : null); }, "foo."); |
| check({ foo(len > 2 ? null : (len == 2 ? makeS(1).get() : null) ); }, "makeS(1).get(1).foo.dtor(1)."); |
| check({ foo(len > 2 ? null : (len == 2 ? null : makeS(1).get() ) ); }, "foo."); |
| check({ foo(len > 2 ? null : (len != 2 ? makeS(1).get() : null) ); }, "foo."); |
| check({ foo(len > 2 ? null : (len != 2 ? null : makeS(1).get() ) ); }, "makeS(1).get(1).foo.dtor(1)."); |
| |
| // temporary in condition and throwing callee |
| // check({ fooThrow(len == 2 ? makeS(1).get() : null); }, "makeS(1).get(1).fooThrow.dtor(1)."); |
| // check({ fooThrow(len == 2 ? null : makeS(1).get() ); }, "fooThrow."); |
| // check({ fooThrow(len != 2 ? makeS(1).get() : null); }, "fooThrow."); |
| // check({ fooThrow(len != 2 ? null : makeS(1).get() ); }, "makeS(1).get(1).fooThrow.dtor(1)."); |
| |
| // temporary in nesting condititions and throwing callee |
| // check({ fooThrow(len >= 2 ? (len == 2 ? makeS(1).get() : null) : null); }, "makeS(1).get(1).fooThrow.dtor(1)."); |
| // check({ fooThrow(len >= 2 ? (len == 2 ? null : makeS(1).get() ) : null); }, "fooThrow."); |
| // check({ fooThrow(len >= 2 ? (len != 2 ? makeS(1).get() : null) : null); }, "fooThrow."); |
| // check({ fooThrow(len >= 2 ? (len != 2 ? null : makeS(1).get() ) : null); }, "makeS(1).get(1).fooThrow.dtor(1)."); |
| // check({ fooThrow(len >= 2 ? null : (len == 2 ? makeS(1).get() : null) ); }, "fooThrow."); |
| // check({ fooThrow(len >= 2 ? null : (len == 2 ? null : makeS(1).get() ) ); }, "fooThrow."); |
| // check({ fooThrow(len >= 2 ? null : (len != 2 ? makeS(1).get() : null) ); }, "fooThrow."); |
| // check({ fooThrow(len >= 2 ? null : (len != 2 ? null : makeS(1).get() ) ); }, "fooThrow."); |
| // check({ fooThrow(len > 2 ? (len == 2 ? makeS(1).get() : null) : null); }, "fooThrow."); |
| // check({ fooThrow(len > 2 ? (len == 2 ? null : makeS(1).get() ) : null); }, "fooThrow."); |
| // check({ fooThrow(len > 2 ? (len != 2 ? makeS(1).get() : null) : null); }, "fooThrow."); |
| // check({ fooThrow(len > 2 ? (len != 2 ? null : makeS(1).get() ) : null); }, "fooThrow."); |
| // check({ fooThrow(len > 2 ? null : (len == 2 ? makeS(1).get() : null) ); }, "makeS(1).get(1).fooThrow.dtor(1)."); |
| // check({ fooThrow(len > 2 ? null : (len == 2 ? null : makeS(1).get() ) ); }, "fooThrow."); |
| // check({ fooThrow(len > 2 ? null : (len != 2 ? makeS(1).get() : null) ); }, "fooThrow."); |
| // check({ fooThrow(len > 2 ? null : (len != 2 ? null : makeS(1).get() ) ); }, "makeS(1).get(1).fooThrow.dtor(1)."); |
| |
| // temporaries in each conditions |
| check({ foo(len == 2 ? makeS(1).get() : null, len == 2 ? makeS(2).get() : null); }, "makeS(1).get(1).makeS(2).get(2).foo.dtor(2).dtor(1)."); |
| check({ foo(len == 2 ? makeS(1).get() : null, len != 2 ? makeS(2).get() : null); }, "makeS(1).get(1).foo.dtor(1)."); |
| check({ foo(len != 2 ? makeS(1).get() : null, len == 2 ? makeS(2).get() : null); }, "makeS(2).get(2).foo.dtor(2)."); |
| check({ foo(len != 2 ? makeS(1).get() : null, len != 2 ? makeS(2).get() : null); }, "foo."); |
| |
| // nesting temporaries in conditions |
| check({ foo(len == 2 ? makeS(1).get(len == 2 ? makeS(2).get() : null) : null); }, "makeS(1).makeS(2).get(2).get(1).foo.dtor(2).dtor(1)."); |
| check({ foo(len == 2 ? makeS(1).get(len != 2 ? makeS(2).get() : null) : null); }, "makeS(1).get(1).foo.dtor(1)."); |
| check({ foo(len != 2 ? makeS(1).get(len == 2 ? makeS(2).get() : null) : null); }, "foo."); |
| check({ foo(len != 2 ? makeS(1).get(len != 2 ? makeS(2).get() : null) : null); }, "foo."); |
| check({ foo(len == 2 ? makeS(makeS(2).n - 1).get() : null); }, "makeS(2).makeS(1).get(1).foo.dtor(1).dtor(2)."); |
| check({ foo(len != 2 ? makeS(makeS(2).n - 1).get() : null); }, "foo."); |
| } |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=14838 |
| |
| int test14838() pure nothrow @safe |
| { |
| int dtor; |
| |
| struct S14838(T) |
| { |
| ~this() { ++dtor; } |
| } |
| struct X14838 |
| { |
| S14838!int ms; |
| const S14838!int cs; |
| |
| S14838!int[2] ma; |
| const S14838!int[2] ca; |
| |
| S14838!int[2][2] ma2x2; |
| const S14838!int[2][2] ca2x2; |
| |
| // number of S14838 = 1*2 + 2*2 + 4*2 = 14 |
| } |
| |
| void test(Dg)(scope Dg code) |
| { |
| dtor = 0; |
| code(); |
| } |
| |
| test(delegate{ S14838!int a; }); assert(dtor == 1); |
| test(delegate{ const S14838!int a; }); assert(dtor == 1); |
| |
| test(delegate{ S14838!int[2] a; }); assert(dtor == 2); |
| test(delegate{ const S14838!int[2] a; }); assert(dtor == 2); |
| |
| test(delegate{ S14838!int[2][2] a; }); assert(dtor == 4); |
| test(delegate{ const S14838!int[2][2] a; }); assert(dtor == 4); |
| |
| test(delegate{ X14838 a; }); assert(dtor == 1 * 14); |
| test(delegate{ const X14838 a; }); assert(dtor == 1 * 14); |
| |
| test(delegate{ X14838[2] a; }); assert(dtor == 2 * 14); |
| test(delegate{ const X14838[2] a; }); assert(dtor == 2 * 14); |
| |
| test(delegate{ X14838[2][2] a; }); assert(dtor == 4 * 14); |
| test(delegate{ const X14838[2][2] a; }); assert(dtor == 4 * 14); |
| |
| return 1; |
| } |
| static assert(test14838()); |
| |
| /**********************************/ |
| |
| // https://issues.dlang.org/show_bug.cgi?id=14639 |
| |
| struct Biggy { |
| ulong[50000] a; |
| @disable this(this); |
| } |
| |
| __gshared Biggy biggy; |
| |
| void test14639() { |
| biggy = Biggy.init; |
| } |
| |
| /**********************************/ |
| |
| struct S63 |
| { |
| private long p = 87; |
| |
| this(int x) |
| { |
| assert(p == 87); |
| p += x; |
| } |
| |
| ~this() { } |
| |
| this(this) { } |
| |
| void funky() { assert(p == 90); } |
| |
| static void tester() |
| { |
| S63(3).funky(); |
| } |
| } |
| |
| void test63() |
| { |
| S63.tester(); |
| } |
| |
| /**********************************/ |
| |
| struct X64 |
| { |
| static int dtor; |
| |
| ~this() { ++dtor; } |
| } |
| |
| struct S64 |
| { |
| int n; |
| long[10] dummy; // S64 needs to be passed by stack |
| } |
| |
| S64 foo64() |
| { |
| X64(); |
| return S64(1); |
| } |
| |
| void test64() |
| { |
| auto s = foo64(); |
| assert(X64.dtor == 1); |
| } |
| |
| /**********************************/ |
| |
| struct S65 |
| { |
| static string t; |
| |
| void bar(int a, int b) |
| { |
| t ~= "d"; |
| } |
| } |
| |
| S65 foo65a() |
| { |
| S65.t ~= "a"; |
| return S65(); |
| } |
| |
| int foo65b() |
| { |
| S65.t ~= "b"; |
| return 1; |
| } |
| |
| int foo65c() |
| { |
| S65.t ~= "c"; |
| return 2; |
| } |
| |
| void test65() |
| { |
| import core.stdc.stdio; |
| foo65a().bar(foo65b(), foo65c()); |
| printf("'%.*s'\n", cast(int)S65.t.length, S65.t.ptr); |
| assert(S65.t == "abcd"); |
| } |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=15661 |
| |
| struct X15661 |
| { |
| ~this() {} |
| } |
| |
| X15661 createX15661() { return X15661(); } |
| |
| struct Y15661 |
| { |
| static int dtor; |
| |
| @disable this(); |
| @disable this(this); |
| this(X15661 a1, X15661 a2) {} |
| ~this() { ++dtor; } |
| } |
| |
| struct Z15661 |
| { |
| this(int) |
| { |
| b = Y15661(createX15661(), createX15661()); |
| assert(Y15661.dtor == 0); |
| } |
| |
| private Y15661 b; |
| } |
| |
| void test15661() |
| { |
| { |
| auto v = Z15661(5); |
| assert(Y15661.dtor == 0); |
| } |
| assert(Y15661.dtor == 1); |
| } |
| |
| /**********************************/ |
| |
| // https://issues.dlang.org/show_bug.cgi?id=18045 |
| |
| struct A18045 |
| { |
| nothrow: |
| __gshared int r; |
| int state; |
| this(this) { printf("postblit: A(%d)\n", state); r += 1; } |
| ~this() { printf("dtor: A(%d)\n", state); r *= 3; } |
| } |
| |
| A18045 fun18045() nothrow |
| { |
| __gshared a = A18045(42); |
| return a; |
| } |
| |
| void test18045() nothrow |
| { |
| alias A = A18045; |
| |
| __gshared a = A(-42); |
| if (fun18045() == a) |
| assert(0); |
| else |
| assert(A.r == 3); |
| |
| A.r = 0; |
| if (a == fun18045()) |
| assert(0); |
| else |
| assert(A.r == 3); |
| } |
| |
| /**********************************/ |
| |
| struct S66 |
| { |
| ~this() { } |
| } |
| |
| nothrow void notthrow() { } |
| |
| class C66 |
| { |
| S66 s; |
| |
| this() nothrow { notthrow(); } |
| } |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=16652 |
| |
| struct Vector |
| { |
| this(ubyte a) |
| { |
| pragma(inline, false); |
| buf = a; |
| } |
| |
| ~this() |
| { |
| pragma(inline, false); |
| buf = 0; |
| } |
| |
| ubyte buf; |
| } |
| |
| int bar16652(ubyte* v) |
| { |
| pragma(inline, true); |
| assert(*v == 1); |
| return 0; |
| } |
| |
| void test16652() |
| { |
| bar16652(&Vector(1).buf); |
| } |
| |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=19676 |
| |
| void test19676() |
| { |
| static struct S |
| { |
| __gshared int count; |
| ~this() { ++count; } |
| } |
| |
| static S foo() { return S(); } |
| |
| static void test1() |
| { |
| cast(void)foo(); |
| } |
| |
| static void test2() |
| { |
| foo(); |
| } |
| |
| test1(); |
| assert(S.count == 1); |
| test2(); |
| assert(S.count == 2); |
| } |
| |
| /**********************************/ |
| |
| // https://issues.dlang.org/show_bug.cgi?id=14708 |
| |
| __gshared bool dtor14078 = false; |
| |
| struct S14078 |
| { |
| int n; |
| |
| void* get(void* p = null) |
| { |
| return null; |
| } |
| |
| ~this() |
| { |
| //printf("dtor\n"); |
| dtor14078 = true; |
| } |
| } |
| |
| S14078 makeS14078(int n) |
| { |
| return S14078(n); |
| } |
| |
| void foo14078(void* x) |
| { |
| throw new Exception("fail!"); |
| } |
| |
| void test(int len = 2) |
| { |
| foo14078(makeS14078(1).get()); |
| // A temporary is allocated on stack for the |
| // return value from makeS14078(1). |
| // When foo14078 throws exception, it's dtor should be called |
| // during unwinding stack, but it does not happen in Win64. |
| } |
| |
| void test14078() |
| { |
| try |
| { |
| test(); |
| } catch (Exception e) {} |
| assert(dtor14078); // fails! |
| } |
| |
| /**********************************/ |
| |
| void test67() |
| { |
| char[] deleted; |
| |
| struct S |
| { |
| char* p; |
| |
| ~this() { deleted ~= *p; } |
| |
| void opAssign(S rhs) |
| { |
| // swap |
| char* tmp = p; |
| this.p = rhs.p; |
| rhs.p = tmp; |
| } |
| } |
| |
| char a = 'a', b = 'b'; |
| { |
| S s = S(&a); |
| s = S(&b); |
| } |
| assert(deleted == "ab", deleted); |
| } |
| |
| /**********************************/ |
| |
| void test68() |
| { |
| static struct S |
| { |
| int i; |
| bool opEquals(S) { return false; } |
| ~this() {} |
| } |
| |
| assert(S(0) != S(1)); |
| } |
| |
| /**********************************/ |
| |
| // https://github.com/dlang/dmd/pull/12012 |
| |
| extern (C++) |
| { |
| struct S12012 |
| { |
| int* ctr; |
| ~this() { } |
| } |
| |
| void bar12012(int value, S12012 s) |
| { |
| } |
| |
| S12012 abc12012(ref S12012 s) |
| { |
| s.ctr = null; |
| return s; |
| } |
| |
| int def12012(ref S12012 s) |
| { |
| return *s.ctr; // seg fault is here |
| } |
| |
| void testPR12012() |
| { |
| int i; |
| S12012 s = S12012(&i); |
| // def must be executed before abc else seg fault |
| bar12012(def12012(s), abc12012(s)); |
| } |
| } |
| |
| /**********************************/ |
| |
| int main() |
| { |
| test1(); |
| |
| 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(); |
| test42(); |
| test43(); |
| test44(); |
| test45(); |
| test46(); |
| test47(); |
| test48(); |
| test49(); |
| test50(); |
| test51(); |
| test52(); |
| |
| test54(); |
| test55(); |
| test56(); |
| test57(); |
| test58(); |
| test59(); |
| test5737(); |
| test6119(); |
| test8741(); |
| test6364(); |
| test6499(); |
| test60(); |
| test4316(); |
| test6177(); |
| test6470(); |
| test6636(); |
| test6637(); |
| test7353(); |
| test61(); |
| test7506(); |
| test7516a(); |
| test7516b(); |
| test7516c(); |
| test7516d(); |
| test7516e(); |
| test7530(); |
| test62(); |
| test7579a(); |
| test7579b(); |
| test8335(); |
| test8356(); |
| test9386(); |
| test9441(); |
| test9720(); |
| test9899(); |
| test9907(); |
| test9985(); |
| test17457(); |
| test9994(); |
| test10094(); |
| test10244(); |
| test10694(); |
| test10789(); |
| test10972(); |
| test11134(); |
| test11197(); |
| test7474(); |
| test11505(); |
| test12045(); |
| test12591(); |
| test12660(); |
| test12686(); |
| test13089(); |
| test11763(); |
| test13303(); |
| test13673(); |
| test13586(); |
| test14443(); |
| test13661(); |
| test13661a(); |
| test14022(); |
| test14023(); |
| test13669(); |
| test13095(); |
| test14264(); |
| test14686(); |
| test14815(); |
| test16197(); |
| test14860(); |
| test14246(); |
| test14696(); |
| test14838(); |
| test14639(); |
| test63(); |
| test64(); |
| test65(); |
| test15661(); |
| test18045(); |
| test16652(); |
| test19676(); |
| test14078(); |
| test67(); |
| test68(); |
| testPR12012(); |
| |
| printf("Success\n"); |
| return 0; |
| } |