1 /*
2 RUN_OUTPUT:
3 ---
4 Success
5 ---
6 */
7 extern (C) int printf(const char* fmt, ...);
8 
pass(int n)9 int pass(int n){ return n; }
10 
11 struct X
12 {
13     int m;
14 
opIndexX15     int opIndex(int m, int n)
16     {
17         return n;
18     }
19 }
20 
21 /**********************************************/
22 
23 struct S1f
24 {
opDispatch(string name,A...)25     int opDispatch(string name, A...)(A args)
26     {
27       static if (args.length)
28         return args[0];
29       else
30         return 0;
31     }
32 }
33 struct S1p
34 {
opDispatchS1p35     @property int opDispatch(string name, A...)(A args)
36     {
37       static if (args.length)
38         return args[0];
39       else
40         return 0;
41     }
42 }
test1()43 void test1()
44 {
45     S1f s1f;
46     assert(s1f.func() == 0);            // ok -> ok
47     assert(s1f.func(1) == 1);           // ok -> ok
48     assert(pass(s1f.func()) == 0);      // ok -> ok
49     assert(pass(s1f.func(1)) == 1);     // ok -> ok
50     assert(X(s1f.func()).m == 0);
51     assert(X()[0, s1f.func()] == 0);
52 
53     S1p s1p;
54     assert(s1p.prop == 0);              // ok   -> ok
55     assert((s1p.prop = 1) == 1);        // CTng -> CTng
56     assert(pass(s1p.prop) == 0);        // ok   -> ok
57     assert(pass(s1p.prop = 2) == 2);    // CTng -> CTng
58     assert(X(s1p.prop).m == 0);
59     assert(X()[0, s1p.prop] == 0);
60 }
61 
62 /**********************************************/
63 
64 struct S2f
65 {
opDispatchS2f66     template opDispatch(string name)
67     {
68         int opDispatch(A...)(A args)
69         {
70           static if (args.length)
71             return args[0];
72           else
73             return 0;
74         }
75     }
76 }
77 struct S2p
78 {
opDispatch(string name)79     template opDispatch(string name)
80     {
81         @property int opDispatch(A...)(A args)
82         {
83           static if (args.length)
84             return args[0];
85           else
86             return 0;
87         }
88     }
89 }
test2()90 void test2()
91 {
92     S2f s2f;
93     assert(s2f.func() == 0);            // ok -> ok
94     assert(s2f.func(1) == 1);           // ok -> ok
95     assert(pass(s2f.func()) == 0);      // ok -> ok
96     assert(pass(s2f.func(1)) == 1);     // ok -> ok
97     assert(X(s2f.func()).m == 0);
98     assert(X()[0, s2f.func()] == 0);
99 
100     S2p s2p;
101     assert(s2p.prop == 0);              // CTng -> ok
102     assert((s2p.prop = 1) == 1);        // ok   -> ok
103     assert(pass(s2p.prop) == 0);        // CTng -> ok
104     assert(pass(s2p.prop = 2) == 2);    // ok   -> ok
105     assert(X(s2p.prop).m == 0);
106     assert(X()[0, s2p.prop] == 0);
107 }
108 
109 /**********************************************/
110 
111 struct S3f
112 {
opDispatchS3f113     template opDispatch(string name)
114     {
115         template opDispatch(T)
116         {
117             int opDispatch(A...)(A args)
118             {
119               static if (args.length)
120                 return args[0];
121               else
122                 return 0;
123             }
124         }
125     }
126 }
127 struct S3p
128 {
opDispatch(string name)129     template opDispatch(string name)
130     {
131         template opDispatch(T)
132         {
133             @property int opDispatch(A...)(A args)
134             {
135               static if (args.length)
136                 return args[0];
137               else
138                 return 0;
139             }
140         }
141     }
142 }
test3()143 void test3()
144 {
145     S3f s3f;
146     assert(s3f.func!int() == 0);            // ok -> ok
147     assert(s3f.func!int(1) == 1);           // ok -> ok
148     assert(pass(s3f.func!int()) == 0);      // ok -> ok
149     assert(pass(s3f.func!int(1)) == 1);     // ok -> ok
150     assert(X(s3f.func!int()).m == 0);
151     assert(X()[0, s3f.func!int()] == 0);
152 
153     S3p s3p;
154     assert(s3p.prop!int == 0);              // CTng -> ok
155     assert((s3p.prop!int = 1) == 1);        // ok   -> ok
156     assert(pass(s3p.prop!int) == 0);        // CTng -> ok
157     assert(pass(s3p.prop!int = 2) == 2);    // ok   -> ok
158     assert(X(s3p.prop!int).m == 0);
159     assert(X()[0, s3p.prop!int] == 0);
160 }
161 
162 /**********************************************/
163 
164 struct S4f
165 {
opDispatchS4f166     ref int opDispatch(string name, A...)(A args)
167     {
168         static int n;
169         n = args.length;
170         return n;
171     }
172 }
173 struct S4p
174 {
opDispatch(string name,A...)175     @property ref int opDispatch(string name, A...)(A args)
176     {
177         static int n;
178         n = args.length;
179         return n;
180     }
181 }
test4()182 void test4()
183 {
184     S4f s4f;
185     assert(s4f.func == 0);          // getter
186     assert((s4f.func = 1) == 1);    // setter
187 
188     S4p s4p;
189     assert(s4p.prop == 0);          // getter
190     assert((s4p.prop = 1) == 1);    // setter
191 }
192 
193 /**********************************************/
194 
195 struct S5f
196 {
opDispatchS5f197     template opDispatch(string name)
198     {
199         ref int opDispatch(A...)(A args)
200         {
201             static int n;
202             n = args.length;
203             return n;
204         }
205     }
206 }
207 struct S5p
208 {
opDispatch(string name)209     template opDispatch(string name)
210     {
211         @property ref int opDispatch(A...)(A args)
212         {
213             static int n;
214             n = args.length;
215             return n;
216         }
217     }
218 }
test5()219 void test5()
220 {
221     S5f s5f;
222     assert(s5f.prop == 0);          // getter   ng -> ok
223     assert((s5f.prop = 1) == 1);    // setter
224 
225     S5p s5p;
226     assert(s5p.prop == 0);          // getter   ng -> ok
227     assert((s5p.prop = 1) == 1);    // setter
228 }
229 
230 /**********************************************/
231 
232 struct S6f
233 {
opDispatchS6f234     template opDispatch(string name)
235     {
236         template opDispatch(T)
237         {
238             ref int opDispatch(A...)(A args)
239             {
240                 static int n;
241                 n = args.length;
242                 return n;
243             }
244         }
245     }
246 }
247 struct S6p
248 {
opDispatch(string name)249     template opDispatch(string name)
250     {
251         template opDispatch(T)
252         {
253             @property ref int opDispatch(A...)(A args)
254             {
255                 static int n;
256                 n = args.length;
257                 return n;
258             }
259         }
260     }
261 }
test6()262 void test6()
263 {
264     S6f s6f;
265     assert(s6f.prop!int == 0);          // getter   ng -> ok
266     assert((s6f.prop!int = 1) == 1);    // setter
267 
268     S6p s6p;
269     assert(s6p.prop!int == 0);          // getter   ng -> ok
270     assert((s6p.prop!int = 1) == 1);    // setter
271 }
272 
273 /**********************************************/
274 // https://issues.dlang.org/show_bug.cgi?id=7578
275 
276 struct Foo7578
277 {
opDispatchFoo7578278     static int[] opDispatch(string op, Args...)(Args)
279     {
280         return [0];
281     }
282 }
283 
test7578()284 void test7578()
285 {
286     Foo7578.attrs[0] = 1;
287 }
288 
289 /**********************************************/
290 
main()291 int main()
292 {
293     test1();
294     test2();
295     test3();
296     test4();
297     test5();
298     test6();
299     test7578();
300 
301     printf("Success\n");
302     return 0;
303 }
304