New tests.
[mono.git] / mcs / class / corlib / System / Int32.cs
1 //
2 // System.Int32.cs
3 //
4 // Author:
5 //   Miguel de Icaza (miguel@ximian.com)
6 //
7 // (C) Ximian, Inc.  http://www.ximian.com
8 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
9 //
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
17 // 
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
20 // 
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 //
29
30 using System.Globalization;
31 using System.Threading;
32
33 namespace System {
34         
35         [Serializable]
36         [System.Runtime.InteropServices.ComVisible (true)]
37         public struct Int32 : IFormattable, IConvertible, IComparable, IComparable<Int32>, IEquatable <Int32>
38         {
39
40                 public const int MaxValue = 0x7fffffff;
41                 public const int MinValue = -2147483648;
42                 
43                 // This field is looked up by name in the runtime
44                 internal int m_value;
45
46                 public int CompareTo (object value)
47                 {
48                         if (value == null)
49                                 return 1;
50                         
51                         if (!(value is System.Int32))
52                                 throw new ArgumentException (Locale.GetText ("Value is not a System.Int32"));
53
54                         int xv = (int) value;
55                         if (m_value == xv)
56                                 return 0;
57                         if (m_value > xv)
58                                 return 1;
59                         else
60                                 return -1;
61                 }
62
63                 public override bool Equals (object obj)
64                 {
65                         if (!(obj is System.Int32))
66                                 return false;
67
68                         return ((int) obj) == m_value;
69                 }
70
71                 public override int GetHashCode ()
72                 {
73                         return m_value;
74                 }
75
76                 public int CompareTo (int value)
77                 {
78                         if (m_value == value)
79                                 return 0;
80                         if (m_value > value)
81                                 return 1;
82                         else
83                                 return -1;
84                 }
85
86                 public bool Equals (int obj)
87                 {
88                         return obj == m_value;
89                 }
90
91                 internal static bool ProcessTrailingWhitespace (bool tryParse, string s, int position, ref Exception exc)
92                 {
93                         int len = s.Length;
94                         
95                         for (int i = position; i < len; i++){
96                                 char c = s [i];
97                                 
98                                 if (c != 0 && !Char.IsWhiteSpace (c)){
99                                         if (!tryParse)
100                                                 exc = GetFormatException ();
101                                         return false;
102                                 }
103                         }
104                         return true;
105                 }
106
107                 internal static bool Parse (string s, bool tryParse, out int result, out Exception exc)
108                 {
109                         int val = 0;
110                         int len;
111                         int i, sign = 1;
112                         bool digits_seen = false;
113
114                         result = 0;
115                         exc = null;
116
117                         if (s == null) {
118                                 if (!tryParse)
119                                         exc = new ArgumentNullException ("s");
120                                 return false;
121                         }
122
123                         len = s.Length;
124
125                         char c;
126                         for (i = 0; i < len; i++){
127                                 c = s [i];
128                                 if (!Char.IsWhiteSpace (c))
129                                         break;
130                         }
131                         
132                         if (i == len) {
133                                 if (!tryParse)
134                                         exc = GetFormatException ();
135                                 return false;
136                         }
137
138                         c = s [i];
139                         if (c == '+')
140                                 i++;
141                         else if (c == '-'){
142                                 sign = -1;
143                                 i++;
144                         }
145                         
146                         for (; i < len; i++){
147                                 c = s [i];
148
149                                 if (c == '\0') {
150                                         i = len;
151                                         continue;
152                                 }
153                                 
154                                 if (c >= '0' && c <= '9'){
155                                         byte d = (byte) (c - '0');
156                                                 
157                                         if (val > (MaxValue/10))
158                                                 goto overflow;
159                                         
160                                         if (val == (MaxValue/10)){
161                                                 if ((d > (MaxValue % 10)) && (sign == 1 || (d > ((MaxValue % 10) + 1))))
162                                                         goto overflow;
163                                                 if (sign == -1)
164                                                         val = (val * sign * 10) - d;
165                                                 else
166                                                         val = (val * 10) + d;
167
168                                                 if (ProcessTrailingWhitespace (tryParse, s, i + 1, ref exc)){
169                                                         result = val;
170                                                         return true;
171                                                 }
172                                                 goto overflow;
173                                         } else 
174                                                 val = val * 10 + d;
175                                         
176                                         digits_seen = true;
177                                 } else if (!ProcessTrailingWhitespace (tryParse, s, i, ref exc))
178                                         return false;
179                         }
180                         if (!digits_seen) {
181                                 if (!tryParse)
182                                         exc = GetFormatException ();
183                                 return false;
184                         }
185
186                         if (sign == -1)
187                                 result = val * sign;
188                         else
189                                 result = val;
190
191                         return true;
192
193                 overflow:
194                         if (!tryParse)
195                                 exc = new OverflowException ("Value is too large");
196                         return false;
197                 }
198
199                 public static int Parse (string s, IFormatProvider provider)
200                 {
201                         return Parse (s, NumberStyles.Integer, provider);
202                 }
203
204                 public static int Parse (string s, NumberStyles style)
205                 {
206                         return Parse (s, style, null);
207                 }
208
209                 internal static bool CheckStyle (NumberStyles style, bool tryParse, ref Exception exc)
210                 {
211                         if ((style & NumberStyles.AllowHexSpecifier) != 0) {
212                                 NumberStyles ne = style ^ NumberStyles.AllowHexSpecifier;
213                                 if ((ne & NumberStyles.AllowLeadingWhite) != 0)
214                                         ne ^= NumberStyles.AllowLeadingWhite;
215                                 if ((ne & NumberStyles.AllowTrailingWhite) != 0)
216                                         ne ^= NumberStyles.AllowTrailingWhite;
217                                 if (ne != 0) {
218                                         if (!tryParse)
219                                                 exc = new ArgumentException (
220                                                         "With AllowHexSpecifier only " + 
221                                                         "AllowLeadingWhite and AllowTrailingWhite " + 
222                                                         "are permitted.");
223                                         return false;
224                                 }
225                         } else if ((uint) style > (uint) NumberStyles.Any){
226                                 if (!tryParse)
227                                         exc = new ArgumentException ("Not a valid number style");
228                                 return false;
229                         }
230
231                         return true;
232                 }
233                 
234                 internal static bool JumpOverWhite (ref int pos, string s, bool reportError, bool tryParse, ref Exception exc)
235                 {
236                         while (pos < s.Length && Char.IsWhiteSpace (s [pos]))
237                                 pos++;
238
239                         if (reportError && pos >= s.Length) {
240                                 if (!tryParse)
241                                         exc = GetFormatException ();
242                                 return false;
243                         }
244
245                         return true;
246                 }
247
248                 internal static void FindSign (ref int pos, string s, NumberFormatInfo nfi, 
249                                       ref bool foundSign, ref bool negative)
250                 {
251                         if ((pos + nfi.NegativeSign.Length) <= s.Length &&
252                                 s.IndexOf (nfi.NegativeSign, pos, nfi.NegativeSign.Length) == pos) {
253                                 negative = true;
254                                 foundSign = true;
255                                 pos += nfi.NegativeSign.Length;
256                         } 
257                         else if ((pos + nfi.PositiveSign.Length) < s.Length &&
258                                 s.IndexOf (nfi.PositiveSign, pos, nfi.PositiveSign.Length) == pos) {
259                                 negative = false;
260                                 pos += nfi.PositiveSign.Length;
261                                 foundSign = true;
262                         } 
263                 }
264
265                 internal static void FindCurrency (ref int pos,
266                                                  string s, 
267                                                  NumberFormatInfo nfi,
268                                                  ref bool foundCurrency)
269                 {
270                         if ((pos + nfi.CurrencySymbol.Length) <= s.Length &&
271                              s.Substring (pos, nfi.CurrencySymbol.Length) == nfi.CurrencySymbol) {
272                                 foundCurrency = true;
273                                 pos += nfi.CurrencySymbol.Length;
274                         } 
275                 }
276
277                 internal static bool FindExponent (ref int pos, string s, ref int exponent, bool tryParse, ref Exception exc)
278                 {
279                                 exponent = 0;
280                                 long exp = 0; // temp long value
281
282                                 int i = s.IndexOfAny(new char [] {'e', 'E'}, pos);
283                                 if (i < 0) {
284                                         exc = null;
285                                         return false;
286                                 }
287
288                                 if (++i == s.Length) {
289                                         exc = tryParse ? null : GetFormatException ();
290                                         return true;
291                                 }
292
293                                 // negative exponent not valid for Int32
294                                 if (s [i] == '-') {
295                                         exc = tryParse ? null : new OverflowException ("Value too large or too small.");
296                                         return true;
297                                 }
298
299                                 if (s [i] == '+' && ++i == s.Length) {
300                                         exc = tryParse ? null : GetFormatException ();
301                                         return true;
302                                 }
303
304                                 for (; i < s.Length; i++) {
305                                         if (!Char.IsDigit (s [i]))  {
306                                                 exc = tryParse ? null : GetFormatException ();
307                                                 return true;
308                                         }
309
310                                         // Reduce the risk of throwing an overflow exc
311                                         exp = checked (exp * 10 - (int) (s [i] - '0'));
312                                         if (exp < Int32.MinValue || exp > Int32.MaxValue) {
313                                                 exc = tryParse ? null : new OverflowException ("Value too large or too small.");
314                                                 return true;
315                                         }
316                                 }
317
318                                 // exp value saved as negative
319                                 exp = -exp;
320
321                                 exc = null;
322                                 exponent = (int)exp;
323                                 pos = i;
324                                 return true;
325                 }
326
327                 internal static bool FindOther (ref int pos,
328                                               string s, 
329                                               string other)
330                 {
331                         if ((pos + other.Length) <= s.Length &&
332                              s.Substring (pos, other.Length) == other) {
333                                 pos += other.Length;
334                                 return true;
335                         } 
336
337                         return false;
338                 }
339
340                 internal static bool ValidDigit (char e, bool allowHex)
341                 {
342                         if (allowHex)
343                                 return Char.IsDigit (e) || (e >= 'A' && e <= 'F') || (e >= 'a' && e <= 'f');
344
345                         return Char.IsDigit (e);
346                 }
347                 
348                 internal static Exception GetFormatException ()
349                 {
350                         return new FormatException ("Input string was not in the correct format");
351                 }
352                 
353                 internal static bool Parse (string s, NumberStyles style, IFormatProvider fp, bool tryParse, out int result, out Exception exc)
354                 {
355                         result = 0;
356                         exc = null;
357
358                         if (s == null) {
359                                 if (!tryParse)
360                                         exc = new ArgumentNullException ();
361                                 return false;
362                         }
363
364                         if (s.Length == 0) {
365                                 if (!tryParse)
366                                         exc = GetFormatException ();
367                                 return false;
368                         }
369
370                         NumberFormatInfo nfi = null;
371                         if (fp != null) {
372                                 Type typeNFI = typeof (System.Globalization.NumberFormatInfo);
373                                 nfi = (NumberFormatInfo) fp.GetFormat (typeNFI);
374                         }
375                         if (nfi == null)
376                                 nfi = Thread.CurrentThread.CurrentCulture.NumberFormat;
377
378                         if (!CheckStyle (style, tryParse, ref exc))
379                                 return false;
380
381                         bool AllowCurrencySymbol = (style & NumberStyles.AllowCurrencySymbol) != 0;
382                         bool AllowHexSpecifier = (style & NumberStyles.AllowHexSpecifier) != 0;
383                         bool AllowThousands = (style & NumberStyles.AllowThousands) != 0;
384                         bool AllowDecimalPoint = (style & NumberStyles.AllowDecimalPoint) != 0;
385                         bool AllowParentheses = (style & NumberStyles.AllowParentheses) != 0;
386                         bool AllowTrailingSign = (style & NumberStyles.AllowTrailingSign) != 0;
387                         bool AllowLeadingSign = (style & NumberStyles.AllowLeadingSign) != 0;
388                         bool AllowTrailingWhite = (style & NumberStyles.AllowTrailingWhite) != 0;
389                         bool AllowLeadingWhite = (style & NumberStyles.AllowLeadingWhite) != 0;
390                         bool AllowExponent = (style & NumberStyles.AllowExponent) != 0;
391
392                         int pos = 0;
393
394                         if (AllowLeadingWhite && !JumpOverWhite (ref pos, s, true, tryParse, ref exc))
395                                 return false;
396
397                         bool foundOpenParentheses = false;
398                         bool negative = false;
399                         bool foundSign = false;
400                         bool foundCurrency = false;
401
402                         // Pre-number stuff
403                         if (AllowParentheses && s [pos] == '(') {
404                                 foundOpenParentheses = true;
405                                 foundSign = true;
406                                 negative = true; // MS always make the number negative when there parentheses
407                                                  // even when NumberFormatInfo.NumberNegativePattern != 0!!!
408                                 pos++;
409                                 if (AllowLeadingWhite && !!JumpOverWhite (ref pos, s, true, tryParse, ref exc))
410                                         return false;
411
412                                 if (s.Substring (pos, nfi.NegativeSign.Length) == nfi.NegativeSign) {
413                                         if (!tryParse)
414                                                 exc = GetFormatException ();
415                                         return false;
416                                 }
417                                 
418                                 if (s.Substring (pos, nfi.PositiveSign.Length) == nfi.PositiveSign) {
419                                         if (!tryParse)
420                                                 exc = GetFormatException ();
421                                         return false;
422                                 }
423                         }
424
425                         if (AllowLeadingSign && !foundSign) {
426                                 // Sign + Currency
427                                 FindSign (ref pos, s, nfi, ref foundSign, ref negative);
428                                 if (foundSign) {
429                                         if (AllowLeadingWhite && !JumpOverWhite (ref pos, s, true, tryParse, ref exc))
430                                                 return false;
431                                         if (AllowCurrencySymbol) {
432                                                 FindCurrency (ref pos, s, nfi,
433                                                               ref foundCurrency);
434                                                 if (foundCurrency && AllowLeadingWhite &&
435                                                                 !JumpOverWhite (ref pos, s, true, tryParse, ref exc))
436                                                         return false;
437                                         }
438                                 }
439                         }
440                         
441                         if (AllowCurrencySymbol && !foundCurrency) {
442                                 // Currency + sign
443                                 FindCurrency (ref pos, s, nfi, ref foundCurrency);
444                                 if (foundCurrency) {
445                                         if (AllowLeadingWhite && !JumpOverWhite (ref pos, s, true, tryParse, ref exc))
446                                                 return false;
447                                         if (foundCurrency) {
448                                                 if (!foundSign && AllowLeadingSign) {
449                                                         FindSign (ref pos, s, nfi, ref foundSign,
450                                                                   ref negative);
451                                                         if (foundSign && AllowLeadingWhite &&
452                                                                         !JumpOverWhite (ref pos, s, true, tryParse, ref exc))
453                                                                 return false;
454                                                 }
455                                         }
456                                 }
457                         }
458
459                         int number = 0;
460                         int nDigits = 0;
461                         bool decimalPointFound = false;
462                         int digitValue;
463                         char hexDigit;
464                         int exponent = 0;
465                                 
466                         // Number stuff
467                         do {
468
469                                 if (!ValidDigit (s [pos], AllowHexSpecifier)) {
470                                         if (AllowThousands &&
471                                             FindOther (ref pos, s, nfi.NumberGroupSeparator))
472                                             continue;
473                                         else
474                                         if (!decimalPointFound && AllowDecimalPoint &&
475                                             FindOther (ref pos, s, nfi.NumberDecimalSeparator)) {
476                                             decimalPointFound = true;
477                                             continue;
478                                         }
479
480                                         break;
481                                 }
482                                 else if (AllowHexSpecifier) {
483                                         nDigits++;
484                                         hexDigit = s [pos++];
485                                         if (Char.IsDigit (hexDigit))
486                                                 digitValue = (int) (hexDigit - '0');
487                                         else if (Char.IsLower (hexDigit))
488                                                 digitValue = (int) (hexDigit - 'a' + 10);
489                                         else
490                                                 digitValue = (int) (hexDigit - 'A' + 10);
491
492                                         uint unumber = (uint)number;
493                                         if (tryParse){
494                                                 if ((unumber & 0xf0000000) != 0)
495                                                         return false;
496                                                 
497                                                 number = (int) (unumber * 16u + (uint) digitValue);
498                                         } else {
499                                                 number = (int)checked (unumber * 16u + (uint)digitValue);
500                                         }
501                                 }
502                                 else if (decimalPointFound) {
503                                         nDigits++;
504                                         // Allows decimal point as long as it's only 
505                                         // followed by zeroes.
506                                         if (s [pos++] != '0') {
507                                                 if (!tryParse)
508                                                         exc = new OverflowException ("Value too large or too " +
509                                                                         "small.");
510                                                 return false;
511                                         }
512                                 }
513                                 else {
514                                         nDigits++;
515
516                                         try {
517                                                 // Calculations done as negative
518                                                 // (abs (MinValue) > abs (MaxValue))
519                                                 number = checked (
520                                                         number * 10 - 
521                                                         (int) (s [pos++] - '0')
522                                                         );
523                                         } catch (OverflowException) {
524                                                 if (!tryParse)
525                                                         exc = new OverflowException ("Value too large or too " +
526                                                                         "small.");
527                                                 return false;
528                                         }
529                                 }
530                         } while (pos < s.Length);
531
532                         // Post number stuff
533                         if (nDigits == 0) {
534                                 if (!tryParse)
535                                         exc = GetFormatException ();
536                                 return false;
537                         }
538
539                         if (AllowExponent)
540                                 if (FindExponent (ref pos, s, ref exponent, tryParse, ref exc) && exc != null)
541                                         return false;
542
543                         if (AllowTrailingSign && !foundSign) {
544                                 // Sign + Currency
545                                 FindSign (ref pos, s, nfi, ref foundSign, ref negative);
546                                 if (foundSign) {
547                                         if (AllowTrailingWhite && !JumpOverWhite (ref pos, s, true, tryParse, ref exc))
548                                                 return false;
549                                         if (AllowCurrencySymbol)
550                                                 FindCurrency (ref pos, s, nfi,
551                                                               ref foundCurrency);
552                                 }
553                         }
554                         
555                         if (AllowCurrencySymbol && !foundCurrency) {
556                                 // Currency + sign
557                                 FindCurrency (ref pos, s, nfi, ref foundCurrency);
558                                 if (foundCurrency) {
559                                         if (AllowTrailingWhite && !JumpOverWhite (ref pos, s, true, tryParse, ref exc))
560                                                 return false;
561                                         if (!foundSign && AllowTrailingSign)
562                                                 FindSign (ref pos, s, nfi, ref foundSign,
563                                                           ref negative);
564                                 }
565                         }
566                         
567                         if (AllowTrailingWhite && pos < s.Length && !JumpOverWhite (ref pos, s, false, tryParse, ref exc))
568                                 return false;
569
570                         if (foundOpenParentheses) {
571                                 if (pos >= s.Length || s [pos++] != ')') {
572                                         if (!tryParse)
573                                                 exc = GetFormatException ();
574                                         return false;
575                                 }
576                                 if (AllowTrailingWhite && pos < s.Length &&
577                                                 !JumpOverWhite (ref pos, s, false, tryParse, ref exc))
578                                         return false;
579                         }
580
581                         if (pos < s.Length && s [pos] != '\u0000') {
582                                 if (!tryParse)
583                                         exc = GetFormatException ();
584                                 return false;
585                         }
586                         
587                         if (!negative && !AllowHexSpecifier){
588                                 if (tryParse){
589                                         long lval = -((long)number);
590
591                                         if (lval < MinValue || lval > MaxValue)
592                                                 return false;
593                                         number = (int) lval;
594                                 } else
595                                         number = checked (-number);
596                         }
597
598                         // result *= 10^exponent
599                         if (exponent > 0) {
600                                 // Reduce the risk of throwing an overflow exc
601                                 double res = checked (Math.Pow (10, exponent) * number);
602                                 if (res < Int32.MinValue || res > Int32.MaxValue) {
603                                         if (!tryParse)
604                                                 exc = new OverflowException ("Value too large or too small.");
605                                         return false;
606                                 }
607
608                                 number = (int)res;
609                         }
610                         
611                         result = number;
612
613                         return true;
614                 }
615
616                 public static int Parse (string s) 
617                 {
618                         Exception exc;
619                         int res;
620
621                         if (!Parse (s, false, out res, out exc))
622                                 throw exc;
623
624                         return res;
625                 }
626
627                 public static int Parse (string s, NumberStyles style, IFormatProvider provider) 
628                 {
629                         Exception exc;
630                         int res;
631
632                         if (!Parse (s, style, provider, false, out res, out exc))
633                                 throw exc;
634
635                         return res;
636                 }
637
638                 public static bool TryParse (string s, out int result) 
639                 {
640                         Exception exc;
641                         
642                         if (!Parse (s, true, out result, out exc)) {
643                                 result = 0;
644                                 return false;
645                         }
646
647                         return true;
648                 }
649
650                 public static bool TryParse (string s, NumberStyles style, IFormatProvider provider, out int result) 
651                 {
652                         Exception exc;
653                         if (!Parse (s, style, provider, true, out result, out exc)) {
654                                 result = 0;
655                                 return false;
656                         }
657
658                         return true;
659                 }
660
661                 public override string ToString ()
662                 {
663                         return NumberFormatter.NumberToString (m_value, null);
664                 }
665
666                 public string ToString (IFormatProvider provider)
667                 {
668                         return NumberFormatter.NumberToString (m_value, provider);
669                 }
670
671                 public string ToString (string format)
672                 {
673                         return ToString (format, null);
674                 }
675
676                 public string ToString (string format, IFormatProvider provider)
677                 {
678                         return NumberFormatter.NumberToString (format, m_value, provider);
679                 }
680
681                 // =========== IConvertible Methods =========== //
682
683                 public TypeCode GetTypeCode ()
684                 {
685                         return TypeCode.Int32;
686                 }
687
688                 bool IConvertible.ToBoolean (IFormatProvider provider)
689                 {
690                         return System.Convert.ToBoolean (m_value);
691                 }
692
693                 byte IConvertible.ToByte (IFormatProvider provider)
694                 {
695                         return System.Convert.ToByte (m_value);
696                 }
697
698                 char IConvertible.ToChar (IFormatProvider provider)
699                 {
700                         return System.Convert.ToChar (m_value);
701                 }
702
703                 DateTime IConvertible.ToDateTime (IFormatProvider provider)
704                 {
705                         return System.Convert.ToDateTime (m_value);
706                 }
707
708                 decimal IConvertible.ToDecimal (IFormatProvider provider)
709                 {
710                         return System.Convert.ToDecimal (m_value);
711                 }
712
713                 double IConvertible.ToDouble (IFormatProvider provider)
714                 {
715                         return System.Convert.ToDouble (m_value);
716                 }
717
718                 short IConvertible.ToInt16 (IFormatProvider provider)
719                 {
720                         return System.Convert.ToInt16 (m_value);
721                 }
722
723                 int IConvertible.ToInt32 (IFormatProvider provider)
724                 {
725                         return m_value;
726                 }
727
728                 long IConvertible.ToInt64 (IFormatProvider provider)
729                 {
730                         return System.Convert.ToInt64 (m_value);
731                 }
732
733                 sbyte IConvertible.ToSByte (IFormatProvider provider)
734                 {
735                         return System.Convert.ToSByte (m_value);
736                 }
737
738                 float IConvertible.ToSingle (IFormatProvider provider)
739                 {
740                         return System.Convert.ToSingle (m_value);
741                 }
742
743                 object IConvertible.ToType (Type targetType, IFormatProvider provider)
744                 {
745                         if (targetType == null)
746                                 throw new ArgumentNullException ("targetType");
747                         return System.Convert.ToType (m_value, targetType, provider, false);
748                 }
749
750                 ushort IConvertible.ToUInt16 (IFormatProvider provider)
751                 {
752                         return System.Convert.ToUInt16 (m_value);
753                 }
754
755                 uint IConvertible.ToUInt32 (IFormatProvider provider)
756                 {
757                         return System.Convert.ToUInt32 (m_value);
758                 }
759
760                 ulong IConvertible.ToUInt64 (IFormatProvider provider)
761                 {
762                         return System.Convert.ToUInt64 (m_value);
763                 }
764         }
765 }