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