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