Updated.
[mono.git] / mcs / tests / dtest-006.cs
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Reflection;
5
6 // Dynamic binary operator, unary operators and convert tests
7
8 public struct InverseLogicalOperator
9 {
10         bool value;
11         public InverseLogicalOperator (bool value)
12         {
13                 this.value = value;
14         }
15
16         public static bool operator true (InverseLogicalOperator u)
17         {
18                 return u.value;
19         }
20
21         public static bool operator false (InverseLogicalOperator u)
22         {
23                 return u.value;
24         }
25 }
26
27 public struct MyType
28 {
29         int value;
30         
31         public MyType (int value) : this ()
32         {
33                 this.value = value;
34         }
35         
36         public short ShortProp { get; set; }
37         
38         public override int GetHashCode ()
39         {
40                 throw new NotImplementedException ();
41         }
42
43         public static bool operator true (MyType a)
44         {
45                 return a.value != 1;
46         }
47
48         public static bool operator false (MyType a)
49         {
50                 return a.value == 0;
51         }
52
53         public static MyType operator + (MyType a, MyType b)
54         {
55                 return new MyType (a.value + b.value);
56         }
57
58         public static MyType operator - (MyType a, MyType b)
59         {
60                 return new MyType (a.value - b.value);
61         }
62
63         public static MyType operator / (MyType a, MyType b)
64         {
65                 return new MyType (a.value / b.value);
66         }
67
68         public static MyType operator * (MyType a, MyType b)
69         {
70                 return new MyType (a.value * b.value);
71         }
72
73         public static MyType operator % (MyType a, MyType b)
74         {
75                 return new MyType (a.value % b.value);
76         }
77
78         public static MyType operator &(MyType a, MyType b)
79         {
80                 return new MyType (a.value & b.value);
81         }
82
83         public static MyType operator | (MyType a, MyType b)
84         {
85                 return new MyType (a.value | b.value);
86         }
87
88         public static MyType operator ^ (MyType a, MyType b)
89         {
90                 return new MyType (a.value ^ b.value);
91         }
92
93         public static bool operator == (MyType a, MyType b)
94         {
95                 return a.value == b.value;
96         }
97
98         public static bool operator != (MyType a, MyType b)
99         {
100                 return a.value != b.value;
101         }
102         
103         public static bool operator > (MyType a, MyType b)
104         {
105                 return a.value > b.value;
106         }
107
108         public static bool operator < (MyType a, MyType b)
109         {
110                 return a.value < b.value;
111         }
112
113         public static bool operator >= (MyType a, MyType b)
114         {
115                 return a.value >= b.value;
116         }
117         
118         public static bool operator <= (MyType a, MyType b)
119         {
120                 return a.value <= b.value;
121         }
122
123         public static bool operator ! (MyType a)
124         {
125                 return a.value > 0;
126         }
127
128         public static int operator ~ (MyType a)
129         {
130                 return ~a.value;
131         }
132
133         public static MyType operator ++ (MyType a)
134         {
135                 return new MyType (a.value * 2);
136         }
137
138         public static MyType operator -- (MyType a)
139         {
140                 return new MyType (a.value / 2);
141         }
142
143         public static int operator >> (MyType a, int b)
144         {
145                 return a.value >> b;
146         }
147         
148         public static int operator << (MyType a, int b)
149         {
150                 return a.value << b;
151         }
152         
153         public static MyType operator - (MyType a)
154         {
155                 return new MyType (-a.value);
156         }
157         
158         public static MyType operator + (MyType a)
159         {
160                 return new MyType (334455); // magic number
161         }
162
163         public override string ToString ()
164         {
165                 return value.ToString ();
166         }
167 }
168
169
170 class MyTypeExplicit
171 {
172         int value;
173         
174         public MyTypeExplicit (int value)
175         {
176                 this.value = value;
177         }
178         
179         public static explicit operator int (MyTypeExplicit m)
180         {
181                 return m.value;
182         }
183 }
184
185 struct MyTypeImplicitOnly
186 {
187         short b;
188
189         public MyTypeImplicitOnly (short b)
190         {
191                 this.b = b;
192         }
193
194         public static implicit operator short (MyTypeImplicitOnly m)
195         {
196                 return m.b;
197         }
198
199         public static implicit operator bool (MyTypeImplicitOnly m)
200         {
201                 return m.b != 0;
202         }
203 }
204
205 enum MyEnum : byte
206 {
207         Value_1 = 1,
208         Value_2 = 2
209 }
210
211 enum MyEnumUlong : ulong
212 {
213         Value_1 = 1,
214         Value_2 = 2
215 }
216
217
218 class Tester
219 {
220         delegate void EmptyDelegate ();
221         delegate int IntDelegate ();
222
223         static void Assert<T> (T expected, T value, string name)
224         {
225                 if (!EqualityComparer<T>.Default.Equals (expected, value)) {
226                         name += ": ";
227                         throw new ApplicationException (name + expected + " != " + value);
228                 }
229         }
230
231         static void AssertChecked<T> (Func<T> expected, T value, string name)
232         {
233                 try {
234                         Assert (expected (), value, name);
235                         throw new ApplicationException (name + ": OverflowException expected");
236                 } catch (OverflowException) {
237                         // passed
238                 }
239         }
240
241         static void AssertChecked (Action expected, string name)
242         {
243                 try {
244                         expected ();
245                         throw new ApplicationException (name + ": OverflowException expected");
246                 } catch (OverflowException) {
247                         // passed
248                 }
249         }
250
251 #pragma warning disable 169
252
253         void AddTest ()
254         {
255                 dynamic d = 5;
256
257                 int v = 2;
258                 Assert (d + v, 7, "#1");
259                 double v2 = 0.5;
260                 Assert (d + v2, 5.5, "#1a");
261
262                 d = new MyType (5);
263                 MyType v3 = new MyType (30);
264                 Assert (d + v3, new MyType (35), "#3");
265                 dynamic d3 = new MyType (-7);
266                 Assert<MyType> (d3 + new MyType (6), new MyType (-1), "#3a");
267
268                 d3 = new MyTypeImplicitOnly (6);
269                 Assert (d3 + new MyTypeImplicitOnly (11), 17, "#3b");
270
271                 d = new MyTypeImplicitOnly (5);
272                 decimal v4 = 4m;
273                 Assert (d + v4, 9m, "#4");
274         }
275
276         void AddNullableTest ()
277         {
278                 dynamic d = 5;
279
280                 int? v2 = null;
281                 Assert<int?> (d + v2, null, "#1");
282                 Assert<int?> (d + null, null, "#1a");
283                 Assert<int?> (null + d, null, "#1b");
284
285                 v2 = -2;
286                 Assert (d + v2, 3, "#2");
287                 dynamic d2 = (int?) -2;
288                 Assert (d2 + 1, -1, "#2a");
289
290                 d = new MyType (5);
291                 MyType? v3 = new MyType (30);
292                 Assert (d + v3, new MyType (35), "#3");
293                 dynamic d3 = new MyType? (new MyType (-7));
294                 Assert (d3 + new MyType (6), new MyType (-1), "#3a");
295                 Assert<MyType?> (d3 + null, null, "#3b");
296
297                 d = new MyTypeImplicitOnly (5);
298                 decimal? v4 = 4m;
299                 Assert (d + v4, 9m, "#4");
300                 v4 = null;
301                 Assert<decimal?> (d + v4, null, "#4a");
302         }
303         
304         void AddEnumTest ()
305         {
306                 dynamic d = MyEnum.Value_1;
307
308                 // CSC: Invalid System.InvalidOperationException
309                 Assert (d + null, null, "#1");
310
311                 Assert (d + 1, MyEnum.Value_2, "#2");
312
313                 dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_1;
314                 Assert (d2 + (byte) 1, MyEnumUlong.Value_2, "#3");
315                 Assert<MyEnumUlong?> (d2 + (object) null, null, "#3a");
316         }
317         
318         void AddCheckedTest ()
319         {
320                 checked {
321                         dynamic d = 5;
322
323                         int v = int.MaxValue;
324                         AssertChecked (() => d + v, 7, "#1");
325
326                         int? v2 = v;
327                         AssertChecked (() => d + v2, null, "#2");
328
329                         d = new MyType (3);
330                         MyType v3 = new MyType (int.MaxValue);
331                         Assert (new MyType (-2147483646), d + v3, "#3");
332                 }
333         }
334         
335         void AddStringTest ()
336         {
337                 dynamic d = "foo";
338                 string v = "->";
339                 Assert (d + v, "foo->", "#1");
340                 Assert (d + 1, "foo1", "#1a");
341                 Assert (d + null, "foo", "#1b");
342                 Assert (d + 1 + v, "foo1->", "#1a");
343
344                 uint? v2 = 4;
345                 Assert (d + v2, "foo4", "#2");
346         }
347
348         void AddAssignTest ()
349         {
350                 dynamic d = 5;
351
352                 int v = 2;
353                 d += v;
354                 Assert (d, 7, "#1");
355
356                 d = 5.0;
357                 double v2 = 0.5;
358                 d += v2;
359                 Assert (d, 5.5, "#1a");
360                 d += v;
361                 Assert (d, 7.5, "#1b");
362
363                 dynamic d3 = new MyType (-7);
364                 d3 += new MyType (6);
365                 Assert<MyType> (d3, new MyType (-1), "#3");
366
367                 d = 5m;
368                 decimal v4 = 4m;
369                 d += v4;
370                 Assert (d, 9m, "#4");
371         }
372
373         void AddAssignNullableTest ()
374         {
375                 dynamic d = (int?) 5;
376
377                 // FEATURE
378                 // For now it's impossible to use nullable compound assignment
379                 // due to the way how DLR works. GetType () on nullable object returns
380                 // underlying type and not nullable type, that means that
381                 // C# binder is initialized with wrong operand type and any operation
382                 // fails to resolve
383 /*
384                 long? v2 = null;
385                 d += v2;
386                 Assert<int?> (d, null, "#1");
387                 d += null;
388                 Assert<int?> (d, null, "#1a");
389
390                 long? l = (long?) 3;
391                 d = l;
392                 v2 = -2;
393                 d += v2;
394                 Assert (d, 3, "#2");
395                 d = (int?) -2;
396                 d += 1;
397                 Assert (d, -1, "#2a");
398
399                 MyType? v3 = new MyType (30);
400                 d += v3;
401                 Assert (d, new MyType (35), "#3");
402                 dynamic d3 = new MyType? (new MyType (-7));
403                 Assert (d3 + new MyType (6), new MyType (-1), "#3a");
404                 Assert<MyType?> (d3 + null, null, "#3b");
405
406                 decimal? v4 = 4m;
407                 d = 2m;
408                 d += v4;
409                 Assert (d, 9m, "#4");
410                 d += null;
411                 Assert<decimal?> (d, null, "#4a");
412  */
413         }
414
415         void AddAssignEnumTest ()
416         {
417                 dynamic d = MyEnum.Value_1;
418
419                 d = MyEnum.Value_1;
420                 d += 1;
421                 Assert (d, MyEnum.Value_2, "#2");
422
423                 dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_1;
424                 d2 += (byte) 1;
425                 Assert (d2, MyEnumUlong.Value_2, "#3");
426         }
427
428         void AddAssignCheckedTest ()
429         {
430                 checked {
431                         dynamic d = 5;
432
433                         int v = int.MaxValue;
434                         AssertChecked (() => { d += v; Assert (d, 0, "#1-"); }, "#1");
435
436                         d = new MyType (5);
437                         MyType v3 = new MyType (int.MaxValue);
438                         d += v3;
439                         Assert (d, new MyType (-2147483644), "#3-");
440                 }
441         }
442
443         void AddAssignStringTest ()
444         {
445                 dynamic d = "foo";
446                 string v = "->";
447                 d += v;
448                 Assert (d, "foo->", "#1");
449
450                 d = "foo";
451                 d += 1;
452                 Assert (d, "foo1", "#1a");
453
454                 d += null;
455                 Assert (d, "foo1", "#1b");
456
457                 uint? v2 = 4;
458                 d = "foo";
459                 d += v2;
460                 Assert (d, "foo4", "#2");
461         }
462
463         // TODO:
464         void AddAssignmentEvent ()
465         {
466                 // IMPLEMENT
467         }
468
469         void AndTest ()
470         {
471                 dynamic d = true;
472
473                 var v = false;
474                 Assert (d & v, false, "#1");
475                 Assert (d & true, true, "#1a");
476
477                 d = 42;
478                 var v2 = 62;
479                 Assert (d & v2, 42, "#2");
480                 Assert (d & 0, 0, "#2a");
481
482                 d = new MyType (10);
483                 MyType v3 = new MyType (30);
484                 Assert (d & v3, new MyType (10), "#3");
485                 dynamic d3 = new MyType (-7);
486                 Assert<MyType> (d3 & new MyType (6), new MyType (0), "#3a");
487
488                 d3 = new MyTypeImplicitOnly (6);
489                 Assert (d3 & 11, 2, "#3b");
490         }
491
492         void AndTestEnum ()
493         {
494                 dynamic d = MyEnum.Value_1;
495
496                 Assert<MyEnum?> (d & null, null, "#1");
497
498                 Assert (d & d, MyEnum.Value_1, "#2");
499
500                 dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_1;
501                 Assert<MyEnumUlong> (d2 & MyEnumUlong.Value_2, 0, "#3");
502         }
503
504         void AndTestNullable ()
505         {
506                 dynamic d = 5;
507
508                 int? v2 = null;
509                 Assert<int?> (d & v2, null, "#1");
510                 Assert<int?> (d & null, null, "#1a");
511                 Assert<int?> (null & d, null, "#1b");
512
513                 v2 = -2;
514                 Assert (d & v2, 4, "#2");
515                 dynamic d2 = (int?) -2;
516                 Assert (d2 & 1, 0, "#2a");
517
518                 d = new MyType (22);
519                 MyType? v3 = new MyType (30);
520                 Assert (d & v3, new MyType (22), "#3");
521                 dynamic d3 = new MyType? (new MyType (-7));
522                 Assert (d3 & new MyType (6), new MyType (0), "#3a");
523                 Assert<MyType?> (d3 + null, null, "#3b");
524         }
525
526         void AndAssignedTest ()
527         {
528                 dynamic d = true;
529
530                 var v = false;
531                 d &= v;
532                 Assert (d, false, "#1");
533                 d = true;
534                 d &= true;
535                 Assert (d, true, "#1a");
536
537                 d = 42;
538                 var v2 = 62;
539                 d &= v2;
540                 Assert (d, 42, "#2");
541
542                 MyType v3 = new MyType (30);
543                 dynamic d3 = new MyType (-7);
544                 d3 &= new MyType (6);
545                 Assert<MyType> (d3, new MyType (0), "#3");
546         }
547
548         void AndAssignedTestEnum ()
549         {
550                 dynamic d = MyEnum.Value_1;
551                 d &= MyEnum.Value_2;
552                 Assert<MyEnum>(d, 0, "#1");
553
554                 d = MyEnum.Value_2;
555                 d &= d;
556                 Assert (d, MyEnum.Value_2, "#2");
557
558                 dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_1;
559                 Assert<MyEnumUlong> (d2 & MyEnumUlong.Value_2, 0, "#3");
560         }
561
562         void AndAlsoTest ()
563         {
564                 dynamic d = true;
565
566                 var v = false;
567                 Assert<bool> (d && v, false, "#1");
568                 
569                 Assert (d && true, true, "#1a");
570
571                 d = true;
572                 Assert (d && d, true, "#2");
573
574                 dynamic d3 = new MyType (-7);
575                 Assert<MyType> (d3 && new MyType (6), new MyType (0), "#3");
576         }
577
578         void DivideTest ()
579         {
580                 dynamic d = 5;
581
582                 int v = 2;
583                 Assert (d / v, 2, "#1");
584
585                 d = new MyType (5);
586                 MyType v3 = new MyType (30);
587                 Assert (d / v3, new MyType (0), "#3");
588                 dynamic d3 = new MyType (-7);
589                 Assert<MyType> (d3 + new MyType (6), new MyType (-1), "#3a");
590
591                 d = new MyTypeImplicitOnly (6);
592                 decimal v4 = 4m;
593                 Assert (d / v4, 1.5m, "#4");
594         }
595
596         void DivideNullableTest ()
597         {
598                 dynamic d = 5;
599
600                 double? v2 = null;
601                 Assert<double?> (d / v2, null, "#1");
602                 Assert<double?> (d / null, null, "#1a");
603                 Assert<double?> (null / d, null, "#1b");
604
605                 v2 = -2;
606                 Assert (d / v2, -2.5, "#2");
607                 dynamic d2 = (int?) -2;
608                 Assert (d2 / 1, -2, "#2a");
609
610                 d = new MyType (5);
611                 MyType? v3 = new MyType (30);
612                 Assert (d / v3, new MyType (0), "#3");
613                 dynamic d3 = new MyType? (new MyType (-7));
614                 Assert (d3 / new MyType (6), new MyType (-1), "#3a");
615                 Assert<MyType?> (d3 + null, null, "#3b");
616
617                 d = new MyTypeImplicitOnly (5);
618                 decimal? v4 = 4m;
619                 Assert (d / v4, 1.25m, "#4");
620                 v4 = null;
621                 Assert<decimal?> (d / v4, null, "#4a");
622         }
623
624         void DivideCheckedTest ()
625         {
626                 checked {
627                         // TODO:
628                 }
629         }
630
631         void DivideAssignTest ()
632         {
633                 dynamic d = 5;
634
635                 int v = 2;
636                 d /= v;
637                 Assert (d, 2, "#1");
638
639                 d = 5.0;
640                 double v2 = 0.5;
641                 d /= v2;
642                 Assert (d, 10, "#1a");
643                 d /= v;
644                 Assert (d, 5, "#1b");
645
646                 dynamic d3 = new MyType (-7);
647                 d3 /= new MyType (6);
648                 Assert<MyType> (d3, new MyType (-1), "#3");
649
650                 d = 5m;
651                 decimal v4 = 4m;
652                 d /= v4;
653                 Assert (d, 1.25m, "#4");
654         }
655
656         void DivideAssignCheckedTest ()
657         {
658                 checked {
659                         // TODO:
660                 }
661         }
662
663         void ConvertImplicitTest ()
664         {
665                 dynamic d = 3;
666                 decimal v1 = d;
667                 Assert (3m, v1, "#1");
668
669                 d = new MyTypeImplicitOnly (5);
670                 int v2 = d;
671                 Assert (5, v2, "#2");
672
673                 d = (byte) 4;
674                 int v3 = d;
675                 Assert (4, v3, "#3");
676
677                 int[] v4 = new int[] { d };
678                 Assert (4, v4[0], "#4");
679
680                 d = true;
681                 var v5 = new [] { d, 1 };
682                 Assert (true, v5[0], "#5");
683                 Assert (1, v5[1], "#5a");
684
685                 d = "aa";
686                 bool b = false;
687                 var r = b ? d : "ss";
688                 Assert ("ss", r, "#6");
689         }
690
691         int ConvertImplicitReturnTest ()
692         {
693                 dynamic d = (byte) 3;
694                 return d;
695         }
696
697         IEnumerable<string> ConvertImplicitReturnTest_2 ()
698         {
699                 dynamic d = "aaa";
700                 yield return d;
701         }
702
703         void ConvertExplicitTest ()
704         {
705                 dynamic d = 300;
706                 Assert (44, (byte) d, "#1");
707                 Assert<byte?> (44, (byte?) d, "#1a");
708
709                 d = 3m;
710                 Assert (3, d, "#2");
711
712                 d = new MyTypeImplicitOnly (5);
713                 Assert (5, (int) d, "#3");
714
715                 d = new MyTypeExplicit (-2);
716                 Assert (-2, (int) d, "#4");
717
718                 d = null;
719                 Assert (null, (object) d, "#5");
720         }
721
722         void ConvertExplicitCheckedTest ()
723         {
724                 checked {
725                         dynamic d = 300;
726                         AssertChecked (() => (byte) d, 7, "#1");
727
728                         d = ulong.MaxValue;
729                         AssertChecked<uint?> (() => (uint?) d, 2, "#2");
730                 }
731         }
732         
733         void ConvertArray ()
734         {
735                 dynamic idx = (uint) 1;
736                 var arr = new int [5];
737                 arr [idx] = 2;
738                 Assert (2, arr [idx], "#1");
739         }
740
741         void EqualTest ()
742         {
743                 dynamic d = 5;
744
745                 int v = 2;
746                 Assert (d == v, false, "#1");
747                 double v2 = 5;
748                 Assert (d == v2, true, "#1a");
749
750                 d = true;
751                 Assert (d == false, false, "#2");
752                 bool b2 = true;
753                 Assert (d == b2, true, "#2a");
754
755                 d = new MyType (30);
756                 MyType v3 = new MyType (30);
757                 Assert (d == v3, true, "#3");
758                 dynamic d3 = new MyTypeImplicitOnly (-7);
759                 Assert (d3 == 11, false, "#3b");
760                 
761                 d = 2m;
762                 decimal v4 = 4m;
763                 Assert (d == v4, false, "#4");
764                 Assert (d == 2m, true, "#4a");
765                 
766                 d = null;
767                 Assert (d == null, true, "#5");
768         }
769
770         void EqualNullableTest ()
771         {
772                 dynamic d = 5;
773
774                 int? v2 = null;
775                 Assert (d == v2, false, "#1");
776                 Assert (d == null, false, "#1a");
777                 Assert (null == d, false, "#1b");
778
779                 v2 = -2;
780                 Assert (d == v2, false, "#2");
781                 dynamic d2 = (int?) -2;
782                 Assert (d2 == 1, false, "#2a");
783                 d2 = (uint?) 44;
784                 Assert (d2 == 44, true, "#2b");
785
786                 d = new MyType (30);
787                 MyType? v3 = new MyType (30);
788                 Assert (d == v3, true, "#3");
789                 dynamic d3 = new MyType? (new MyType (-7));
790                 Assert (d3 == new MyType (6), false, "#3a");
791                 Assert (d3 == null, false, "#3b");
792                 
793                 d = 4.1m;
794                 decimal? v4 = 4m;
795                 Assert (d == v4, false, "#4");
796                 v4 = null;
797                 Assert (d == v4, false, "#4a");
798
799                 d = (bool?) true;
800                 Assert (d == true, true, "#5");
801                 Assert (d == null, false, "#5a");
802                 Assert (d == false, false, "#5b");
803         }
804
805         void EqualEnumTest ()
806         {
807                 dynamic d = MyEnum.Value_1;
808
809                 Assert (d == null, false, "#1");
810
811                 Assert (d == MyEnum.Value_1, true, "#2");
812                 Assert (d == 0, false, "#2a");
813
814                 dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_2;
815                 Assert (d2 == MyEnumUlong.Value_2, true, "#3");
816                 Assert (d2 == null, false, "#3a");
817         }
818
819         void EqualStringTest ()
820         {
821                 dynamic d = "text";
822
823                 Assert (d == "te", false, "#1");
824                 Assert (d == "text", true, "#1a");
825                 Assert (d == null, false, "#1b");
826         }
827
828         void EqualDelegateTest ()
829         {
830                 dynamic d = this;
831
832 //              Assert (d == delegate { }, true, "#1");
833
834                 EmptyDelegate b = EqualDelegateTest;
835                 d = b;
836
837                 //Assert (d == EqualDelegateTest, true, "#2");
838         
839 /*
840
841         void EqualTestDelegate_2 ()
842         {
843                 EmptyDelegate ed = delegate () {};
844
845                 Expression<Func<EmptyDelegate, EmptyDelegate, bool>> e2 = (a, b) => a == b;
846                 AssertNodeType (e2, ExpressionType.Equal);
847                 Assert (false, e2.Compile ().Invoke (delegate () {}, null));
848                 Assert (false, e2.Compile ().Invoke (delegate () {}, delegate {}));
849                 Assert (false, e2.Compile ().Invoke (ed, delegate {}));
850                 Assert (true, e2.Compile ().Invoke (ed, ed));
851 */
852         }
853
854         void ExclusiveOrTest ()
855         {
856                 dynamic d = true;
857
858                 var v = false;
859                 Assert (d ^ v, true, "#1");
860                 Assert (d ^ true, false, "#1a");
861
862                 d = 42;
863                 var v2 = 62;
864                 Assert (d ^ v2, 20, "#2");
865                 Assert (d ^ 0, 42, "#2a");
866
867                 d = new MyType (42);
868                 MyType v3 = new MyType (30);
869                 Assert (d ^ v3, new MyType (52), "#3");
870                 dynamic d3 = new MyType (-7);
871                 Assert<MyType> (d3 ^ new MyType (6), new MyType (-1), "#3a");
872
873                 d3 = new MyTypeImplicitOnly (-7);
874                 Assert (d3 ^ 11, -14, "#3b");
875         }
876
877         void ExclusiveOrNullableTest ()
878         {
879                 dynamic d = 5;
880
881                 int? v2 = null;
882                 Assert<int?> (d ^ v2, null, "#1");
883                 Assert<int?> (d ^ null, null, "#1a");
884                 Assert<int?> (null ^ d, null, "#1b");
885
886                 v2 = -2;
887                 Assert (d ^ v2, -5, "#2");
888                 dynamic d2 = (int?) -2;
889                 Assert (d2 ^ 1, -1, "#2a");
890
891                 d = new MyType (5);
892                 MyType? v3 = new MyType (30);
893                 Assert (d ^ v3, new MyType (27), "#3");
894                 dynamic d3 = new MyType? (new MyType (-7));
895                 Assert (d3 ^ new MyType (6), new MyType (-1), "#3a");
896                 Assert<MyType?> (d3 ^ null, null, "#3b");
897         }
898
899         void ExclusiveOrTestEnum ()
900         {
901                 dynamic d = MyEnum.Value_1;
902
903                 Assert<MyEnum?> (d ^ null, null, "#1");
904
905                 Assert<MyEnum> (d ^ d, 0, "#2");
906
907                 dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_1;
908                 Assert<MyEnumUlong> (d2 ^ MyEnumUlong.Value_2, (MyEnumUlong) 3, "#3");
909         }
910
911         void ExclusiveOrAssignedTest ()
912         {
913                 dynamic d = true;
914
915                 var v = false;
916                 d ^= v;
917                 Assert (d, true, "#1");
918                 d = true;
919                 d ^= true;
920                 Assert (d, false, "#1a");
921
922                 d = 42;
923                 var v2 = 62;
924                 d ^= v2;
925                 Assert (d, 20, "#2");
926
927                 MyType v3 = new MyType (30);
928                 dynamic d3 = new MyType (-7);
929                 d3 ^= new MyType (6);
930                 Assert (d3, new MyType (-1), "#3");
931         }
932
933         void ExclusiveOrAssignedTestEnum ()
934         {
935                 dynamic d = MyEnum.Value_1;
936                 d ^= MyEnum.Value_2;
937                 Assert<MyEnum>(d, (MyEnum) 3, "#1");
938
939                 d = MyEnum.Value_2;
940                 d ^= d;
941                 Assert<MyEnum> (d, 0, "#2");
942
943                 dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_1;
944                 Assert (d2 ^ MyEnumUlong.Value_2, (MyEnumUlong)3, "#3");
945         }
946
947         void GreaterThanTest ()
948         {
949                 dynamic d = 5;
950
951                 int v = 2;
952                 Assert (d > v, true, "#1");
953                 double v2 = 5;
954                 Assert (d > v2, false, "#1a");
955
956                 d = 4.6;
957                 Assert (d > 4.59, true, "#2");
958                 var b2 = 4.6;
959                 Assert (d > b2, false, "#2a");
960
961                 d = new MyType (30);
962                 MyType v3 = new MyType (30);
963                 Assert (d > v3, false, "#3");
964                 dynamic d3 = new MyType (-7);
965                 Assert (d3 > new MyType (6), false, "#3a");
966
967                 d3 = new MyTypeImplicitOnly (-7);
968                 Assert (d3 > 11, false, "#3b");
969
970                 d = 2m;
971                 decimal v4 = 4m;
972                 Assert (d > v4, false, "#4");
973                 Assert (d > 2m, false, "#4a");
974         }
975
976         void GreaterThanNullableTest ()
977         {
978                 dynamic d = 5;
979
980                 int? v2 = null;
981                 Assert (d > v2, false, "#1");
982                 Assert (d > null, false, "#1a");
983                 Assert (null > d, false, "#1b");
984
985                 v2 = -2;
986                 Assert (d > v2, true, "#2");
987                 dynamic d2 = (int?) -2;
988                 Assert (d2 > 1, false, "#2a");
989                 d2 = (uint?) 44;
990                 Assert (d2 > 44, false, "#2b");
991
992                 d = new MyType (30);
993                 MyType? v3 = new MyType (30);
994                 Assert (d > v3, false, "#3");
995                 dynamic d3 = new MyType? (new MyType (-7));
996                 Assert (d3 > new MyType (6), false, "#3a");
997                 Assert (d3 > null, false, "#3b");
998
999                 d = 4.1m;
1000                 decimal? v4 = 4m;
1001                 Assert (d > v4, true, "#4");
1002                 v4 = null;
1003                 Assert (d > v4, false, "#4a");
1004         }
1005
1006         void GreaterThanEnumTest ()
1007         {
1008                 dynamic d = MyEnum.Value_1;
1009
1010                 Assert (d > null, false, "#1");
1011
1012                 Assert (d > MyEnum.Value_1, false, "#2");
1013                 Assert (d > 0, true, "#2a");
1014
1015                 dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_2;
1016                 Assert (d2 > MyEnumUlong.Value_2, false, "#3");
1017                 Assert (d2 > null, false, "#3a");
1018         }
1019
1020         void GreaterThanEqualTest ()
1021         {
1022                 dynamic d = 5;
1023
1024                 int v = 2;
1025                 Assert (d >= v, true, "#1");
1026                 double v2 = 5;
1027                 Assert (d >= v2, true, "#1a");
1028
1029                 d = 4.6;
1030                 Assert (d >= 4.59, true, "#2");
1031                 var b2 = 4.6;
1032                 Assert (d >= b2, true, "#2a");
1033
1034                 d = new MyType (30);
1035                 MyType v3 = new MyType (30);
1036                 Assert (d >= v3, true, "#3");
1037                 dynamic d3 = new MyType (-7);
1038                 Assert (d3 >= new MyType (6), false, "#3a");
1039
1040                 d3 = new MyTypeImplicitOnly (-7);
1041                 Assert (d3 >= 11, false, "#3b");
1042
1043                 d = 2m;
1044                 decimal v4 = 4m;
1045                 Assert (d >= v4, false, "#4");
1046                 Assert (d >= 2m, true, "#4a");
1047         }
1048
1049         void GreaterThanEqualNullableTest ()
1050         {
1051                 dynamic d = 5;
1052
1053                 int? v2 = null;
1054                 Assert (d >= v2, false, "#1");
1055                 Assert (d >= null, false, "#1a");
1056                 Assert (null >= d, false, "#1b");
1057
1058                 v2 = -2;
1059                 Assert (d >= v2, true, "#2");
1060                 dynamic d2 = (int?) -2;
1061                 Assert (d2 >= 1, false, "#2a");
1062                 d2 = (uint?) 44;
1063                 Assert (d2 >= 44, true, "#2b");
1064
1065                 d = new MyType (30);
1066                 MyType? v3 = new MyType (30);
1067                 Assert (d >= v3, true, "#3");
1068                 dynamic d3 = new MyType? (new MyType (-7));
1069                 Assert (d3 >= new MyType (6), false, "#3a");
1070                 Assert (d3 >= null, false, "#3b");
1071
1072                 d = 4.1m;
1073                 decimal? v4 = 4m;
1074                 Assert (d >= v4, true, "#4");
1075                 v4 = null;
1076                 Assert (d >= v4, false, "#4a");
1077         }
1078
1079         void GreaterThanEqualEnumTest ()
1080         {
1081                 dynamic d = MyEnum.Value_1;
1082
1083                 Assert (d >= null, false, "#1");
1084
1085                 Assert (d >= MyEnum.Value_1, true, "#2");
1086                 Assert (d >= 0, true, "#2a");
1087
1088                 dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_2;
1089                 Assert (d2 >= MyEnumUlong.Value_2, true, "#3");
1090                 Assert (d2 >= null, false, "#3a");
1091         }
1092
1093         void LeftShiftTest ()
1094         {
1095                 dynamic d = (ulong) 0x7F000;
1096
1097                 int v = 2;
1098                 Assert<ulong> (d << v, 0x1FC000, "#1");
1099                 Assert<ulong> (d << 1, 0xFE000, "#1a");
1100                 short s = 2;
1101                 Assert<ulong> (d << s, 0x1FC000, "#1b");
1102
1103                 d = 0x7F000;
1104                 MyTypeImplicitOnly v3 = new MyTypeImplicitOnly (3);
1105                 Assert (d << v3, 0x3F8000, "#3");
1106                 dynamic d3 = new MyType (-7);
1107                 Assert (d3 << new MyTypeImplicitOnly (6), -448, "#3a");
1108                 Assert (d3 << 11, -14336, "#3b");
1109         }
1110
1111         void LeftShiftNullableTest ()
1112         {
1113                 dynamic d = 5;
1114
1115                 int? v2 = null;
1116                 Assert<int?> (d << v2, null, "#1");
1117                 d = 5;
1118                 Assert<int?> (d << null, null, "#1a");
1119                 d = 5;
1120                 Assert<int?> (null << d, null, "#1b");
1121
1122                 v2 = -2;
1123                 Assert (d << v2, 0x40000000, "#2");
1124                 dynamic d2 = (int?) -2;
1125                 Assert (d2 << 1, -4, "#2a");
1126         }
1127
1128         void LeftShiftAssignTest ()
1129         {
1130                 dynamic d = 0x7F000;
1131
1132                 int v = 2;
1133                 d <<= v;
1134                 Assert (d, 0x1FC000, "#1");
1135                 d <<= 1;
1136                 Assert (d, 0x3F8000, "#1a");
1137                 sbyte s = 2;
1138                 d <<= s;
1139                 Assert (d, 0xFE0000, "#1b");
1140         }
1141
1142         void LeftShiftAssignNullableTest ()
1143         {
1144                 dynamic d = 5;
1145
1146                 var v2 = -2;
1147                 d <<= v2;
1148                 Assert (d, 0x40000000, "#2");
1149                 dynamic d2 = (int?) -2;
1150                 d2 <<= 1;
1151                 Assert (d2, -4, "#2a");
1152         }
1153
1154         void LessThanTest ()
1155         {
1156                 dynamic d = 5;
1157
1158                 int v = 2;
1159                 Assert (d < v, false, "#1");
1160                 double v2 = 5;
1161                 Assert (d < v2, false, "#1a");
1162
1163                 d = 4.6;
1164                 Assert (d < 4.59, false, "#2");
1165                 var b2 = 4.6;
1166                 Assert (d < b2, false, "#2a");
1167
1168                 d = new MyType (30);
1169                 MyType v3 = new MyType (30);
1170                 Assert (d < v3, false, "#3");
1171                 dynamic d3 = new MyType (-7);
1172                 Assert (d3 < new MyType (6), true, "#3a");
1173
1174                 d3 = new MyTypeImplicitOnly (-7);
1175                 Assert (d3 < 11, true, "#3b");
1176
1177                 d = 2m;
1178                 decimal v4 = 4m;
1179                 Assert (d < v4, true, "#4");
1180                 Assert (d < 2m, false, "#4a");
1181         }
1182
1183         void LessThanNullableTest ()
1184         {
1185                 dynamic d = 5;
1186
1187                 int? v2 = null;
1188                 Assert (d < v2, false, "#1");
1189                 Assert (d < null, false, "#1a");
1190                 Assert (null < d, false, "#1b");
1191
1192                 v2 = -2;
1193                 Assert (d < v2, false, "#2");
1194                 dynamic d2 = (int?) -2;
1195                 Assert (d2 < 1, true, "#2a");
1196                 d2 = (uint?) 44;
1197                 Assert (d2 < 44, false, "#2b");
1198
1199                 d = new MyType (30);
1200                 MyType? v3 = new MyType (30);
1201                 Assert (d < v3, false, "#3");
1202                 dynamic d3 = new MyType? (new MyType (-7));
1203                 Assert (d3 < new MyType (6), true, "#3a");
1204
1205                 d3 = new MyTypeImplicitOnly (-7);
1206                 Assert (d3 < null, false, "#3b");
1207
1208                 d = 4.1m;
1209                 decimal? v4 = 4m;
1210                 Assert (d < v4, false, "#4");
1211                 v4 = null;
1212                 Assert (d < v4, false, "#4a");
1213         }
1214
1215         void LessThanEnumTest ()
1216         {
1217                 dynamic d = MyEnum.Value_1;
1218
1219                 Assert (d < null, false, "#1");
1220
1221                 Assert (d < MyEnum.Value_1, false, "#2");
1222                 Assert (d < 0, false, "#2a");
1223
1224                 dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_2;
1225                 Assert (d2 < MyEnumUlong.Value_2, false, "#3");
1226                 Assert (d2 < null, false, "#3a");
1227         }
1228
1229         void LessThanOrEqualTest ()
1230         {
1231                 dynamic d = 5;
1232
1233                 int v = 2;
1234                 Assert (d <= v, false, "#1");
1235                 double v2 = 5;
1236                 Assert (d <= v2, true, "#1a");
1237
1238                 d = 4.6;
1239                 Assert (d <= 4.59, false, "#2");
1240                 var b2 = 4.6;
1241                 Assert (d <= b2, true, "#2a");
1242
1243                 d = new MyType (30);
1244                 MyType v3 = new MyType (30);
1245                 Assert (d <= v3, true, "#3");
1246                 dynamic d3 = new MyType (-7);
1247                 Assert (d3 <= new MyType (6), true, "#3a");
1248
1249                 d3 = new MyTypeImplicitOnly (-7);
1250                 Assert (d3 <= 11, true, "#3b");
1251
1252                 d = 2m;
1253                 decimal v4 = 4m;
1254                 Assert (d <= v4, true, "#4");
1255                 Assert (d <= 2m, true, "#4a");
1256         }
1257
1258         void LessThanOrEqualNullableTest ()
1259         {
1260                 dynamic d = 5;
1261
1262                 int? v2 = null;
1263                 Assert (d <= v2, false, "#1");
1264                 Assert (d <= null, false, "#1a");
1265                 Assert (null <= d, false, "#1b");
1266
1267                 v2 = -2;
1268                 Assert (d <= v2, false, "#2");
1269                 dynamic d2 = (int?) -2;
1270                 Assert (d2 <= 1, true, "#2a");
1271                 d2 = (uint?) 44;
1272                 Assert (d2 <= 44, true, "#2b");
1273
1274                 d = new MyType (30);
1275                 MyType? v3 = new MyType (30);
1276                 Assert (d <= v3, true, "#3");
1277                 dynamic d3 = new MyType? (new MyType (-7));
1278                 Assert (d3 <= new MyType (6), true, "#3a");
1279                 Assert (d3 <= null, false, "#3b");
1280
1281                 d = 4.1m;
1282                 decimal? v4 = 4m;
1283                 Assert (d <= v4, false, "#4");
1284                 v4 = null;
1285                 Assert (d <= v4, false, "#4a");
1286         }
1287
1288         void LessThanOrEqualEnumTest ()
1289         {
1290                 dynamic d = MyEnum.Value_1;
1291
1292                 Assert (d <= null, false, "#1");
1293
1294                 Assert (d <= MyEnum.Value_1, true, "#2");
1295                 Assert (d <= 0, false, "#2a");
1296
1297                 dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_2;
1298                 Assert (d2 <= MyEnumUlong.Value_2, true, "#3");
1299                 Assert (d2 <= null, false, "#3a");
1300         }
1301
1302         void ModuloTest ()
1303         {
1304                 dynamic d = 5;
1305
1306                 int v = 2;
1307                 Assert (d % v, 1, "#1");
1308
1309                 d = new MyType (5);
1310                 MyType v3 = new MyType (30);
1311                 Assert (d % v3, new MyType (5), "#3");
1312                 dynamic d3 = new MyType (-7);
1313                 Assert<MyType> (d3 % new MyType (6), new MyType (-1), "#3a");
1314
1315                 d = new MyTypeImplicitOnly (5);
1316                 decimal v4 = 4m;
1317                 Assert (d % v4, 1m, "#4");
1318         }
1319
1320         void ModuloNullableTest ()
1321         {
1322                 dynamic d = 5;
1323
1324                 double? v2 = null;
1325                 Assert<double?> (d % v2, null, "#1");
1326                 Assert<double?> (d % null, null, "#1a");
1327                 Assert<double?> (null % d, null, "#1b");
1328
1329                 v2 = -2;
1330                 Assert (d % v2, 1, "#2");
1331                 dynamic d2 = (int?) -2;
1332                 Assert (d2 % 1, 0, "#2a");
1333
1334                 d = new MyType (-2);
1335                 MyType? v3 = new MyType (30);
1336                 Assert (d % v3, new MyType (-2), "#3");
1337                 dynamic d3 = new MyType? (new MyType (-7));
1338                 Assert (d3 % new MyType (6), new MyType (-1), "#3a");
1339                 Assert<MyType?> (d3 + null, null, "#3b");
1340
1341                 d = new MyTypeImplicitOnly (5);
1342                 decimal? v4 = 4m;
1343                 Assert (d % v4, 1m, "#4");
1344                 v4 = null;
1345                 Assert<decimal?> (d % v4, null, "#4a");
1346         }
1347
1348         void ModuloAssignTest ()
1349         {
1350                 dynamic d = 5;
1351
1352                 int v = 2;
1353                 d %= v;
1354                 Assert (d, 1, "#1");
1355
1356                 d = 5.0;
1357                 double v2 = 0.5;
1358                 d %= v2;
1359                 Assert (d, 0, "#1a");
1360                 d %= v;
1361                 Assert (d, 0, "#1b");
1362
1363                 dynamic d3 = new MyType (-7);
1364                 d3 %= new MyType (6);
1365                 Assert<MyType> (d3, new MyType (-1), "#3");
1366
1367                 d = 5m;
1368                 decimal v4 = 4m;
1369                 d %= v4;
1370                 Assert (d, 1m, "#4");
1371         }
1372
1373         void MultiplyTest ()
1374         {
1375                 dynamic d = 5;
1376
1377                 int v = 2;
1378                 Assert (d * v, 10, "#1");
1379                 double v2 = 0.5;
1380                 Assert (d * v2, 2.5, "#1a");
1381
1382                 d = new MyType (5);
1383                 MyType v3 = new MyType (30);
1384                 Assert (d * v3, new MyType (150), "#3");
1385                 dynamic d3 = new MyType (-7);
1386                 Assert<MyType> (d3 * new MyType (6), new MyType (-42), "#3a");
1387
1388                 decimal v4 = 4m;
1389                 d = 7.9m;
1390                 Assert (d * v4, 31.6m, "#4");
1391         }
1392
1393         void MultiplyNullableTest ()
1394         {
1395                 dynamic d = 5;
1396
1397                 int? v2 = null;
1398                 Assert<int?> (d * v2, null, "#1");
1399                 Assert<int?> (d * null, null, "#1a");
1400                 Assert<int?> (null * d, null, "#1b");
1401
1402                 v2 = -2;
1403                 Assert (d * v2, -10, "#2");
1404                 dynamic d2 = (int?) -2;
1405                 Assert (d2 * 1, -2, "#2a");
1406
1407                 d = new MyType (5);
1408                 MyType? v3 = new MyType (30);
1409                 Assert (d * v3, new MyType (150), "#3");
1410                 dynamic d3 = new MyType? (new MyType (-7));
1411                 Assert (d3 * new MyType (6), new MyType (-42), "#3a");
1412                 Assert<MyType?> (d3 * null, null, "#3b");
1413
1414                 d = new MyTypeImplicitOnly (5);
1415                 decimal? v4 = 4m;
1416                 Assert (d * v4, 20m, "#4");
1417                 v4 = null;
1418                 Assert<decimal?> (d * v4, null, "#4a");
1419         }
1420
1421         void MultiplyCheckedTest ()
1422         {
1423                 checked {
1424                         dynamic d = 5;
1425
1426                         int v = int.MaxValue;
1427                         AssertChecked (() => d * v, 7, "#1");
1428
1429                         int? v2 = v;
1430                         AssertChecked (() => d * v2, null, "#2");
1431
1432                         d = new MyType (4);
1433                         MyType v3 = new MyType (int.MaxValue);
1434                         Assert (d * v3, new MyType (-4), "#3");
1435                 }
1436         }
1437
1438         void MultiplyAssignTest ()
1439         {
1440                 dynamic d = 5;
1441
1442                 int v = 2;
1443                 d *= v;
1444                 Assert (d, 10, "#1");
1445
1446                 d = 5.0;
1447                 double v2 = 0.5;
1448                 d *= v2;
1449                 Assert (d, 2.5, "#1a");
1450                 d *= v;
1451                 Assert (d, 5, "#1b");
1452
1453                 dynamic d3 = new MyType (-7);
1454                 d3 *= new MyType (6);
1455                 Assert<MyType> (d3, new MyType (-42), "#3");
1456
1457                 d = 5m;
1458                 decimal v4 = 4m;
1459                 d *= v4;
1460                 Assert (d, 20m, "#4");
1461         }
1462
1463         void MultiplyAssignCheckedTest ()
1464         {
1465                 checked {
1466                         dynamic d = 5;
1467
1468                         int v = int.MaxValue;
1469                         AssertChecked (() => { d *= v; Assert (d, 0, "#1-"); }, "#1");
1470
1471                         d = new MyType (44);
1472                         MyType v3 = new MyType (int.MaxValue);
1473                         d *= v3;
1474                         Assert (d, new MyType (-44), "#3-");
1475                 }
1476         }
1477
1478         void Negate ()
1479         {
1480                 dynamic d = -8;
1481                 Assert (8, -d, "#1");
1482                 Assert (-8, -(-d), "#1a");
1483
1484                 d = new MyType (-14);
1485                 Assert (new MyType (14), -d, "#2");
1486
1487                 d = new MyTypeImplicitOnly (4);
1488                 Assert (-4, -d, "#3");
1489
1490                 d = (uint) 7;
1491                 Assert (-7, -d, "#4");
1492
1493                 d = double.NegativeInfinity;
1494                 Assert (double.PositiveInfinity, -d, "#5");
1495         }
1496
1497         void NegateNullable ()
1498         {
1499                 dynamic d = (int?) -8;
1500                 Assert (8, -d, "#1");
1501                 Assert (-8, -(-d), "#1a");
1502
1503                 MyType? n1 = new MyType (4);
1504                 d = n1;
1505                 Assert (new MyType (-4), -d, "#2");
1506
1507                 MyTypeImplicitOnly? n2 = new MyTypeImplicitOnly (4);
1508                 d = n2;
1509                 Assert (-4, -d, "#3");
1510
1511                 d = (sbyte?) 7;
1512                 Assert (-7, -d, "#4");
1513         }
1514
1515         void NegateChecked ()
1516         {
1517                 checked {
1518                         dynamic d = int.MinValue;
1519                         AssertChecked (() => -d, 0, "#1");
1520                 }
1521         }
1522
1523         void Not ()
1524         {
1525                 dynamic d = true;
1526                 Assert (false, !d, "#1");
1527
1528                 var de = new MyType (-1);
1529                 Assert (false, !d, "#2");
1530         }
1531
1532         void NotEqualTest ()
1533         {
1534                 dynamic d = 5;
1535
1536                 int v = 2;
1537                 Assert (d != v, true, "#1");
1538                 double v2 = 5;
1539                 Assert (d != v2, false, "#1a");
1540
1541                 d = true;
1542                 Assert (d != false, true, "#2");
1543                 bool b2 = true;
1544                 Assert (d != b2, false, "#2a");
1545
1546                 d = new MyType (30);
1547                 MyType v3 = new MyType (30);
1548                 Assert (d != v3, false, "#3");
1549                 dynamic d3 = new MyType (-7);
1550                 Assert (d3 != new MyType (6), true, "#3a");
1551
1552                 d = 2m;
1553                 decimal v4 = 4m;
1554                 Assert (d != v4, true, "#4");
1555                 Assert (d != 2m, false, "#4a");
1556
1557                 d = null;
1558                 Assert (d != null, false, "#5");
1559         }
1560
1561         void NotEqualNullableTest ()
1562         {
1563                 dynamic d = 5;
1564
1565                 int? v2 = null;
1566                 Assert (d != v2, true, "#1");
1567                 Assert (d != null, true, "#1a");
1568                 Assert (null != d, true, "#1b");
1569
1570                 v2 = -2;
1571                 Assert (d != v2, true, "#2");
1572                 dynamic d2 = (int?) -2;
1573                 Assert (d2 != 1, true, "#2a");
1574                 d2 = (uint?) 44;
1575                 Assert (d2 != 44, false, "#2b");
1576
1577                 d = new MyType (30);
1578                 MyType? v3 = new MyType (30);
1579                 Assert (d != v3, false, "#3");
1580                 dynamic d3 = new MyType? (new MyType (-7));
1581                 Assert (d3 != new MyType (6), true, "#3a");
1582                 Assert (d3 != null, true, "#3b");
1583
1584                 d = 4.1m;
1585                 decimal? v4 = 4m;
1586                 Assert (d != v4, true, "#4");
1587                 v4 = null;
1588                 Assert (d != v4, true, "#4a");
1589
1590                 d = (bool?) true;
1591                 Assert (d != true, false, "#5");
1592                 Assert (d != null, true, "#5a");
1593                 Assert (d != false, true, "#5b");
1594         }
1595
1596         void NotEqualEnumTest ()
1597         {
1598                 dynamic d = MyEnum.Value_1;
1599
1600                 Assert (d != null, true, "#1");
1601
1602                 Assert (d != MyEnum.Value_1, false, "#2");
1603                 Assert (d != 0, true, "#2a");
1604
1605                 dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_2;
1606                 Assert (d2 != MyEnumUlong.Value_2, false, "#3");
1607                 Assert (d2 != null, true, "#3a");
1608         }
1609
1610         void NotEqualStringTest ()
1611         {
1612                 dynamic d = "text";
1613
1614                 Assert (d != "te", true, "#1");
1615                 Assert (d != "text", false, "#1a");
1616                 Assert (d != null, true, "#1b");
1617         }
1618
1619         void OnesComplement ()
1620         {
1621                 dynamic d = 7;
1622                 Assert (-8, ~d, "#1");
1623
1624                 d = new MyType (-1);
1625                 Assert (0, ~d, "#2");
1626
1627                 d = (ulong) 7;
1628                 Assert (18446744073709551608, ~d, "#3");
1629
1630                 d = MyEnum.Value_1;
1631                 Assert ((MyEnum) 254, ~d, "#4");
1632         }
1633
1634         void OnesComplementNullable ()
1635         {
1636                 dynamic d = (int?) 7;
1637                 Assert (-8, ~d, "#1");
1638
1639                 d = (MyEnum?) MyEnum.Value_1;
1640                 Assert ((MyEnum) 254, ~d, "#4");
1641         }
1642
1643         void OrTest ()
1644         {
1645                 dynamic d = true;
1646
1647                 var v = false;
1648                 Assert (d | v, true, "#1");
1649                 Assert (d | false, true, "#1a");
1650
1651                 d = 42;
1652                 var v2 = 62;
1653                 Assert (d | v2, 62, "#2");
1654                 Assert (d | 0, 42, "#2a");
1655
1656                 d = new MyType (42);
1657                 MyType v3 = new MyType (30);
1658                 Assert (d | v3, new MyType (62), "#3");
1659                 dynamic d3 = new MyType (-7);
1660                 Assert<MyType> (d3 | new MyType (6), new MyType (-1), "#3a");
1661
1662                 d3 = new MyTypeImplicitOnly (-7);
1663                 Assert (d3 | 11, -5, "#3b");
1664         }
1665
1666         void OrTestEnum ()
1667         {
1668                 dynamic d = MyEnum.Value_1;
1669
1670                 Assert<MyEnum?> (d | null, null, "#1");
1671
1672                 Assert (d | d, MyEnum.Value_1, "#2");
1673
1674                 dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_1;
1675                 Assert<MyEnumUlong> (d2 | MyEnumUlong.Value_2, (MyEnumUlong) 3, "#3");
1676         }
1677
1678         void OrTestNullable ()
1679         {
1680                 dynamic d = 5;
1681
1682                 int? v2 = null;
1683                 Assert<int?> (d | v2, null, "#1");
1684                 Assert<int?> (d | null, null, "#1a");
1685                 Assert<int?> (null | d, null, "#1b");
1686
1687                 v2 = -2;
1688                 Assert (d | v2, -1, "#2");
1689                 dynamic d2 = (int?) -2;
1690                 Assert (d2 | 1, -1, "#2a");
1691
1692                 d = new MyType (-2);
1693                 MyType? v3 = new MyType (30);
1694                 Assert (d | v3, new MyType (-2), "#3");
1695                 dynamic d3 = new MyType? (new MyType (-7));
1696                 Assert (d3 | new MyType (6), new MyType (-1), "#3a");
1697         }
1698
1699         void OrAssignedTest ()
1700         {
1701                 dynamic d = true;
1702
1703                 var v = false;
1704                 d |= v;
1705                 Assert (d, true, "#1");
1706                 d = true;
1707                 d |= true;
1708                 Assert (d, true, "#1a");
1709
1710                 d = 42;
1711                 var v2 = 62;
1712                 d |= v2;
1713                 Assert (d, 62, "#2");
1714
1715                 MyType v3 = new MyType (30);
1716                 dynamic d3 = new MyType (-7);
1717                 d3 |= new MyType (6);
1718                 Assert<MyType> (d3, new MyType (-1), "#3");
1719         }
1720
1721         void OrAssignedTestEnum ()
1722         {
1723                 dynamic d = MyEnum.Value_1;
1724                 d |= MyEnum.Value_2;
1725                 Assert<MyEnum> (d, (MyEnum) 3, "#1");
1726
1727                 d = MyEnum.Value_2;
1728                 d |= d;
1729                 Assert (d, MyEnum.Value_2, "#2");
1730
1731                 dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_1;
1732                 Assert<MyEnumUlong> (d2 | MyEnumUlong.Value_2, (MyEnumUlong)3, "#3");
1733         }
1734
1735         void OrElseTest ()
1736         {
1737                 dynamic d = true;
1738
1739                 var v = false;
1740                 Assert<bool> (d || v, true, "#1");
1741
1742                 Assert (d || true, true, "#1a");
1743
1744                 d = true;
1745                 Assert (d || d, true, "#2");
1746
1747                 dynamic d3 = new MyType (-7);
1748                 Assert<MyType> (d3 || new MyType (6), new MyType (-1), "#3");
1749         }
1750
1751         void RightShiftTest ()
1752         {
1753                 dynamic d = (ulong) 0x7F000;
1754
1755                 int v = 2;
1756                 Assert<ulong> (d >> v, 0x1FC00, "#1");
1757                 Assert<ulong> (d >> 1, 0x3F800, "#1a");
1758                 short s = 2;
1759                 Assert<ulong> (d >> s, 0x1FC00, "#1b");
1760
1761                 d = 0x7F000;
1762                 MyTypeImplicitOnly v3 = new MyTypeImplicitOnly (3);
1763                 Assert (d >> v3, 0xFE00, "#3");
1764                 dynamic d3 = new MyType (-7);
1765                 Assert (d3 >> new MyTypeImplicitOnly (11), -1, "#3a");
1766         }
1767
1768         void RightShiftNullableTest ()
1769         {
1770                 dynamic d = 5;
1771
1772                 int? v2 = null;
1773                 Assert<int?> (d >> v2, null, "#1");
1774                 d = 5;
1775                 Assert<int?> (d >> null, null, "#1a");
1776                 d = 5;
1777                 Assert<int?> (null >> d, null, "#1b");
1778
1779                 v2 = -2;
1780                 Assert (d >> v2, 0, "#2");
1781                 dynamic d2 = (int?) -200;
1782                 Assert (d2 >> 1, -100, "#2a");
1783         }
1784
1785         void RightShiftAssignTest ()
1786         {
1787                 dynamic d = 0x7F000;
1788
1789                 int v = 2;
1790                 d >>= v;
1791                 Assert (d, 0x1FC00, "#1");
1792                 d >>= 1;
1793                 Assert (d, 0xFE00, "#1a");
1794                 sbyte s = 2;
1795                 d >>= s;
1796                 Assert (d, 0x3F80, "#1b");
1797         }
1798
1799         void RightShiftAssignNullableTest ()
1800         {
1801                 dynamic d = 0x2A0;
1802
1803                 var v2 = -2;
1804                 d >>= v2;
1805                 Assert (d, 0, "#2");
1806                 dynamic d2 = (int?) -2;
1807                 d2 >>= 1;
1808                 Assert (d2, -1, "#2a");
1809         }
1810
1811         void SubtractTest ()
1812         {
1813                 dynamic d = 5;
1814
1815                 int v = 2;
1816                 Assert (d - v, 3, "#1");
1817                 double v2 = 0.5;
1818                 Assert (d - v2, 4.5, "#1a");
1819
1820                 d = new MyType (5);
1821                 MyType v3 = new MyType (30);
1822                 Assert (d - v3, new MyType (-25), "#3");
1823                 dynamic d3 = new MyType (-7);
1824                 Assert (d3 - new MyType (6), new MyType (-13), "#3a");
1825
1826                 d = new MyTypeImplicitOnly (5);
1827                 decimal v4 = 4m;
1828                 Assert (d - v4, 1m, "#4");
1829         }
1830
1831         void SubtractNullableTest ()
1832         {
1833                 dynamic d = 5;
1834
1835                 int? v2 = null;
1836                 Assert<int?> (d - v2, null, "#1");
1837                 Assert<int?> (d - null, null, "#1a");
1838                 Assert<int?> (null - d, null, "#1b");
1839
1840                 v2 = -2;
1841                 Assert (d - v2, 7, "#2");
1842                 dynamic d2 = (int?) -2;
1843                 Assert (d2 - 1, -3, "#2a");
1844
1845                 d = new MyType (5);
1846                 MyType? v3 = new MyType (30);
1847                 Assert (d - v3, new MyType (-25), "#3");
1848                 dynamic d3 = new MyType? (new MyType (-7));
1849                 Assert (d3 - new MyType (6), new MyType (-13), "#3a");
1850                 Assert<MyType?> (d3 - null, null, "#3b");
1851
1852                 d = new MyTypeImplicitOnly (5);
1853                 decimal? v4 = 4m;
1854                 Assert (d - v4, 1m, "#4");
1855                 v4 = null;
1856                 Assert<decimal?> (d - v4, null, "#4a");
1857         }
1858
1859         void SubtractEnumTest ()
1860         {
1861                 dynamic d = MyEnum.Value_1;
1862
1863                 // CSC: Invalid System.InvalidOperationException
1864                 Assert (d - null, null, "#1");
1865
1866                 Assert (d - 1, MyEnum.Value_2, "#2");
1867
1868                 dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_1;
1869                 Assert (d2 - (byte) 1, MyEnumUlong.Value_2, "#3");
1870                 Assert<MyEnumUlong?> (d2 - (object) null, null, "#3a");
1871         }
1872
1873         void SubtractCheckedTest ()
1874         {
1875                 checked {
1876                         dynamic d = 5;
1877
1878                         int v = int.MinValue;
1879                         AssertChecked (() => d - v, 7, "#1");
1880
1881                         int? v2 = v;
1882                         AssertChecked (() => d - v2, null, "#2");
1883
1884                         d = new MyType (5);
1885                         MyType v3 = new MyType (int.MinValue);
1886                         Assert (d - v3, new MyType (-2147483643), "#3");
1887                 }
1888         }
1889
1890         void SubtractAssignTest ()
1891         {
1892                 dynamic d = 5;
1893
1894                 int v = 2;
1895                 d -= v;
1896                 Assert (d, 3, "#1");
1897
1898                 d = 5.0;
1899                 double v2 = 0.5;
1900                 d -= v2;
1901                 Assert (d, 4.5, "#1a");
1902                 d -= v;
1903                 Assert (d, 2.5, "#1b");
1904
1905                 dynamic d3 = new MyType (-7);
1906                 d3 -= new MyType (6);
1907                 Assert<MyType> (d3, new MyType (-13), "#3");
1908
1909                 d = 5m;
1910                 decimal v4 = 4m;
1911                 d -= v4;
1912                 Assert (d, 1m, "#4");
1913         }
1914
1915         void SubtractAssignEnumTest ()
1916         {
1917                 dynamic d = MyEnum.Value_1;
1918
1919                 d -= 1;
1920                 Assert<MyEnum> (d, 0, "#2");
1921
1922                 dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_2;
1923                 d2 -= (byte) 1;
1924                 Assert (d2, MyEnumUlong.Value_1, "#3");
1925         }
1926
1927         void SubtractAssignCheckedTest ()
1928         {
1929                 checked {
1930                         dynamic d = 5;
1931
1932                         int v = int.MinValue;
1933                         AssertChecked (() => { d -= v; Assert (d, 0, "#1a"); }, "#1");
1934
1935                         d = new MyType (5);
1936                         MyType v3 = new MyType (int.MinValue);
1937                         d -= v3;
1938                         Assert (d, new MyType (-2147483643), "#3a");
1939                 }
1940         }
1941
1942         // TODO:
1943         void SubtractAssignmentEvent ()
1944         {
1945                 // IMPLEMENT
1946         }
1947
1948         void UnaryDecrement ()
1949         {
1950                 dynamic d = 3;
1951                 Assert (3, d--, "#1");
1952                 Assert (2, d, "#1a");
1953
1954                 d = 3;
1955                 Assert (2, --d, "#2");
1956                 Assert (2, d, "#2a");
1957
1958                 d = new MyType (-3);
1959                 Assert (new MyType (-3), d--, "#3");
1960                 Assert (new MyType (-1), d, "#3a");
1961         }
1962
1963         void UnaryDecrementCheckedTest ()
1964         {
1965                 checked {
1966                         dynamic d = int.MinValue;
1967
1968                         AssertChecked (() => { d--; Assert (d, -1073741824, "#1a"); }, "#1");
1969
1970                         d = new MyType (int.MinValue);
1971                         d--;
1972                         Assert (d, new MyType (-1073741824), "#2");
1973                 }
1974         }
1975
1976         void UnaryIncrement ()
1977         {
1978                 dynamic d = 3;
1979                 Assert (3, d++, "#1");
1980                 Assert (4, d, "#1a");
1981
1982                 d = 3;
1983                 Assert (4, ++d, "#2");
1984                 Assert (4, d, "#2a");
1985
1986                 d = new MyType (-3);
1987                 Assert (new MyType (-3), d++, "#3");
1988                 Assert (new MyType (-6), d, "#3a");
1989         }
1990
1991         void UnaryIncrementCheckedTest ()
1992         {
1993                 checked {
1994                         dynamic d = int.MaxValue;
1995
1996                         AssertChecked (() => { d++; Assert (d, 0, "#1a"); }, "#1");
1997
1998                         d = new MyType (int.MaxValue);
1999                         d++;
2000                         Assert (d, new MyType (-2), "#2");
2001                 }
2002         }
2003
2004         //void UnaryIsFalse ()
2005         //{
2006         //    dynamic d = this;
2007         //    object r = d == null;
2008         //    Assert (false, (bool) r, "#1");
2009         //    Assert<object> (true, d != null, "#1a");
2010         //}
2011
2012         void UnaryIsTrue ()
2013         {
2014                 dynamic d = true;
2015                 Assert (3, d ? 3 : 5, "#1");
2016
2017                 d = 4;
2018                 Assert (false, d < 1, "#2");
2019
2020                 d = new InverseLogicalOperator (true);
2021                 Assert (1, d ? 1 : -1, "#3");
2022         }
2023
2024         void UnaryPlus ()
2025         {
2026                 dynamic d = -8;
2027                 Assert (-8, +d, "#1");
2028                 Assert (-8, +(+d), "#1a");
2029
2030                 d = new MyType (14);
2031                 Assert (new MyType (334455), +d, "#2");
2032
2033                 d = new MyTypeImplicitOnly (4);
2034                 Assert (4, +d, "#3");
2035
2036                 d = (uint) 7;
2037                 Assert<uint> (7, +d, "#4");
2038         }
2039
2040         void UnaryPlusNullable ()
2041         {
2042                 dynamic d = (int?) -8;
2043                 Assert (-8, +d, "#1");
2044                 Assert (-8, +(+d), "#1a");
2045
2046                 MyType? n1 = new MyType (4);
2047                 d = n1;
2048                 Assert (new MyType (334455), +d, "#2");
2049
2050                 MyTypeImplicitOnly? n2 = new MyTypeImplicitOnly (4);
2051                 d = n2;
2052                 Assert (4, +d, "#3");
2053
2054                 d = (sbyte?) 7;
2055                 Assert (7, +d, "#4");
2056         }
2057
2058 #pragma warning restore 169
2059
2060         static bool RunTest (MethodInfo test)
2061         {
2062                 Console.Write ("Running test {0, -25}", test.Name);
2063                 try {
2064                         test.Invoke (new Tester (), null);
2065                         Console.WriteLine ("OK");
2066                         return true;
2067                 } catch (Exception e) {
2068                         Console.WriteLine ("FAILED");
2069                         Console.WriteLine (e.ToString ());
2070                         return false;
2071                 }
2072         }
2073
2074         public static int Main ()
2075         {
2076                 var tests = from test in typeof (Tester).GetMethods (BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.DeclaredOnly)
2077                                         where test.GetParameters ().Length == 0
2078                                         orderby test.Name
2079                                         select RunTest (test);
2080
2081                 int failures = tests.Count (a => !a);
2082                 Console.WriteLine (failures + " tests failed");
2083                 return failures;
2084         }
2085 }
2086