Moved ProviderCollectionTest.cs from System assembly to System.Configuration.
[mono.git] / mono / mini / generics.cs
1 using System;
2 using System.Collections.Generic;
3
4 class Tests {
5
6         struct TestStruct {
7                 public int i;
8                 public int j;
9
10                 public TestStruct (int i, int j) {
11                         this.i = i;
12                         this.j = j;
13                 }
14         }
15
16         class Enumerator <T> : MyIEnumerator <T> {
17                 T MyIEnumerator<T>.Current {
18                         get {
19                                 return default(T);
20                         }
21                 }
22
23                 bool MyIEnumerator<T>.MoveNext () {
24                         return true;
25                 }
26         }
27
28         class Comparer <T> : IComparer <T> {
29                 bool IComparer<T>.Compare (T x, T y) {
30                         return true;
31                 }
32         }
33
34         static int Main ()
35         {
36                 return TestDriver.RunTests (typeof (Tests));
37         }
38
39         public static int test_1_nullable_unbox ()
40         {
41                 return Unbox<int?> (1).Value;
42         }
43
44         public static int test_1_nullable_unbox_null ()
45         {
46                 return Unbox<int?> (null).HasValue ? 0 : 1;
47         }
48
49         public static int test_1_nullable_box ()
50         {
51                 return (int) Box<int?> (1);
52         }
53
54         public static int test_1_nullable_box_null ()
55         {
56                 return Box<int?> (null) == null ? 1 : 0;
57         }
58
59         public static int test_1_isinst_nullable ()
60         {
61                 object o = 1;
62                 return (o is int?) ? 1 : 0;
63         }
64
65         public static int test_1_nullable_unbox_vtype ()
66         {
67                 return Unbox<TestStruct?> (new TestStruct (1, 2)).Value.i;
68         }
69
70         public static int test_1_nullable_unbox_null_vtype ()
71         {
72                 return Unbox<TestStruct?> (null).HasValue ? 0 : 1;
73         }
74
75         public static int test_1_nullable_box_vtype ()
76         {
77                 return ((TestStruct)(Box<TestStruct?> (new TestStruct (1, 2)))).i;
78         }
79
80         public static int test_1_nullable_box_null_vtype ()
81         {
82                 return Box<TestStruct?> (null) == null ? 1 : 0;
83         }
84
85         public static int test_1_isinst_nullable_vtype ()
86         {
87                 object o = new TestStruct (1, 2);
88                 return (o is TestStruct?) ? 1 : 0;
89         }
90
91         public static int test_0_nullable_normal_unbox ()
92         {
93                 int? i = 5;
94
95                 object o = i;
96                 // This uses unbox instead of unbox_any
97                 int? j = (int?)o;
98
99                 if (j != 5)
100                         return 1;
101
102                 return 0;
103         }
104
105         public static void stelem_any<T> (T[] arr, T elem) {
106                 arr [0] = elem;
107         }
108
109         public static T ldelem_any<T> (T[] arr) {
110                 return arr [0];
111         }
112
113         public static int test_1_ldelem_stelem_any_int () {
114                 int[] arr = new int [3];
115                 stelem_any (arr, 1);
116
117                 return ldelem_any (arr);
118         }
119
120         interface ITest
121         {
122                 void Foo<T> ();
123         }
124
125         public static int test_0_iface_call_null_bug_77442 () {
126                 ITest test = null;
127
128                 try {
129                         test.Foo<int> ();
130                 }
131                 catch (NullReferenceException) {
132                         return 0;
133                 }
134                 
135                 return 1;
136         }
137
138         public static int test_18_ldobj_stobj_generics () {
139                 GenericClass<int> t = new GenericClass <int> ();
140                 int i = 5;
141                 int j = 6;
142                 return t.ldobj_stobj (ref i, ref j) + i + j;
143         }
144
145         public static int test_5_ldelem_stelem_generics () {
146                 GenericClass<TestStruct> t = new GenericClass<TestStruct> ();
147
148                 TestStruct s = new TestStruct (5, 5);
149                 return t.ldelem_stelem (s).i;
150         }
151
152         public static int test_0_constrained_vtype_box () {
153                 GenericClass<TestStruct> t = new GenericClass<TestStruct> ();
154
155                 return t.toString (new TestStruct ()) == "Tests+TestStruct" ? 0 : 1;
156         }
157
158         public static int test_0_constrained_vtype () {
159                 GenericClass<int> t = new GenericClass<int> ();
160
161                 return t.toString (1234) == "1234" ? 0 : 1;
162         }
163
164         public static int test_0_constrained_reftype () {
165                 GenericClass<String> t = new GenericClass<String> ();
166
167                 return t.toString ("1234") == "1234" ? 0 : 1;
168         }
169
170         public static int test_0_box_brtrue_optimizations () {
171                 if (IsNull<int>(5))
172                         return 1;
173
174                 if (!IsNull<object>(null))
175                         return 1;
176
177                 return 0;
178         }
179
180         public static int test_0_generic_get_value_optimization_int () {
181                 int[] x = new int[] {100, 200};
182
183                 if (GenericClass<int>.Z (x, 0) != 100)
184                         return 2;
185
186                 if (GenericClass<int>.Z (x, 1) != 200)
187                         return 3;
188
189                 return 0;
190         }
191
192         public static int test_0_generic_get_value_optimization_vtype () {
193                 TestStruct[] arr = new TestStruct[] { new TestStruct (100, 200), new TestStruct (300, 400) };
194                 IEnumerator<TestStruct> enumerator = GenericClass<TestStruct>.Y (arr);
195                 TestStruct s;
196                 int sum = 0;
197                 while (enumerator.MoveNext ()) {
198                         s = enumerator.Current;
199                         sum += s.i + s.j;
200                 }
201
202                 if (sum != 1000)
203                         return 1;
204
205                 s = GenericClass<TestStruct>.Z (arr, 0);
206                 if (s.i != 100 || s.j != 200)
207                         return 2;
208
209                 s = GenericClass<TestStruct>.Z (arr, 1);
210                 if (s.i != 300 || s.j != 400)
211                         return 3;
212
213                 return 0;
214         }
215
216         public struct GenericStruct<T> {
217                 public T t;
218
219                 public GenericStruct (T t) {
220                         this.t = t;
221                 }
222         }
223
224         public class GenericClass<T> {
225                 public T t;
226
227                 public GenericClass (T t) {
228                         this.t = t;
229                 }
230
231                 public GenericClass () {
232                 }
233
234                 public T ldobj_stobj (ref T t1, ref T t2) {
235                         t1 = t2;
236                         T t = t1;
237
238                         return t;
239                 }
240
241                 public T ldelem_stelem (T t) {
242                         T[] arr = new T [10];
243                         arr [0] = t;
244
245                         return arr [0];
246                 }
247
248                 public String toString (T t) {
249                         return t.ToString ();
250                 }
251
252                 public static IEnumerator<T> Y (IEnumerable <T> x)
253                 {
254                         return x.GetEnumerator ();
255                 }
256
257                 public static T Z (IList<T> x, int index)
258                 {
259                         return x [index];
260                 }
261         }
262
263         public class MRO : MarshalByRefObject {
264                 public GenericStruct<int> struct_field;
265                 public GenericClass<int> class_field;
266         }
267
268         public static int test_0_ldfld_stfld_mro () {
269                 MRO m = new MRO ();
270                 GenericStruct<int> s = new GenericStruct<int> (5);
271                 // This generates stfld
272                 m.struct_field = s;
273
274                 // This generates ldflda
275                 if (m.struct_field.t != 5)
276                         return 1;
277
278                 // This generates ldfld
279                 GenericStruct<int> s2 = m.struct_field;
280                 if (s2.t != 5)
281                         return 2;
282
283                 if (m.struct_field.t != 5)
284                         return 3;
285
286                 m.class_field = new GenericClass<int> (5);
287                 if (m.class_field.t != 5)
288                         return 4;
289
290                 return 0;
291         }
292
293     public static int test_0_generic_virtual_call_on_vtype_unbox () {
294                 object o = new Object ();
295         IMyHandler h = new Handler(o);
296
297         if (h.Bar<object> () != o)
298                         return 1;
299                 else
300                         return 0;
301     }
302
303         public static int test_0_box_brtrue_opt () {
304                 Foo<int> f = new Foo<int> (5);
305
306                 f [123] = 5;
307
308                 return 0;
309         }
310
311         public static int test_0_box_brtrue_opt_regress_81102 () {
312                 if (new Foo<int>(5).ToString () == "null")
313                         return 0;
314                 else
315                         return 1;
316         }
317
318         struct S {
319                 public int i;
320         }
321
322         public static int test_0_ldloca_initobj_opt () {
323                 if (new Foo<S> (new S ()).get_default ().i != 0)
324                         return 1;
325                 if (new Foo<object> (null).get_default () != null)
326                         return 2;
327                 return 0;
328         }
329
330         public static int test_0_variance_reflection () {
331                 // covariance on IEnumerator
332                 if (!typeof (MyIEnumerator<object>).IsAssignableFrom (typeof (MyIEnumerator<string>)))
333                         return 1;
334                 // covariance on IEnumerator and covariance on arrays
335                 if (!typeof (MyIEnumerator<object>[]).IsAssignableFrom (typeof (MyIEnumerator<string>[])))
336                         return 2;
337                 // covariance and implemented interfaces
338                 if (!typeof (MyIEnumerator<object>).IsAssignableFrom (typeof (Enumerator<string>)))
339                         return 3;
340
341                 // contravariance on IComparer
342                 if (!typeof (IComparer<string>).IsAssignableFrom (typeof (IComparer<object>)))
343                         return 4;
344                 // contravariance on IComparer, contravariance on arrays
345                 if (!typeof (IComparer<string>[]).IsAssignableFrom (typeof (IComparer<object>[])))
346                         return 5;
347                 // contravariance and interface inheritance
348                 if (!typeof (IComparer<string>[]).IsAssignableFrom (typeof (IKeyComparer<object>[])))
349                         return 6;
350                 return 0;
351         }
352
353         public static int test_0_ldvirtftn_generic_method () {
354                 new Tests ().ldvirtftn<string> ();              
355
356                 return the_type == typeof (string) ? 0 : 1;
357         }
358
359         public static Type the_type;
360
361         public void ldvirtftn<T> () {
362                 Foo <T> binding = new Foo <T> (default (T));
363
364                 binding.GenericEvent += event_handler;
365                 binding.fire ();
366         }
367
368         public virtual void event_handler<T> (Foo<T> sender) {
369                 the_type = typeof (T);
370         }
371
372         public class Foo<T1>
373         {
374                 public Foo(T1 t1)
375                 {
376                         m_t1 = t1;
377                 }
378                 
379                 public override string ToString()
380                 {
381                         return Bar(m_t1 == null ? "null" : "null");
382                 }
383
384                 public String Bar (String s) {
385                         return s;
386                 }
387
388                 public int this [T1 key] {
389                         set {
390                                 if (key == null)
391                                         throw new ArgumentNullException ("key");
392                         }
393                 }
394
395                 public T1 get_default () {
396                         return default (T1);
397                 }
398                 
399                 readonly T1 m_t1;
400
401                 public delegate void GenericEventHandler (Foo<T1> sender);
402
403                 public event GenericEventHandler GenericEvent;
404
405                 public void fire () {
406                         GenericEvent (this);
407                 }
408
409         }
410
411         public interface IMyHandler {
412                 object Bar<T>();
413         }
414
415         struct Handler : IMyHandler {
416                 object o;
417
418                 public Handler(object o) {
419                         this.o = o;
420                 }
421
422                 public object Bar<T>() {
423                         return o;
424                 }
425         }
426
427         static bool IsNull<T> (T t)
428         {
429                 if (t == null)
430                         return true;
431                 else
432                         return false;
433         }
434
435         static object Box<T> (T t)
436         {
437                 return t;
438         }
439         
440         static T Unbox <T> (object o) {
441                 return (T) o;
442         }
443 }