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