1 extern(C) int printf(const char*, ...);
2 
3 /***************************************************/
4 
testfp()5 void testfp()
6 {
7     static int func1(int n = 1) { return n; }
8     static int func2(int n    ) { return n; }
9     static assert(typeof(func1).stringof == "pure nothrow @nogc @safe int(int n = 1)");
10     static assert(typeof(func2).stringof == "pure nothrow @nogc @safe int(int n)");
11     static assert( is(typeof(func1())));     // OK
12     static assert(!is(typeof(func2())));     // NG
13 
14     alias typeof(func1) Func1;
15     alias typeof(func2) Func2;
16     static assert(is(Func1 == Func2));
17     static assert(Func1.stringof == "pure nothrow @nogc @safe int(int n = 1)");
18     static assert(Func2.stringof == "pure nothrow @nogc @safe int(int n)");
19 
20     auto fp1 = &func1;
21     auto fp2 = &func2;
22     static assert(typeof(fp1).stringof == "int function(int n = 1) pure nothrow @nogc @safe");
23     static assert(typeof(fp2).stringof == "int function(int n) pure nothrow @nogc @safe");
24     static assert( is(typeof(fp1())));     // OK
25     static assert(!is(typeof(fp2())));     // NG
26 
27     alias typeof(fp1) Fp1;
28     alias typeof(fp2) Fp2;
29     static assert(is(Fp1 == Fp2));
30     static assert(Fp1.stringof == "int function(int n = 1) pure nothrow @nogc @safe");
31     static assert(Fp2.stringof == "int function(int n) pure nothrow @nogc @safe");
32 
33     typeof(fp1) fp3 = fp1;
34     typeof(fp2) fp4 = fp2;
35     static assert(is(typeof(fp3) == typeof(fp4)));
36     static assert(typeof(fp3).stringof == "int function(int n = 1) pure nothrow @nogc @safe");
37     static assert(typeof(fp4).stringof == "int function(int n) pure nothrow @nogc @safe");
38     static assert( is(typeof(fp3())));     // OK
39     static assert(!is(typeof(fp4())));     // NG
40 
41     alias typeof(fp3) Fp3;
42     alias typeof(fp4) Fp4;
43     static assert(is(Fp3 == Fp4));
44     static assert(Fp3.stringof == "int function(int n = 1) pure nothrow @nogc @safe");
45     static assert(Fp4.stringof == "int function(int n) pure nothrow @nogc @safe");
46 
47     auto fplit1 = function(int n = 1) { return n; };
48     auto fplit2 = function(int n    ) { return n; };
49     static assert( is(typeof(fplit1())));   // OK
50     static assert(!is(typeof(fplit2())));   // NG
51 }
52 
testdg()53 void testdg()
54 {
55     int nest1(int n = 1) { return n; }
56     int nest2(int n    ) { return n; }
57     static assert(typeof(nest1).stringof == "pure nothrow @nogc @safe int(int n = 1)");
58     static assert(typeof(nest2).stringof == "pure nothrow @nogc @safe int(int n)");
59     static assert( is(typeof(nest1())));     // OK
60     static assert(!is(typeof(nest2())));     // NG
61 
62     alias typeof(nest1) Nest1;
63     alias typeof(nest2) Nest2;
64     static assert(is(Nest1 == Nest2));
65     static assert(Nest1.stringof == "pure nothrow @nogc @safe int(int n = 1)");
66     static assert(Nest2.stringof == "pure nothrow @nogc @safe int(int n)");
67 
68     auto dg1 = &nest1;
69     auto dg2 = &nest2;
70     static assert(typeof(dg1).stringof == "int delegate(int n = 1) pure nothrow @nogc @safe");
71     static assert(typeof(dg2).stringof == "int delegate(int n) pure nothrow @nogc @safe");
72     static assert( is(typeof(dg1())));     // OK
73     static assert(!is(typeof(dg2())));     // NG
74 
75     alias typeof(dg1) Dg1;
76     alias typeof(dg2) Dg2;
77     static assert(is(Dg1 == Dg2));
78     static assert(Dg1.stringof == "int delegate(int n = 1) pure nothrow @nogc @safe");
79     static assert(Dg2.stringof == "int delegate(int n) pure nothrow @nogc @safe");
80 
81     typeof(dg1) dg3 = dg1;
82     typeof(dg2) dg4 = dg2;
83     static assert(typeof(dg3).stringof == "int delegate(int n = 1) pure nothrow @nogc @safe");
84     static assert(typeof(dg4).stringof == "int delegate(int n) pure nothrow @nogc @safe");
85     static assert( is(typeof(dg3())));     // OK
86     static assert(!is(typeof(dg4())));     // NG
87 
88     alias typeof(dg3) Dg3;
89     alias typeof(dg4) Dg4;
90     static assert(is(Dg3 == Dg4));
91     static assert(Dg3.stringof == "int delegate(int n = 1) pure nothrow @nogc @safe");
92     static assert(Dg4.stringof == "int delegate(int n) pure nothrow @nogc @safe");
93 
94     auto dglit1 = delegate(int n = 1) { return n; };
95     auto dglit2 = delegate(int n    ) { return n; };
96     static assert( is(typeof(dglit1())));   // OK
97     static assert(!is(typeof(dglit2())));   // NG
98 }
99 
testda()100 void testda()
101 {
102     // Unsupported cases with current implementation.
103 
104     int function(int n = 1)[] fpda = [n => n + 1, n => n+2];
105     assert(fpda[0](1) == 2);
106     assert(fpda[1](1) == 3);
107     static assert(!is(typeof(fpda[0]() == 1)));     // cannot call with using defArgs
108     static assert(!is(typeof(fpda[1]() == 2)));     // cannot call with using defArgs
109     static assert(typeof(fpda).stringof == "int function(int)[]");
110     static assert(typeof(fpda).stringof != "int function(int n = 1)[]");
111 
112     int delegate(int n = 1)[] dgda = [n => n + 1, n => n+2];
113     assert(dgda[0](1) == 2);
114     assert(dgda[1](1) == 3);
115     static assert(!is(typeof(dgda[0]() == 1)));     // cannot call with using defArgs
116     static assert(!is(typeof(dgda[1]() == 2)));     // cannot call with using defArgs
117     static assert(typeof(dgda).stringof == "int delegate(int)[]");
118     static assert(typeof(fpda).stringof != "int delegate(int n = 1)[]");
119 }
120 
StringOf(T)121 template StringOf(T)
122 {
123     // template type parameter cannot have redundant information
124     enum StringOf = T.stringof;
125 }
126 
testti()127 void testti()
128 {
129     int[] test(int[] a = []) { return a; }
130     static assert(typeof(test).stringof == "pure nothrow @nogc @safe int[](int[] a = [])");
131     static assert(StringOf!(typeof(test)) == "pure nothrow @nogc @safe int[](int[])");
132 
133     float function(float x = 0F) fp = x => x;
134     static assert(typeof(fp).stringof == "float function(float x = " ~ (0F).stringof ~ ")");
135     static assert(StringOf!(typeof(fp)) == "float function(float)");
136 
137     double delegate(double x = 0.0) dg = x => x;
138     static assert(typeof(dg).stringof == "double delegate(double x = " ~ (0.0).stringof ~ ")");
139     static assert(StringOf!(typeof(dg)) == "double delegate(double)");
140 
141     template F(T) {}
142     auto fp1 = (int a = 1) {};
143     auto fp2 = (int b = 2) {};
144     static assert(typeof(fp1).stringof != typeof(fp2).stringof);
145     alias F1 = F!(typeof(fp1));
146     alias F2 = F!(typeof(fp2));
147     static assert(__traits(isSame, F1, F2));
148     static assert(F1.mangleof == F2.mangleof);
149 }
150 
testxx()151 void testxx()
152 {
153     // The corner cases which I had introduced in forum discussion
154 
155     // f will inherit default args from its initializer, if it's declared with 'auto'
156     auto f1 = (int n = 10){ return 10; };
157     assert(f1() == 10);
158 
159     // what is the actual default arg of f?
160     int function(int n = 10) f2 = (int n = 20){ return n; };
161     int function(int n     ) f3 = (int n = 30){ return n; };
162     int function(int n = 40) f4 = (int n     ){ return n; };
163     assert(f2() == 10);
164     static assert(!is(typeof(f3())));
165     assert(f4() == 40);
166 
167     // conditional expression and the type of its result
168     auto f5 = true ? (int n = 10){ return n; }
169                    : (int n = 20){ return n; } ;
170     auto f6 = true ? (int n = 10, string s = "hello"){ return n; }
171                    : (int n = 10, string s = "world"){ return n; } ;
172     static assert(!is(typeof(f5())));   // cannot call
173     static assert(!is(typeof(f6())));   // cannot call
174 
175     int function(int n = 10) f7;    // default arg of the first parameter is 10
176     f7 = (int n = 20){ return n; }; // function literal's default arg will be ignored
177     assert(f7() == 10);
178 
179     // returning function pointer/delegate type can have default args
180     int delegate(int n = 10) foo(int x) { return n => n + x; }
181     auto f = foo(1);
182     assert(f() == 11);
183 }
184 
185 /***************************************************/
186 // 3646
187 
188 int bar3646(int x = 10) { printf("bar %d\n", x); return x; }
bam3646(int y)189 int bam3646(int y)      { printf("bam %d\n", y); return y; }
190 
qux3646()191 int qux3646()      { printf("quux\n");       return 20; }
qux3646(int i)192 int qux3646(int i) { printf("quux %d\n", i); return 30; }
193 
foo3646a(Fn)194 void foo3646a(Fn)(Fn fn)
195 {
196     fn();
197 }
198 
foo3646b(alias fn)199 void foo3646b(alias fn)(int res1, int res2)
200 {
201     assert(fn() == res1);
202     assert(fn(42) == res2);
203 }
204 
test3646()205 void test3646()
206 {
207     static assert(!is(typeof(foo3646(&bar3646))));
208     static assert(!is(typeof(foo3646(&bam3646))));
209     static assert(typeof(&bar3646).stringof == "int function(int x = 10)");
210     static assert(typeof(&bam3646).stringof == "int function(int y)");
211 
212     foo3646b!bar3646(10, 42);
213     static assert(!is(typeof(foo3646b!bam3646(0, 0))));
214     foo3646b!qux3646(20, 30);
215 }
216 
217 /***************************************************/
218 // 3866
219 
test3866()220 void test3866()
221 {
222 
223     auto foo = (int a = 1) { return a; };
224     auto bar = (int a) { return a; };
225 
226     assert(foo() == 1);
227     static assert(!is(typeof(bar())));
228     assert(foo(2) == 2);
229     assert(bar(3) == 3);
230 }
231 
232 /***************************************************/
233 // 8579
234 
test8579()235 void test8579()
236 {
237     static void func1(int i, double j = 1.0) {}
238     static void func2(int x, double y) {}
239     auto fn1 = &func1;
240     auto fn2 = &func2;
241     static assert(is(typeof(fn1) == typeof(fn2)));
242            assert(   typeid(fn1) is typeid(fn2) );
243     static assert(typeof(fn1).stringof == "void function(int i, double j = " ~ (1.0).stringof ~ ") pure nothrow @nogc @safe");
244     static assert(typeof(fn2).stringof == "void function(int x, double y) pure nothrow @nogc @safe");
245 
246     static int func3(int x, double y) { return 0; }
247     static int func4(int i, double j = 1.0) { return 0; }
248     auto fn3 = &func3;
249     auto fn4 = &func4;
250     static assert(is(typeof(fn3) == typeof(fn4)));
251            assert(   typeid(fn3) is typeid(fn4) );
252     static assert(typeof(fn3).stringof == "int function(int x, double y) pure nothrow @nogc @safe");
253     static assert(typeof(fn4).stringof == "int function(int i, double j = " ~ (1.0).stringof ~ ") pure nothrow @nogc @safe");
254 }
255 
256 /***************************************************/
257 // 14210
258 
foo14210a(DT)259 string foo14210a(DT)(string name, DT dg)
260 {
261     return name ~ " :: " ~ typeof(dg).stringof;
262 }
foo14210b(DT)263 string foo14210b(DT)(string name, DT dg)
264 {
265     return name ~ " :: " ~ typeof(dg).stringof;
266 }
test14210()267 void test14210()
268 {
269     assert(foo14210a("1", (int a)    => a+0) == "1 :: int function(int) pure nothrow @nogc @safe");
270     assert(foo14210a("2", (int a=40) => a+2) == "2 :: int function(int) pure nothrow @nogc @safe");
271 
272     assert(foo14210b("2", (int a=40) => a+2) == "2 :: int function(int) pure nothrow @nogc @safe");
273     assert(foo14210b("1", (int a)    => a+0) == "1 :: int function(int) pure nothrow @nogc @safe");
274 }
275 
276 /***************************************************/
277 // 10734
278 
279 // There's no platform independent export symbol, so
280 // test just only in Win32.
version(Win32)281 version(Win32)
282 {
283 
284 extern(Windows)
285 {
286     // use a symbol from kernel32.lib, not user32.lib. The latter might not
287     //  be passed automatically on the command line
288     export void* GetModuleHandleA(const(char)*moduleName);
289     alias void* function(const(char)*moduleName) PROC;
290 }
291 
292 void test10734()
293 {
294     PROC lpfnProc = &GetModuleHandleA;
295 }
296 
297 }
298 
299 /***************************************************/
300 // 14656
301 
test14656()302 void test14656()
303 {
304     //void unaryFun()(auto int a) pure nothrow @safe @nogc {}   // changed to invalid by fixing issue 14669
305     alias Identity(F) = F;
306     //unaryFun!()(41);
307     static void fun(int n) pure nothrow @safe @nogc {}
308     alias F = typeof(fun);
309     assert(Identity!F.stringof == "pure nothrow @nogc @safe void(int)");
310 }
311 
test14656_ref()312 void test14656_ref()
313 {
314     void unaryFun()(auto ref int a) pure nothrow @safe @nogc {}
315     alias Identity(F) = F;
316     unaryFun!()(41);
317     static void fun(int n) pure nothrow @safe @nogc {}
318     alias F = typeof(fun);
319     assert(Identity!F.stringof == "pure nothrow @nogc @safe void(int)");
320 }
321 
322 /***************************************************/
323 
main()324 int main()
325 {
326     testfp();
327     testdg();
328     testda();
329     testti();
330     testxx();
331     test3646();
332     test3866();
333     test8579();
334     test14210();
335     test14656();
336     test14656_ref();
337 
338     printf("Success\n");
339     return 0;
340 }
341 
342