Add TryFormat methods to {S}Byte, {U}Int16/32/64, and Boolean
authorStephen Toub <stoub@microsoft.com>
Thu, 16 Nov 2017 18:59:51 +0000 (13:59 -0500)
committerStephen Toub <stoub@microsoft.com>
Sat, 18 Nov 2017 22:59:16 +0000 (17:59 -0500)
src/mscorlib/shared/System/Boolean.cs
src/mscorlib/shared/System/Byte.cs
src/mscorlib/shared/System/Int16.cs
src/mscorlib/shared/System/Int32.cs
src/mscorlib/shared/System/Int64.cs
src/mscorlib/shared/System/Number.Formatting.cs
src/mscorlib/shared/System/SByte.cs
src/mscorlib/shared/System/Text/ValueStringBuilder.cs
src/mscorlib/shared/System/UInt16.cs
src/mscorlib/shared/System/UInt32.cs
src/mscorlib/shared/System/UInt64.cs

index 70edd94..896e5f1 100644 (file)
@@ -12,7 +12,7 @@
 ** 
 ===========================================================*/
 
-using System.Globalization;
+using System.Diagnostics;
 using System.Runtime.CompilerServices;
 using System.Runtime.Versioning;
 
@@ -96,6 +96,24 @@ namespace System
             return ToString();
         }
 
+        public bool TryFormat(Span<char> destination, out int charsWritten)
+        {
+            string s = m_value ? TrueLiteral : FalseLiteral;
+
+            if (s.Length <= destination.Length)
+            {
+                bool copied = s.AsReadOnlySpan().TryCopyTo(destination);
+                Debug.Assert(copied);
+                charsWritten = s.Length;
+                return true;
+            }
+            else
+            {
+                charsWritten = 0;
+                return false;
+            }
+        }
+
         // Determines whether two Boolean objects are equal.
         public override bool Equals(Object obj)
         {
index e32ab2b..30ec6b7 100644 (file)
@@ -196,6 +196,11 @@ namespace System
             return Number.FormatInt32(m_value, format, NumberFormatInfo.GetInstance(provider));
         }
 
+        public bool TryFormat(Span<char> destination, out int charsWritten, string format = null, IFormatProvider provider = null)
+        {
+            return Number.TryFormatInt32(m_value, format, NumberFormatInfo.GetInstance(provider), destination, out charsWritten);
+        }
+
         //
         // IConvertible implementation
         // 
index fb0aa11..19e1b05 100644 (file)
@@ -87,6 +87,18 @@ namespace System
             return ToString(format, NumberFormatInfo.GetInstance(provider));
         }
 
+        public bool TryFormat(Span<char> destination, out int charsWritten, string format = null, IFormatProvider provider = null)
+        {
+            NumberFormatInfo info = NumberFormatInfo.GetInstance(provider);
+
+            if (m_value < 0 && format != null && format.Length > 0 && (format[0] == 'X' || format[0] == 'x'))
+            {
+                uint temp = (uint)(m_value & 0x0000FFFF);
+                return Number.TryFormatUInt32(temp, format, info, destination, out charsWritten);
+            }
+            return Number.TryFormatInt32(m_value, format, info, destination, out charsWritten);
+        }
+
         private String ToString(String format, NumberFormatInfo info)
         {
             if (m_value < 0 && format != null && format.Length > 0 && (format[0] == 'X' || format[0] == 'x'))
index cb5db68..fab38c4 100644 (file)
@@ -96,6 +96,11 @@ namespace System
             return Number.FormatInt32(m_value, format, NumberFormatInfo.GetInstance(provider));
         }
 
+        public bool TryFormat(Span<char> destination, out int charsWritten, string format = null, IFormatProvider provider = null)
+        {
+            return Number.TryFormatInt32(m_value, format, NumberFormatInfo.GetInstance(provider), destination, out charsWritten);
+        }
+
         public static int Parse(String s)
         {
             if (s == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.s);
index b6275f4..1f33b48 100644 (file)
@@ -93,6 +93,11 @@ namespace System
             return Number.FormatInt64(m_value, format, NumberFormatInfo.GetInstance(provider));
         }
 
+        public bool TryFormat(Span<char> destination, out int charsWritten, string format = null, IFormatProvider provider = null)
+        {
+            return Number.TryFormatInt64(m_value, format, NumberFormatInfo.GetInstance(provider), destination, out charsWritten);
+        }
+
         public static long Parse(String s)
         {
             if (s == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.s);
index f4221f6..a49f4a0 100644 (file)
@@ -74,9 +74,51 @@ namespace System
             {
                 NumberBuffer number = default;
                 Int32ToNumber(value, ref number);
-                return fmt != 0 ?
-                    NumberToString(ref number, fmt, digits, info, false) :
-                    NumberToStringFormat(ref number, format, info);
+                var sb = new ValueStringBuilder(s_numberToStringScratch);
+                if (fmt != 0)
+                {
+                    NumberToString(ref sb, ref number, fmt, digits, info, false);
+                }
+                else
+                {
+                    NumberToStringFormat(ref sb, ref number, format, info);
+                }
+                return sb.GetString();
+            }
+        }
+
+        public static bool TryFormatInt32(int value, string format, NumberFormatInfo info, Span<char> destination, out int charsWritten)
+        {
+            int digits;
+            char fmt = ParseFormatSpecifier(format, out digits);
+
+            char fmtUpper = (char)(fmt & 0xFFDF); // ensure fmt is upper-cased for purposes of comparison
+            if ((fmtUpper == 'G' && digits < 1) || fmtUpper == 'D')
+            {
+                return value >= 0 ?
+                    TryUInt32ToDecStr((uint)value, digits, destination, out charsWritten) :
+                    TryNegativeInt32ToDecStr(value, digits, info.NegativeSign, destination, out charsWritten);
+            }
+            else if (fmtUpper == 'X')
+            {
+                // The fmt-(X-A+10) hack has the effect of dictating whether we produce uppercase or lowercase
+                // hex numbers for a-f. 'X' as the fmt code produces uppercase. 'x' as the format code produces lowercase.
+                return TryInt32ToHexStr(value, (char)(fmt - ('X' - 'A' + 10)), digits, destination, out charsWritten);
+            }
+            else
+            {
+                NumberBuffer number = default;
+                Int32ToNumber(value, ref number);
+                var sb = new ValueStringBuilder(s_numberToStringScratch);
+                if (fmt != 0)
+                {
+                    NumberToString(ref sb, ref number, fmt, digits, info, false);
+                }
+                else
+                {
+                    NumberToStringFormat(ref sb, ref number, format, info);
+                }
+                return sb.TryCopyTo(destination, out charsWritten);
             }
         }
 
@@ -100,9 +142,49 @@ namespace System
             {
                 NumberBuffer number = default;
                 UInt32ToNumber(value, ref number);
-                return fmt != 0 ?
-                    NumberToString(ref number, fmt, digits, info, false) :
-                    NumberToStringFormat(ref number, format, info);
+                var sb = new ValueStringBuilder(s_numberToStringScratch);
+                if (fmt != 0)
+                {
+                    NumberToString(ref sb, ref number, fmt, digits, info, false);
+                }
+                else
+                {
+                    NumberToStringFormat(ref sb, ref number, format, info);
+                }
+                return sb.GetString();
+            }
+        }
+
+        public static bool TryFormatUInt32(uint value, string format, NumberFormatInfo info, Span<char> destination, out int charsWritten)
+        {
+            int digits;
+            char fmt = ParseFormatSpecifier(format, out digits);
+
+            char fmtUpper = (char)(fmt & 0xFFDF); // ensure fmt is upper-cased for purposes of comparison
+            if ((fmtUpper == 'G' && digits < 1) || fmtUpper == 'D')
+            {
+                return TryUInt32ToDecStr(value, digits, destination, out charsWritten);
+            }
+            else if (fmtUpper == 'X')
+            {
+                // The fmt-(X-A+10) hack has the effect of dictating whether we produce uppercase or lowercase
+                // hex numbers for a-f. 'X' as the fmt code produces uppercase. 'x' as the format code produces lowercase.
+                return TryInt32ToHexStr((int)value, (char)(fmt - ('X' - 'A' + 10)), digits, destination, out charsWritten);
+            }
+            else
+            {
+                NumberBuffer number = default;
+                UInt32ToNumber(value, ref number);
+                var sb = new ValueStringBuilder(s_numberToStringScratch);
+                if (fmt != 0)
+                {
+                    NumberToString(ref sb, ref number, fmt, digits, info, false);
+                }
+                else
+                {
+                    NumberToStringFormat(ref sb, ref number, format, info);
+                }
+                return sb.TryCopyTo(destination, out charsWritten);
             }
         }
 
@@ -129,9 +211,52 @@ namespace System
             {
                 NumberBuffer number = default;
                 Int64ToNumber(value, ref number);
-                return fmt != 0 ?
-                    NumberToString(ref number, fmt, digits, info, false) :
-                    NumberToStringFormat(ref number, format, info);
+                var sb = new ValueStringBuilder(s_numberToStringScratch);
+                if (fmt != 0)
+                {
+                    NumberToString(ref sb, ref number, fmt, digits, info, false);
+                }
+                else
+                {
+                    NumberToStringFormat(ref sb, ref number, format, info);
+                }
+                return sb.GetString();
+            }
+        }
+
+        public static bool TryFormatInt64(long value, string format, NumberFormatInfo info, Span<char> destination, out int charsWritten)
+        {
+            int digits;
+            char fmt = ParseFormatSpecifier(format, out digits);
+
+            char fmtUpper = (char)(fmt & 0xFFDF); // ensure fmt is upper-cased for purposes of comparison
+            if ((fmtUpper == 'G' && digits < 1) || fmtUpper == 'D')
+            {
+                return value >= 0 ?
+                    TryUInt64ToDecStr((ulong)value, digits, destination, out charsWritten) :
+                    TryNegativeInt64ToDecStr(value, digits, info.NegativeSign, destination, out charsWritten);
+            }
+            else if (fmtUpper == 'X')
+            {
+                // The fmt-(X-A+10) hack has the effect of dictating whether we produce uppercase or lowercase
+                // hex numbers for a-f. 'X' as the fmt code produces uppercase. 'x' as the format code
+                // produces lowercase.
+                return TryInt64ToHexStr(value, (char)(fmt - ('X' - 'A' + 10)), digits, destination, out charsWritten);
+            }
+            else
+            {
+                NumberBuffer number = default;
+                Int64ToNumber(value, ref number);
+                var sb = new ValueStringBuilder(s_numberToStringScratch);
+                if (fmt != 0)
+                {
+                    NumberToString(ref sb, ref number, fmt, digits, info, false);
+                }
+                else
+                {
+                    NumberToStringFormat(ref sb, ref number, format, info);
+                }
+                return sb.TryCopyTo(destination, out charsWritten);
             }
         }
 
@@ -156,9 +281,50 @@ namespace System
             {
                 NumberBuffer number = default;
                 UInt64ToNumber(value, ref number);
-                return fmt != 0 ?
-                    NumberToString(ref number, fmt, digits, info, false) :
-                    NumberToStringFormat(ref number, format, info);
+                var sb = new ValueStringBuilder(s_numberToStringScratch);
+                if (fmt != 0)
+                {
+                    NumberToString(ref sb, ref number, fmt, digits, info, false);
+                }
+                else
+                {
+                    NumberToStringFormat(ref sb, ref number, format, info);
+                }
+                return sb.GetString();
+            }
+        }
+
+        public static bool TryFormatUInt64(ulong value, string format, NumberFormatInfo info, Span<char> destination, out int charsWritten)
+        {
+            int digits;
+            char fmt = ParseFormatSpecifier(format, out digits);
+
+            char fmtUpper = (char)(fmt & 0xFFDF); // ensure fmt is upper-cased for purposes of comparison
+            if ((fmtUpper == 'G' && digits < 1) || fmtUpper == 'D')
+            {
+                return TryUInt64ToDecStr(value, digits, destination, out charsWritten);
+            }
+            else if (fmtUpper == 'X')
+            {
+                // The fmt-(X-A+10) hack has the effect of dictating whether we produce uppercase or lowercase
+                // hex numbers for a-f. 'X' as the fmt code produces uppercase. 'x' as the format code
+                // produces lowercase.
+                return TryInt64ToHexStr((long)value, (char)(fmt - ('X' - 'A' + 10)), digits, destination, out charsWritten);
+            }
+            else
+            {
+                NumberBuffer number = default;
+                UInt64ToNumber(value, ref number);
+                var sb = new ValueStringBuilder(s_numberToStringScratch);
+                if (fmt != 0)
+                {
+                    NumberToString(ref sb, ref number, fmt, digits, info, false);
+                }
+                else
+                {
+                    NumberToStringFormat(ref sb, ref number, format, info);
+                }
+                return sb.TryCopyTo(destination, out charsWritten);
             }
         }
 
@@ -210,6 +376,27 @@ namespace System
             return new string(p, 0, (int)(buffer + bufferLength - p));
         }
 
+        private static unsafe bool TryNegativeInt32ToDecStr(int value, int digits, string sNegative, Span<char> destination, out int charsWritten)
+        {
+            Debug.Assert(value < 0);
+
+            if (digits < 1)
+                digits = 1;
+
+            int bufferLength = Math.Max(digits, MaxUInt32DecDigits) + sNegative.Length;
+            int index = bufferLength;
+
+            char* buffer = stackalloc char[bufferLength];
+            char* p = UInt32ToDecChars(buffer + bufferLength, (uint)(-value), digits);
+            for (int i = sNegative.Length - 1; i >= 0; i--)
+            {
+                *(--p) = sNegative[i];
+            }
+
+            Debug.Assert(buffer + bufferLength - p >= 0 && buffer <= p);
+            return TryCopyTo(p, (int)(buffer + bufferLength - p), destination, out charsWritten);
+        }
+
         private static unsafe string Int32ToHexStr(int value, char hexBase, int digits)
         {
             if (digits < 1)
@@ -222,6 +409,18 @@ namespace System
             return new string(p, 0, (int)(buffer + bufferLength - p));
         }
 
+        private static unsafe bool TryInt32ToHexStr(int value, char hexBase, int digits, Span<char> destination, out int charsWritten)
+        {
+            if (digits < 1)
+                digits = 1;
+
+            int bufferLength = Math.Max(digits, MaxUInt32HexDigits);
+            char* buffer = stackalloc char[bufferLength];
+
+            char* p = Int32ToHexChars(buffer + bufferLength, (uint)value, hexBase, digits);
+            return TryCopyTo(p, (int)(buffer + bufferLength - p), destination, out charsWritten);
+        }
+
         private static unsafe char* Int32ToHexChars(char* buffer, uint value, int hexBase, int digits)
         {
             while (--digits >= 0 || value != 0)
@@ -290,6 +489,49 @@ namespace System
             }
         }
 
+        private static unsafe bool TryUInt32ToDecStr(uint value, int digits, Span<char> destination, out int charsWritten)
+        {
+            if (digits <= 1)
+            {
+                char* buffer = stackalloc char[MaxUInt32DecDigits];
+                char* start = buffer + MaxUInt32DecDigits;
+                char* p = start;
+                do
+                {
+                    // TODO https://github.com/dotnet/coreclr/issues/3439
+                    uint div = value / 10;
+                    *(--p) = (char)('0' + value - (div * 10));
+                    value = div;
+                }
+                while (value != 0);
+                return TryCopyTo(p, (int)(start - p), destination, out charsWritten);
+            }
+            else
+            {
+                int bufferSize = Math.Max(digits, MaxUInt32DecDigits);
+                char* buffer = stackalloc char[bufferSize];
+                char* p = UInt32ToDecChars(buffer + bufferSize, value, digits);
+                return TryCopyTo(p, (int)(buffer + bufferSize - p), destination, out charsWritten);
+            }
+        }
+
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        private static unsafe bool TryCopyTo(char* src, int length, Span<char> destination, out int charsWritten)
+        {
+            if (length <= destination.Length)
+            {
+                bool copied = new ReadOnlySpan<char>(src, length).TryCopyTo(destination);
+                Debug.Assert(copied);
+                charsWritten = length;
+                return true;
+            }
+            else
+            {
+                charsWritten = 0;
+                return false;
+            }
+        }
+
         private static unsafe void Int64ToNumber(long input, ref NumberBuffer number)
         {
             ulong value = (ulong)input;
@@ -346,6 +588,37 @@ namespace System
             return new string(p, 0, (int)(buffer + bufferLength - p));
         }
 
+        private static unsafe bool TryNegativeInt64ToDecStr(long input, int digits, string sNegative, Span<char> destination, out int charsWritten)
+        {
+            Debug.Assert(input < 0);
+
+            if (digits < 1)
+            {
+                digits = 1;
+            }
+
+            ulong value = (ulong)(-input);
+
+            int bufferLength = Math.Max(digits, MaxUInt64DecDigits) + sNegative.Length;
+            int index = bufferLength;
+
+            char* buffer = stackalloc char[bufferLength];
+            char* p = buffer + bufferLength;
+            while (High32(value) != 0)
+            {
+                p = UInt32ToDecChars(p, Int64DivMod1E9(ref value), 9);
+                digits -= 9;
+            }
+            p = UInt32ToDecChars(p, Low32(value), digits);
+
+            for (int i = sNegative.Length - 1; i >= 0; i--)
+            {
+                *(--p) = sNegative[i];
+            }
+
+            return TryCopyTo(p, (int)(buffer + bufferLength - p), destination, out charsWritten);
+        }
+
         private static unsafe string Int64ToHexStr(long value, char hexBase, int digits)
         {
             int bufferLength = Math.Max(digits, MaxUInt32HexDigits * 2);
@@ -360,14 +633,32 @@ namespace System
             }
             else
             {
-                if (digits < 1)
-                    digits = 1;
-                p = Int32ToHexChars(buffer + index, Low32((ulong)value), hexBase, digits);
+                p = Int32ToHexChars(buffer + index, Low32((ulong)value), hexBase, Math.Max(digits, 1));
             }
 
             return new string(p, 0, (int)(buffer + bufferLength - p));
         }
 
+        private static unsafe bool TryInt64ToHexStr(long value, char hexBase, int digits, Span<char> destination, out int charsWritten)
+        {
+            int bufferLength = Math.Max(digits, MaxUInt32HexDigits * 2);
+            char* buffer = stackalloc char[bufferLength];
+            int index = bufferLength;
+
+            char* p;
+            if (High32((ulong)value) != 0)
+            {
+                p = Int32ToHexChars(buffer + index, Low32((ulong)value), hexBase, 8);
+                p = Int32ToHexChars(p, High32((ulong)value), hexBase, digits - 8);
+            }
+            else
+            {
+                p = Int32ToHexChars(buffer + index, Low32((ulong)value), hexBase, Math.Max(digits, 1));
+            }
+
+            return TryCopyTo(p, (int)(buffer + bufferLength - p), destination, out charsWritten);
+        }
+
         private static unsafe void UInt64ToNumber(ulong value, ref NumberBuffer number)
         {
             number.precision = UInt64Precision;
@@ -407,6 +698,24 @@ namespace System
             return new string(p, 0, (int)(buffer + bufferSize - p));
         }
 
+        private static unsafe bool TryUInt64ToDecStr(ulong value, int digits, Span<char> destination, out int charsWritten)
+        {
+            if (digits < 1)
+                digits = 1;
+
+            int bufferSize = Math.Max(digits, MaxUInt64DecDigits);
+            char* buffer = stackalloc char[bufferSize];
+            char* p = buffer + bufferSize;
+            while (High32(value) != 0)
+            {
+                p = UInt32ToDecChars(p, Int64DivMod1E9(ref value), 9);
+                digits -= 9;
+            }
+            p = UInt32ToDecChars(p, Low32(value), digits);
+
+            return TryCopyTo(p, (int)(buffer + bufferSize - p), destination, out charsWritten);
+        }
+
         internal static unsafe char ParseFormatSpecifier(string format, out int digits)
         {
             if (format != null)
@@ -448,10 +757,9 @@ namespace System
             return 'G';
         }
 
-        internal static unsafe string NumberToString(ref NumberBuffer number, char format, int nMaxDigits, NumberFormatInfo info, bool isDecimal)
+        internal static unsafe void NumberToString(ref ValueStringBuilder sb, ref NumberBuffer number, char format, int nMaxDigits, NumberFormatInfo info, bool isDecimal)
         {
             int nMinDigits = -1;
-            var sb = new ValueStringBuilder(s_numberToStringScratch);
 
             switch (format)
             {
@@ -581,11 +889,9 @@ namespace System
                 default:
                     throw new FormatException(SR.Argument_BadFormatSpecifier);
             }
-
-            return sb.GetString();
         }
 
-        internal static unsafe string NumberToStringFormat(ref NumberBuffer number, string format, NumberFormatInfo info)
+        internal static unsafe void NumberToStringFormat(ref ValueStringBuilder sb, ref NumberBuffer number, string format, NumberFormatInfo info)
         {
             int digitCount;
             int decimalPos;
@@ -782,9 +1088,7 @@ namespace System
                     }
                 }
             }
-
-            var sb = new ValueStringBuilder(s_numberToStringScratch);
-
+            
             if (number.sign && section == 0)
                 sb.Append(info.NegativeSign);
 
@@ -940,8 +1244,6 @@ namespace System
                     }
                 }
             }
-
-            return sb.GetString();
         }
 
         private static void FormatCurrency(ref ValueStringBuilder sb, ref NumberBuffer number, int nMinDigits, int nMaxDigits, NumberFormatInfo info)
index 1d3fded..5e9e446 100644 (file)
@@ -91,6 +91,18 @@ namespace System
             return ToString(format, NumberFormatInfo.GetInstance(provider));
         }
 
+        public bool TryFormat(Span<char> destination, out int charsWritten, string format = null, IFormatProvider provider = null)
+        {
+            NumberFormatInfo info = NumberFormatInfo.GetInstance(provider);
+
+            if (m_value < 0 && format != null && format.Length > 0 && (format[0] == 'X' || format[0] == 'x'))
+            {
+                uint temp = (uint)(m_value & 0x000000FF);
+                return Number.TryFormatUInt32(temp, format, info, destination, out charsWritten);
+            }
+            return Number.TryFormatInt32(m_value, format, info, destination, out charsWritten);
+        }
+
         private String ToString(String format, NumberFormatInfo info)
         {
             if (m_value < 0 && format != null && format.Length > 0 && (format[0] == 'X' || format[0] == 'x'))
index 8e1b96b..0ee9c81 100644 (file)
@@ -36,6 +36,29 @@ namespace System.Text
             return s;
         }
 
+        public bool TryCopyTo(Span<char> destination, out int charsWritten)
+        {
+            if (_pos > destination.Length)
+            {
+                charsWritten = 0;
+                return false;
+            }
+
+            bool copied = _chars.Slice(0, _pos).TryCopyTo(destination);
+            Debug.Assert(copied);
+            charsWritten = _pos;
+
+            char[] toReturn = _arrayToReturnToPool;
+            this = default; // for safety, to avoid using pooled array if this instance is erroneously appended to again
+
+            if (toReturn != null)
+            {
+                ArrayPool<char>.Shared.Return(toReturn);
+            }
+
+            return true;
+        }
+
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
         public void Append(char c)
         {
index b06b625..91ef123 100644 (file)
@@ -88,6 +88,11 @@ namespace System
             return Number.FormatUInt32(m_value, format, NumberFormatInfo.GetInstance(provider));
         }
 
+        public bool TryFormat(Span<char> destination, out int charsWritten, string format = null, IFormatProvider provider = null)
+        {
+            return Number.TryFormatUInt32(m_value, format, NumberFormatInfo.GetInstance(provider), destination, out charsWritten);
+        }
+
         [CLSCompliant(false)]
         public static ushort Parse(String s)
         {
index 04f459d..7461dea 100644 (file)
@@ -96,6 +96,11 @@ namespace System
             return Number.FormatUInt32(m_value, format, NumberFormatInfo.GetInstance(provider));
         }
 
+        public bool TryFormat(Span<char> destination, out int charsWritten, string format = null, IFormatProvider provider = null)
+        {
+            return Number.TryFormatUInt32(m_value, format, NumberFormatInfo.GetInstance(provider), destination, out charsWritten);
+        }
+
         [CLSCompliant(false)]
         public static uint Parse(String s)
         {
index fbaf542..1870cf3 100644 (file)
@@ -94,6 +94,11 @@ namespace System
             return Number.FormatUInt64(m_value, format, NumberFormatInfo.GetInstance(provider));
         }
 
+        public bool TryFormat(Span<char> destination, out int charsWritten, string format = null, IFormatProvider provider = null)
+        {
+            return Number.TryFormatUInt64(m_value, format, NumberFormatInfo.GetInstance(provider), destination, out charsWritten);
+        }
+
         [CLSCompliant(false)]
         public static ulong Parse(String s)
         {